Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/sharepoint/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Math 模型空间中的光照计算_Math_Opengl_Glsl_Opengl 4 - Fatal编程技术网

Math 模型空间中的光照计算

Math 模型空间中的光照计算,math,opengl,glsl,opengl-4,Math,Opengl,Glsl,Opengl 4,我有一个有效的逐片段照明,但我想知道如何在模型空间中保持照明计算,而不必像下面在片段着色器中那样将法线乘以normalModelMatrix 着色器:ViewMatrix-摄影机变换、ModelMatrix-对象变换。 灯光位置-glm::vec4灯光位置(3.0f、2.0f、-30.0f、1.0f) 渲染循环: glUseProgram(ProgramId); glUniformMatrix4fv(ViewMatrixUniformLocation, 1, GL_FALSE, glm::val

我有一个有效的逐片段照明,但我想知道如何在模型空间中保持照明计算,而不必像下面在片段着色器中那样将法线乘以normalModelMatrix

着色器:ViewMatrix-摄影机变换、ModelMatrix-对象变换。 灯光位置-glm::vec4灯光位置(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

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 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;
}
#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;
}

在模型空间中进行照明的计算成本实际上比在眼睛空间中进行照明的计算成本更高,因为您必须分别变换每个模型的灯光位置和方向。这些通常发生在CPU端。然而,您仍然需要执行法线的变换

模型空间,我不必在片段着色器中将法线与normalModelMatrix相乘,如下所示

该计算在顶点着色器中也能正常工作。把它移到那里


更新/编辑 如需澄清,请参见修改的着色器代码:

顶点着色器:

#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

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 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;
}
#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;
}


顺便说一句:你的法线变换矩阵是错误的。为此,必须使用转置的modelview矩阵的倒数。

如果我正确理解您的情况,在模型空间中进行照明可能会是这样的:在顶点着色器中,我可以在不与ModelMatrix相乘的情况下发送到片段着色器(位置=位置)然后在上次ModelMatrix变换后的渲染循环中,我需要计算ModelMatrix的逆,并将其乘以lightPos:glm::mat4 invTransform=glm::inverse(ModelMatrix);glUniform3fv(dirToLightUniformLocation,1,glm::value_ptr(invTransform*lightPos));最后,我不必在着色器中将法线与normalModelMatrix相乘。@Irbis:不,我不是这个意思。我告诉过你把所有的变换都放到顶点着色器中。只将容易变换的向量传递给片段着色器。但只要我不使用非均匀缩放,我的法线变换矩阵就足够了。我使用ViewMatrix来处理我的fps相机,所以在_位置应该有eyespaceposition=ModelMatrix*,因为我想将灯光保持在固定位置。此外,我认为eyespaceNormal应该在片段着色器中进行规格化。对于上面提到的一个不必使用法线变换矩阵的概念,您怎么看?如果法线在面上的变化很大,则在片段着色器中规范化变换的法线是有意义的。从技术上讲,正确的方法不是带归一化的重心插值,而是球面插值。您应该在CPU上将灯光转换为视觉空间,以节省GPU的计算资源(您将几乎没有超过20个光源照亮一张脸)。在CPU上计算这一点比一次又一次地计算每个顶点要高效得多。记住:CPU并不比GPU慢,它们只是没有那么并行。如果一个任务没有从并行化(例如,只转换一把光照位置)中获益,则在CPU上执行。