Advertisement

Comparing depth bias in DX vs Vulkan

Started by November 02, 2017 12:02 PM
5 comments, last by Hodgman 7 years, 3 months ago

Hi,

As part of writing a unified interface on top of DirectX (11 and 12) as well as Vulkan I have noticed that they represent depth bias in the rasterizer state quite differently. Depth bias in DX is described here: https://msdn.microsoft.com/en-us/library/windows/desktop/cc308048(v=vs.85).aspx and a typical values seems to be in the tens of thousands.

For the Vulkan counterpart I haven't seen any as in-depth explanation. The reference page for VkPipelineRasterizationStateCreateInfo, https://www.khronos.org/registry/vulkan/specs/1.0/man/html/VkPipelineRasterizationStateCreateInfo.html, simply states that "depthBiasConstantFactor is a scalar factor controlling the constant depth value added to each fragment". The value is in floating point and a typical value seems to be around 2.0-3.0.

I have a PSO description struct containing a value for the depth bias and I would like to convert it into the format each graphics API expects, but I am unsure what that conversion is. Eg. how would I convert Vulkan's representation (not even sure what unit it is in, some fraction of the depth buffer) into the one used by DirectX?

Cheers!

D3D11:

Bias = (float)DepthBias * r + SlopeScaledDepthBias * MaxDepthSlope;
where r is the minimum representable value > 0 in the depth-buffer format converted to float32.

For a 24-bit depth buffer, r = 1 / 2^24.
Example: DepthBias = 100000 ==> Actual DepthBias = 100000/2^24 = .006

For a 16-bit depth buffer, r = 1 / 2^16.
Example: DepthBias = 100000 ==> Actual DepthBias = 100000/2^16 = 1.52

 

 

🧙

Advertisement

Yes, that is all taken directly from the page I linked to. Is the "actual depthbias", as they call it, what Vulkan expects?

1 hour ago, GuyWithBeard said:

Yes, that is all taken directly from the page I linked to.

I needed the formula :P The actual bias stuff is not mentioned at your link.

The actual depth bias is the real addend for the depth. I have no idea what Vulkan uses or expects, but my guess is that you must be able to calculate something similar for all other APIs, because the rasterizer will add some value anyway.

🧙

I did some research and it actually seems like Vulkan works roughly the same as DX. The Vulkan programming guide contains the same formulas as the DX documentation: https://books.google.fi/books?id=XVBxDQAAQBAJ&pg=PT355&dq=vulkan+depth+bias&hl=en&sa=X&ved=0ahUKEwjw0JL4yqDXAhWIzaQKHf58BSwQ6AEIJzAA#v=onepage&q=vulkan depth bias&f=false

What through me off was the fact that in Vulkan the depth bias is a float while it is an int in DX. The DX documentation claims it is cast to float immediately so no idea why it is an int in the interface. Also, I stumbled upon some Vulkan samples that used a much smaller constant bias, but the slope bias was quite high. However, because the slope bias has a much larger weight than the constant one it pretty much worked the same.

After passing the same values to DX and Vulkan I now get (pretty much) the same visual result. Let me know if there is something I should be aware of.

47 minutes ago, GuyWithBeard said:

What through me off was the fact that in Vulkan the depth bias is a float while it is an int in DX. The DX documentation claims it is cast to float immediately so no idea why it is an int in the interface.

What's weirder is that in D3D9 it was actually a float, but passed through the API as a DWORD, so you had to set it like this:


float bias = 0.003f;
DWORD biasBits = *reinterpret_cast<DWORD*>&bias;
SetRenderState(D3DRS_DEPTHBIAS, biasBits);

:D

This topic is closed to new replies.

Advertisement