如何在GLSL中实现THREE.js中的MeshNormalMaterial?

use*_*095 3 shader glsl webgl three.js

我想实现像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);
}
Run Code Online (Sandbox Code Playgroud)

结果非常糟糕

我的测试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);
}
Run Code Online (Sandbox Code Playgroud)

这比上面好.

这些只是测试,我找不到任何有关如何计算颜色的资源...

谁能帮我 ?

谢谢.

Rab*_*d76 7

如果要在视图空间中查看法线向量,则必须将法线向量从模型空间转换为世界空间,并将世界空间转换为视图空间.这可以通过用法转换法向量一步完成normalMatrix.

varying vec3 vNormal;

void main(void)
{
    vNormal      = normalMatrix * normalize(normal); 
    gl_Position  = matrix_viewProjection * matrix_model * vec4(position, 1.0);
}
Run Code Online (Sandbox Code Playgroud)

由于变量变量在从顶点着色器传递到片段着色器时被插值,因此根据其重心坐标,应在片段着色器中完成对颜色的变换.注意,在插值之后,法向量必须再次归一化

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);
}
Run Code Online (Sandbox Code Playgroud)

由于法向量被归一化,因此其分量在[-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);
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述