0
votes

I use DirectX11 to draw scenes. But I only got black color shapes. Then I use Microsoft Visual Studio's Graphic Debugger to look at the data process. All constant Buffer, input buffer data were corrected transferred from main memory to GPU memory. But in pixel shader, the debugger only process the ambient light. The other light and NoramlW, EyePostion vectors display as "not in scope" or "not used". The instruction pointer skip all these "not in scope" variables program lines. The result is very little ambient light color about (0.1+f), so basic it is black. When I increase the initial ambient light to 1.0f, then the shape has some color. But, the whole Pixel shader works not as I intend to.

I check the variables that "not in scope", and none of them are mis-spelled. I don't know why. The following Vertex Shader and Pixel shader functions are only simple basic fix function rendering in old days plus bone animation. I checked all the data in GPU: constant buffer, input buffer data are correct in in the debugger. But it shows "not in scope" in step by step execution.

cbuffer cbPerFrame : register(b0) {
float4x4 gViewProj;
DirectionalLight gDirLight[3];
float3 gEyePosW;
float pad;
float4 gFogColor;
float gFogStart;
float gFogRange;
};
cbuffer cbPerObject : register(b1) {
float4x4 gWorld;
float4x4 gWorldInvTranspose;
float4x4 gTexTransform;
Material gMaterial;
};

cbuffer cbAnimationBones : register(b2) {
float4x4 gBoneTransforms[58];
};
struct VertexIn {
float3 PosL         :POSITION;
float3 NormalL      :NORMAL;
float2 Tex          :TEXCOORD;
float4 TangentL     :TANGENT;
float3 Weights      :WEIGHTS;
uint4 BoneIndices   :BONEINDICES;
};

struct VertexOut {
float3 PosW             :   POSITION;
float3 NormalW          :   NORMAL;
float2 Tex              :   TEXCOORD;
float4 PosH             :   SV_POSITION;
};

VertexOut main( VertexIn vin) {
VertexOut vout;
float weights[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
float3 posL = float3(0.0f, 0.0f, 0.0f);
float3 normalL = float3(0.0f, 0.0f, 0.0f);
weights[0] = vin.Weights.x;
weights[1] = vin.Weights.y;
weights[2] = vin.Weights.z;
weights[3] = 1.0f - weights[0] - weights[1] - weights[2];

//blend skin vertex
[unroll]
for (int i = 0; i < 4; ++i) {
    posL += weights[i] * mul(float4(vin.PosL, 1.0f), gBoneTransforms[vin.BoneIndices[i]]).xyz;
    normalL += weights[i] * mul(vin.NormalL, (float3x3)gBoneTransforms[vin.BoneIndices[i]]);
}
//coordinates transformation
vout.PosW = mul(float4(posL, 1.0f), gWorld).xyz;
vout.NormalW = mul(normalL, (float3x3)gWorldInvTranspose);
vout.PosH = mul(float4(vout.PosW, 1.0f), gViewProj);

//transform texture
vout.Tex = mul(float4(vin.Tex, 0.0f, 1.0f), gTexTransform).xy;
return vout;
 }

struct PixelIn {
float3 PosW     :   POSITION;
float3 NormalW          :   NORMAL;
float2 Tex      :   TEXCOORD;
};
Texture2D gDiffuseMap : register(t0);
SamplerState samState : register(s0);

float4 main(PixelIn pin) : SV_TARGET
{

//the debugger will skip these vectors calculation
//since pin.NormalW, pin.PosW are not in scope.
// only pin.Tex has two values which means Vertex Shader has passed variable  here
pin.NormalW = normalize(pin.NormalW);
float3 toEye = gEyePosW - pin.PosW;
float distanceToEye = length(toEye);
toEye /= distanceToEye;

//the debugger start from the following line:
float4 texColor = float4(1, 1, 1, 1);
texColor = gDiffuseMap.Sample(samState, pin.Tex);

float4 lightColor = texColor;

float4 ambient = float4(0.0f, 0.0f, 0.0f, 0.0f);
float4 diffuse = float4(0.0f, 0.0f, 0.0f, 0.0f);
float4 spec = float4(0.0f, 0.0f, 0.0f, 0.0f);

[unroll]
for (uint i = 0; i < 3; ++i) {
        float4 A, D, S;
    //the debugger will skip A assignment since it says A is not in scope
    A = float4(0.0f, 0.0f, 0.0f, 0.0f);
    D = float4(0.0f, 0.0f, 0.0f, 0.0f);
    S = float4(0.0f, 0.0f, 0.0f, 0.0f);
    ComputeDirectionalLight(gMaterial, gDirLight[i], pin.NormalW, toEye, A, D, S);

// the gMaterial only gMateria.ambient has value, the rest of part "not in scope, but I can see the whole values passed correctly in the GPU object.
// The computeDirectinalLight function only calculate the ambient light since the Normal, eye, vectors "not in scope"

    ambient += A;
    diffuse += D;
    spec    += S;
}
lightColor = texColor * (ambient + diffuse) + spec;
lightColor.a = gMaterial.Diffuse.a * texColor.a;
return lightColor;
}

struct Material {
float4 Ambient;
float4 Diffuse;
float4 Specular;
float4 Reflect;
};
struct DirectionalLight {
float4 Ambient;
float4 Diffuse;
float4 Specular;
float3 Direction;
float pad;
};

void ComputeDirectionalLight(Material mat, DirectionalLight L, float3 normal, float3 toEye, out float4 ambient, float4 diffuse, float4 spec) {

// the debugger skip the following line since L.Direction vector "not in scope"
float3 lightVec = -L.Direction;

//the debugger only execute the following one line
ambient = mat.Ambient * L.Ambient;

 //the debugger return here and skip all the following lines:
float diffuseFactor = dot(lightVec, normal);
[flatten]
if (diffuseFactor > 0.0f) {
    float3 v = reflect(-lightVec, normal);
    float specFactor = pow(max(dot(v, toEye), 0.0f), mat.Specular.w);

    diffuse = diffuseFactor * mat.Diffuse * L.Diffuse;
    spec = specFactor * mat.Specular * L.Specular;
}
}
1

1 Answers

0
votes

I got it myself: In function "ComputerDirectionalLight" function, I forgot add "out" keyword before diffuse, spec.

void ComputeDirectionalLight(Material mat, DirectionalLight L, float3 normal, float3 toEye, out float4 ambient, float4 diffuse, float4 spec) 

should be:

void ComputeDirectionalLight(Material mat, DirectionalLight L, float3 normal, float3 toEye, out float4 ambient, out float4 diffuse, out float4 spec)