OpenGL阴影立方体贴图深度值获取

问题描述

我没有解决办法。我实现了定向光的阴影贴图和2D阴影图的聚光灯,没有任何问题。但是用点光源我无法解决问题。

我做了很多测试,以确保我的阴影立方体贴图正确渲染。这是渲染最终场景时nsight的捕获。我们可以在小窗口中看到活动的纹理单元,并且立方体贴图将场景正确地呈现为深度纹理。

Shadow cubemap

但是完全没有阴影。

我的想法是方向矢量(在来自顶点着色器的世界空间中,光位置减去了顶点位置)对于获取深度纹理中的样本无效。所以我在这张照片中将方向显示为颜色:

Light direction in world space

我不确定是否正确,但是至少,我知道每个片段之间的方向是可变的。

我不知道为什么我什么都看不见,甚至是越野车的影子。

我什至在vec4中甚至直接从texture()函数中使用深度值,场景完全精简了,因此我假定该值始终为1.0或更大。

这是我的片段着色器的GLSL代码(用于最终渲染):

#version 450 core

/* Fragment shader: Render a geometry using MilkMaterial. */

/* Program uniforms */
uniform vec4 em_AmbientLight = vec4(0.1);
uniform vec4 em_DirectionalLightColor[1];
uniform int em_DirectionalLightCount = 0;
uniform vec4 em_DirectionalLightDirection[1];
uniform float em_DirectionalLightIntensity[1];
uniform sampler2DShadow em_DirectionalLightShadowMap[1];
uniform vec4 em_PointLightColor[1];
uniform int em_PointLightCount = 0;
uniform float em_PointLightIntensity[1];
uniform samplerCubeShadow em_PointLightShadowMap[1];
uniform vec4 em_PrimaryColor = vec4(1.0);
uniform float em_Shininess = 2.0;
uniform vec4 em_SpotLightColor[2];
uniform int em_SpotLightCount = 0;
uniform vec4 em_SpotLightDirection[2];
uniform float em_SpotLightInnerCosAngle[2];
uniform float em_SpotLightIntensity[2];
uniform float em_SpotLightOuterCosAngle[2];
uniform sampler2DShadow em_SpotLightShadowMap[2];

/* Program interface blocks (Shader) */
in DirectionalLightShaderBlock
{
    smooth vec4 fragmentPosition;
} isv_DirectionalLight[1];

in PointLightShaderBlock
{
    smooth vec3 directionEyeSpace;
    smooth vec4 directionWorldspace;
    smooth float attenuation;
} isv_PointLight[1];

in SpotLightShaderBlock
{
    smooth vec4 fragmentPosition;
    smooth vec3 directionEyeSpace;
    smooth float attenuation;
} isv_SpotLight[2];


/* Stage inputs */
smooth in vec3 isv_normalEyeSpace;
smooth in vec3 isv_PositionEyeSpace;

/* Stage outputs */
layout(location = 0) out vec4 em_OutputFragment;

void compute_directional_light (const in int lightIndex,const in vec3 N,inout vec4 lightColor,inout vec4 lightspecularFactor)
{
    float shadow = textureProj(em_DirectionalLightShadowMap[lightIndex],isv_DirectionalLight[lightIndex].fragmentPosition);

    if ( shadow <= 0.0 ) {return;}
    
    vec3 L = normalize(-em_DirectionalLightDirection[lightIndex].xyz);

    float diffuseFactor = dot(L,N);

    if ( diffuseFactor <= 0.0 ) {return;}

    lightColor += diffuseFactor * em_DirectionalLightColor[lightIndex] * em_DirectionalLightIntensity[lightIndex];
    
    vec3 R = normalize(reflect(-L,N));
    vec3 E = normalize(isv_PositionEyeSpace);

    float specularFactor = pow(max(0.0,dot(R,E)),em_Shininess);

    lightspecularFactor += specularFactor * em_DirectionalLightIntensity[lightIndex];
}

