由于我使用的纹理颜色较暗(这些文物不可见),因此我的阴影从未见过,我有一种奇怪的行为。以下是3个不同阴影贴图分辨率的问题截图:
1)Shadowmap 160 * 120
如你所见,立方体表面有一些牙齿。
这里是光线位置的场景视图:
这是影子地图:
2)Shadowmap 640 * 480
分辨率越高,伪像就越不可见,因为阴影贴图会带来更高的精度。
这里是光线位置的场景视图:
这是影子地图:
我尝试了更高的其他分辨率。当然,工件越来越小,但如果放大表面,它们仍然可见。
这是我在第二次传递期间在片段着色器中使用的代码:
[...]
uniform sampler2DShadow ShadowSampler[MAX_LIGHT_COUNT];
[...]
float GetDynamicShadowBias(vec3 normalDir_cs, vec3 lightDir_cs)
{
float cosTheta = clamp(dot(normalDir_cs, lightDir_cs), 0.0f, 1.0f);
float bias = 0.005f * tan(acos(cosTheta));
return (clamp(bias, 0.0f, 0.01f));
}
float GetBiased_Hard_ShadowFactor(vec3 normalDir, vec3 lightDir, int idx)
{
if (ShadowCoords[idx].w > 0.0f)
{
float bias = GetDynamicShadowBias(normalDir, lightDir);
float LightToOccluderClipDist = texture(
ShadowSampler[idx], ShadowCoords[idx].xyz/ShadowCoords[idx].w);
float LightToVertexClipDist = (ShadowCoords[idx].z - bias)/ShadowCoords[idx].w;
if (LightToOccluderClipDist < LightToVertexClipDist)
return (0.0f);
}
return (1.0f);
}
所以我想知道是否有可能在立方体的边缘上移除这些瑕疵。我尝试使用阴影偏差而没有真正的成功(对于我在第一次传递期间使用FRONT_FACE剔除(填充深度纹理)的信息)。
答案 0 :(得分:1)
这里有两件事。一个是这是标准阴影贴图的限制。因为任何给定对象的阴影将占据地图中可能较少数量的像素,当您将该地图投射到场景上时,这些部分可以重新放大并且您将获得锯齿。
似乎正在发生的第二件事是你的阴影基本上是1位,它出现了。它们是黑色或白色。如果你以某种方式在制作它时对地图进行抗锯齿处理(比如超级采样或其他一些技术),那就不太明显了(虽然根据我的经验它不会完全消失)。
有一些基于经典阴影贴图的技术。一个是来自SIGGRAPH 2013的Subpixel Shadow Mapping。(有some other shadow papers that year, too。)我最近还看到了通过GLSL实时实现的光线投影阴影。 (对不起,找不到链接!如果我能把它挖出来,我会稍后发帖。)