模型空间中的光计算

时间:2012-05-03 09:22:53

标签: math opengl glsl opengl-4

我有一个每片段照明工作,但我想知道如何在模型空间中保持照明计算,我不必将片段着色器中的normalModelMatrix乘以法线。

着色器:ViewMatrix - 相机转换,ModelMatrix - 对象转换。 光位 - glm :: vec4 lightPos(3.0f,2.0f,-30.0f,1.0f)

渲染循环:

glUseProgram(ProgramId);
glUniformMatrix4fv(ViewMatrixUniformLocation, 1, GL_FALSE, glm::value_ptr(ViewMatrix));
glUniform4f(lightIntensityUniformLocation, 0.8f, 0.8f, 0.8f, 1.0f);
glUniform4f(ambientIntensityUniformLocation, 0.2f, 0.2f, 0.2f, 0.2f);
glUniform3fv(dirToLightUniformLocation, 1, glm::value_ptr( lightPos));

ModelMatrixStack.push(ModelMatrix);
ModelMatrix = glm::translate(ModelMatrix, glm::vec3(0, 0, -30));
ModelMatrix = glm::rotate(ModelMatrix, 75.0f, glm::vec3(0,0,1)); 
normMatrix = glm::mat3(ModelMatrix);
glUniformMatrix4fv(ModelMatrixUniformLocation, 1, GL_FALSE,           
glm::value_ptr(ModelMatrix));   
glUniformMatrix3fv(normalModelMatrixUniformLocation, 1, GL_FALSE, 
glm::value_ptr(normMatrix));
drawTeapot();

ModelMatrix = ModelMatrixStack.top();
normMatrix = glm::mat3(ModelMatrix);

glUniformMatrix4fv(ModelMatrixUniformLocation, 1, GL_FALSE,  
glm::value_ptr(ModelMatrix));
glUniformMatrix3fv(normalModelMatrixUniformLocation, 1, GL_FALSE,  
glm::value_ptr(normMatrix));
myground.draw();

glUseProgram(0);

顶点着色器:

#version 400

layout(location=0) in vec4 in_position;
layout(location=1) in vec3 in_normal;
out vec3 normal;
out vec4 position;

uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;

void main(void)
{
     vec4 vertexPosition = ModelMatrix * in_position;
     gl_Position = ProjectionMatrix * ViewMatrix * vertexPosition;
     normal = in_normal;
     position = vertexPosition;
}

片段着色器:

version 400

in vec3 normal;
in vec4 position;
out vec4 outputColor;

uniform vec3 lightPos;
uniform vec4 lightIntensity;
uniform vec4 ambientIntensity;
uniform mat3 normalModelMatrix;

void main(void)
{
     vec3 normCamSpace = normalize(normalModelMatrix * normalize(normal));
     vec3 dirToLight = normalize(lightPos - vec3(position));
     float cosAngIncidence = dot(normCamSpace, dirToLight);
     cosAngIncidence = clamp(cosAngIncidence, 0, 1);
     outputColor = (lightIntensity * cosAngIncidence) + ambientIntensity;
}

1 个答案:

答案 0 :(得分:1)

在模型空间中进行照明的计算成本实际上高于在眼睛空间中进行照明,因为您需要为每个模型单独转换光的位置和方向。那些通常发生在CPU方面。然而,你仍然需要对法线进行转换。

  

模型空间,我不需要在片段着色器中将normalTodelMatrix乘以法线,如下所示。

该计算在顶点着色器中也起作用。把它移到那里。


更新/修改

为了澄清修改后的着色器代码:

顶点着色器:

#version 400

layout(location=0) in vec4 in_position;
layout(location=1) in vec3 in_normal;

out vec3 eyespaceNormal;
out vec4 eyespacePosition;

uniform mat4 ModelviewMatrix;
uniform mat3 NormalMatrix; // == inverse(transpose(ModelviewMatrix))
uniform mat4 ProjectionMatrixq;

void main(void)
{
     eyespacePosition = ModelviewMatrix * in_position;
     eyespaceNormal = normalize(NormalMatrix * in_normal);
     gl_Position = ProjectionMatrix * eyespacePosition;
}

片段着色器:

#version 400

in vec3 eyespaceNormal;
in vec4 eyespacePosition;
out vec4 outputColor;

uniform vec3 lightPos;
uniform vec4 lightIntensity;
uniform vec4 ambientIntensity;

void main(void)
{
     vec3 dirToLight = normalize(lightPos - vec3(eyespacePosition));
     float cosAngIncidence = dot(eyespaceNormal, dirToLight);
     cosAngIncidence = clamp(cosAngIncidence, 0, 1);
     outputColor = (lightIntensity * cosAngIncidence) + ambientIntensity;
}

BTW:您正常的转换矩阵是错误的。您必须使用转置模型视图矩阵的逆矩阵。