我正在尝试在我的顶点着色器中实现照明,但是,顶点的颜色似乎并没有太大变化。
#version 330
顶点属性的结构化布局
layout (location = 0 ) in vec3 vertex_position;
layout (location = 1 ) in vec3 vertex_color;
layout (location = 2 ) in vec3 vertex_normal;
///统一变量
uniform mat4 ModelMatrix;
uniform mat4 ProjectionMatrix;
uniform mat4 ViewMatrix;
uniform mat4 NormalMatrix;
uniform vec3 AmbientFinal;
/// struct处理灯光信息和材质信息
struct lightInfo
{
vec3 LightPosition;
vec3 ambientLightInt;
vec3 diffuseLightInt;
vec3 SpecularLightInt;
};
uniform lightInfo lights;
struct MaterialInfo
{
vec3 ka;
vec3 kd;
vec3 ks;
float Shineness;
};
uniform MaterialInfo material;
out vec3 colour;
主要照明计算
void main()
{
///light position in eye coordinates
vec4 lighteye = ViewMatrix * ModelMatrix * vec4(lights.LightPosition, 1.0f);
vec3 tnorm = normalize(mat3(NormalMatrix) * vertex_normal);
///在眼球中的位置
vec4 eyeCoords = ViewMatrix*ModelMatrix* vec4(vertex_position, 1.f);
vec3 s = normalize(vec3(lighteye - eyeCoords));
vec3 v = normalize(-eyeCoords.xyz);
vec3 r = reflect(-s, tnorm);
vec3 ambient = material.ka * lights.ambientLightInt;
float sdotn = max(dot(s, tnorm),0.0);
vec3 diffuse = lights.diffuseLightInt * material.kd * sdotn;
vec3 spec = vec3(0.0);
if(sdotn > 0)
spec = lights.SpecularLightInt * material.ks * pow (max(dot(r,v), 0.0), material.Shineness);
gl_Position = ProjectionMatrix *ViewMatrix*ModelMatrix* vec4(vertex_position, 1.f);
colour = (diffuse + ambient + spec) + vertex_color;
}
生产的输出
没有光照计算的输出
这些是变量
///lights and Mats
lightInfo lights;
lights.LightPosition = glm::vec3(0.f, 0.f, 2.f);
lights.ambientLightInt = glm::vec3(0.1f, 0.1f, 0.1f);
lights.diffuseLightInt = glm::vec3(1.f);
lights.SpecularLightInt = glm::vec3(1.f);
MaterialInfo mat;
mat.ka = glm::vec3(0.1f, 0.1f, 0.1f);
mat.kd = glm::vec3(0.5f, 0.5f, 0.5f);
mat.ks = glm::vec3(0.5f, 0.5f, 0.5f);
mat.Shineness = 30.f;
也许我对照明的理解是错误的?我不明白为什么3d对象没有真正受到光照计算的影响
答案 0 :(得分:0)
通常您的程序可以正常工作。
但是普通矩阵应为mat3
类型。共有的光照位置是世界空间中的一个位置,并且仅可以通过视图矩阵进行转换(如果光照计算是在视图空间中完成的话):
uniform mat3 NormalMatrix;
// [...]
vond main()
{
vec4 lighteye = ViewMatrix * vec4(lights.LightPosition, 1.0f);
vec3 tnorm = normalize(NormalMatrix * vertex_normal);
// [...]
}
确保视图位置不在矩形上。视图位置必须在矩形的前面:
例如
glm::mat4 view = glm::lookAt(
glm::vec3(0.0f, 0.0f, 0.5f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
我使用以下程序测试您的代码并生成小型动画(我使用了glew,glm和glfw库):
顶点着色器:
#version 330
layout (location = 0 ) in vec3 vertex_position;
layout (location = 1 ) in vec3 vertex_color;
layout (location = 2 ) in vec3 vertex_normal;
uniform mat4 ModelMatrix;
uniform mat4 ProjectionMatrix;
uniform mat4 ViewMatrix;
uniform mat3 NormalMatrix;
uniform vec3 AmbientFinal;
struct lightInfo
{
vec3 LightPosition;
vec3 ambientLightInt;
vec3 diffuseLightInt;
vec3 SpecularLightInt;
};
uniform lightInfo lights;
struct MaterialInfo
{
vec3 ka;
vec3 kd;
vec3 ks;
float Shineness;
};
uniform MaterialInfo material;
out vec3 colour;
void main()
{
///light position in eye coordinates
vec4 lighteye = ViewMatrix * vec4(lights.LightPosition, 1.0f);
vec3 tnorm = normalize(NormalMatrix * vertex_normal);
vec4 eyeCoords = ViewMatrix*ModelMatrix* vec4(vertex_position, 1.f);
vec3 s = normalize(vec3(lighteye - eyeCoords));
vec3 v = normalize(-eyeCoords.xyz);
vec3 r = reflect(-s, tnorm);
vec3 ambient = material.ka * lights.ambientLightInt;
float sdotn = max(dot(s, tnorm),0.0);
vec3 diffuse = lights.diffuseLightInt * material.kd * sdotn;
vec3 spec = vec3(0.0);
if(sdotn > 0)
spec = lights.SpecularLightInt * material.ks * pow (max(dot(r,v), 0.0), material.Shineness);
gl_Position = ProjectionMatrix *ViewMatrix*ModelMatrix* vec4(vertex_position, 1.f);
colour = (diffuse + ambient + spec) + vertex_color;
}
片段着色器:
#version 330
in vec3 colour;
out vec4 fragColor;
void main()
{
fragColor = vec4(colour, 1.0);
}
main
程序:
int main(void)
{
if ( glfwInit() == 0 )
return 0;
GLFWwindow *wnd = glfwCreateWindow( 800, 600, "OGL window", nullptr, nullptr );
if ( wnd == nullptr )
return 0;
glfwMakeContextCurrent(wnd);
glewExperimental = true;
if ( glewInit() != GLEW_OK )
return 0;
GLuint program = CreateProgram( sh_vert, sh_frag );
GLint loc_normal = glGetUniformLocation(program, "NormalMatrix");
GLint loc_model = glGetUniformLocation(program, "ModelMatrix");
GLint loc_view = glGetUniformLocation(program, "ViewMatrix");
GLint loc_proj = glGetUniformLocation(program, "ProjectionMatrix");
GLint loc_l_lp = glGetUniformLocation(program, "lights.LightPosition");
GLint loc_l_al = glGetUniformLocation(program, "lights.ambientLightInt");
GLint loc_l_dl = glGetUniformLocation(program, "lights.diffuseLightInt");
GLint loc_l_sl = glGetUniformLocation(program, "lights.SpecularLightInt");
GLint loc_m_ka = glGetUniformLocation(program, "material.ka");
GLint loc_m_kd = glGetUniformLocation(program, "material.kd");
GLint loc_m_ks = glGetUniformLocation(program, "material.ks");
GLint loc_m_sh = glGetUniformLocation(program, "material.Shineness");
glUseProgram(program);
glm::mat4 proj(1.0f);
glm::mat4 view = glm::lookAt(glm::vec3(0.0f, 0.0f, 0.5f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 model(1.0f);
glm::mat3 normal = glm::transpose(glm::inverse(glm::mat3(view * model)));
glUniformMatrix3fv(loc_normal, 1, GL_FALSE, glm::value_ptr(normal) );
glUniformMatrix4fv(loc_model, 1, GL_FALSE, glm::value_ptr(model) );
glUniformMatrix4fv(loc_view, 1, GL_FALSE, glm::value_ptr(view) );
glUniformMatrix4fv(loc_proj, 1, GL_FALSE, glm::value_ptr(proj) );
glUniform3f(loc_l_lp, 0.f, 0.f, 1.f);
glUniform3f(loc_l_al, 0.1f, 0.1f, 0.1f);
glUniform3f(loc_l_dl, 1.f, 1.f, 1.f);
glUniform3f(loc_l_sl, 1.f, 1.f, 1.f);
glUniform3f(loc_m_ka, 0.1f, 0.1f, 0.1f);
glUniform3f(loc_m_kd, 0.7f, 0.7f, 0.7f);
glUniform3f(loc_m_ks, 1.0f, 1.0f, 1.0f);
glUniform1f(loc_m_sh, 30.f);
const std::vector<float> varray
{
-0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
const std::vector<unsigned int> iarray{ 0, 1, 2, 0, 2, 3 };
GLuint bo[2];
glGenBuffers(1, bo);
glBindBuffer(GL_ARRAY_BUFFER, bo[0]);
glBufferData(GL_ARRAY_BUFFER, varray.size()*sizeof(*varray.data()), varray.data(), GL_STATIC_DRAW);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 9*sizeof(*varray.data()), 0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 9*sizeof(*varray.data()), (void*)(2*sizeof(*varray.data())));
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 9*sizeof(*varray.data()), (void*)(6*sizeof(*varray.data())));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bo[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, iarray.size()*sizeof(*iarray.data()), iarray.data(), GL_STATIC_DRAW);
float ang = 0.0;
while (!glfwWindowShouldClose(wnd))
{
int vpSize[2];
glfwGetFramebufferSize( wnd, &vpSize[0], &vpSize[1] );
glViewport( 0, 0, vpSize[0], vpSize[1] );
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
float sa = sin( ang );
ang += 0.05f;
glUniform3f(loc_l_lp, 0.5f*sa, 0.5f*sa, 0.5f);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
glfwSwapBuffers(wnd);
glfwPollEvents();
}
glfwTerminate();
return 0;
}