我刚开始搞乱阴影贴图。我理解使用的算法。事情是我不能为我的生活找出我在HLSL代码搞乱的地方。这是:
//These change
float4x4 worldViewProj;
float4x4 world;
texture tex;
//These remain constant
float4x4 lightSpace;
float4x4 lightViewProj;
float4x4 textureBias;
texture shadowMap;
sampler TexS = sampler_state
{
Texture = <tex>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
AddressU = WRAP;
AddressV = WRAP;
};
sampler TexShadow = sampler_state
{
Texture = <shadowMap>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
};
struct A2V
{
float3 posL : POSITION0;
float2 texCo : TEXCOORD0;
};
struct OutputVS
{
float4 posH : POSITION0;
float2 texCo : TEXCOORD0;
float4 posW : TEXCOORD2;
};
//Vertex Shader Depth Pass
OutputVS DepthVS(A2V IN)
{
OutputVS OUT = (OutputVS)0;
//Get screen coordinates in light space for texture map
OUT.posH = mul(float4(IN.posL, 1.f), lightViewProj);
//Get the depth by performing a perspective divide on the projected coordinates
OUT.posW.x = OUT.posH.z/OUT.posH.w;
return OUT;
}
//Pixel shader depth Pass
float4 DepthPS(OutputVS IN) : COLOR
{
//Texture only uses red channel, just store it there
return float4(IN.posW.x, 0, 0, 1);
}
//VertexShader Draw Pass
OutputVS DrawVS(A2V IN)
{
OutputVS OUT = (OutputVS)0;
//Get the screen coordinates for this pixel
OUT.posH = mul(float4(IN.posL, 1.f), worldViewProj);
//Send texture coordinates through
OUT.texCo = IN.texCo;
//Pass its world coordinates through
OUT.posW = mul(float4(IN.posL, 1.f), world);
return OUT;
}
//PixelShader Draw Pass
float4 DrawPS(OutputVS IN) : COLOR
{
//Get the pixels screen position in light space
float4 texCoord = mul(IN.posW, lightViewProj);
//Perform perspective divide to normalize coordinates [-1,1]
//texCoord.x = texCoord.x/texCoord.w;
//texCoord.y = texCoord.y/texCoord.w;
//Multiply by texture bias to bring in range 0-1
texCoord = mul(texCoord, textureBias);
//Get corresponding depth value
float prevDepth = tex2D(TexShadow, texCoord.xy);
//Check if it is in shadow
float4 posLight = mul(IN.posW, lightViewProj);
float currDepth = posLight.z/posLight.w;
if (currDepth >= prevDepth)
return float4(0.f, 0.f, 0.f, 1.f);
else
return tex2D(TexS, IN.texCo);
}
//Effect info
technique ShadowMap
{
pass p0
{
vertexShader = compile vs_2_0 DepthVS();
pixelShader = compile ps_2_0 DepthPS();
}
pass p1
{
vertexShader = compile vs_2_0 DrawVS();
pixelShader = compile ps_2_0 DrawPS();
}
}
我已经确认我的所有矩阵都正确并且正确绘制了深度贴图。重写了处理这段代码的所有C ++并使它更整洁,我仍然遇到同样的问题。我目前没有混合阴影,只是将它们画成黑色,直到我可以让它们正确绘制。光使用正交投影,因为它是定向光。我没有足够的声誉点来嵌入图片,但这里是URL:深度图 - http://i.imgur.com/T2nITid.png 节目输出 - http://i.imgur.com/ae3U3N0.png
任何帮助或见解都会受到学校项目的青睐。感谢
答案 0 :(得分:2)
从深度缓冲区获得的值是浮点值,从0到1.您可能已经知道,浮点数不准确,您请求的小数点越多,它就越不准确,这就是您结束的地方有文物。
你可以做一些事情。最简单的方法是使投影矩阵中远近Z的值更接近彼此,以便深度缓冲区不会使用这么多小数位来表示对象的距离。我通常发现值为1-200会给我一个相当不错的准确结果。
你可以做的另一件容易的事情是增加你正在绘制的纹理的大小,因为这会给你更多的像素,因此它将更准确地表示场景。
游戏引擎还可以做很多复杂的事情来改进阴影贴图工件,但是你可以写一本关于它的书,如果你真的想进入它,那么我建议你从{{{ 3}}