我正在研究一个显示建筑物的项目。 要求是根据摄像机和建筑物之间的距离让建筑物逐渐淡出(透明)。此外,这种效果还必须跟随摄像机的运动。
我考虑使用THREE.Fog()
,但雾似乎只能改变材质的颜色。
上面是白雾蒙蒙的建筑物的照片。
var bigGeometry = new THREE.Geometry();
bigGeometry.merge(smallGeometry);
ground.material.fog = false;
是地面。因此地面不会与雾相互作用。我的问题是:
alphaMap
。如果是这样,则每个建筑图块都必须映射一个alphaMap,并且所有这些alphaMap必须与相机的运动进行交互。这将需要大量的工作。有什么建议吗?
最好的问候, 亚瑟
答案 0 :(得分:1)
注意:我怀疑可能比不透明更容易/更漂亮的方法来解决此问题。特别要注意的是,部分不透明的建筑物将在其后面显示其他建筑物。要解决此问题,请考虑使用渐变或其他场景背景,并选择雾色来匹配该颜色,而不要使用不透明度。但是为了尝试...
以下是根据对象的距离更改对象的不透明度的方法。这实际上并不需要THREE.Fog
,我不确定您将如何直接使用雾化数据。相反,我将使用THREE.NodeMaterial
,它(从three.js r96开始)是相当实验的。另一种选择是使用THREE.ShaderMaterial
编写自定义着色器,这也很好。
const material = new THREE.StandardNodeMaterial();
material.transparent = true;
material.color = new THREE.ColorNode( 0xeeeeee );
// Calculate alpha of each fragment roughly as:
// alpha = 1.0 - saturate( distance / cutoff )
//
// Technically this is distance from the origin, for the demo, but
// distance from a custom THREE.Vector3Node would work just as well.
const distance = new THREE.Math2Node(
new THREE.PositionNode( THREE.PositionNode.WORLD ),
new THREE.PositionNode( THREE.PositionNode.WORLD ),
THREE.Math2Node.DOT
);
const normalizedDistance = new THREE.Math1Node(
new THREE.OperatorNode(
distance,
new THREE.FloatNode( 50 * 50 ),
THREE.OperatorNode.DIV
),
THREE.Math1Node.SAT
);
material.alpha = new THREE.OperatorNode(
new THREE.FloatNode( 1.0 ),
normalizedDistance,
THREE.OperatorNode.SUB
);
答案 1 :(得分:0)
我是OP。在花了一些时间阅读如何使用Three.js的Shader材料之后。我得到了一些可以正常工作的代码。
代码如下:https://jsfiddle.net/yingcai/4dxnysvq/
基本思想是:
另一个重要的事情是:因为淡入淡出的遮罩应该随着相机的移动而变化,所以请不要忘记在每一帧中更新制服中的控件。
// Create uniforms that contains control position value.
uniforms = {
texture: {
value: new THREE.TextureLoader().load("https://threejs.org/examples/textures/water.jpg")
},
control: {
value: controls.target
}
};
// In the render() method.
// Update the uniforms value every frame.
uniforms.control.value = controls.target;