位置照明在GLSL着色器代码中无法正常工作

时间:2015-02-11 13:38:26

标签: c++ opengl glsl

我在网上找到的教程中创建了以下GLSL着色器,但位置照明似乎根本不起作用。

另外,我的整个场景光线不足,我不确定我有什么错误才能使用这个二进制文件" on,off"照明效果。

这是一张只有位置照明的场景照片:

Positional Lighting not working.

当我按照着色器代码启用方向照明时;我从正确的方向得到了光,但它基本上是作为一个"开,关"事情。你会看到我突出显示了下图中的区域,其中物体基本上变亮,然后在下一个像素中右边没有光线:

Weird triangulation in image.

为了向人们展示我正在加载法线,我在着色器代码中做了一个简单的finalColor = NormalColor着色器。

以下是相同角度的场景结果图像:

Scene with just normals.

这是我的顶点着色器:

#version 330 core
#extension GL_ARB_explicit_attrib_location : require

layout(location = 0) in vec3 vPosition;
layout(location = 1) in vec3 vNormal;
layout(location = 2) in vec2 vUV;

layout (std140) uniform Sunlight
{

  vec4 SunlightPosition;
  vec4 SunlightDiffuse;
  vec4 SunlightSpecular;
  vec4 SunlightDirection;
  float constantAttenuation, linearAttenuation, quadraticAttenuation;
  float spotCutoff, spotExponent;
  float EnableLighting;
  float EnableSun;
  float ExtraValue;

};

out vec4 worldSpacePosition;  // position of the vertex (and fragment) in world space
out vec3 vertexNormalDirection;  // surface normal vector in world space
out vec2 TextureCoordinates;
out vec3 NormalColor;

uniform mat4 MVP;
uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ViewModelMatrix;
uniform mat4 InverseViewMatrix;
uniform mat3 NormalMatrix;

void main()
{

    gl_Position = MVP * vec4(vPosition, 1.0);
    TextureCoordinates = vUV;
    worldSpacePosition = ModelMatrix * vec4(vPosition, 1.0);
    vertexNormalDirection = normalize(NormalMatrix * vNormal);
    NormalColor = vNormal;

}

这是我的片段着色器代码:

#version 330
#extension GL_ARB_explicit_attrib_location : require

precision highp float;

uniform mat4 MVP;
uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ViewModelMatrix;
uniform mat4 InverseViewMatrix;
uniform mat3 NormalMatrix;

//
// These values vary per Mesh
//

uniform vec4    AmbientMeshColor;
uniform vec4    EmissiveMeshColor;
uniform vec4    DiffuseMeshColor;
uniform vec4    SpecularMeshColor;
uniform vec4    SceneBrightnessColor;
uniform float   MeshShininess;
uniform float   ObjectHasTextureFile;

//
// Sunlight Settings.
//

layout (std140) uniform Sunlight
{

  vec4 SunlightPosition;
  vec4 SunlightDiffuse;
  vec4 SunlightSpecular;
  vec4 SunlightDirection;
  float constantAttenuation, linearAttenuation, quadraticAttenuation;
  float spotCutoff, spotExponent;
  float EnableLighting;
  float EnableSun;
  float ExtraValue;

};

uniform vec4        SceneAmbient;

//
// Whether Materials are enabled at all.
//

uniform float       IfEnableTextures;

//
// If we are just simply drawing the skybox.
//

uniform float       DrawingSkyBox;

uniform float       DrawNormals;

uniform float       EnableWireframe;

uniform vec4        WireframeColor;

uniform float       TextureCoordinateDebug;

uniform sampler2D MainTextureSampler; 

in vec4 worldSpacePosition;
in vec3 vertexNormalDirection;
in vec2 TextureCoordinates;
in vec3 NormalColor;

vec4 finalDiffuseColor;

out vec4 finalColor;

void DrawSkyBox() {

    finalColor = texture(MainTextureSampler, TextureCoordinates);

}

void DrawWireFrame() {

    finalColor = WireframeColor;

}

