我具有非常基础的OpenGL知识,但是我正在尝试复制MeshLab的可视化器具有的阴影效果。
如果在MeshLab中加载网格,您将意识到,如果一个面向相机的面完全照亮了,并且在旋转模型时,光照会随着面向相机的面的变化而改变。我在MeshLab中加载了一个带有12个面的简单单位立方体,并捕获了以下屏幕截图,以使我的观点更加清楚:
从我的头顶上,我认为它的工作方式是通过某种方式在着色器中为每个面分配颜色。如果脸部法线与相机之间的角度为零,则脸部将完全照亮(根据脸部的颜色),否则,其照亮与法向矢量和相机矢量之间的点积成比例。
我已经有了用着色器/ VBO绘制网格的代码。我什至可以分配每个顶点的颜色。但是,我不知道如何实现类似的效果。据我所知,片段着色器可以在顶点上工作。快速搜索发现了this之类的问题。但是当答案涉及重复顶点时,我感到困惑。
如果有任何不同,在我的应用程序中,我加载*.ply
文件,其中包含顶点位置,三角形索引和每个顶点的颜色。
我创建了重复的顶点数组,并使用以下着色器获得所需的照明效果。从发布的屏幕截图中可以看出,相似之处是不可思议的:)
the answer by @DietrichEpp
#version 330 core
uniform mat4 projection_matrix;
uniform mat4 model_matrix;
uniform mat4 view_matrix;
in vec3 in_position; // The vertex position
in vec3 in_normal; // The computed vertex normal
in vec4 in_color; // The vertex color
out vec4 color; // The vertex color (pass-through)
void main(void)
{
gl_Position = projection_matrix * view_matrix * model_matrix * vec4(in_position, 1);
// Compute the vertex's normal in camera space
vec3 normal_cameraspace = normalize(( view_matrix * model_matrix * vec4(in_normal,0)).xyz);
// Vector from the vertex (in camera space) to the camera (which is at the origin)
vec3 cameraVector = normalize(vec3(0, 0, 0) - (view_matrix * model_matrix * vec4(in_position, 1)).xyz);
// Compute the angle between the two vectors
float cosTheta = clamp( dot( normal_cameraspace, cameraVector ), 0,1 );
// The coefficient will create a nice looking shining effect.
// Also, we shouldn't modify the alpha channel value.
color = vec4(0.3 * in_color.rgb + cosTheta * in_color.rgb, in_color.a);
}
#version 330 core
in vec4 color;
out vec4 out_frag_color;
void main(void)
{
out_frag_color = color;
}
这是简单的平面阴影,您可以使用此GLSL代码段来评估每个面法线,而不是使用每个顶点法线:
dFdy()
然后使用vec3 x = dFdx(FragPos);
vec3 y = dFdy(FragPos);
vec3 normal = cross(x, y);
vec3 norm = normalize(normal);
施加一些漫射照明:
norm