问题描述
我想实现一个 MeshNormalMaterial 这样的着色器,但我不知道如何将法线转换为颜色.
I want to implement a shader like MeshNormalMaterial, but I have no idea how to convert normal to color.
在THREE.js中:
In 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);
}
这些只是测试,我找不到有关如何计算颜色的任何资源...
These are just test, I can't find any resources about how to calculate the color...
有人可以帮助我吗?
谢谢.
推荐答案
如果要在视图空间中查看法线向量,则必须将法线向量从模型空间转换为世界空间,再从世界空间进行转换.到视图空间.通过使用 normalMatrix
.
If you want to see the normal vector in view space, the you have to transform the normal vector from the model space to the world space and from the world space to the view space. This can be done in one step by transforming the normal vector with the normalMatrix
.
varying vec3 vNormal;
void main(void)
{
vNormal = normalMatrix * normalize(normal);
gl_Position = matrix_viewProjection * matrix_model * vec4(position, 1.0);
}
根据变量重心坐标,则应在片段着色器中完成对颜色的转换.注意,插值后,必须再次将法线向量归一化
Since a varying variable is interpolated when it is passed from the vertex shader to the fragment shader, according to its Barycentric coordinates, the transformation to the color should be done in the fragment shader. Note, after the interpolation the normal vector has to be normalized again
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
值,则大小相同的正负值将具有相同的颜色表示.颜色的强度随值的渐变而增加.
Since the normal vector is normalized, its component are in the range [-1.0, 1.0]. How to represent it as a color is up to you.
If you use the abs
value, then a positive and negative value with the same size have the same color representation. The intensity of the color increases with the grad of the value.
使用公式normal * 0.5 + 0.5
,强度从0增加到1.
With the formula normal * 0.5 + 0.5
the intensity increases from 0 to 1.
通常,x分量表示为红色,y分量表示为绿色,z分量表示为蓝色.
In common the x component is represented red, the y component is green and the z component is blue.
通过除以其分量的最大值,可以使颜色饱和:
The colors can be saturated, by dividing with the maximum value of its components:
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);
}
这篇关于如何通过GLSL在THREE.js中实现MeshNormalMaterial?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!