我是GLSL的新手,我一直在努力寻找一种方法来将旋转的立方体的表面涂成红色。我已经实现了在一张具有法线x的面上绘制红色的效果,但是我的目标是使立方体在相机正面所面对的任何面上绘制一张红色的面。
片段着色器
#version 330
in vec3 normal;
out vec4 fragColor;
in vec4 color;
in vec4 vertexColor;
void main() {
vec3 nor = normalize(normal);
fragColor = vec4(nor.x, 0.0, 0.0, 1.0);
}
顶点着色器
#version 330
uniform mat4 u_m_matrix;
uniform mat4 u_vp_matrix;
layout (location=0) in vec3 a_position;
layout (location=1) in vec3 a_normal;
out vec3 normal;
out vec4 fragColor;
out vec4 vertexColor;
out vec4 color;
void main()
{
normal = a_normal;
gl_Position = u_vp_matrix * u_m_matrix * vec4(a_position, 1.0);
}
[我尝试用法线和相机看向的方向(0、0、1)弄乱点积,但是我还没做任何事情。
这将是理想的效果:
实际上,我确实认为它涉及一些数学(点积),也许得到cosTetha并查看矢量是否完全垂直,并取决于绘制的面是红色还是黑色?
我查看空间,z轴指向视口之外。当立方体的一侧面向摄像机时,视图空间中的法向矢量为(0,0,1)。红色可以从法线向量的z分量获得。
但是法向矢量必须从模型空间转换为视图空间(在顶点着色器中)。为此,您必须了解视图矩阵:
mat3 normalMat = inverse(transpose(mat3(u_v_matrix * u_m_matrix)));
normal = normalMat * a_normal;
在片段着色器中,红色通道可以从z组件获取:
vec3 nor = normalize(normal);
fragColor = vec4(nor.z, 0.0, 0.0, 1.0);
您也可以在规范化的设备空间中使用法线向量。在规范化的设备空间中,z轴指向视口。这是不准确的,但是也会根据其方向对脸部进行着色,例如:
顶点着色器:
#version 330
uniform mat4 u_m_matrix;
uniform mat4 u_vp_matrix;
layout (location=0) in vec3 a_position;
layout (location=1) in vec3 a_normal;
out vec3 normal;
void main()
{
normal = mat3(u_vp_matrix * u_m_matrix) * a_normal;
gl_Position = u_vp_matrix * u_m_matrix * vec4(a_position, 1.0);
}
片段着色器:
#version 330
in vec3 normal;
out vec4 fragColor;
void main() {
vec3 nor = normalize(normal);
fragColor = vec4(-nor.z, 0.0, 0.0, 1.0);
}
如果只想给照相机的脸部上色,则必须以45°的余弦来比较人脸的法线向量和视图空间z轴之间的角度的余弦。 step
将值与边进行比较,并根据结果返回0.0或1.0:
顶点着色器:
step
片段着色器:
mat3 normalMat = inverse(transpose(mat3(u_v_matrix * u_m_matrix)));
normal = normalMat * a_normal;
vec3 nor = normalize(normal);
//float red = step(0.707, abs(dot(nor, vec3(0.0, 0.0, 1.0))));
float red = step(0.707, dot(nor, vec3(0.0, 0.0, 1.0)));
fragColor = vec4(red, 0.0, 0.0, 1.0);