Jump to content

  • Log In with Google      Sign In   
  • Create Account


Questions about shaders


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 george7378   Members   -  Reputation: 1132

Like
0Likes
Like

Posted 12 April 2013 - 01:00 PM

OK, I've been trying to implement some simple shaders today, and I can't get it working. Here are my problems:

 

- Do fixed function things like SetRenderState, etc.. still work if I use a shader too? Say I want to enable specular lighting alongside my simple diffuse lighting shader - can't I just enable specular lighting via SetRenderState? Do I now have to do all this stuff with my shader? The same goes for transforms - do I still need to use SetTransform to make my objects appear in the right place, or should this be done in the shader?

 

- I don't really get vertex declarations - I've been using FVFs up until now, but they don't seem to be used for shaders. How do I know what I need to have in my vertex declaration? What happens if I don't provide the right declaration?

 

Thanks.


Edited by george7378, 12 April 2013 - 01:01 PM.


Sponsor:

#2 belfegor   Crossbones+   -  Reputation: 2362

Like
1Likes
Like

Posted 12 April 2013 - 01:45 PM

1. Enable maximum debug level, and check all functions that returns HRESULT

2. You don't need SetTransform, you pass transformation matrices to shader

3. Forget about D3DMATERIAL9, D3DLIGHT9, SetTextureStageState...

4. If you are using id3dxeffect interface you can also forget about SetRenderState since you set them in technique block:

 

technique myTech
{
    pass myPass0
    {
        VerttexShader = ...;
        PixelShader = ...;
       
        // this will call SetRenderState under the hood by id3dxeffect
        CULLMODE = CW;
        STENCILENABLE = TRUE;
        ALPHABLENDENABLE = FALSE;
        ...// and what not
    }
};

 

5.

...can't I just enable specular lighting via SetRenderState?

No, you are doing it "manually" since you wish to use shaders.

 

6

What happens if I don't provide the right declaration?

It may draw and it may not. There should be some error/warning in debug output (if you are using VS) about that (provided that you enabled some debug flags).

 

7.

How do I know what I need to have in my vertex declaration?

 

It depends on your need. What vertex elements does your geometry have?


Edited by belfegor, 12 April 2013 - 01:47 PM.


#3 george7378   Members   -  Reputation: 1132

Like
0Likes
Like

Posted 12 April 2013 - 05:08 PM

OK, I'm still thinking in terms of fixed function pipeline, clearly... I now see exactly what you mean about setting the render state in the block - it looks like pretty much the same thing.

 

By doing it manually do you mean creating it from scratch in a shader, or setting the render state via a shader? I don't mind creating my own shader to do it - it sounds like a good challenge!

 

OK, I read that I can still use FVFs if they can cover my geometry's needs. So by 'What vertex elements does my geometry have' are you talking about how it's defined in the vertex buffer/mesh file, or what the input structs in the shaders have? I'm still a little confused about that one.

 

Thanks for the great answer! You've actually just helped me to successfully implement my very first shader - a shadow mapping one.



#4 belfegor   Crossbones+   -  Reputation: 2362

Like
3Likes
Like

Posted 13 April 2013 - 04:55 AM

1.

By doing it manually do you mean creating it from scratch in a shader, or setting the render state via a shader?

Usually this is done in pixel shader by using (or even creating new) existing lightning algorithms (like these ones , you should be able to easily convert these to dx9).

 

2.

OK, I read that I can still use FVFs if they can cover my geometry's needs. So by 'What vertex elements does my geometry have' are you talking about how it's defined in the vertex buffer/mesh file, or what the input structs in the shaders have?

This depends on witch file format you are using for your meshes, and even on export options from modeling program that you used. And options you choose depends on what your shader needs for input.

 

This is not easy to explain. Normaly, there is this as some kind of common vertex elements you could find in a mesh:

 

D3DVERTEXELEMENT9 vertexElements[] =
            {
                {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},
                D3DDECL_END()
            };
            hr = d3d9device->CreateVertexDeclaration(vertexElements, &vDeclaration);
            if(FAILED(hr))
                 // handle fail

 

