【发布时间】:2012-08-28 09:17:41
【问题描述】:
例如,给定一个地形,上面有一个虚拟形象,头顶远处有一个摄像头:是否可以渲染雾,使虚拟形象完全不被雾化,而虚拟形象周围的地形消失在雾中?
【问题讨论】:
-
你的意思是像角色是雾的中心,离角色越远雾越浓?还是“正常”的雾,只是角色没有被雾化?
-
第一个;感谢您的澄清。
标签: javascript webgl three.js fog
例如,给定一个地形,上面有一个虚拟形象,头顶远处有一个摄像头:是否可以渲染雾,使虚拟形象完全不被雾化,而虚拟形象周围的地形消失在雾中?
【问题讨论】:
标签: javascript webgl three.js fog
当然,但据我所知,您必须制作自己的着色器,而不是使用 three.js 提供的着色器。可能有办法以这种方式自定义它们,但如果有,我不熟悉。
查看this answer 将雾化作为与相机的距离。正如那里所解释的那样,这个想法是将相机位置作为制服传递给着色器,然后在所有对象的顶点着色器中,找到从相机位置到要转换的顶点的距离。然后,您将该距离作为变量传递给片段着色器,您可以计算出每个像素的距离,您可以使用该距离在雾化颜色和对象的常规颜色之间进行混合。你可以在this example from the OpenGL ES 2.0 Programming guide看到。
将其更改为基于与角色的距离很简单:您只需将角色位置作为您计算距离的制服而不是相机位置传递(在该示例代码中,您将替换 @987654324 @ 使用 u_characterPos 之类的东西,并且可能将变量从 v_eyeDist 更改为 v_characterDist)。除了任何名称更改外,片段着色器可以完全相同。
所以,类似这样的事情(警告:未测试。您将不得不解决这个问题,让 three.js 满意地使用它。不过,有很多这样的例子,比如 this one) :
顶点着色器:
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;
}
片段着色器:
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);
}
【讨论】: