为什么只有在正确的位置呈现第一个阴影?
问题描述:
我正在研究Java + LWJGL项目。目前我正在尝试实现方差阴影贴图,但只有我在着色器中采样的第一个阴影贴图出现在正确的位置。为什么只有在正确的位置呈现第一个阴影?
片段着色器:
#version 330 core
in vec2 passTexCoords;
in vec4[4] shadowCoords;
//Fragment color
out vec4 out_Color;
uniform sampler2D modelTexture;
uniform sampler2D[4] shadowMaps;
#define SHADOW_BIAS 0.0005
float linstep(float low, float high, float v) {
return clamp((v-low)/(high-low), 0.0, 1.0);
}
//compare ... The depth of the fragment in shadow map sapce
float sampleVarianceShadowMap(in sampler2D shadowMap, in vec2 coords, in float compare) {
/* This is the Code that I want to use when I know what the problem was.
vec2 moments = texture(shadowMap, coords.xy).rg;
float p = step(compare, moments.x);
float variance = max(moments.y - moments.x * moments.x, 0.00002);
float d = compare - moments.x;
float pMax = linstep(0.2, 1.0, variance/(variance + d*d));
return min(max(p, pMax), 1.0);
*/
//============================================================================HERE=========================================================================HERE====================
//THE ERROR OCCURES HERE:
//This doesn't work:
float visibility = step(compare-SHADOW_BIAS, texture(shadowMap, coords.xy).r);
return visibility;
//The shadows on the ground move in a weird way when the camera moves.
//But this does:
return step(compare-SHADOW_BIAS, texture(shadowMap, coords.xy).r);
//With this code the shadows are at the correct place.
//===========================================================================HERE==========================================================================HERE=====================
}
//To create a smooth darkness falloff at the edge of the shadow map
float calcShadowMapVisibilityFalloff(in vec2 coords, in float falloffStart, in float gradient) {
float distFromTexCenter = length(coords * vec2(2.0) - vec2(1.0));
float falloff = (clamp(pow(distFromTexCenter, gradient), falloffStart, 1.0) - falloffStart) * (1/(1-falloffStart));
if(falloff > 1.0 || falloff < 0.0) {
falloff = 0;
}
return 1-falloff;
}
void main(void){
float shadowInvertedBrightness = 1.0;
for(int i = 0; i < shadowMaps.length(); i++)
{
float visibility = 1 - sampleVarianceShadowMap(shadowMaps[i], shadowCoords[i].xy, shadowCoords[i].z);
shadowInvertedBrightness -= (visibility/shadowMaps.length()) * calcShadowMapVisibilityFalloff(shadowCoords[i].xy, 0.85, 2.0);
}
shadowInvertedBrightness = clamp(shadowInvertedBrightness, 0.2, 1.0);
//.bgra because I save textures with the BGRA format (I've read its faster)
out_Color = texture(modelTexture, passTexCoords).bgra * vec4(shadowInvertedBrightness,shadowInvertedBrightness,shadowInvertedBrightness,1);
}
顶点着色器:
#version 330 core
//Vertex coords
in vec3 position;
//Texture coords
in vec2 texCoords;
//The MVP matrix of the entity
uniform mat4 MVPMat;
//The "To Shadow Map Space" matrix
uniform mat4[4] shadowMVPBiasMats;
//The Transformation matrix of the entity
uniform mat4 transformMat;
out vec2 passTexCoords;
//Shadow map sample coords
out vec4[4] shadowCoords;
void main(void) {
gl_Position = MVPMat * vec4(position, 1.0);
vec4 worldPos = transformMat * vec4(position, 1.0);
for(int i = 0; i < shadowMVPBiasMats.length(); i++) {
shadowCoords[i] = shadowMVPBiasMats[i] * worldPos;
}
passTexCoords = texCoords;
}
完整的代码(示例项目,你可以在Eclipse中导入)和截图:
- Screenshots and source code(着色器文件在src/ShadowTest/rendering /,屏幕截图/)
系统信息:
- 操作系统:Windows主页,版本:10.0.15063
- GPU:英特尔高清显卡520
- GPU驱动程序版本:20.19.15.4642(通过Medion公司)
答
这似乎是驱动程序中的一个错误,因为它在我使用NVIDIA GPU运行程序时不会发生。
的规避问题:
float textureShadowMap(in sampler2D shadowMap, in vec2 coords) {
return texture(shadowMap, coords).r;
}
而在sampleVarianceShadowMap方法:
float visibility = step(compare-SHADOW_BIAS, textureShadowMap(shadowMap, coords));
return visibility;
因为我不是100%肯定,这是一个错误,它会如果有人可真好确认这一点。
请提供更多信息。一些截图等。你看到人们低估了你。这是因为没有办法帮助你提供的数据。而且,GLSL是不够的。你的问题可以在客户端使用着色器输入。 –
我会建议一个一个地测试你的shadowMap,首先删除你的main,然后加上float visibility = 1;如果(shadowCoord [i] .z-SHADOW_BIAS> texture(shadowMap [i],shadowCoord [i] .xy).r){visibility = 0; } out_Color = texture(modelTexture,passTexCoords).bgra * vec4(visibility,visibility,visibility,1);并告诉我们你看到的一个。您也可以尝试将影子地图保存在磁盘上并在查看器中显示它们 –
如果您需要更多代码或屏幕截图,请查看Google Drive链接。我也会尝试Draykoon D说的。 – Wendelin