C++ 使用不同颜色和强度照明对象

C++ 使用不同颜色和强度照明对象,c++,opengl,glsl,C++,Opengl,Glsl,我正在做一个游戏,玩家需要穿越吊环才能得分。我想为我的船使用不同的灯光,为场景使用光环和灯光。我在照明这三件事上有问题。如果我在main.cpp中使用三个函数调用运行代码,那么只有第一个函数调用会被正确激活。如果我把第一个注释掉,第二个就会被执行,以此类推,但这三个都不会 World.cpp glm::vec4 lightPositionWorld = Model * glm::vec4(.0f, 20.0f, -30.0f, 1.0f); glUniform3f(glGetUniformL

我正在做一个游戏,玩家需要穿越吊环才能得分。我想为我的船使用不同的灯光,为场景使用光环和灯光。我在照明这三件事上有问题。如果我在main.cpp中使用三个函数调用运行代码,那么只有第一个函数调用会被正确激活。如果我把第一个注释掉,第二个就会被执行,以此类推,但这三个都不会

World.cpp

glm::vec4 lightPositionWorld = Model * glm::vec4(.0f, 20.0f, -30.0f, 1.0f);  
glUniform3f(glGetUniformLocation(programID, "LightPositionWorld"), lightPositionWorld.x, lightPositionWorld.y, lightPositionWorld.z);
Ship.cpp

glm::vec3 lightPositionSpaceShip = glm::vec3(.0, 7.0, .0);
glUniform3f(glGetUniformLocation(programID, "LightPositionSpaceShip"), lightPositionSpaceShip.x, lightPositionSpaceShip.y, lightPositionSpaceShip.z);
Gate.cpp

glm::vec3 lightPositionGate = glm::vec3(5.0, 3.0, .0);
glUniform3f(glGetUniformLocation(programID, "LightPositionGate"), lightPositionGate.x, lightPositionGate.y, lightPositionGate.z);
SimpleFragmentShader.fragmentshader

#version 330 core

in vec2 UV;
in vec3 Position_worldspace;
in vec3 Normal_cameraspace;
in vec3 EyeDirection_cameraspace;
in vec3 LightDirectionCameraWorld;
in vec3 LightDirectionCameraSpaceShip;
in vec3 LightDirectionCameraGate;

out vec3 colorWorld;
out vec3 colorSpaceShip;
out vec3 colorGate;

uniform sampler2D objectTexture;
uniform vec3 LightPositionWorld;
uniform vec3 LightPositionSpaceShip;
uniform vec3 LightPositionGate;

vec3 lighting(float red, float green, float blue, float power, vec2 UV, vec3 Position_worldspace, vec3 Normal_cameraspace, vec3 EyeDirection_cameraspace, vec3 LightDirectionCamera, vec3 LightPosition)
{ 
    vec3 LightColor = vec3(red, green, blue);
    float LightPower = power; 
    vec3 MaterialDiffuseColor = texture(objectTexture, UV ).rgb;
    vec3 MaterialAmbientColor = vec3(0.3, 0.3, 0.3) * MaterialDiffuseColor; 
    vec3 MaterialSpecularColor = vec3(1.0, 1.0, 1.0);

    float distance = length( LightPosition - Position_worldspace );
    vec3 normal = normalize(Normal_cameraspace);
    vec3 light = normalize(LightDirectionCamera);
    float cosTheta = clamp(dot(normal, light), .0, 1.0);

    vec3 eye = normalize(EyeDirection_cameraspace);
    vec3 reflect = reflect(-light, normal);
    float cosAlpha = clamp( dot(eye, reflect), .0, 1.0);    
    vec3 color =    MaterialAmbientColor + 
                    MaterialDiffuseColor * LightColor * LightPower * cosTheta / (distance * distance) +
                    MaterialSpecularColor * LightColor * LightPower * pow(cosAlpha, 5) / (distance * distance);

    return color;
}

void main()
{
    colorWorld = lighting(0.81f, 0.71f, 0.23f, 90.0f, UV, Position_worldspace, Normal_cameraspace, EyeDirection_cameraspace, LightDirectionCameraWorld, LightPositionWorld);
    colorSpaceShip = lighting(0.329412f, 0.329412f, 0.329412f, 90.0f, UV, Position_worldspace, Normal_cameraspace, EyeDirection_cameraspace, LightDirectionCameraSpaceShip, LightPositionSpaceShip);
    colorGate = lighting(0.81f, 0.71f, 0.23f, 90.0f, UV, Position_worldspace, Normal_cameraspace, EyeDirection_cameraspace, LightDirectionCameraGate, LightPositionGate);
}

我希望场景和两个对象以不同的颜色和强度照亮

要获得您期望的行为,您不应该输出多种颜色,您应该为每个片段输出一种颜色:
out vec4 fragColor

然后,更正代码的最简单方法是添加3种不同的照明结果:

fragColor = vec4(lighting(0.81f, 0.71f, 0.23f, 90.0f, UV, Position_worldspace, Normal_cameraspace, EyeDirection_cameraspace, LightDirectionCameraWorld, LightPositionWorld) +
        lighting(0.329412f, 0.329412f, 0.329412f, 90.0f, UV, Position_worldspace, Normal_cameraspace, EyeDirection_cameraspace, LightDirectionCameraSpaceShip, LightPositionSpaceShip) +
        lighting(0.81f, 0.71f, 0.23f, 90.0f, UV, Position_worldspace, Normal_cameraspace, EyeDirection_cameraspace, LightDirectionCameraGate, LightPositionGate), 1.0);

此外,在照明方法中,
MaterialAmbientColor
也应随距离衰减,否则在计算最终颜色时,环境光将增加3倍。

要获得预期的行为,不应输出多种颜色,您应该为每个片段输出一种颜色:
out vec4 fragColor

然后,更正代码的最简单方法是添加3种不同的照明结果:

fragColor = vec4(lighting(0.81f, 0.71f, 0.23f, 90.0f, UV, Position_worldspace, Normal_cameraspace, EyeDirection_cameraspace, LightDirectionCameraWorld, LightPositionWorld) +
        lighting(0.329412f, 0.329412f, 0.329412f, 90.0f, UV, Position_worldspace, Normal_cameraspace, EyeDirection_cameraspace, LightDirectionCameraSpaceShip, LightPositionSpaceShip) +
        lighting(0.81f, 0.71f, 0.23f, 90.0f, UV, Position_worldspace, Normal_cameraspace, EyeDirection_cameraspace, LightDirectionCameraGate, LightPositionGate), 1.0);

同样,在照明方法中,
MaterialAmbientColor
也应随距离衰减,否则在计算最终颜色时,环境光将增加3次。

这是什么奇怪的语法:
在vec2 UV中?我从没见过。对我来说似乎不正确。这正是fragmentshader的OpenGL教程语法。@kebs这是正常的GLSL语法。好的,谢谢,我学到了一些东西(我只做裸C++)。你正在输出3种不同的颜色。您希望如何将这些应用于您正在绘制的3个不同对象?还有,你是如何绘制几何图形的?这种奇怪的语法是什么:
在vec2uv?我从没见过。对我来说似乎不正确。这正是fragmentshader的OpenGL教程语法。@kebs这是正常的GLSL语法。好的,谢谢,我学到了一些东西(我只做裸C++)。你正在输出3种不同的颜色。您希望如何将这些应用于您正在绘制的3个不同对象?另外,您如何绘制几何图形?