javascript - 如何通过GLSL在THREE.js中实现MeshNormalMaterial?

标签 javascript three.js glsl shader webgl

我想实现一个像 MeshNormalMaterial 这样的着色器,但我不知道如何将法线转换为彩色。

在 THREE.js 中:

enter image description here

我的测试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);
}

The result is really bad

我的测试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);
}

This is better than above.

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

谁能帮我吗?

谢谢。

最佳答案

如果你想在 View 空间中看到法线向量,你必须将法线向量从模型空间变换到世界空间,再从世界空间变换到 View 空间。这可以通过使用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 值,则具有相同大小的正值和负值具有相同的颜色表示。颜色的强度随着值的梯度而增加。

enter image description here

使用公式正常 * 0.5 + 0.5,强度从 0 增加到 1。

enter image description here

通常,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);
}

enter image description here

关于javascript - 如何通过GLSL在THREE.js中实现MeshNormalMaterial?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47710377/

相关文章:

javascript - ThreeJS无法加载Json文件

javascript - 如何动态叠加来自 GLTF 模型的纹理 - Three.js

c++ - 在 OpenGL 中缩放投影矩阵时出现意外行为

javascript - 管理通过ajax发送到php的表单数据+其他变量

javascript - 使用删除后长度不变

javascript - 使用 JavaScript 的 Ajax 代码

c++ - 从 C++ 代码中获取已编译的 glsl 着色器统一参数的大小

javascript - 无法根据特定意图在谷歌助手内联中添加建议芯片

javascript - Three.js - 让用户上传 .gltf/.glb 3d 模型

opengl - 每片段光照坐标系