"for" error in cg shader

Problems building or running the engine, queries about how to use features etc.
cdkeito
Orc
Posts: 468
Joined: Sat Jan 27, 2007 12:06 pm

"for" error in cg shader

Post by cdkeito »

hi,

i'm getting this error, do you know how to "bypass" it? any suggestions?

Code: Select all

error X6077: texld/texldb/texldp/dsx/dsy instructions with r# as source cannot be used inside dynamic conditional 'if' blocks, dynamic conditional subroutine calls, or loop/rep with break*.
here shader code (ps_3_0):

Code: Select all

// rendering on a "cinema" quad aligned with rrt1 and rtt2
float4 main_fp(
              float4 colorIN : COLOR,
              float2 texCoord: TEXCOORD0,
              uniform sampler front: register(s0), //rtt cube clockwise
              uniform sampler back: register(s1), //rtt cube anticlockwise
              uniform sampler modtex: register(s2) //pre-int 3d texture 32MB 256*256*128
              ) : COLOR
{
// rendering to rtt a cube with vertex colors=coords (0->1)
  float4 frontC = tex2D(front,   texCoord);
// rendering to another rtt the same cube anticlockwise
  float4 backC = tex2D(back,   texCoord);
// building the "directions" texture
  float4 tempdirtex = backC - frontC;
  float4 dirtex = float4(normalize(tempdirtex.xyz),length(tempdirtex));
  
//raytracing
  float4 colorSample;
  
  for(int i=0;i<dirtex.a;i++)
  {
    //test method, very simple
    colorSample += tex3D(modtex, frontC + dirtex * i);
    if(colorSample.a == 1.0) break;
  }
  
  return colorSample;
}
i'm on ati x1650 -> vs and ps 3.0
Image
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Post by nullsquared »

You cannot do conditional lookups in loops in PS3.0 without calculating the derivatives outside of the loop:

Code: Select all

float4 dd = float4(ddx(originalUV), ddy(originalUV));
for (...) {
... = tex2D(sampler, yourUVCoordinates, dd.xy, dd.zw);
}
You don't need to use the same UV coords, obviously, but you must explicitly calculate the derivatives (distance on screen from one texel to another).

(your "break" in there makes it conditional)
cdkeito
Orc
Posts: 468
Joined: Sat Jan 27, 2007 12:06 pm

Post by cdkeito »

mmm, i see. thank you.

question: aren't those 0? i'm seeking on all UVW coords on a ray from the camera, so screen distance (texel-texel) is zero... no?
Edit: shame me, texel not pixel!

what about Mr. break ?

PS: do you have some readings on this? thanks again!
Last edited by cdkeito on Sun May 11, 2008 8:26 pm, edited 1 time in total.
Image
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Post by nullsquared »

question: aren't those 0? i'm seeking on all UVW coords on a ray from the camera, so screen distance (texel-texel) is zero... no?
Regardless of what they are, the shader compiler needs them to be explicitly specified in a conditional loop.
what about Mr. break ?
I just meant to say that your "if (...) break;" is what made the loop conditional - if you removed that line there, your original code would compile and run.
PS: do you have some readings on this? thanks again!
This thread will help: http://www.ogre3d.org/phpBB2/viewtopic. ... light=loop
cdkeito
Orc
Posts: 468
Joined: Sat Jan 27, 2007 12:06 pm

Post by cdkeito »

thanks again!
i've made some adjustments here and there, now it compile and run, only thing i'm not getting the raycasting (only on some angles, parts/slices not the whole thing).

Could you check if i've messed the code or now is grammatically right?

Code: Select all

