GLSL 330点光影阴影

时间:2016-10-03 10:08:24

标签: opengl glsl

我有一个片段着色器,可以计算方向,点和点光源。没有阴影贴图,这很好用。奇怪的是,在添加阴影贴图(sampler2D)之后,点亮一些如何踩踏阴影。这是我的片段着色器:(跳到底部查看详细信息的注释)

#version 330 core

const int MAX_POINT_LIGHTS = 4;
const int MAX_SPOT_LIGHTS = 4;

in vec2 TexCoord0;
in vec3 WorldNormal0;
in vec3 WorldPos0;
in vec4 LightSpacePos0;
in vec3 Tangent0;

out vec4 FragmentColor;

struct BaseLight
{
    vec3 Color;
    float AmbientIntensity;
    float DiffuseIntensity;
};

struct DirectionalLight
{
    BaseLight Base;
    vec3 Direction;
};

struct Attenuation
{
    float Constant;
    float Linear;
    float Exp;
};

struct PointLight
{
    BaseLight Base;
    vec3 Position;
    Attenuation Atten;
};

struct SpotLight
{
    PointLight Base;
    vec3 Direction;
    float Cutoff;
};

uniform int gNumPointLights;
uniform int gNumSpotLights;
uniform DirectionalLight gDirectionalLight;
uniform PointLight gPointLights[MAX_POINT_LIGHTS];
uniform SpotLight gSpotLights[MAX_SPOT_LIGHTS];
uniform sampler2D gTextureSampler0; //unit 0
uniform sampler2D gShadowMap;       //unit 1
uniform vec3 gEyeWorldPos;
uniform float gMatSpecularIntensity;
uniform float gSpecularPower;

float CalculateShadowFactor(vec4 light_space_pos)
{
    //perspective divide
    vec3 projected_coords = light_space_pos.xyz / light_space_pos.w;
    //map [-1, 1] to [0, 1]
    vec2 uv_coords;
    uv_coords.x = 0.5 * projected_coords.x + 0.5;
    uv_coords.y = 0.5 * projected_coords.y + 0.5;
    float z = 0.5 * projected_coords.z + 0.5;
    float depth = texture(gShadowMap, uv_coords).x;
    if (depth < z - 0.0005)
    {
        return 0.5; //in shadow
    }
    else
    {
        return 1.0;
    }
}

vec4 CalculateLightInternal(BaseLight light, vec3 direction, vec3 normal)
{
    vec4 ambient_color = vec4(light.Color * light.AmbientIntensity, 1.0f);
    float diffuse_factor = dot(normal, -direction);

    vec4 diffuse_color  = vec4(0, 0, 0, 0);
    vec4 specular_color = vec4(0, 0, 0, 0);

    if (diffuse_factor > 0)
    {
        diffuse_color = vec4(light.Color * light.DiffuseIntensity * diffuse_factor, 1.0f);
        vec3 vertex_to_eye = normalize(gEyeWorldPos - WorldPos0);
        vec3 light_reflect = normalize(reflect(direction, normal));
        float specular_factor = dot(vertex_to_eye, light_reflect);
        if (specular_factor > 0)
        {
            specular_factor = pow(specular_factor, gSpecularPower);
            specular_color = vec4(light.Color * gMatSpecularIntensity * specular_factor, 1.0f);
        }
    }

    return ambient_color + diffuse_color + specular_color;
}

vec4 CalculateDirectionalLight(vec3 normal)
{
    return CalculateLightInternal(gDirectionalLight.Base, gDirectionalLight.Direction, normal);
}

vec4 CalculatePointLight(PointLight light, vec3 normal)
{
    vec3 light_direction = WorldPos0 - light.Position;
    float dist = length(light_direction);
    light_direction = normalize(light_direction);

    vec4 color = CalculateLightInternal(light.Base, light_direction, normal);
    float inv_attenuation =  1.0 / (light.Atten.Constant + light.Atten.Linear * dist + light.Atten.Exp * dist * dist);

    return color * inv_attenuation;
}

vec4 CalculateSpotLight(SpotLight light, vec3 normal)
{
    vec3 light_to_pixel = normalize(WorldPos0 - light.Base.Position);
    float spot_factor = dot(light_to_pixel, light.Direction);

    if (spot_factor > light.Cutoff)
    {
        vec4 color = CalculatePointLight(light.Base, normal);
        return color * (1.0 - (1.0 - spot_factor) * 1.0/(1.0 - light.Cutoff));   //remaps to [0,1] from cosine value so that it's a smooth fall-off
    }
    else
    {
        return vec4(0,0,0,0);
    }
}

void main()
{
    float shadow_factor = CalculateShadowFactor(LightSpacePos0);
    vec4 texture_color = texture( gTextureSampler0, TexCoord0 );
    vec3 pixel_normal = normalize(WorldNormal0);
    vec4 total_light = CalculateDirectionalLight(pixel_normal);

    for (int i = 0; i < gNumSpotLights; ++i)
    {
        total_light += CalculateSpotLight(gSpotLights[i], pixel_normal);
    }

    //If uncomment the for-loop below, the shadow disappears ...
    //I have tried even setting gNumPointLights to 0 and some how
    //it still "kills" the shadow ...
    //I also tried changing the logic to total_light += vec4(0);
    //magically this still kills it.
    /*
    for (int i = 0; i < gNumPointLights; ++i)
    {
        total_light += CalculatePointLight(gPointLights[i], pixel_normal);
    }
     */

    FragmentColor = texture_color * total_light * shadow_factor;
}

注释掉for循环,阴影很好! correct rendering with shadows

取消注释for循环,阴影消失,没有任何其他修改。即使删除了循环内部的逻辑,阴影仍然不会出现,我试过这个。 shadows gone with the for-loop uncommented

以下是一些额外信息:我在Mac OS 10.11.6上使用XCode运行它。我在编译后和链接后检查我的着色器。没有显示错误。

那为什么会这样呢?我尝试了一切,但我没有想法,请帮忙!

1 个答案:

答案 0 :(得分:0)

经过一些调试后,事实证明是未使用的统一变量弄乱了。