【发布时间】:2012-03-24 18:39:19
【问题描述】:
首先,截图:
如您所见,阴影的顶部看起来不错(如果您看一下灌木顶部投影的泥土,它看起来或多或少是正确的),但阴影的底部距离很远。
图像的左下角显示了我计算的阴影贴图。这是来自光的 POV 的深度图,这也是我的角色站立的位置。
这是另一个角度的照片:
任何想法可能导致它出现这样的结果?灌木面的深度是否与它后面的地面深度太相似了,也许?如果是这样,我该如何解决?
我将在下面发布片段着色器,如果您还有什么需要看的,请发表评论。
片段着色器
#version 330
in vec2 TexCoord0;
in vec3 Tint0;
in vec4 WorldPos;
in vec4 LightPos;
out vec4 FragColor;
uniform sampler2D TexSampler;
uniform sampler2D ShadowSampler;
uniform bool Blend;
const int MAX_LIGHTS = 16;
uniform int NumLights;
uniform vec3 Lights[MAX_LIGHTS];
const float lightRadius = 100;
float distSq(vec3 v1, vec3 v2) {
vec3 d = v1-v2;
return dot(d,d);
}
float CalcShadowFactor(vec4 LightSpacePos)
{
vec3 ProjCoords = LightSpacePos.xyz / LightSpacePos.w;
vec2 UVCoords;
UVCoords.x = 0.5 * ProjCoords.x + 0.5;
UVCoords.y = 0.5 * ProjCoords.y + 0.5;
float Depth = texture(ShadowSampler, UVCoords).x;
if (Depth < (ProjCoords.z + 0.0001))
return 0.5;
else
return 1.0;
}
void main()
{
float scale;
FragColor = texture2D(TexSampler, TexCoord0.xy);
// transparency
if(!Blend && FragColor.a < 0.5) discard;
// biome blending
FragColor *= vec4(Tint0, 1.0f);
// fog
float depth = gl_FragCoord.z / gl_FragCoord.w;
if(depth>20) {
scale = clamp(1.2-15/(depth-19),0,1);
vec3 destColor = vec3(0.671,0.792,1.00);
vec3 colorDist = destColor - FragColor.xyz;
FragColor.xyz += colorDist*scale;
}
// lighting
scale = 0.30;
for(int i=0; i<NumLights; ++i) {
float dist = distSq(WorldPos.xyz, Lights[i]);
if(dist < lightRadius) {
scale += (lightRadius-dist)/lightRadius;
}
}
scale *= CalcShadowFactor(LightPos);
FragColor.xyz *= clamp(scale,0,1.5);
}
我相当肯定这是一个偏移问题。我的阴影看起来大约有 1 个街区,但我不知道如何移动它们,也不知道是什么导致它们关闭。
实际上看起来像“depth map bias”:
不完全确定如何设置这个......我只是在渲染场景之前调用glPolygonOffset 吗?会试试...
将glPolygonOffset 设置为 100,100 会放大问题:
我在渲染阴影贴图之前设置了这个:
GL.Enable(EnableCap.PolygonOffsetFill);
GL.PolygonOffset(100f, 100.0f);
然后再次禁用它。我不确定我是否应该这样做。增加值会放大问题....将它们减小到 1 以下似乎并没有改善它。
还要注意左下角的阴影贴图是如何变化的。
顶点着色器
#version 330
layout(location = 0) in vec3 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 2) in mat4 Transform;
layout(location = 6) in vec4 TexSrc; // x=x, y=y, z=width, w=height
layout(location = 7) in vec3 Tint; // x=R, y=G, z=B
uniform mat4 ProjectionMatrix;
uniform mat4 LightMatrix;
out vec2 TexCoord0;
out vec3 Tint0;
out vec4 WorldPos;
out vec4 LightPos;
void main()
{
WorldPos = Transform * vec4(Position, 1.0);
gl_Position = ProjectionMatrix * WorldPos;
LightPos = LightMatrix * WorldPos;
TexCoord0 = vec2(TexSrc.x+TexCoord.x*TexSrc.z, TexSrc.y+TexCoord.y*TexSrc.w);
Tint0 = Tint;
}
【问题讨论】:
-
所以摄像头位于人的头部。顶部是矿灯。然后阴影贴图应该从稍微抬高的位置查看场景的深度 -
-
@StefanHanke:不知道你所说的“稍微抬高”是什么意思。这只是一个观察,还是我可以做点什么?
-
观察。由于我从未实现过阴影贴图,因此我不确定以下几点:阴影贴图是使用灯光的位置生成的。由于这是在人的头上,我希望视图是从上面看的。从图像来看,灯似乎低于头部。那么,也许与光矩阵有关?对不起,如果这完全是假的......
-
@StefanHanke:你的观察是正确的。灯比头部低一点;我相信“矿工的光”表达只是意味着光接近相机,而不是实际上直接上方,或完全相同的点。
-
您介意发布顶点着色器吗?