Matrix array in HLSL problem.

E96bdd9352bdf5f0e17646cd08c83b0e
0
yakul 101 Mar 21, 2008 at 15:26

Solution: It might seem like I just posted it and immediatly solved it. But the truth is I posted this after trying to solving the problem for more then a day.
The problem was that SM3 allowes to use more VS constant registers then a graphic cards might have.
So the .fx compiled but didn’t run properly on the graphics card.
You can see the maximum VS registers on D3DCAPS9, mine was 256, and after compiling using fxc.exe, I saw that for 31 the registers amount was above 256, and for 20 it was just bellow.

I have written a shader that draws multiple rigid objects and uses two arrays of float4x4. One for world transformationm and the other for world inverse.
When I set those arrays to 30, everything works fine.
However, when I set those arrays to 31, things starting to get peculiar.
When the arrays are set to 31, it seems like the vertex shader is not compiled properly, and it uses the fixed function rendering type instead of the shader pipeline.
Here is the the minimal code I have set to reproduce the error.
It contains both CPP code, and the shader.
When the code breaks on the drawSubset, I get the following error:

“Direct3D9: (ERROR) : ps_3_0 shader can only be used with vs_3_0+ shader (SWVP or HWVP), or transformed vertices.

First-chance exception at 0x7c81eb33 in Laby.exe : Microsoft C++ exception: long at memory location 0x0012e4ec..
Direct3D9: (ERROR) : DrawIndexedPrimitive failed.”

I have no idea what I am doing wrong.

Edit: CreateDebugEffectFromFile simply use D3DXCreateEffectFromFile
Code:

{
        ReferencePointer<Scope> pMaintainScope;

        pMaintainScope = A_Scope->CreateDirect3DHardware (A_Game->hWnd, "");
        this->D3DHwd = pMaintainScope->GetData();
        pMaintainScope = A_Scope->CreateDirect3DDevice (this->D3DHwd, 0, false, 1024, 768, false, A_Game->pRestoreHandle, "");
//      pMaintainScope = A_Scope->CreateDirect3DDevice (this->D3DHwd, 0, true, 1024, 768, false, A_Game->pRestoreHandle, "");
        this->D3DDevice = pMaintainScope->GetData();
        this->D3DDevice->SetDimentionsChangers(A_WindowChanger);
        pMaintainScope = A_Scope->CreateVertexDeclarationInspectorComplete (A_Game->pOutputHandle, A_Game->pPreRestoreReleaseHandle, "");
        this->Inspector = pMaintainScope->GetData();
        // TODO: HERE!!!
/**********************************/
        
D3DVERTEXELEMENT9 El[] = 
{
    {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_FLOAT1,   D3DDECLMETHOD_DEFAULT, 
                                      D3DDECLUSAGE_TEXCOORD, 1},
    {0,  36, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, 
                                      D3DDECLUSAGE_TANGENT, 0},
    {0,  48, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, 
                                      D3DDECLUSAGE_BINORMAL, 0},
    D3DDECL_END()
};
IDirect3DVertexDeclaration9 * Dec;
    GlobalErrorWrap::HandleDirect3DError(this->D3DDevice->pD3DDevice->CreateVertexDeclaration(El, &Dec));
ID3DXMesh * Mesh;
    this->D3DDevice->CreateD3DMesh (1, 3, D3DXMESH_MANAGED, El, &Mesh);
    ID3DXBuffer * Buffer;
    HRESULT Error;
    ID3DXEffect * Effect;
    this->D3DDevice->CreateDebugEffectFromFile ("MultipleRigidCel.fx", Effect);
    Effect->SetTechnique ("NormalMapTechnique");
    MultipleNormalVertexStruct *p;
    Mesh->LockVertexBuffer (0, (void **)&p);
    p[0].InstanceNumber = 0.;
    p[1].InstanceNumber = 0.;
    p[2].InstanceNumber = 0.;
    Mesh->UnlockVertexBuffer ();
    this->D3DDevice->BeginScene();
    UINT PassAmount;
    GlobalErrorWrap::HandleDirect3DError(Effect->Begin(&PassAmount, 0));
    GlobalErrorWrap::HandleDirect3DError(Effect->BeginPass(0));
    GlobalErrorWrap::HandleDirect3DError(Mesh->DrawSubset (0)); // <- Breaks
    GlobalErrorWrap::HandleDirect3DError(Effect->EndPass());
    GlobalErrorWrap::HandleDirect3DError(Effect->End());
    this->D3DDevice->EndScene();
}

Shader:

// Multiple rigid cel

struct Material
{
    float4 Ambient;
    float4 Reflection;
    float4 Diffuse;
    float4 Specular;
    float  SpecularPower;
};

