Справка по z-борьбе с каркасом DirectX11 (или почему D3D11_RASTERIZER_DESC.DepthBias — это INT?)

Я пытаюсь использовать свойство DepthBias в состоянии растеризатора в DirectX 11 (D3D11_RASTERIZER_DESC), чтобы помочь с z-борьбой, которая возникает, когда я выполняю рендеринг в режиме каркаса над сплошными полигонами (наложение каркаса), и, кажется, устанавливаю для него любое значение. ничего не меняет в результате. Но я заметил кое-что странное... значение определяется как INT, а не как FLOAT. Это не имеет для меня смысла, но все равно не работает так, как ожидалось. Как нам правильно установить это значение, если это INT, которое нужно интерпретировать как UNORM в конвейере шейдера?

Вот что я делаю:

  1. Рендеринг всей геометрии
  2. Установите растеризатор для рендеринга в каркасе
  3. Рендеринг всей геометрии заново

Я ясно вижу наложение каркаса, но z-борьба ужасна. Я пытался установить DepthBias на множество разных значений, таких как 0.000001, 0.1, 1, 10, 1000 и все минус эквиваленты, все равно никаких результатов... очевидно, я знаю, что при преобразовании числа с плавающей запятой как целого числа десятичные дроби обрезаются... а?

D3D11_RASTERIZER_DESC RasterizerDesc;
ZeroMemory(&RasterizerDesc, sizeof(RasterizerDesc));
RasterizerDesc.FillMode = D3D11_FILL_WIREFRAME;
RasterizerDesc.CullMode = D3D11_CULL_BACK;
RasterizerDesc.FrontCounterClockwise = FALSE;
RasterizerDesc.DepthBias = ???
RasterizerDesc.SlopeScaledDepthBias = 0.0f;
RasterizerDesc.DepthBiasClamp = 0.0f;
RasterizerDesc.DepthClipEnable = TRUE;
RasterizerDesc.ScissorEnable = FALSE;
RasterizerDesc.MultisampleEnable = FALSE;
RasterizerDesc.AntialiasedLineEnable = FALSE;

Кто-нибудь разобрался, как правильно настроить DepthBias? Или, возможно, это ошибка в DirectX (в чем я сомневаюсь), или, может быть, есть лучший способ добиться этого, чем использование DepthBias?

Спасибо!


person Deathicon    schedule 19.06.2013    source источник


Ответы (2)


http://msdn.microsoft.com/en-us/library/windows/desktop/cc308048(v=vs.85).aspx

В зависимости от того, является ли ваш буфер глубины UNORM или с плавающей запятой, значение числа меняется. В большинстве случаев вы просто ищете наименьшее возможное значение, которое избавит вас от z-борьбы, а не какое-то конкретное значение. Маленькие значения — это маленькое смещение, большие значения — это большое смещение, но то, как это соответствует смещению в числовом выражении, зависит от формата вашего буфера глубины.

Что касается значений, которые вы пробовали, все, что меньше 1, округлялось бы до нуля и не имело никакого эффекта. 1, 10, 1000 может просто не хватить для решения проблемы. В случае буфера глубины D24 UNORM формула предполагает, что смещение глубины, равное 1000, компенсирует глубину на: 1000 * (1/2^24), что равно 0,0000596, не очень значительный сдвиг в терминах z-буферизации.

Исправит ли большое значение 100 000 или 1 000 000 Z-борьбу?

person Adam Miles    schedule 19.06.2013
comment
Да, это сработало. Я использую буфер глубины D32_FLOAT, так что это мне помогло. Благодаря вашему объяснению я теперь понимаю это намного лучше, спасибо! - person Deathicon; 20.06.2013

Если кому интересно, я сделал себе макрос, чтобы было проще. Обратите внимание, что этот макрос будет работать, только если вы используете 32-битный формат буфера глубины с плавающей запятой. Если вы используете другой формат буфера глубины, может потребоваться другой макрос.

#define DEPTH_BIAS_D32_FLOAT(d) (d/(1/pow(2,23)))

Таким образом, вы можете просто установить смещение глубины, используя стандартные значения, такие как:

RasterizerDesc.DepthBias = DEPTH_BIAS_D32_FLOAT(-0.00001);
person Deathicon    schedule 20.06.2013