float4 main_fp(
              float4 colorIN : COLOR,
              float2 texCoord: TEXCOORD0,
              uniform sampler front: register(s0),
              uniform sampler back: register(s1),
              uniform sampler modtex: register(s2)
              ) : COLOR
{
  float4 frontC = tex2D(front,   texCoord);
  frontC = frontC.xzyw;  // the 3D texture z is the up
  float4 backC = tex2D(back,   texCoord);
  backC = backC.xzyw;  // the 3D texture z is the up
  float4 tempdirtex = backC - frontC;
  float4 dirtex = float4(normalize(tempdirtex.xyz),length(tempdirtex));
  
  float4 colorSample = float4(0,0,0,0);
  
  float3 dsdx = ddx(frontC);
  float3 dsdy = ddy(frontC);
  
  for(int i=0; (i+1)<dirtex.a; i++) // i+1 so it doesn't draw borders (dirth there is messing the rtts, maybe a filter later)
  {
    colorSample += tex3D(modtex, frontC + dirtex * i, dsdx, dsdy);
    if(colorSample.a == 1.0) break;
  }

  return colorSample;
}
PS:
I just meant to say that your "if (...) break;" is what made the loop conditional - if you removed that line there, your original code would compile and run.
yes, but only till i=249 (first thing i changed)
Last edited by cdkeito on Sun May 11, 2008 8:25 pm, edited 1 time in total.
Image
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Post by nullsquared »

Try using the ddx/ddy of your texCoord variable, instead of your calculate frontC.
cdkeito
Orc
Posts: 468
Joined: Sat Jan 27, 2007 12:06 pm

Post by cdkeito »

mmm...
i'm running this on quad ( = imposter) (i don't know how to do this on a cube and/or in a single pass) so :
texcoord isn't about the quad coords?
instead frontC and backC are about the real thing.

Testing with:
float3 dsdx = ddx(float3(texCoord,0));
float3 dsdy = ddy(float3(texCoord,0));
it's the same, i can't see any difference

as before i'm "viewing" something only when at about 45°. The actual code is:

Code: Select all

float4 main_fp(
              float4 colorIN : COLOR,
              float2 texCoord: TEXCOORD0,
              uniform sampler front: register(s0),
              uniform sampler back: register(s1),
              uniform sampler modtex: register(s2)
              ) : COLOR
{
	float4 frontC = tex2D(front,   texCoord);
  frontC = frontC.xzyw;
	float4 backC = tex2D(back,   texCoord);
  backC = backC.xzyw;
  float4 tempdirtex = backC - frontC;
  float4 dirtex = float4(normalize(tempdirtex.xyz),length(tempdirtex.xyz));
  
  float4 colorSample = float4(0,0,0,0);
  float3 dsdx = ddx(frontC.xyz);
  float3 dsdy = ddy(frontC.xyz);
  
  float i = 0;
  
  if(dirtex.a > 0.0)
  { for(i=0.0; i<dirtex.a; i++)
    {
      colorSample += tex3D(modtex, frontC.xyz + dirtex.xyz * i, dsdx, dsdy);
      if(colorSample.a > 1.0) break;
    }
  }
    //**
  return colorSample;
}
i've checked (with this : if(i>n.0) colorSample = float4(1,1,1,1); at "//**"; rude but work), "i" never go over 4, and this isn't expected, the texture is 256*256*128 and with data around th middle (about 8 pixel height), so i expected a i>40. isn't dirtex.xyz length = 1 ??

Edit:
well, it's crazy! if i use:
colorSample += tex3D(modtex, frontC.xyz + dirtex.xyz * (i*0.5), dsdx, dsdy);
i'm getting something, but, looking from the sides -> a slice, looking from the top the datas, but it seems that the rays is cutted before, even without the "break" line. only 0.5 give this, with 0.6 or 0.4 the "effect" fade away toward black.
Video: http://www.mediafire.com/?d3i2drjsh3x
Image
cdkeito
Orc
Posts: 468
Joined: Sat Jan 27, 2007 12:06 pm

Post by cdkeito »

no hints ?
Image
cdkeito
Orc
Posts: 468
Joined: Sat Jan 27, 2007 12:06 pm

Post by cdkeito »

solved: i was adding to a texcoord (0->1) a normalize vector = length 1 so it end outside the textcoord! :oops:
Image