[DX10] HLSL: gradient based operation error

Recommended Posts

Hello, I'm writing a pixel shader for lighting, and if the light distance attentuation is zero I want to skip all the calculation and just return a black color. The problem is that I get this error: warning X4121: gradient based operation must be moved outside of flow control to prevent divergence. Performance may be improved by using a non-gradient operation. This pixel shader uses more textures to compute lighting (pos and normals are from texture beacause of deferred rendering). I've used the [flatten] attribute on the if statement but as far I as understand the documentation this will also execute all lighting code. Any ideas how I can overcome this?

Share on other sites
Got the exact same problem here... at the end I just dropped the "if" and do the calculations even if the light is too far. Is it better to have a warning or to skip complex code?

Share on other sites

When you do a regular texture sampling operation (Texture2D.Sample), gradients are calculated using the partial derivatives of the texture coordinates in screen space. These derivatives determine which mipmap level to use. When you're using dynamic branching, your shader can't automatically calculate derivatives for texture coordinates inside a dynamic branch. This is because adjacent pixels in a quad might not take the same branch.

You have two easy solutions:

-Explicitly calculate the derivatives outside the branch, and pass them in to Texture2D.SampleGrad.

-Just use Texture2D.SampleLevel and explicitly specify the mipmap level. Since you're sampling G-Buffer textures, your probably don't have mipmaps which means this would be your best option.

Edited by MJP

Share on other sites
First, sorry to hijack the OP thread but I guess it's better if I ask here cause it's related.

float2 GetFilterSize(float2 dx, float2 dy, float2 TexSize){    return 2 * (abs(dx) + abs(dy)) * TexSize;}

dx and dy are the already calculated derivative values of the uvs using ddx() and ddy(). Texture reading is done using .Load (no sample) after. Both ddx() and .Load() can be in a "if" branch without warning, but not the simple math function above. Why?

Share on other sites
Texture2D.SampleLevel does the trick, thanks MJP

Create an account

Register a new account

• Partner Spotlight

• Forum Statistics

• Total Topics
627652
• Total Posts
2978421

• 10
• 12
• 22
• 13
• 33