[Solved] Error with while loop in a hlsl shader

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
porcus
Posts: 149
Joined: Sun May 27, 2007 6:24 pm
Location: Germany

[Solved] Error with while loop in a hlsl shader

Post by porcus »

Hi,

I tried to convert a glsl shader to hlsl.
The most things are working but in one line a get a very strange error:
HLSL pixel shader compilation failed:
(54): error X3511: loop does not appear to terminate in a timely manner (1024 iterations)

Code: Select all

[...]
while (NB.r < height) {<-----this is line 54
height -= step;
offsetCoord += delta;
NB = tex2D(heightMap, offsetCoord);
}
[...]
The glsl version of this shader is working fine.
What I don't understand is: How should the compiler even know how many iterations will happen, because
step and delta are depending on what is set in the ShaderCallback (height is 1.0 at the beginning).

If I replace (NB.r < height) with (1.0 < 0.9) which is always false the error disappears, but of course
this would not be a acceptable solution (and the results are not right of course).

I hope anybody can help me.
Last edited by porcus on Thu Jun 04, 2009 3:53 pm, edited 1 time in total.
9YkKsvXM
Posts: 64
Joined: Tue Mar 11, 2008 11:45 pm

Post by 9YkKsvXM »

-
Last edited by 9YkKsvXM on Mon Jun 08, 2020 1:20 am, edited 1 time in total.
porcus
Posts: 149
Joined: Sun May 27, 2007 6:24 pm
Location: Germany

Post by porcus »

Yes, I am using shader model 3.0
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

You might wanna try replacing these 2 lines:

Code: Select all

while (NB.r < height) {<-----this is line 54
height -= step;
With

Code: Select all

height = min(NB.r, height);
Or perhaps

Code: Select all

height = fmod(height, NB.r);
Or maybe even

Code: Select all

height = min(NB.r, height) - fmod(NB.r, step);
Just pick whatever works (If any).
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
porcus
Posts: 149
Joined: Sun May 27, 2007 6:24 pm
Location: Germany

Post by porcus »

Nothing of that works. There's no way to do this without a loop.
I've read on some other sites that the hlsl compiler tries to unroll
the loop and that's why it don't works. Is there any way to tell the
compiler that he shall not try to unroll it ?
Mel
Competition winner
Posts: 2292
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Post by Mel »

HLSL are compiled in the video card, outside the exectuable. In fact, anything in a shader SHOULD ALWAYS have an easy to track end point. I mean, it may happen that the shader works for a small part of the image, anything that doesn't take 1024 iterations to render a single pixel (that's crazy, by the way)

If you have to iterate through a while loop, you should make sure it is always under control, anyway, what are you trying to do that takes imperatively a while loop to render? Are you sure there are no other ways to do it?
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
porcus
Posts: 149
Joined: Sun May 27, 2007 6:24 pm
Location: Germany

Post by porcus »

This loop calculates the collision point between the ray from the eye and
a heightmap. And this is impossible without a loop.
sio2
Competition winner
Posts: 1003
Joined: Thu Sep 21, 2006 5:33 pm
Location: UK

Post by sio2 »

Try something like this:

Code: Select all

int maxIterations = 32; // Change this to suit your precision needs
while (maxIterations && (NB.r < height))
{
    height -= step;
    offsetCoord += delta;
    NB = tex2D(heightMap, offsetCoord);
    --maxIterations;
}
porcus
Posts: 149
Joined: Sun May 27, 2007 6:24 pm
Location: Germany

Post by porcus »

Thanks for your reply, but I with this I get only a white
screen with the sand glass mouse pointer. The program crashes during the
hlsl compiler tries to compile it. I get no error messages.
sio2
Competition winner
Posts: 1003
Joined: Thu Sep 21, 2006 5:33 pm
Location: UK

Post by sio2 »

If you can post the shader we may be able to help further. You should be able to see messages from the offline compiler though...
porcus
Posts: 149
Joined: Sun May 27, 2007 6:24 pm
Location: Germany

Post by porcus »

Hello,

I solved the problem with this code:

Code: Select all

int i = 0;
for(i=0;i<200;i++) {
if(NB.r < height){
height -= step;
offsetCoord += delta;
NB = tex2D(heightMap, offsetCoord);
}
}
It's a little bit slow (60 fps in hlsl instead of 300 in glsl) but it works so far.
Darktib
Posts: 167
Joined: Sun Mar 23, 2008 8:25 pm
Location: France

Post by Darktib »

This loop calculates the collision point between the ray from the eye and
a heightmap
It reminds me of picking. You can do this without a loop in one function call, but not in the shader. And I think it can be much efficient.

See arras's Shifted Terrain Scene Node, which allow you to perform this operation.
porcus
Posts: 149
Joined: Sun May 27, 2007 6:24 pm
Location: Germany

Post by porcus »

No that has nothing to do with picking or terrains.
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Post by Nadro »

porcus wrote:Hello,

I solved the problem with this code:

Code: Select all

int i = 0;
for(i=0;i<200;i++) {
if(NB.r < height){
height -= step;
offsetCoord += delta;
NB = tex2D(heightMap, offsetCoord);
}
}
It's a little bit slow (60 fps in hlsl instead of 300 in glsl) but it works so far.
What is Your graphic card? What is performane in both modes without shader? Maybe You have got enable VSync for DX apps in drivers? Difference is too big, it isn't cause by "HLSL".
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
sudi
Posts: 1686
Joined: Fri Aug 26, 2005 8:38 pm

Post by sudi »

porcus wrote:Hello,

I solved the problem with this code:

Code: Select all

int i = 0;
for(i=0;i<200;i++) {
if(NB.r < height){
height -= step;
offsetCoord += delta;
NB = tex2D(heightMap, offsetCoord);
}
}
It's a little bit slow (60 fps in hlsl instead of 300 in glsl) but it works so far.
Maybe try

Code: Select all

if(NB.r < height){
int data = height - NB.r;
int data2 = data/step;
height -= data2;
offsetCoord += delta*data2;
NB = tex2D(heightMap, offsetCoord);
}
without any loop.

The datatype of data and data2 should be adjusted to the stuff u use there. But i think this might work.
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
Post Reply