Shaders and conditionals? (Solved!)

Started by
8 comments, last by OuncleJulien 19 years, 7 months ago
I seem to be having issue with if statements in my vertex shader (I'm using vs_1_1). Here are some conditional expressions I'm using and their results: 1.0f < 2.0f // would return true, as expected 1.0f > 2.0f // would return false, as expected bone is a float4 passed in with the vertex data bone.x < 10000.0f // Returns true, as expected because bone.x is between 0 and 1 bone.x > 10000.0f // Returns true for some odd reason? I can't figure out why the shader would find this to be true? Can anyone think of a reason why it would be doing this? Are there some quirks I'm not aware of that I missed in the docs? [Edited by - OuncleJulien on September 21, 2004 11:27:36 PM]
Advertisement
Anyone? =/
It's probably worth compiling the shader into vs1.1 assembly and checking whether the output makes sense.

vs 1.1 has two instructions it can use for comparison:

1) SLT which does:
if (a < b)   result=1.0; else    result=0.0;


2) SGE which does:
if (a >= b)
result=1.0;
else
result=0.0;


So first thought is that because vs 1.1 doesn't actually have a "a > b" operator, something has gone awry with the compilation.

- Maybe the compiler has run out of constant register space to store the 10000.0f in?

- Maybe the compiler thinks the 10000.0f isn't constant and hasn't found a suitable way to convert the comparison to "a >= b"


Checking the compiler output would be my first port of call.

The above could be the result of forgetting to mark any local constants as const and any external parameters as uniform.


Something else to check is your vertex declaration - I presume "bone" is coming in from the vertex (bone weights?).

What data type are you specifying in the declaration ?

If it's D3DVSDT_UBYTE4 or D3DVSDT_FLOAT4, try D3DVSDT_D3DCOLOR instead (and scale appropriately) and vice versa.

Check the DeclTypes member of the caps for your device to determine whether the hardware actually supports the data type you're using. For example, some early vs 1.1 hardware couldn't UBYTE4s but did support colours (or was it the other way around, I forget ;o)


If you suspect a problem with the drivers for your device, check with the REF device - if it works with that, first check the caps to see if there's any relevent ones you've missed, then get a simple repro case to Microsoft and the IHV concerned.

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Sorry for the late reply, I was at school and just came home.

So the float4 bones variable stores the bone indicies. There are 4 bones (0-3) so "if (bones[0] > 10000.0f)" should never return true. But it does for some reason.

I just got the shader debugger working and noticed that for the bones variable it says it's {1, *, *, *} for some reason. The weights variable isn't listed as a local and I can't put a watch on it or it says "unable to evaluate expression".

Moreover if I expand the bones variable in the debugger it says:
+bones
+- x 1
+- y * (no storage)
+- z * (no storage)
+- w * (no storage)

Why would this be?


here's the shader code:

const uniform float4x4 mat;
const uniform float index;

void main( float4 position : POSITION,
out float4 oPosition : POSITION,
float3 n : NORMAL,
float2 tex : TEXCOORD0,
out float2 oTex : TEXCOORD0,
float4 bones : BLENDINDICES0,
float4 weights : BLENDWEIGHT0)
{

if (bones[0] > 10000.0f)
{
position.y = position.y + (position.y * (1.2 + sin(index*3.0f + position.x*0.3f)))*0.05f;
}

oPosition = mul(mat,position);
oTex = tex;

}




here's my vertex format and declaration:

struct Vertex
{
public:
D3DXVECTOR3 v;
D3DXVECTOR3 n;
float tu,tv;

D3DXVECTOR4 boneIds; //4 bone id's
D3DXVECTOR4 weights; //4 bone weights

static const int FVF = D3DFVF_XYZ
| D3DFVF_NORMAL
| D3DFVF_TEX3
| D3DFVF_TEXCOORDSIZE2(0)
| D3DFVF_TEXCOORDSIZE4(1)
| D3DFVF_TEXCOORDSIZE4(2);
};

D3DVERTEXELEMENT9 decl[] =
{
{0, 0 , D3DDECLTYPE_FLOAT3 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_POSITION , 0},
{0, 12 , D3DDECLTYPE_FLOAT3 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_NORMAL , 0},
{0, 24 , D3DDECLTYPE_FLOAT2 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_TEXCOORD , 0},
{0, 32 , D3DDECLTYPE_FLOAT4 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_BLENDINDICES , 0},
{0, 48 , D3DDECLTYPE_FLOAT4 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_BLENDWEIGHT , 0},
D3DDECL_END()
};
Oops, I forgot to post the dissasembly:

--- c:\c\direct3d\view3d\shader.vsh --------------------------------------------
if (bones.x > 10000.0f)
V00000001:00000000 vs_1_1
V00000001:00000004 comment DBUG
V00000001:00000334 comment CTAB
V00000001:000003e4 def c5, 1, 1.2, 0.05, 0
V00000001:000003fc def c6, 10000, 3, 0.3, 0.159155
V00000001:00000414 def c7, 0.25, 6.28319, -3.14159, -2.52399e-007
V00000001:0000042c def c8, 2.47609e-005, -0.00138884, 0.0416666, -0.5
V00000001:00000444 dcl_position0 v0
V00000001:00000450 dcl_texcoord0 v1
V00000001:0000045c dcl_blendindices0 v2
V00000001:00000468 slt r2.w, c6.xxxx, v2.xxxx
position.y = position.y + (position.y * (1.2 + sin(index*3.0f + position.x*0.3f)))*0.05f;
V00000001:00000478 mov r4.w, c4.xxxx
V00000001:00000484 mul r1.w, r4.wwww, c6.yyyy
V00000001:00000494 mul r3.w, v0.xxxx, c6.zzzz
V00000001:000004a4 add r0.w, r1.wwww, r3.wwww
V00000001:000004b4 mul r5.w, r0.wwww, c6.wwww
V00000001:000004c4 add r4.w, r5.wwww, c7.xxxx
V00000001:000004d4 expp r6.y, r4.wwww
V00000001:000004e0 mov r3.w, r6.yyyy
V00000001:000004ec mul r1.w, r3.wwww, c7.yyyy
V00000001:000004fc add r0.w, r1.wwww, c7.zzzz
V00000001:0000050c mul r0.w, r0.wwww, r0.wwww
V00000001:0000051c mul r5.w, r0.wwww, c7.wwww
V00000001:0000052c add r4.w, r5.wwww, c8.xxxx
V00000001:0000053c mul r3.w, r0.wwww, r4.wwww
V00000001:0000054c add r1.w, r3.wwww, c8.yyyy
V00000001:0000055c mul r5.w, r0.wwww, r1.wwww
V00000001:0000056c add r4.w, r5.wwww, c8.zzzz
V00000001:0000057c mul r3.w, r0.wwww, r4.wwww
V00000001:0000058c add r1.w, r3.wwww, c8.wwww
V00000001:0000059c mul r5.w, r0.wwww, r1.wwww
V00000001:000005ac add r4.w, r5.wwww, c5.xxxx
V00000001:000005bc add r3.w, r4.wwww, c5.yyyy
V00000001:000005cc mul r1.w, r3.wwww, v0.yyyy
V00000001:000005dc mul r0.w, r1.wwww, c5.zzzz
V00000001:000005ec add r4.w, r0.wwww, v0.yyyy
if (bones.x > 10000.0f)
V00000001:000005fc mov r5.w, -v0.yyyy
V00000001:00000608 add r3.w, r4.wwww, r5.wwww
V00000001:00000618 mul r1.w, r2.wwww, r3.wwww
V00000001:00000628 add r0.w, r1.wwww, v0.yyyy
oPosition = mul(mat,position);
V00000001:00000638 mul r4, v0.xxxx, c0
V00000001:00000648 mul r5, r0.wwww, c1
V00000001:00000658 add r2, r4, r5
V00000001:00000668 mul r3, v0.zzzz, c2
V00000001:00000678 add r0, r2, r3
V00000001:00000688 mul r1, v0.wwww, c3
V00000001:00000698 add oPos, r0, r1
oTex = tex;
V00000001:000006a8 mov oT0.xy, v1
V00000001:000006b4 end
Anyone have any ideas?

[Edited by - OuncleJulien on September 21, 2004 5:51:34 PM]
16 bit or 32 bit? The maxium value of a 16 bit float may be less than 10000 and well, percision would explain that behavior.
I just tried it with:

if (bones[0] > 100.0f)
{
...
}
and

if (bones[0] < 100.0f)
{
...
}


And they're both still evaluating as true ;/ (I tried both in REF and HAL modes to make sure it's not my driver). Still does the same in both modes.


I might add that == has the same effect.

eg-

if (bones[0] == 100.0f && bones[0] == 101.0f)
{
... // Every vertex will be effected by what's in here.
}


It make absloutely no sence whatsoever to mw why it'd be doing this. I'm about ready to give up on shaders =(
VS 1.1 does not suport branching. The compiler may be able to fudge it, but it would probably be better just to use VS 2.0. Have you tried this? The docs suggest that software vertex processing is not much slower than hardware, heck it is at least worth a try just to see if it is a branching problem.
Buahahaha! All this time! lol!

Thank you for telling me this!

Does it say that vs_1_1 doesn't support branching in the DX SDK? Cause I've looked them over 1000 times.

Thanks again!

This topic is closed to new replies.

Advertisement