and in a shader your input struct then should be (to mach these):

 

struct VertexInput
{
   float3 Position : POSITION;
   float3 Normal : NORMAL;
   float2 TexCoord : TEXCOORD0;
};

 

If you want to use bump-mapping (as most games do), you probably need these (if you don't have the export options for these in modeling program, you should generate this programatically (find some algo's by googling):

 

D3DVERTEXELEMENT9 vertexElements[] =
            {
                {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
                {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0},
                {0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,  0},
                {0, 36, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
                {0, 48, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
                D3DDECL_END()
            };
            hr = d3d9device->CreateVertexDeclaration(vertexElements, &vDeclaration);
            if(FAILED(hr))
                 // handle fail

 

and in a shader your vertex input struct then should be:

 

struct VertexInput
{
    float3 Position  : POSITION;
    float3 Normal    : NORMAL;
    float3 Tangent   : TANGENT;
    float3 Binormal  : BINORMAL;
    float2 TexCoord0 : TEXCOORD0;
};

 

For example, for my grass i use instancing and input vertex looks like this:

 

D3DVERTEXELEMENT9 vertexElements[] =
            {
                {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
                {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0},
                {0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,  0},
                {0, 36, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
                {0, 48, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
                {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
                {1, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
                {1, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
                {1, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4},
                D3DDECL_END()
            };
            hr = d3d9device->CreateVertexDeclaration(vertexElements, &vDeclaration);

Last 4 texcoords actually stores transformation matrix for each instance. There is no "one way - best way", some people does it different based on their needs.

 

You could extract info for which vertex elements your mesh have programatically (cropped from my code. this is for 'X' file format meshes):

 

 

D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE];

        hr = mesh->GetDeclaration(decl);
        if(FAILED(hr))
            // handle error
...
bool havePosition  = false;
        bool haveNormal    = false;
        bool haveTexCoord0 = false;
        bool haveTexCoord1 = false;
        bool haveTangent   = false;
        bool haveBinormal  = false;

        WORD offsetToPosition  = 0;
        WORD offsetToNormal    = 0;
        WORD offsetToTexCoord0 = 0;
        WORD offsetToTexCoord1 = 0;
        WORD offsetToTangent   = 0;
        WORD offsetToBinormal  = 0;

        for(UINT i = 0; i < MAX_FVF_DECL_SIZE; ++i)
        {
            // if end of declaration, exit loop
            if(decl[i].Stream == 0xFF || decl[i].Stream != 0)
            {
                break;
            }

            if(decl[i].Usage == D3DDECLUSAGE_POSITION)
            {
                offsetToPosition = decl[i].Offset;
                havePosition      = true;
                continue;
            }

            if(decl[i].Usage == D3DDECLUSAGE_NORMAL)
            {
                offsetToNormal = decl[i].Offset;
                haveNormal      = true;
                continue;
            }

            if(decl[i].Usage == D3DDECLUSAGE_TEXCOORD && decl[i].UsageIndex == 0)
            {
                offsetToTexCoord0 = decl[i].Offset;
                haveTexCoord0      = true;
                continue;
            }

            if(decl[i].Usage == D3DDECLUSAGE_TEXCOORD && decl[i].UsageIndex == 1)
            {
                offsetToTexCoord1 = decl[i].Offset;
                haveTexCoord1      = true;
                continue;
            }

            if(decl[i].Usage == D3DDECLUSAGE_TANGENT)
            {
                offsetToTangent = decl[i].Offset;
                haveTangent      = true;
                continue;
            }

            if(decl[i].Usage == D3DDECLUSAGE_BINORMAL)
            {
                offsetToBinormal = decl[i].Offset;
                haveBinormal      = true;
                continue;
            }
        }
...

 

I just checked for elements that i need, you could check for others and even for their sizes (there is no rule that for example TEXCOORD be float2, it could be float4...). You get the idea?


Edited by belfegor, 13 April 2013 - 05:04 AM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS