为什么照明会出现在对面? [英] Why lighting appears on opposite side?

查看:67
本文介绍了为什么照明会出现在对面?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用

从对象背面查看:

为了调试,我从主循环中删除了对象旋转矩阵:

  glm :: mat4 phantomtTransformation;phantomtTransformation = glm :: rotate(phantomtTransformation,-glm :: pi< float>()/2.0f,glm :: vec3(1.0f,0.0f,0.0f));phantomtTransformation = glm :: rotate(phantomtTransformation,-glm :: pi< float>(),glm :: vec3(0.0f,0.0f,1.0f));shaderProgram.setUniform("transform",phantomtTransformation); 

并从片段着色器中更改了行

  frag_color = vec4(结果,vert_color.w); 

  frag_color = vec4(Normal,vert_color.w); 

以便可视化正常值.结果,我注意到当相机改变位置时,幻像也会改变颜色,这意味着正常值也会改变.

解决方案

我认为问题的原因在于,您没有将模型转换应用于法线向量.由于您绝对不想倾斜它们,因此必须为法线创建一个特殊的矩阵.

正如您所提到的教程中进一步解释的那样,矩阵可以像这样构造

  Normal = mat3(transpose(inverse(model)))* aNormal; 

在您的顶点着色器中.但是,我强烈建议您改为在应用程序代码中计算矩阵,因为在上述示例中,您将按顶点计算矩阵.由于您使用的是glm库,因此它看起来像这样:

  glm :: mat3 model_normal = glm :: mat3(glm :: transpose(glm :: inverse(model))); 

然后,您可以将新的 model_normal 矩阵作为 uniform mat3 加载到着色器中.

I am trying to build lighting using this tutorial. However, lighting appears on wrong side of human object and I do not know why.

Normals were created per triangle. Vertices of a triangle basically have the same normal:

glm::vec3 calculateNormal(glm::vec3 vertice_1, glm::vec3 vertice_2, glm::vec3 vertice_3)
{
    glm::vec3 vector_1 = vertice_2 - vertice_1;
    glm::vec3 vector_2 = vertice_3 - vertice_1;
    return glm::normalize(glm::cross(vector_1, vector_2));
}

Here is code for vertex shader:

#version 330 core

layout (location = 0) in vec3 pos;
layout (location = 1) in vec3 normal;
out vec4 vert_color;
out vec3 Normal;
out vec3 FragPos;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform mat4 transform;
uniform vec4 color;

void main()
{
    vert_color = color;
    gl_Position = projection * view * model * transform * vec4(pos.x, pos.y, pos.z, 1.0);
    FragPos = vec3(model * transform *  vec4(pos, 1.0));
    Normal = normal;
}

Fragment shader:

#version 330 core

uniform vec3 cameraPos;
uniform vec3 lightPos;
uniform vec3 lightColor;

in vec4 vert_color;
in vec3 FragPos;
in vec3 Normal;
out vec4 frag_color;

void main()
{
    float ambientStrength = 0.1;
    float specularStrength = 0.5;
    vec3 ambient = ambientStrength * lightColor;

    vec3 lightDir = normalize(lightPos - FragPos);
    float diff = max(dot(Normal, lightDir), 0.0);
    vec3 diffuse = diff * lightColor;

    vec3 viewDir = normalize(cameraPos - FragPos);
    vec3 reflectDir = reflect(-lightDir, Normal);

    float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
    vec3 specular = specularStrength * spec * lightColor; 

    vec3 result = (ambient + diffuse + specular) * vec3(vert_color.x, vert_color.y, vert_color.z);
    frag_color = vec4(result, vert_color.w);
}

Main loop:

    wxGLCanvas::SetCurrent(*glContext);
    glClearDepth(1.0f);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDepthFunc(GL_LEQUAL);
    glEnable(GL_DEPTH_TEST);

    glm::mat4 model, view, projection;
    model = glm::translate(model, modelPos); // modelPos is 
    view = fpsCamera->getViewMatrix();
    projection = fpsCamera->getProjectionMatrix(windowWidth, windowHeight);
    color = glm::vec4(0.310f, 0.747f, 0.185f, 1.0f);
    glm::vec3 lightPos = glm::vec3(0.0f, 1.0f, 0.0f);
    glm::vec3 lightColor = glm::vec3(1.0f, 1.0f, 1.0f);

    glm::mat4 phantomtTransformation;
    phantomtTransformation = glm::rotate(phantomtTransformation, - glm::pi<float>() / 2.0f, glm::vec3(1.0f, 0.0f, 0.0f));
    phantomtTransformation = glm::rotate(phantomtTransformation, - glm::pi<float>() , glm::vec3(0.0f, 0.0f, 1.0f));
    
    ShaderProgram shaderProgram;
    shaderProgram.loadShaders("Shaders/phantom.vert", "Shaders/phantom.frag");

    glClearStencil(0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    shaderProgram.use();
    shaderProgram.setUniform("transform", phantomtTransformation);
    shaderProgram.setUniform("model", model);
    shaderProgram.setUniform("view", view);
    shaderProgram.setUniform("projection", projection);
    shaderProgram.setUniform("color", color);
    shaderProgram.setUniform("lightColor", lightColor);
    shaderProgram.setUniform("lightPos", lightPos);
    shaderProgram.setUniform("cameraPos", fpsCamera->getPosition());

    
    glStencilMask(0xFF); // Write to stencil buffer
    glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
    glStencilFunc(GL_ALWAYS, 0, 0xFF);  // Set any stencil to 0

    glStencilFunc(GL_ALWAYS, 1, 0xFF); // Set any stencil to object ID
    m_pantomMesh->draw();
    glStencilFunc(GL_ALWAYS, 0, 0xFF);  // Set any stencil to 0        // no need for testing

    glFlush();
    wxGLCanvas::SwapBuffers();

View from front of the object:

View from back of the object:

EDIT: In order to debug I removed object rotation matrix from main loop:

 glm::mat4 phantomtTransformation;
    phantomtTransformation = glm::rotate(phantomtTransformation, - glm::pi<float>() / 2.0f, glm::vec3(1.0f, 0.0f, 0.0f));
    phantomtTransformation = glm::rotate(phantomtTransformation, - glm::pi<float>() , glm::vec3(0.0f, 0.0f, 1.0f));
 
shaderProgram.setUniform("transform", phantomtTransformation);

and changed line in fragment shader from

frag_color = vec4(result, vert_color.w);

to

frag_color = vec4(Normal, vert_color.w);

in order to visualize Normal values. As a result I noticed that when camera changes position phantom also changes color which means that normal values are also changing.

解决方案

I think the cause of your problem is that you are not applying your model transformation to your normal vectors. Since you definitely do not want to skew them, you will have to create a special matrix for your normals.

As is explained further down the tutorial that you mentioned, the matrix can be constructed like this

Normal = mat3(transpose(inverse(model))) * aNormal;

in your vertex shader. However, I highly recommend that you calculate the matrix in your application code instead, since you would calculate it per vertex in the above example. Since you are using the glm library, it would look like this instead:

glm::mat3 model_normal = glm::mat3(glm::transpose(glm::inverse(model)));

You can then load your new model_normal matrix into the shader as a uniform mat3.

这篇关于为什么照明会出现在对面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