My vertex shader doesn't affect texture coords or diffuse info but works for position

Posted by tina nyaa on Game Development See other posts from Game Development or by tina nyaa
Published on 2012-10-08T09:21:41Z Indexed on 2012/10/08 9:48 UTC
Read the original article Hit count: 309

Filed under:
|
|
|

I am new to 3D and DirectX - in the past I have only used abstractions for 2D drawing. Over the past month I've been studying really hard and I'm trying to modify and adapt some of the shaders as part of my personal 'study project'.

Below I have a shader, modified from one of the Microsoft samples. I set diffuse and tex0 vertex shader outputs to zero, but my model still shows the full texture and lighting as if I hadn't changed the values from the vertex buffer. Changing the position of the model works, but nothing else. Why is this?

//
// Skinned Mesh Effect file 
// Copyright (c) 2000-2002 Microsoft Corporation. All rights reserved.
//

float4 lhtDir = {0.0f, 0.0f, -1.0f, 1.0f};    //light Direction 
float4 lightDiffuse = {0.6f, 0.6f, 0.6f, 1.0f}; // Light Diffuse
float4 MaterialAmbient : MATERIALAMBIENT = {0.1f, 0.1f, 0.1f, 1.0f};
float4 MaterialDiffuse : MATERIALDIFFUSE = {0.8f, 0.8f, 0.8f, 1.0f};

// Matrix Pallette
static const int MAX_MATRICES = 100;
float4x3    mWorldMatrixArray[MAX_MATRICES] : WORLDMATRIXARRAY;
float4x4    mViewProj : VIEWPROJECTION;

///////////////////////////////////////////////////////
struct VS_INPUT
{
    float4  Pos             : POSITION;
    float4  BlendWeights    : BLENDWEIGHT;
    float4  BlendIndices    : BLENDINDICES;
    float3  Normal          : NORMAL;
    float3  Tex0            : TEXCOORD0;
};

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

float3 Diffuse(float3 Normal)
{
    float CosTheta;

    // N.L Clamped
    CosTheta = max(0.0f, dot(Normal, lhtDir.xyz));

    // propogate scalar result to vector
    return (CosTheta);
}

VS_OUTPUT VShade(VS_INPUT i, uniform int NumBones)
{
    VS_OUTPUT   o;
    float3      Pos = 0.0f;
    float3      Normal = 0.0f;    
    float       LastWeight = 0.0f;

    // Compensate for lack of UBYTE4 on Geforce3
    int4 IndexVector = D3DCOLORtoUBYTE4(i.BlendIndices);

    // cast the vectors to arrays for use in the for loop below
    float BlendWeightsArray[4] = (float[4])i.BlendWeights;
    int   IndexArray[4]        = (int[4])IndexVector;

    // calculate the pos/normal using the "normal" weights 
    //        and accumulate the weights to calculate the last weight
    for (int iBone = 0; iBone < NumBones-1; iBone++)
    {
        LastWeight = LastWeight + BlendWeightsArray[iBone];

        Pos += mul(i.Pos, mWorldMatrixArray[IndexArray[iBone]]) * BlendWeightsArray[iBone];
        Normal += mul(i.Normal, mWorldMatrixArray[IndexArray[iBone]]) * BlendWeightsArray[iBone];
    }
    LastWeight = 1.0f - LastWeight; 

    // Now that we have the calculated weight, add in the final influence
    Pos += (mul(i.Pos, mWorldMatrixArray[IndexArray[NumBones-1]]) * LastWeight);
    Normal += (mul(i.Normal, mWorldMatrixArray[IndexArray[NumBones-1]]) * LastWeight); 

    // transform position from world space into view and then projection space
    //o.Pos = mul(float4(Pos.xyz, 1.0f), mViewProj);
    o.Pos = mul(float4(Pos.xyz, 1.0f), mViewProj);
    o.Diffuse.x = 0.0f;
    o.Diffuse.y = 0.0f;
    o.Diffuse.z = 0.0f;
    o.Diffuse.w = 0.0f;
    o.Tex0  = float2(0,0);
    return o;
}

technique t0
{
    pass p0
    {
        VertexShader = compile vs_3_0 VShade(4);
    }
}

I am currently using the SlimDX .NET wrapper around DirectX, but the API is extremely similar:

public void Draw()
{
    var device = vertexBuffer.Device;

    device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.White, 1.0f, 0);

    device.SetRenderState(RenderState.Lighting, true);
    device.SetRenderState(RenderState.DitherEnable, true);
    device.SetRenderState(RenderState.ZEnable, true);
    device.SetRenderState(RenderState.CullMode, Cull.Counterclockwise);
    device.SetRenderState(RenderState.NormalizeNormals, true);

    device.SetSamplerState(0, SamplerState.MagFilter, TextureFilter.Anisotropic);
    device.SetSamplerState(0, SamplerState.MinFilter, TextureFilter.Anisotropic);

    device.SetTransform(TransformState.World, Matrix.Identity * Matrix.Translation(0, -50, 0));
    device.SetTransform(TransformState.View, Matrix.LookAtLH(new Vector3(-200, 0, 0), Vector3.Zero, Vector3.UnitY));
    device.SetTransform(TransformState.Projection, Matrix.PerspectiveFovLH((float)Math.PI / 4, (float)device.Viewport.Width / device.Viewport.Height, 10, 10000000));

    var material = new Material();
    material.Ambient = material.Diffuse = material.Emissive = material.Specular = new Color4(Color.White);
    material.Power = 1f;

    device.SetStreamSource(0, vertexBuffer, 0, vertexSize);
    device.VertexDeclaration = vertexDeclaration;
    device.Indices = indexBuffer;
    device.Material = material;
    device.SetTexture(0, texture);

    var param = effect.GetParameter(null, "mWorldMatrixArray");
    var boneWorldTransforms = bones.OrderedBones.OrderBy(x => x.Id).Select(x => x.CombinedTransformation).ToArray();
    effect.SetValue(param, boneWorldTransforms);
    effect.SetValue(effect.GetParameter(null, "mViewProj"), Matrix.Identity);// Matrix.PerspectiveFovLH((float)Math.PI / 4, (float)device.Viewport.Width / device.Viewport.Height, 10, 10000000));
    effect.SetValue(effect.GetParameter(null, "MaterialDiffuse"), material.Diffuse);
    effect.SetValue(effect.GetParameter(null, "MaterialAmbient"), material.Ambient);

    effect.Technique = effect.GetTechnique(0);
    var passes = effect.Begin(FX.DoNotSaveState);
    for (var i = 0; i < passes; i++)
    {
        effect.BeginPass(i);
        device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, skin.Vertices.Length, 0, skin.Indicies.Length / 3);
        effect.EndPass();
    }
    effect.End();
}

Again, I set diffuse and tex0 vertex shader outputs to zero, but my model still shows the full texture and lighting as if I hadn't changed the values from the vertex buffer. Changing the position of the model works, but nothing else. Why is this?

Also, whatever I set in the bone transformation matrices doesn't seem to have an effect on my model. If I set every bone transformation to a zero matrix, the model still shows up as if nothing had happened, but changing the Pos field in shader output makes the model disappear. I don't understand why I'm getting this kind of behaviour.

Thank you!

© Game Development or respective owner

Related posts about directx

Related posts about shaders