void main()

{

    if (DrawingSkyBox != 1.0) {

        if (DrawNormals == 1.0) {

            finalColor = vec4(NormalColor, 1.0);

        } else {

            vec3 normalDirection = normalize(vertexNormalDirection);

            vec3 viewDirection = normalize(vec3(InverseViewMatrix * vec4(0.0, 0.0, 0.0, 1.0) - worldSpacePosition));

            vec3 lightDirection;

            float attenuation;

            if (SunlightPosition.w == 0.0) // directional light?
            {

                attenuation = 1.0; // no attenuation
                lightDirection = normalize(vec3(SunlightPosition));

            } 
            else // point light or spotlight (or other kind of light) 
            {

                vec3 positionToLightSource = vec3(SunlightPosition - worldSpacePosition);
                float distance = length(positionToLightSource);
                lightDirection = normalize(positionToLightSource);
                attenuation = 1.0 / (constantAttenuation
                               + linearAttenuation * distance
                               + quadraticAttenuation * distance * distance);

                if (spotCutoff <= 90.0) // spotlight?
                {

                    float clampedCosine = max(0.0, dot(-lightDirection, vec3(SunlightDirection)));
                    if (clampedCosine < cos(radians(spotCutoff))) // outside of spotlight cone?
                    {
                        attenuation = 0.0;
                    }
                    else
                    {

                      attenuation = attenuation * pow(clampedCosine, spotExponent); 

                    }
                }
            }

            vec4 ambientLighting = SceneAmbient * AmbientMeshColor;

            vec3 diffuseReflection;

            if (ObjectHasTextureFile == 1.0) {

                diffuseReflection = attenuation * vec3(SunlightDiffuse) * vec3(texture(MainTextureSampler, TextureCoordinates)) * max(0.0, dot(normalDirection, normalDirection));

            } else {

                diffuseReflection = attenuation * vec3(SunlightDiffuse) * vec3(DiffuseMeshColor) * max(0.0, dot(normalDirection, normalDirection));

            }

            vec3 specularReflection;

            if (dot(normalDirection, lightDirection) < 0.0) // light source on the wrong side?
            {

                specularReflection = vec3(0.0, 0.0, 0.0); // no specular reflection

            }
            else // light source on the right side
            {

                specularReflection = attenuation * vec3(SunlightSpecular) * vec3(SpecularMeshColor) * pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)), MeshShininess);

            }

            finalColor = vec4(vec3(ambientLighting) + diffuseReflection + specularReflection, DiffuseMeshColor.a);

        }

    } else {

        DrawSkyBox();

    }

}

编辑(1):

根据BWG的评论,我简化了顶点和片段着色器:

顶点着色器:

#version 330 core
#extension GL_ARB_explicit_attrib_location : require

layout(location = 0) in vec3 vPosition;
layout(location = 1) in vec3 vNormal;
layout(location = 2) in vec2 vUV;

layout (std140) uniform Sunlight
{

  vec4 SunlightPosition;
  vec4 SunlightDiffuse;
  vec4 SunlightSpecular;
  vec4 SunlightDirection;
  float constantAttenuation, linearAttenuation, quadraticAttenuation;
  float spotCutoff, spotExponent;
  float EnableLighting;
  float EnableSun;
  float ExtraValue;

};

out vec4 worldSpacePosition;  // position of the vertex (and fragment) in world space
out vec3 vertexNormalDirection;  // surface normal vector in world space
out vec2 TextureCoordinates;

uniform mat4 MVP;
uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ViewModelMatrix;
uniform mat4 InverseViewMatrix;
uniform mat3 NormalMatrix;

void main()
{

    gl_Position = MVP * vec4(vPosition, 1.0);
    TextureCoordinates = vUV;
    worldSpacePosition = ModelMatrix * vec4(vPosition, 1.0);
    vertexNormalDirection = normalize(NormalMatrix * vNormal);

}

Fragment Shader:

#version 330
#extension GL_ARB_explicit_attrib_location : require

precision highp float;

uniform mat4 MVP;
uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ViewModelMatrix;
uniform mat4 InverseViewMatrix;
uniform mat3 NormalMatrix;

//
// These values vary per Mesh
//

uniform vec4    AmbientMeshColor;
uniform vec4    EmissiveMeshColor;
uniform vec4    DiffuseMeshColor;
uniform vec4    SpecularMeshColor;
uniform vec4    SceneBrightnessColor;
uniform float   MeshShininess;
uniform float   ObjectHasTextureFile;

//
// Sunlight Settings.
//

layout (std140) uniform Sunlight
{

  vec4 SunlightPosition;
  vec4 SunlightDiffuse;
  vec4 SunlightSpecular;
  vec4 SunlightDirection;
  float constantAttenuation, linearAttenuation, quadraticAttenuation;
  float spotCutoff, spotExponent;
  float EnableLighting;
  float EnableSun;
  float ExtraValue;

};

uniform vec4        SceneAmbient;

uniform sampler2D MainTextureSampler; 

in vec4 worldSpacePosition;
in vec3 vertexNormalDirection;
in vec2 TextureCoordinates;

out vec4 finalColor;

void main()

{

    vec3 normalDirection = normalize(vertexNormalDirection);

    vec3 viewDirection = normalize(vec3(InverseViewMatrix * vec4(0.0, 0.0, 0.0, 1.0) - worldSpacePosition));

    vec3 lightDirection;

    float attenuation;

    if (SunlightPosition.w == 0.0) // directional light?
    {

        attenuation = 1.0; // no attenuation
        lightDirection = normalize(vec3(SunlightPosition));

    } 
    else // point light or spotlight (or other kind of light) 
    {

        vec3 positionToLightSource = vec3(SunlightPosition - worldSpacePosition);
        float distance = length(positionToLightSource);
        lightDirection = normalize(positionToLightSource);
        attenuation = 1.0 / (constantAttenuation
                       + linearAttenuation * distance
                       + quadraticAttenuation * distance * distance);

        if (spotCutoff <= 90.0) // spotlight?
        {

            float clampedCosine = max(0.0, dot(-lightDirection, vec3(SunlightDirection)));
            if (clampedCosine < cos(radians(spotCutoff))) // outside of spotlight cone?
            {
                attenuation = 0.0;
            }
            else
            {

              attenuation = attenuation * pow(clampedCosine, spotExponent); 

            }
        }
    }

    vec4 ambientLighting = SceneAmbient * AmbientMeshColor;

    vec3 diffuseReflection;

    if (ObjectHasTextureFile == 1.0) {

        diffuseReflection = attenuation * vec3(SunlightDiffuse) * vec3(texture(MainTextureSampler, TextureCoordinates)) * max(0.0, dot(normalDirection, lightDirection));

    } else {

        diffuseReflection = attenuation * vec3(SunlightDiffuse) * vec3(DiffuseMeshColor) * max(0.0, dot(normalDirection, lightDirection));

    }

    vec3 specularReflection;

    if (dot(normalDirection, lightDirection) < 0.0) // light source on the wrong side?
    {

        specularReflection = vec3(0.0, 0.0, 0.0); // no specular reflection

    }
    else // light source on the right side
    {

        specularReflection = attenuation * vec3(SunlightSpecular) * vec3(SpecularMeshColor) * pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)), MeshShininess);

    }

    finalColor = vec4(vec3(ambientLighting) + diffuseReflection + specularReflection, DiffuseMeshColor.a);

}

我还更改了导入实用程序的导入器设置,用于使网格数据(ASSIMP)无法生成平滑法线。

这摆脱了三角测量,但

  1. 我仍然没有定向照明工作(前方场景仍然是黑色)
  2. 位置照明仍会产生开/关效果。例如,我将鼠标放在地面点亮的某个位置。
  3. Ground Lit

    现在,如果我只是将鼠标移动一点点,那么地面会变黑。没有褪色。

    Ground black

0 个答案:

没有答案