Inconsistent negated if-statement outcome

Hi all,

i do some computations in a fragment shader (GPGPU stuff, i spare you the details) where i accumulate some values in the floating point framebuffer like accum=accum+delta and now i want to check in the FS wether delta is large enough to actually change accum and thereby accum != accum+delta. I put up an if statement for the test and it didn’t work out. So i put up a negated if statement inside the first one to double-check what was happening and both seem to hold true - which can’t be. (or maybe i am too tired to see the obvious)

Anyway, please have look at:


#version 420 compatibility
#pragma optimize(off)  //testing, doesn't help 
...
flat in vec4 VSresult;
out vec4 result;
uniform sampler2D loopIn_result;
...
vec4 accum = texture2D(loopIn_result, gl_FragCoord.xy/bufSize); //get old accumulated value
float testMachineEpsilon = accum.r+VSresult.b; // if this now equals accum.r again, then VSresult.b is too small to make a difference

  if (((accum.r - testMachineEpsilon) != 0.0f) && (VSresult.r != 0.0f) && (VSresult.b > 0.0f)) // ensure the "delta" VSresult.b makes a difference
  {
  
   if ((accum.r - testMachineEpsilon) == 0.0f ) // if it makes no difference...
    {
      result.r = 5000; // indicate fail
    } else {
      result.r = 1; //ensure output written in any case
    }

  } else {
    result.r = 1; //ensure output written in any case
  }
...

As you might have guessed from my question, the outcome is 5000 all the time, indicating that (accum.r - testMachineEpsilon) equals and does not equal 0 at the same time. Why is that?

Also note, that it seems to work if i drop the second and third term in the outer if statement and just state


  if (((accum.r - testMachineEpsilon) != 0.0f))

or - alternatively - it also works when i precompute


precise float test = (accum.r+VSresult.b) - accum.r;

before each if statement and then just compare test!=0 or test==0.

It seems the subtraction together with the logical &&'s in the first statement don’t work.

I would buzz out your component values with isnan() and isinf(), just to make sure we don’t have any funny business going on.

Could be a driver bug.

Also, typically when you want to fetch an image value using gl_FragCoord.xy (without interpolation) you’d use texelFetch( tex, ivec2( gl_FragCoord.xy )[, sample] )

[QUOTE=Dark Photon;1261195]I would buzz out your component values with isnan() and isinf(), just to make sure we don’t have any funny business going on.

Could be a driver bug.

Also, typically when you want to fetch an image value using gl_FragCoord.xy (without interpolation) you’d use texelFetch( tex, ivec2( gl_FragCoord.xy )[, sample] )[/QUOTE]

Good idea, but i cannot find any nan or inf values.

Looks like checking machine epsilon this way might not be a good idea due to different outcomes and i maybe rather check every delta against float machine epsilon or sth slightly larger to be sure (~1.192e-7). I will test this later.

Also i will consider your texelFetch, thanks.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.