【发布时间】:2015-12-28 01:26:43
【问题描述】:
我有非常基本的 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;
}
单位立方体的不可思议的结果:
【问题讨论】:
-
在相机上放一盏灯不是更容易吗? “片段着色器也适用于顶点”:不,它们适用于fragments。
-
@NicolBolas 但这不会需要使用固定函数管道吗?抱歉,我只是不知道在 OpenGL 中有可以作为单独实体使用的照明。想详细说明一下吗?