2016-08-15 103 views
4

所以我一直试图围绕过去一周的OpenGL中的阴影贴图进行环绕,而且它并没有那么棒。所以我希望有人能帮助我。 我一直在学习从LearnOpenGL的阴影映射教程中使用前向渲染和从我收集的阴影映射,它似乎像阴影映射与延迟有点不同。 对于初学者来说,这里是我的阴影贴图:使用延迟渲染(OpenGL)进行阴影贴图

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中烦恼紫外线地图的结果。但除此之外,你可以清楚地看到它是各种各样的混乱。我甚至尝试禁用其中一个灯,以确保它不会破坏,因为我有两个灯做shadowCalc函数,但事实并非如此。但我不是100%确定的。

如果任何人有任何想法,为什么发生这种情况,那么我都耳熟能详。这让我困惑了一个星期,似乎无法弄清楚为什么会发生这种情况。我只知道,当我使用阴影偏差时,地面上的条纹会消失,但金字塔后面的巨大阴影仍然存在。它不仅看起来不好,它还指向完全错误的方向,如果将它与阴影贴图的渲染角度进行比较,那么它必须与坐标有关。我读了一些关于延迟渲染如何要求你做某些事情的不同方法,但我还没有设法得到正确的答案。

这已经是相当庞大的帖子,但如果我忘记显示任何可能会清理的东西,那么请告诉。

+1

[* Grimm * Shado](https://www.penny-arcade.com/comic/2009/01/19/further-songs-of-sorcelation-part-two)wmapping [?](http://stackoverflow.com/revisions/38961661/2) – genpfault

+1

没有关于你的位置纹理(你应该考虑在未来通过使用重建进行优化)的编码进行编码。您已将用于对深度纹理进行采样的纹理坐标缩放到[0.0,1.0],但我不知道您的位置缓冲区。除非它是浮点数,否则你的位置既不正常也不能保证为正数,这可能是一个非常大的问题。 –

+1

您只读取深度图中的红色值,您确定在深度通道中正确地将值写入红色组件?并且您正在从z组件读取currentDepth,是否可以发布这些代码以便我们可以检查代码的其余部分。否则,对我来说似乎很好 – codetiger

回答

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;