我想实现一个像MeshNormalMaterial这样的着色器,但我不知道如何将normal转换为color。
在THREE.js中:
我的测试1:
varying vec3 vNormal;
void main(void) {
vNormal = abs(normal);
gl_Position = matrix_viewProjection * matrix_model * vec4(position, 1.0);
}
varying vec3 vNormal;
void main(void) {
gl_FragColor = vec4(vNormal, 1.0);
}
我的测试2:
varying vec3 vNormal;
void main(void) {
vNormal = normalize(normal) * 0.5 + 0.5;
gl_Position = matrix_viewProjection * matrix_model * vec4(position, 1.0);
}
varying vec3 vNormal;
void main(void) {
gl_FragColor = vec4(vNormal, 1.0);
}
这些只是测试,我找不到任何有关如何计算颜色的资源......
任何人都可以帮助我吗?
感谢。
答案 0 :(得分:7)
如果要在视图空间中查看法线向量,则必须将法线向量从模型空间转换为世界空间,并从世界空间转换为视图空间。这可以通过使用normalMatrix
转换法线向量一步完成。
varying vec3 vNormal;
void main(void)
{
vNormal = normalMatrix * normalize(normal);
gl_Position = matrix_viewProjection * matrix_model * vec4(position, 1.0);
}
由于变量变量在从顶点着色器传递到片段着色器时被插值,根据其Barycentric coordinates,变换到颜色应该在片段着色器中完成。注意,在插值之后,法向量必须再次归一化
varying vec3 vNormal;
void main(void)
{
vec3 view_nv = normalize(vNormal);
vec3 nv_color = view_nv * 0.5 + 0.5;
gl_FragColor = vec4(nv_color, 1.0);
}
由于法向量被归一化,其分量在[-1.0,1.0]范围内。如何将其表示为颜色取决于您
如果使用abs
值,则具有相同大小的正值和负值具有相同的颜色表示。颜色的强度随着值的增加而增加。
使用公式normal * 0.5 + 0.5
,强度从0增加到1.
通常,x分量表示为红色,y分量表示绿色,z分量表示蓝色。
颜色可以通过除以其组分的最大值来饱和:
varying vec3 vNormal;
void main(void)
{
vec3 view_nv = normalize(vNormal);
vec3 nv_color = abs(view_nv);
nv_color /= max(nv_color.x, max(nv_color.y, nv_color.z));
gl_FragColor = vec4(nv_color, 1.0);
}