如何仅对法线垂直于相机的面孔着色

时间:2019-07-16 08:42:18

标签: three.js glsl

我正在尝试为需要在垂直于相机的法线(点积为0)的面部变暗的着色器进行数学运算。那么,基本上我该如何获得该点积? 我该如何解决以下问题?

uniform float time;
uniform vec3 eye_dir;

varying float darkening;

void main(){

  float product=dot(normalize(eye_dir),normalize(normal.xyz));

  darkening=product;

  gl_Position=
  projectionMatrix*
  modelViewMatrix*
  vec4(position,1.);
}
// in THREE.js
this.camera.getWorldDirection(this.eyeDir);
...
cell.material.uniforms.eye_dir = new Uniform(this.eyeDir);

1 个答案:

答案 0 :(得分:1)

要执行所需的操作,您必须计算从片段到相机的向量。最简单的方法是在视图空间(相机空间)中进行操作,因为在视图空间中相机的位置为(0,0,0)。
从模型空间到视图空间将position转换为modelViewMatrix,从模型空间到视图空间将normal转换为normalMatrix。参见WebGLProgram

由于向量在相同方向上的点积结果为1.0,因此变暗为1.0 - abs(dotproduct)

varying float darkening;

void main(){

    vec4 view_pos = modelViewMatrix * vec4(position, 1.0);

    vec3 view_dir = normalize(-view_pos.xyz); // vec3(0.0) - view_pos;
    vec3 view_nv  = normalize(normalMatrix * normal.xyz);

    float NdotV   = dot(view_dir, view_nv);
    darkening     = 1.0 - abs(NdotV);

    gl_Position   = projectionMatrix * view_pos;
}

请注意,eye_dirnormal中的Dot product毫无意义,因为eye_dir是世界空间中的向量,而normal是模型(对象)空间中的向量。