使用延迟渲染的阴影映射(OpenGL)

4
我已经尝试了一个星期来理解OpenGL中的阴影映射,但效果并不好。因此,我希望有人能在这里给我提供帮助。我一直在学习LearnOpenGL的阴影映射教程,该教程使用前向渲染方式,从我的理解来看,使用延迟渲染的阴影映射会有所不同。以下是我的阴影贴图: Shadow map picture 它是红色的,但根据朋友的说法,这是可以接受的。但我仍然觉得我做错了什么。假设这不是问题,阴影贴图将被正确地渲染,并在延迟渲染的光照通道中到达。我还发送了一个包含所有光空间中片段的缓冲区,我已经使用光空间变换矩阵进行了转换。
//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);

然后我像往常一样输出了结果颜色,结果就是这样:

Picture of the result

可怕的纹理只是因为我现在不想在Maya中正确UV映射事物。但除此之外,你可以清楚地看到它变得混乱不堪。我甚至尝试禁用一个灯光以确保它没有因为我有两个灯光执行shadowCalc函数而被破坏,但那不是原因。但我不确定是否百分之百正确。如果有人对发生这种情况有任何想法,我愿意倾听。这让我感到困惑已经一个星期了,但我似乎无法弄清楚为什么会发生这种情况。我只知道地面上的条纹在使用阴影偏差时会消失,但金字塔后面的巨大阴影仍然存在。它不仅看起来很糟糕,而且与渲染阴影贴图的角度完全相反。因此,这必须是与坐标有关的问题。我读到过关于延迟渲染需要您以不同方式处理一些事情的内容,但我还没有找到一个合适的答案。这已经是一个相当庞大的帖子了,但如果我忘记展示任何可以澄清问题的内容,请告诉我。

1
Grimm Shado wmapping? - genpfault
1
关于你的位置纹理的编码,没有讨论(你应该考虑通过使用重建来进行优化)。你已经将用于采样深度纹理的纹理坐标缩放到[0.0, 1.0],但我不知道你的位置缓冲区是什么情况。除非它是浮点数,否则你的位置既没有归一化也不能保证为正数,这可能是一个很大的问题。 - Andon M. Coleman
1
你只从深度图中读取了红色值,你确定你已经正确地将该值写入深度通道的红色分量中吗?而且你正在从z分量中读取currentDepth,你能否发布这些代码,以便我们可以检查其余的代码。否则,对我来说看起来很好。 - codetiger
1
请在初始化深度图格式时添加代码。您是否使用单通道缓冲区? - Harish
2
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Andon M. Coleman
显示剩余4条评论
1个回答

0
仅供参考:我曾经遇到过与延迟渲染结合使用的阴影映射问题,看起来与您在屏幕截图中展示的情况非常相似。在我的情况下,我从深度纹理中错误地读取了Z值。深度纹理中的值是通过以下方式创建的: gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT16, 2048, 2048, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT, null); 这些值被归一化为(-1;+1),因此我必须将它们修改回来,如下所示: texture(shadowMap, projCoords.xy).r - .5) * 2. 可见性计算如下:
float bias = .01;
float visibility = (texture(shadowMap, projCoords.xy).r - .5) * 2. < projCoords.z - bias ? 0.1: 1.0;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接