首页 > 解决方案 > three.js 对象淡入/淡出或应用不透明度

问题描述

我将three.js 用于图形Web 项目。

我有很多圈子,它像这样散开。

在此处输入图像描述

我想知道,如果物体和相机之间的距离越来越远,

对象的不透明度可以降低吗?(或淡出)

此外,如果距离越来越近,请将对象的不透明度设置为更高(或淡入)

我在 docs( https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene) 中搜索过,但没有明确的描述。

有什么解决办法吗?

谢谢。

标签: javascriptthree.js

解决方案


使用 的默认材质无法在相机靠近对象时更改不透明度three.js。但是使用以下代码行增强材质的片段着色器以达到预期的效果并不难:

gl_FragColor.a *= pow( gl_FragCoord.z, f );

我在下面的演示中增强了MeshNormalMaterialvia 。onBeforeCompile()这个想法是在物体靠近相机时逐渐降低不透明度。您可以使用变量来控制此转换过程f。高值意味着对象更快开始变得透明。

let camera, scene, renderer;

init();
animate();

function init() {

  camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 1000);
  camera.position.z = 50;

  scene = new THREE.Scene();

  const geometry = new THREE.BoxBufferGeometry(2, 2, 2);
  const material = new THREE.MeshNormalMaterial({
    transparent: true
  });

  material.onBeforeCompile = function(shader) {

    shader.fragmentShader = shader.fragmentShader.replace(
      'gl_FragColor = vec4( packNormalToRGB( normal ), opacity );',
      [
        'gl_FragColor = vec4( packNormalToRGB( normal ), opacity );',
        'gl_FragColor.a *= pow( gl_FragCoord.z, 50.0 );',
      ].join('\n')
    );

  };

  for (let i = 0; i < 1000; i++) {

    const object = new THREE.Mesh(geometry, material);
    object.position.x = Math.random() * 80 - 40;
    object.position.y = Math.random() * 80 - 40;
    object.position.z = Math.random() * 80 - 40;
    object.rotation.x = Math.random() * 2 * Math.PI;
    object.rotation.y = Math.random() * 2 * Math.PI;
    object.rotation.z = Math.random() * 2 * Math.PI;
    object.scale.x = Math.random() + 0.5;
    object.scale.y = Math.random() + 0.5;
    object.scale.z = Math.random() + 0.5;
    scene.add(object);

  }

  renderer = new THREE.WebGLRenderer({
    antialias: true
  });
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  new THREE.OrbitControls(camera, renderer.domElement);

}

function animate() {

  requestAnimationFrame(animate);
  renderer.render(scene, camera);

}
body {
      margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three@0.131.3/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.131.3/examples/js/controls/OrbitControls.js"></script>


推荐阅读