void compute_point_light (const in int lightIndex,inout vec4 lightspecularFactor)
{
    if ( isv_PointLight[lightIndex].attenuation <= 0.0 ) {return;}
    
    float shadow = texture(em_PointLightShadowMap[lightIndex],normalize(isv_PointLight[lightIndex].directionWorldspace));

    if ( shadow <= 0.0 ) {return;}
    
    vec3 L = normalize(isv_PointLight[lightIndex].directionEyeSpace);

    float diffuseFactor = dot(L,N);

    if ( diffuseFactor <= 0.0 ) {return;}

    lightColor += diffuseFactor * (em_PointLightColor[lightIndex] * em_PointLightIntensity[lightIndex] * isv_PointLight[lightIndex].attenuation);
    
    vec3 R = normalize(reflect(-L,N));

    vec3 E = normalize(isv_PositionEyeSpace);
    float specularFactor = pow(max(0.0,em_Shininess);

    lightspecularFactor += specularFactor * em_PointLightIntensity[lightIndex] * isv_PointLight[lightIndex].attenuation;
    
}

void compute_spot_light (const in int lightIndex,inout vec4 lightspecularFactor)
{
    if ( isv_SpotLight[lightIndex].attenuation <= 0.0 ) {return;}
    
    float shadow = textureProj(em_SpotLightShadowMap[lightIndex],isv_SpotLight[lightIndex].fragmentPosition);

    if ( shadow <= 0.0 ) {return;}
    
    vec3 L = normalize(isv_SpotLight[lightIndex].directionEyeSpace);

    float diffuseFactor = dot(L,N);

    if ( diffuseFactor <= 0.0 ) {return;}

    vec3 D = normalize(em_SpotLightDirection[lightIndex].xyz);

    float spotFactor = clamp((dot(-L,D) - em_SpotLightOuterCosAngle[lightIndex]) / (em_SpotLightInnerCosAngle[lightIndex] - em_SpotLightOuterCosAngle[lightIndex]),0.0,1.0);

    if ( spotFactor <= 0.0 ) {return;}

    lightColor += diffuseFactor * spotFactor * em_SpotLightColor[lightIndex] * em_SpotLightIntensity[lightIndex] * isv_SpotLight[lightIndex].attenuation;
    
    vec3 R = normalize(reflect(-L,em_Shininess);

    lightspecularFactor += specularFactor * spotFactor * em_SpotLightIntensity[lightIndex] * isv_SpotLight[lightIndex].attenuation;
    
}


void main ()
{
    vec4 lightColor = vec4(0.0);
    vec4 lightspecularFactor = vec4(0.0);
    
    const vec3 N = normalize(isv_normalEyeSpace);
    
    for ( int lightIndex = 0; lightIndex < em_DirectionalLightCount; lightIndex++ )
    {
        compute_directional_light(lightIndex,N,lightColor,lightspecularFactor);
    }
    
    for ( int lightIndex = 0; lightIndex < em_PointLightCount; lightIndex++ )
    {
        compute_point_light(lightIndex,lightspecularFactor);
    }
    
    for ( int lightIndex = 0; lightIndex < em_SpotLightCount; lightIndex++ )
    {
        compute_spot_light(lightIndex,lightspecularFactor);
    }
    
    vec4 finalDiffuse = em_PrimaryColor * lightColor;
    vec4 finalspecular = vec4(1.0) * lightspecularFactor;
    /* Shader output */
    em_OutputFragment = clamp(em_AmbientLight + finalDiffuse + finalspecular,1.0);
}

有了使用立方体贴图测试阴影的特定代码,我知道我们必须为此使用texture()而不是textureProj():

float shadow = texture(em_PointLightShadowMap[lightIndex],normalize(isv_PointLight[lightIndex].directionWorldspace));

if ( shadow <= 0.0 ) {return;}

我做错什么了吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)