为什么在使用透明胶片的阴影贴图技术时,这条黑线会出现在投影阴影的边界上?
Why does this black line appear on the borders of projected shadows when using the shadowmap technique with transparencies?
这是问题截图:http://s13.postimg.org/672twurfr/shadowmap_saturn_rings.jpg
你可以注意到在土星上环的投影阴影顶部有一条黑线,它出现在任何物体阴影的所有边界上。
这是我用来渲染深度图的像素着色器,我使用颜色的绿色和蓝色值来存储 alpha 值。
float depthValue;
float4 color;
float4 textureColor;
textureColor = shaderTexture.Sample(SampleType, input.tex);
depthValue = input.depthPosition.z / input.depthPosition.w;
color = float4(depthValue, textureColor.a, textureColor.a, 1.0f);
return color;
这是我用来渲染将要显示的最终颜色的像素着色器片段:
if((saturate(projectTexCoord.x) == projectTexCoord.x) && (saturate(projectTexCoord.y) == projectTexCoord.y))
{
float4 color_d = depthMapTexture.Sample(SampleTypeClamp, projectTexCoord);
depthValue = color_d.r;
lightDepthValue = input.lightViewPosition.z / input.lightViewPosition.w;
lightDepthValue = lightDepthValue - bias;
if(lightDepthValue < depthValue)
{
lightIntensity = saturate(dot(input.normal, lightDir));
}
else
{
lightIntensity = saturate(dot(input.normal, lightDir))*(1.0f - color_d.g);
}
}
抱歉,信息模糊,但我真的不知道问题出在哪里,也许是代码中的其他地方,但绝对不是我正在使用的纹理文件,所以它必须是代码。
知道我可以从哪里开始寻找问题吗?
可能是阴影贴图纹理坐标采样越界。我可以看到你正在检查它,但我还是会测试它。
在您的 SamplerState 中,您是否设置了 BorderColor?尝试将其设置为红色,看看是否是问题所在。
阴影贴图的深度是否与您应用着色器的渲染目标相同?
编辑。这是我的 SampleCmpLevelZero 着色器代码:
if (ShadowCoord.x > 0.0f && ShadowCoord.x < 1.0f && ShadowCoord.y > 0.0f && ShadowCoord.y < 1.0f)
{
ShadowCoord.z -= 0.001f;
float a = 1;
a = ShadowMap.SampleCmpLevelZero(ShadowSampler, ShadowCoord.xy, ShadowCoord.z).r;
a = linearizeDepth(a);
ambient = float4(a,a,a, 0);
}
问题出在 D3D11_SAMPLER_DESC 使用的纹理过滤器上,它被设置为 D3D11_FILTER_MIN_MAG_MIP_LINEAR,因此纹理被插值,有点柔化了边界处的颜色和 alpha 值,这导致着色器读取那些软 alpha 值并在不应该的地方投射阴影。
我使用 D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT 作为过滤器创建了一个新的 samplerdesc,因此纹理将呈现出边框基本不变,就像深度着色器最初创建它一样。现在阴影投射正确,边界处不再有奇怪的黑线。
这是问题截图:http://s13.postimg.org/672twurfr/shadowmap_saturn_rings.jpg
你可以注意到在土星上环的投影阴影顶部有一条黑线,它出现在任何物体阴影的所有边界上。
这是我用来渲染深度图的像素着色器,我使用颜色的绿色和蓝色值来存储 alpha 值。
float depthValue;
float4 color;
float4 textureColor;
textureColor = shaderTexture.Sample(SampleType, input.tex);
depthValue = input.depthPosition.z / input.depthPosition.w;
color = float4(depthValue, textureColor.a, textureColor.a, 1.0f);
return color;
这是我用来渲染将要显示的最终颜色的像素着色器片段:
if((saturate(projectTexCoord.x) == projectTexCoord.x) && (saturate(projectTexCoord.y) == projectTexCoord.y))
{
float4 color_d = depthMapTexture.Sample(SampleTypeClamp, projectTexCoord);
depthValue = color_d.r;
lightDepthValue = input.lightViewPosition.z / input.lightViewPosition.w;
lightDepthValue = lightDepthValue - bias;
if(lightDepthValue < depthValue)
{
lightIntensity = saturate(dot(input.normal, lightDir));
}
else
{
lightIntensity = saturate(dot(input.normal, lightDir))*(1.0f - color_d.g);
}
}
抱歉,信息模糊,但我真的不知道问题出在哪里,也许是代码中的其他地方,但绝对不是我正在使用的纹理文件,所以它必须是代码。
知道我可以从哪里开始寻找问题吗?
可能是阴影贴图纹理坐标采样越界。我可以看到你正在检查它,但我还是会测试它。 在您的 SamplerState 中,您是否设置了 BorderColor?尝试将其设置为红色,看看是否是问题所在。
阴影贴图的深度是否与您应用着色器的渲染目标相同?
编辑。这是我的 SampleCmpLevelZero 着色器代码:
if (ShadowCoord.x > 0.0f && ShadowCoord.x < 1.0f && ShadowCoord.y > 0.0f && ShadowCoord.y < 1.0f)
{
ShadowCoord.z -= 0.001f;
float a = 1;
a = ShadowMap.SampleCmpLevelZero(ShadowSampler, ShadowCoord.xy, ShadowCoord.z).r;
a = linearizeDepth(a);
ambient = float4(a,a,a, 0);
}
问题出在 D3D11_SAMPLER_DESC 使用的纹理过滤器上,它被设置为 D3D11_FILTER_MIN_MAG_MIP_LINEAR,因此纹理被插值,有点柔化了边界处的颜色和 alpha 值,这导致着色器读取那些软 alpha 值并在不应该的地方投射阴影。
我使用 D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT 作为过滤器创建了一个新的 samplerdesc,因此纹理将呈现出边框基本不变,就像深度着色器最初创建它一样。现在阴影投射正确,边界处不再有奇怪的黑线。