How to implement MeshNormalMaterial in THREE.js by GLSL?

故事扮演 提交于 2019-12-18 05:12:32

问题


I want to implement a shader like MeshNormalMaterial, but I have no idea how to convert normal to color.

In THREE.js:

My test1:

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);
}

My test2:

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...

Can anyone help me ?

Thanks.


回答1:


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);
}

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.

With the formula normal * 0.5 + 0.5 the intensity increases from 0 to 1.

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);
}



来源:https://stackoverflow.com/questions/47710377/how-to-implement-meshnormalmaterial-in-three-js-by-glsl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!