struct DirectionalLight
{
    float4 Diffuse;
    float4 Specular;
    float3 DirectionWorld;  
};

uniform extern float4x4         gViewProjection;
uniform extern float4x4         gLightViewProjection;
uniform extern float4x4         gWorld[31];
uniform extern Material         gMaterial;
uniform extern DirectionalLight gLight;
uniform extern float4x4         gWorldInverse[31];
uniform extern float3           gEyePositionWorld;
uniform extern texture          gColorTexture;
uniform extern texture          gNormalMap;
uniform extern texture          gShadowMap;

sampler ColorTextureSampler = sampler_state
{
    Texture = <gColorTexture>;
    MinFilter = ANISOTROPIC;
    MaxAnisotropy = 8;
    MagFilter = LINEAR;
    MipFilter = LINEAR;
    AddressU  = WRAP;
    AddressV  = WRAP;
};

sampler NormalMapSampler = sampler_state
{
    Texture = <gNormalMap>;
    MinFilter = ANISOTROPIC;
    MaxAnisotropy = 8;
    MagFilter = LINEAR;
    MipFilter = LINEAR;
    AddressU  = WRAP;
    AddressV  = WRAP;
};

sampler ShadowMapSampler = sampler_state
{
    Texture = <gShadowMap>;
    MinFilter = POINT;
    MagFilter = POINT;
    MipFilter = POINT;
    AddressU  = CLAMP;
    AddressV  = CLAMP;
};

struct OutputVS
{
    float4 PositionHomogeneous   : POSITION0;
    float3 ToEyeTangent          : TEXCOORD0;
    float3 LightDirectionTangent : TEXCOORD1;
    float2 TextureCoordinates    : TEXCOORD2;
    float4 LightCoordinates : TEXCOORD4;
    float3 SecondLightDirectionTangent : TEXCOORD5;
};

OutputVS MultipleRigidCelVS(float3 PositionLocal      : POSITION0, 
                     float3 TangentLocal       : TANGENT0,
                     float3 BinormalLocal      : BINORMAL0,
                     float3 NormalLocal        : NORMAL0, 
                     float2 TextureCoordinates : TEXCOORD0,
                     float InstanceNumber      : TEXCOORD1)
{
    // Zero out our output.
    OutputVS ReturnValue = (OutputVS)0;
    
    float4 p = float4(PositionLocal, 1.);

    float3x3 TBN;
    TBN[0] = TangentLocal;
    TBN[1] = BinormalLocal;
    TBN[2] = NormalLocal;

    int n = InstanceNumber; 
    // Object space to tangent space transform matrix.
    float3x3 ToTangentSpace = transpose(TBN);
    
    // Eye position transform to local space.
    float3 EyePositionLocal = mul(float4(gEyePositionWorld, 1.0f), gWorldInverse[n]);
    
    // Local ToEye vector to tangent space.
    float3 ToEyeLocal = EyePositionLocal - p.xyz;
    ReturnValue.ToEyeTangent = mul(ToEyeLocal, ToTangentSpace);
    
    // Local light direction to tangent space.
    float3 LightDirectionLocal = mul(float4(gLight.DirectionWorld, 0.0f), gWorldInverse[n]).xyz;
    ReturnValue.LightDirectionTangent  = mul(LightDirectionLocal, ToTangentSpace);
    
    // Local position to homogeneous clip space.
    ReturnValue.PositionHomogeneous = mul(p, mul(gWorld[n], gViewProjection));
    
    ReturnValue.TextureCoordinates = TextureCoordinates;
    
    ReturnValue.LightCoordinates = mul(p, mul(gWorld[n], gLightViewProjection));
    
    return ReturnValue;
}

float4 MultipleRigidCelPS(float3 ToEyeTangent : TEXCOORD0,
                   float3 LightDirectionTangent : TEXCOORD1,
                   float2 TextureCoordinates    : TEXCOORD2,
                   float4 LightCoordinates     : TEXCOORD4,
                   float3 SecondLightDirectionTangent : TEXCOORD5) : COLOR
{
    return 0;   
}

technique NormalMapTechnique
{
    pass P0
    {
        // Specify the vertex and pixel shader associated with this pass.
        // TODO: HERE!!!
        vertexShader = compile vs_3_0 MultipleRigidCelVS();
        pixelShader  = compile ps_3_0 MultipleRigidCelPS();
  
        CullMode = CCW; 
        Lighting = True;
        ZEnable = True;
        ZWriteEnable = True;
        AlphaBlendEnable = False;
    }
}

0 Replies

Please log in or register to post a reply.

No replies have been made yet.