是否可以从独立于相机的three.js场景中的一点应用雾?

shi*_*ino 5 javascript webgl three.js fog

例如,给定一个地形,上面有一个头像,相机在头顶很远:是否可以渲染雾,使头像保持完全无雾,而头像周围的地形淡入雾中?

Bre*_*nny 4

当然,但据我所知,您必须制作自己的着色器,而不是使用 Three.js 提供的着色器。可能有一种方法可以通过这种方式自定义它们,但如果有的话,我不熟悉。

查看关于将雾化为与相机的距离的答案。正如此处所解释的,其想法是将相机位置作为统一传递给着色器,然后在所有对象的顶点着色器中,您可以找到从相机位置到要变换的顶点的距离。然后,您将该距离作为片段着色器的变量传递,并且可以计算出每个像素的距离,用于在雾化颜色和对象的常规颜色之间进行混合。您可以在本示例中从 OpenGL ES 2.0 编程指南中看到这一点。

将其更改为基于与角色的距离很简单:您只需将角色位置作为要计算距离的制服传递,而不是相机位置(在该示例代码中,您将替换为u_eyePos类似的内容u_characterPos,也许将变化从 更改v_eyeDistv_characterDist)。除了任何名称更改之外,片段着色器可以完全相同。

所以,像这样的东西(警告:未经测试。你必须修复这个问题才能让 Three.js 满意地使用它。不过,有很多这样的例子,比如这个):

顶点着色器:

uniform mat4 matViewProjection;
uniform mat4 matView;
uniform vec4 u_characterPos;

attribute vec4 rm_Vertex;
attribute vec2 rm_TexCoord0;

varying vec2 v_texCoord;
varying float v_characterDist;

void main() {
  // Transform vertex to view-space
  vec4 vViewPos = matView * rm_Vertex;

  // Compute the distance to character
  v_characterDist = length(vViewPos - u_characterPos);                  

  gl_Position = matViewProjection * rm_Vertex;
  v_texCoord    = rm_TexCoord0.xy;
}
Run Code Online (Sandbox Code Playgroud)

片段着色器:

precision mediump float;

uniform vec4 u_fogColor;
uniform float u_fogMaxDist;
uniform float u_fogMinDist;
uniform sampler2D baseMap;

varying vec2 v_texCoord;
varying float v_characterDist;

float computeLinearFogFactor() {
  float factor;

  // Compute linear fog equation
  factor = (u_fogMaxDist - v_characterDist) /
        (u_fogMaxDist - u_fogMinDist );

  // Clamp in the [0,1] range
  factor = clamp(factor, 0.0, 1.0);

  return factor;            
}

void main() {
  float fogFactor = computeLinearFogFactor();
  vec4 fogColor = fogFactor * u_fogColor;
  vec4 baseColor = texture2D(baseMap, v_texCoord);

  // Compute final color as a lerp with fog factor
  gl_FragColor = baseColor * fogFactor +
               fogColor * (1.0 - fogFactor); 
}
Run Code Online (Sandbox Code Playgroud)