Jump to content
  • Advertisement
Sign in to follow this  
vajuras

Are If statements unreliable in HLSL Vertex Shaders? (solved)

This topic is 5464 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm having problems getting an if statement to work. I have a float that equals 0 (IN.Weights.xyzw). However, in my if statement it appears to ignore my conditional. Is there some kind of limit on conditionals in shaders or something? Here is my shader (based on Paletteskin from NVSDK 8):
//
// Matrix Palette Skinning
// References:
// PaletteSkin.fx NVIDIA SDK example

float4 lhtDir = {-2.0f, 2.0f, 2.6f, 12.0f};    //light Direction 

// Matrix Pallette
static const int MAX_MATRICES = 26;
float4x3    mWorldMatrixArray[MAX_MATRICES] : WORLDMATRIXARRAY;
float4x4 WorldViewProj : WorldViewProj;

///////////////////////////////////////////////////////
struct VS_INPUT
{
    float3  Position   : POSITION;
    float3  Normal     : NORMAL;
    float2  Tex0       : TEXCOORD0;
    float4  Weights    : TEXCOORD1;
    float4  Indices    : TEXCOORD2;    
};

struct VS_OUTPUT
{
    float4  Pos     : POSITION;
    float3  Diffuse : COLOR;
    float2  Tex0    : TEXCOORD0;
};


VS_OUTPUT main(VS_INPUT IN)
{
    VS_OUTPUT   OUT;
    float3      Normal = 0.0f;    

    float i;        // Index into matrix palette

    float4 inPos;
    inPos.xyz = IN.Position;
    inPos.w = 1.0;

    float3 tempPos, tempNormal;

    /////////////////////////////////////////////////////////////////////
    // FIRST BONE
    // We don't worry about the ELSE condition because we defined the 
    // initial conditions.

    // grab first bone matrix
    i = IN.Indices.x;

    // First transformed position and normal
    tempPos = mul(inPos, mWorldMatrixArray) * IN.Weights.x;
    tempNormal = mul(IN.Normal, (float3x3)mWorldMatrixArray) * IN.Weights.x;

    /////////////////////////////////////////////////////////////////////
    // SECOND BONE
    // Next bone.

    if(IN.Weights.y > 0.0f)
    {
        i = IN.Indices.y;

        // Add second transformed position and normal
        tempPos += mul(inPos, mWorldMatrixArray) * IN.Weights.y;
        tempNormal += mul(IN.Normal, (float3x3)mWorldMatrixArray) * IN.Weights.y;

        /////////////////////////////////////////////////////////////////////
        // THIRD BONE
        // Note we only skin the normal by the first two bones, these are by 
        // far the most significant.

        if(IN.Weights.z > 0.0f)
        {
            i = IN.Indices.z;

            // Add third transformed position only
            tempPos += mul(inPos, mWorldMatrixArray) * IN.Weights.z;

            /////////////////////////////////////////////////////////////////////
            // FOURTH BONE

            if(IN.Weights.w > 0.0f)
            {
                i = IN.Indices.w;
                
                // Add fourth transformed position only
                tempPos += mul(inPos, mWorldMatrixArray) * IN.Weights.w;
            }
        }
    }

    // normalize normals
    Normal = normalize(tempNormal);

    // Shade (Ambient + etc.)
   // OUT.Diffuse.xyz = MaterialAmbient.xyz + Diffuse(Normal) * MaterialDiffuse.xyz;
   // OUT.Diffuse.w = 1.0f;
   OUT.Diffuse.xyz = max(dot(Normal, lhtDir), 0).xxx;

    // copy the input texture coordinate through
    OUT.Tex0  = IN.Tex0.xy;

    float4 finalPos;
    finalPos.xyz = tempPos;
    finalPos.w = 1.0;
    
    // Transform the final skinned position
    OUT.Pos = mul(finalPos, WorldViewProj);
    return OUT;
}


//////////////////////////////////////
// Techniques specs follow
//////////////////////////////////////
technique t0
{
    pass p0
    {
        VertexShader = compile vs_1_1 main();
    }
}







[Edited by - vajuras on October 5, 2004 1:31:13 AM]

Share this post


Link to post
Share on other sites
Advertisement
I never used HLSL, but what I can tell you is that vs 1.x does NOT support conditional branches and such, so if you place an if, both parts of the code WILL be executed, but the compiler will do some tricky operations in order to make it work as if it was an "if". So I don't think if statements are totally reliable.

Share this post


Link to post
Share on other sites
thanks, yeah I just found that if statements were not supported until VS 2_0. what is strange is that Nvidia's PaletteSkin.fx sample is set to vs 1_1. I suppose either matrix at index 0 was either an identity matrix or that their example always has 4 bones per vert. what i have decided to do is just have a vert reference an indentity matrix if their weight = 0 (if they don't have 4 bones for that vert).

Share this post


Link to post
Share on other sites
Quote:
Original post by Pipo DeClown
You're using floats? Floats float around the desired float-value.


hehe, I always like to read your comments :)

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
"If" statements aren't supported in VS 1.x hardware. But this doesn't mean they can't be used in HLSL. But since the hardware cannot do the dynamic branching, it will essentially execute the code for both sides of the if/else statement and then use an instruction such as sge or a lerp to put the right result into your destination register.

So if using "If"'s in your 1.1 HLSL code, yet it will appear as it is ignoring your code as it must run all the code anyways.

Share this post


Link to post
Share on other sites
hey thanks, Coder.

okay this is still strange- I compiled the shader for vs 2_0 and I got the same result. The value of IN.Weight.w equals 0. however, my if (IN.Weight.w > 0) branch still gets executed.

Next, I try my model that is single boned and run it through the vs 1_1 shader. The if statements appear to work- the shader never tried to execute if (IN.Weight.y) -> IN.Weight.w > 0. Man, that's crazy... I always wondered why my single boned model looked perfect but the multi-bone vertex models look somewhat distorted...

Hard to believe I'm having so much problems with an if statement in HLSL :(

Share this post


Link to post
Share on other sites
Still no luck but thanks anyway. You gave me hope for a few moments :)

I even tried switching to vs_3_0 compile target this time. It still marches right pass my conditional. This is a really humbling experience. I've been re-reading all the HLSL intro tuts I can find. I've also been looking at my switches, vertex declarations,etc. Something must be wrong with my code or something.

At leas t i do know an alternative. So i'm not stuck. But it would be nice to know why this fails. Below I've attached some snippets.


//code i use to compile my shader
DWORD compile_flags=0;
if (driver->IsVSDebugEnabled()) //this is set to true
{
compile_flags=D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION | D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT | D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
}

HRESULT hr = D3DXCreateEffectFromFile( pd3dDevice,
shaderFile,
NULL,
NULL,
compile_flags,
NULL,
&pEffect,
&errorBuffer );

//assert(pCode!=NULL); //wrong path to shader?
if (errorBuffer)
{
::MessageBox(0, (char*)errorBuffer->GetBufferPointer(), 0, 0);
Release<ID3DXBuffer*>(errorBuffer);
}

if (FAILED(hr))
{
::MessageBox(0, "D3DXCompileShaderFromFile() - FAILED", 0, 0);
}






//skinning declaration for the vertex shader
static const D3DVERTEXELEMENT9 DVE_MATRIX_PALETTE[] =
{
{ 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_TEXCOORD, 1 },
{ 0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2 },
D3DDECL_END()
};


Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!