我正在一个需要在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),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个小时的尝试之后,这是我能够设法加载并看起来甚至可以远程纠正的最佳方法。
填充光几乎应该是白光,照常照亮纹理。按键灯应该是绿色的,因此暴露于按键灯的一面应具有绿色外观。目前,整个金字塔仅以相同的绿色照明(没有阴影或灯光有方向性)。