Some Problem when trying to implement ParallaxMapping

Recommended Posts

Hi, guys, I'm trying to implement parallax mapping in hlsl, I use the algorithm in "ParallaxOcclusionMapping" in D3D Sample, But I always get a complie error X3511: Unable to unroll loop, loop does not appear to terminate in a timely manner (1024 iterations). I have tried on RenderMonkey and D3D9,neither of them works. Here is my code(simplified, I just implemented the height profile-ray intersection):

Share this post

Link to post

Share on other sites

Next time please post the entire shader, since what you posted doesn't include the textures and constants that you use.

Anyway the problem is that you're using tex2D inside a loop, which isn't allowed since the hardware can't compute gradients for mipmapping inside of dynamic flow control (since neighboring pixels in a 2x2 quad might take different paths at a branch). You should compute the gradients outside the loop and pass them into tex2Dgrad, like the sample does. The reason the compiler isn't giving the right error message is because it's trying to be too clever for its own good. When you try to use gradient operations inside a branch or loop, it will try to either pull the operation out of the loop/branch or flatten/unroll the branch. In your particular case it tried to unroll, but it failed to do it since the loop is meant to be dynamic. If you force the compiler to try to use a dynamic loop instead of unrolling it by putting [loop] above the while loop, it gives the correct error message.

BTW once you fix that you'll also want to change "if(fCurrHeight > fCurrHeight)" to "if(fCurrHeight > fCurrBound)", otherwise it's never going to take that branch and the whole thing will get optimized away.

Share this post

Link to post

Share on other sites

Next time please post the entire shader, since what you posted doesn't include the textures and constants that you use.

Anyway the problem is that you're using tex2D inside a loop, which isn't allowed since the hardware can't compute gradients for mipmapping inside of dynamic flow control (since neighboring pixels in a 2x2 quad might take different paths at a branch). You should compute the gradients outside the loop and pass them into tex2Dgrad, like the sample does. The reason the compiler isn't giving the right error message is because it's trying to be too clever for its own good. When you try to use gradient operations inside a branch or loop, it will try to either pull the operation out of the loop/branch or flatten/unroll the branch. In your particular case it tried to unroll, but it failed to do it since the loop is meant to be dynamic. If you force the compiler to try to use a dynamic loop instead of unrolling it by putting [loop] above the while loop, it gives the correct error message.

BTW once you fix that you'll also want to change "if(fCurrHeight > fCurrHeight)" to "if(fCurrHeight > fCurrBound)", otherwise it's never going to take that branch and the whole thing will get optimized away.

Thanks, that works ! But I'm a little bit confused about gradient operation in dynamic flow. I read the "Flow Control Limitations" in MSDN. This is how it describes:

"When flow control is present in a shader, the result of a gradient calculation requested inside a given branch path is ambiguous when adjacent pixels may execute separate flow control paths. Therefore, it is deemed illegal to use any pixel shader operation that requests a gradient calculation to occur at a location that is inside a flow control construct which could vary across pixels for a given primitive being rasterized."

I couldn't imagine how the error occurs when there are some gradient operations inside a dynamic flow. Can you show me some examples about this ? Thanks again !