Pixel Shader仅处理从Vertex Shader传递的部分数据

时间:2015-10-25 23:15:37

标签: directx

我使用DirectX11绘制场景。但我只有黑色的形状。然后我使用Microsoft Visual Studio的图形调试器来查看数据过程。所有常量缓冲区,输入缓冲区数据都被校正从主存储器传输到GPU内存。但在像素着色器中,调试器仅处理环境光。另一个灯和NoramlW,EyePostion矢量显示为"不在范围"或"未使用"。指令指针跳过所有这些"不在范围内#34;变量程序行。结果是环境光的颜色很少(约0.1 + f),所以基本是黑色。当我将初始环境光增加到1.0f时,形状会有一些颜色。但是,整个Pixel着色器的工作方式并不像我想要的那样。

我检查了"不在范围"中的变量,并且它们都没有拼写错误。 我不知道为什么。以下“顶点着色器”和“像素着色器”功能仅是过去简单的基本修复函数渲染以及骨骼动画。 我检查了GPU中的所有数据:常量缓冲区,输入缓冲区数据在调试器中是否正确。但它显示"不在范围"一步一步地执行。

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 个答案:

答案 0 :(得分:0)

我自己得到了: 在功能&#34; ComputerDirectionalLight&#34;功能,我忘了添加&#34; out&#34; diffuse之前的关键字,spec。

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

应该是:

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