我已经尝试了一个星期来理解OpenGL中的阴影映射,但效果并不好。因此,我希望有人能在这里给我提供帮助。我一直在学习LearnOpenGL的阴影映射教程,该教程使用前向渲染方式,从我的理解来看,使用延迟渲染的阴影映射会有所不同。以下是我的阴影贴图:
它是红色的,但根据朋友的说法,这是可以接受的。但我仍然觉得我做错了什么。假设这不是问题,阴影贴图将被正确地渲染,并在延迟渲染的光照通道中到达。我还发送了一个包含所有光空间中片段的缓冲区,我已经使用光空间变换矩阵进行了转换。
最后,我将这个阴影值应用于我的漫反射和镜面光照值:
然后我像往常一样输出了结果颜色,结果就是这样:
![Shadow map picture](https://istack.dev59.com/ZXSv8.webp)
//Create LSMatrix
GLfloat near_plane = 1.0f;
GLfloat far_plane = 10.0f;
glm::mat4 lightProjMat = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane);
glm::mat4 lightPerspective = glm::lookAt(glm::vec3(-2.0f, 6.0f, -1.0f),
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f));
shadowBuf.lightSpaceMat = lightProjMat * lightPerspective;
我现在没有定向光,只有两个点光源。因此,使用正交投影等方法会给我一个不正确的阴影。但是,仍然会有一个阴影。现在无论阴影来自哪里都不重要,我只是想学习。然后我可以担心如何使它与光源匹配。
这里是在几何通道的GLSL顶点着色器中使用的(LSMat)。
void main()
{
gl_Position = vec4(position, 1.0f);
vs_out.uv = uv;
vs_out.normal = normal;
vs_out.FragPos = vec3(model * vec4(position, 1.0f));
vs_out.FragPosLS = LSMat * vec4(vs_out.FragPos, 1.0f); //Fragment position in light space
}
然后在片段着色器中,它被保存到纹理中并发送到光照通道。
现在我已经拥有了在我的光照通道中进行阴影计算所需的一切。(希望至少如此)
这是我在光照通道中进行阴影计算的片段着色器的部分:
float shadowCalc()
{
vec4 fragPosLS = texture(gFragPosLS, uvs); //Fetch the lightspace frag pos from the texture
vec3 projCoords = fragPosLS.xyz / fragPosLS.w; //Manually do perspective divison
projCoords = projCoords * 0.5 + 0.5; //Get the pos in [0,1] range
float closestDepth = texture(shadowMap, projCoords.xy).r;
float currentDepth = projCoords.z;
float shadow = currentDepth > closestDepth ? 1.0 : 0.0;
return shadow;
}
最后,我将这个阴影值应用于我的漫反射和镜面光照值:
float shadowValue = shadowCalc();
diffuse = diffuse * (1.0 - shadowValue);
specular = specular * (1.0 - shadowValue);
return ((diffuse * vec4(gColor, 1.0f)) + specular + ambient);
然后我像往常一样输出了结果颜色,结果就是这样: