在OpenGL中使用多个光源时如何解决我的照明问题(片段着色器问题?)>

问题描述 投票:0回答:1

这是我第一次问问题,因此,如果我缺少应该在这里的内容,我表示歉意。

我正在一个需要在opengl中安装两个光源的项目中。这些应该是定向灯。我99%的确定自己所走的路线比所需的复杂,但是我对项目的理解不尽如人意,所以我上班所能做的就是我所走的路线。我有一个带有纹理的金字塔对象。我也有两个单独的灯,一个补光灯和一个键灯。补光灯更多地用于环境照明,而按键灯本身就是主要的“灯泡”。对于所有3个对象,我都有一个顶点着色器和片段着色器(尽管我不知道我是否真的需要/应该这样做)。我有一系列绘制形状,包含法线和纹理坐标的顶点。主要金字塔对象使用所有这三个属性,但是灯光仅使用顶点,因此它们具有相同的形状。

我的主要问题是灯工作不正常。仅通过钥匙灯的环境照明来点亮金字塔。它没有正确地合并漫反射或镜面照明组件。补光灯似乎也被很大程度上忽略了,但这似乎是因为关键灯覆盖了所有其他灯光数据。

这是主金字塔的着色器的外观:

/* Pyramid Vertex Shader Source Code */
const GLchar * pyramidVertexShaderSource = GLSL(330,
    layout (location = 0) in vec3 position; // Vertex data from Vertex Attrib Pointer 0
    layout (location = 1) in vec3 normal; // VAP position 1 for normals
    layout (location = 2) in vec2 textureCoordinate; // Color data from Vertex Attrib Pointer 1

    out vec3 Normal; // For outgoing normals to fragment shader
    out vec3 FragmentPos; // For outgoing color / pixels to fragment shader
    out vec2 mobileTextureCoordinate; // variable to transfer Texture data to the fragment shader


    // Global variables for the transform matrices
    uniform mat4 model;
    uniform mat4 view;
    uniform mat4 projection;

void main(){
        gl_Position = projection * view * model * vec4(position, 1.0f); // transforms vertices to clip coordinates
        FragmentPos = vec3(model * vec4(position, 1.0f)); // Gets fragment / pixel position in world space only (exclude view and projection)
        mobileTextureCoordinate = vec2(textureCoordinate.x, 1.0f - textureCoordinate.y); // flips the texture horizontal
        Normal = mat3(transpose(inverse(model))) * normal; // get normal vectors in world space only and exclude normal translation properties
    }
);


/* Pyramid Fragment Shader Source Code */
const GLchar * pyramidFragmentShaderSource = GLSL(330,

        in vec2 mobileTextureCoordinate; // Variable to hold incoming color data from vertex shader
        in vec3 Normal; // For incoming normals
        in vec3 FragmentPos; // For incoming fragment position

        out vec4 pyramidColor; // For outgoing pyramid color


        // Uniform variables for object color, light color, light position, and camera/view position
        uniform vec3 fillLightColor;
        uniform vec3 fillLightPos;
        uniform vec3 keyLightColor;
        uniform vec3 keyLightPos;
        uniform vec3 viewPosition;
        uniform sampler2D uTexture; // Useful when working with multiple textures

        void main() {
            /* Phong lighting model calculations to generate ambient, diffuse, and specular components */

            // Calculate Ambient lighting
            float ambientStrength = 0.3f; // Set ambient or global lighting strength
            vec3 ambient = ambientStrength * fillLightColor; // Generate ambient light color

            // Calculate Diffuse lighting for fill lamp
            vec3 norm = normalize(Normal); // Normalize vectors to 1 unit
            vec3 lightDirection = normalize(fillLightPos - FragmentPos); // Calculate distance (light direction) between fill light source and fragments/pixels
            float impact = max(dot(norm, lightDirection), 0.0); // Calculate diffuse impact by generating dot product of normal and light
            vec3 diffuse = impact * fillLightColor; // Generate diffuse light color

            // Calculate Specular lighting for fill lamp
            float specularIntensity = 0.8f; // Set specular light strength
            float highlightSize = 16.0f; // Set specular highlight size
            vec3 viewDir = normalize(viewPosition - FragmentPos); // Calculate view direction
            vec3 reflectDir = reflect (-lightDirection, norm); // Calculate reflection vector
            //Calculate specular component
            float specularComponent = pow(max(dot(viewDir, reflectDir), 0.0), highlightSize);
            vec3 specular = specularIntensity * specularComponent * fillLightColor;

            // Calculate Ambient lighting for key lamp
            float keyAmbientStrength = 1.0f;
            vec3 keyAmbient = keyAmbientStrength * keyLightColor;

            // Calculate Diffuse lighting for key lamp
            vec3 keyLightDirection = normalize(keyLightPos - FragmentPos); // Calculate distance between key light source and fragments
            float keyImpact = max(dot(norm, keyLightDirection), 0.0);
            vec3 keyDiffuse = keyImpact * keyLightColor;

            // Calculate Specular lighting for key lamp
            float keySpecularIntensity = 0.8f; // Set specular light strength
            float keyHighlightSize = 32.0f; // Set specular highlight size
            vec3 keyReflectDir = reflect (-keyLightDirection, norm); // Calculate reflection vector
            //Calculate specular component
            float keySpecularComponent = pow(max(dot(viewDir, keyReflectDir), 0.0), keyHighlightSize);
            vec3 keySpecular = keySpecularIntensity * keySpecularComponent * keyLightColor;

            // Calculate phong result
            vec3 objectColor = texture(uTexture, mobileTextureCoordinate).xyz;
            vec3 fillResult = (ambient + diffuse + specular);
            vec3 keyResult = (keyAmbient + keyDiffuse + keySpecular);
            vec3 lightingResult = fillResult + keyResult;
            vec3 phong = (lightingResult) * objectColor;
            pyramidColor = vec4(phong, 1.0f); // Send lighting results to GPU

        }
    ); 

据我所知,我的问题在于计算照明的数学中,但是无论我如何尝试改变它……我都不够聪明,无法确切地知道发生了什么。诚然,我的线性代数技能是垃圾,所以我真的很难受。我确定我的代码中有很多错误以及如何解决此问题,但是经过15到20个小时的尝试之后,这是我能够设法加载并看起来甚至可以远程纠正的最佳方法。

补光几乎应该是白光,照常照亮纹理。按键灯应该是绿色的,因此暴露于按键灯的一面应具有绿色外观。当前,整个金字塔仅以相同的绿色照明(没有阴影或灯光有方向性)。

任何帮助将不胜感激!

这是我第一次问一个问题,因此,如果我缺少应该在此处的内容,我深表歉意。我正在一个需要在opengl中安装两个光源的项目。这些应该是定向灯。...

opengl glsl
1个回答
0
投票

似乎您在汇总光源时错了。

© www.soinside.com 2019 - 2024. All rights reserved.