首页 > 解决方案 > Three.js 材质透明度无法按预期工作

问题描述

我正在尝试从交叉平面创建一棵“树”,每个平面都有来自 png 的透明纹理。而且看起来网格的一部分总是缺乏透明度。

这是一个例子: https ://jsfiddle.net/tncku896/5/

let camera, scene, renderer;
let group;

init();
animate();

function init() {
    camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 100);
    camera.position.z = 1.5;
    scene = new THREE.Scene();
    scene.background = new THREE.Color(0xbbbbbb);
    renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);
    
    let loader = new THREE.TextureLoader();
    let texture = loader.load('https://i.imgur.com/QxFQi1G.png');
    texture.magFilter = THREE.NearestFilter;
    texture.minFilter = THREE.NearestFilter;
    let geometry = new THREE.PlaneBufferGeometry(83/100, 139/100);
    let material = new THREE.MeshBasicMaterial({
        map: texture,
        side: THREE.DoubleSide,
        transparent: true
    });
    
    group = new THREE.Group();
    
    let planes = 2;
    for (let i = 0; i < planes; i++) {
        let mesh = new THREE.Mesh(geometry, material);
        mesh.rotation.y = (Math.PI / planes) * i;
        group.add(mesh);
    }
    
    scene.add(group);
}

function animate() {
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
    
    group.rotation.y += 0.005;
}

标签: three.js

解决方案


如果您将树设置为不透明并进行配置alphaTest以生成 alpha 切口,您将获得更好的结果。

let camera, scene, renderer;
let group;

init();
animate();

function init() {
  camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 100);
  camera.position.z = 1.5;
  scene = new THREE.Scene();
  scene.background = new THREE.Color(0xbbbbbb);
  renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  let loader = new THREE.TextureLoader();
  let texture = loader.load('https://i.imgur.com/QxFQi1G.png');
  texture.magFilter = THREE.NearestFilter;
  texture.minFilter = THREE.NearestFilter;
  let geometry = new THREE.PlaneBufferGeometry(83 / 100, 139 / 100);
  let material = new THREE.MeshBasicMaterial({
    map: texture,
    side: THREE.DoubleSide,
    alphaTest: 0.5
  });

  group = new THREE.Group();

  let planes = 2;
  for (let i = 0; i < planes; i++) {
    let mesh = new THREE.Mesh(geometry, material);
    mesh.rotation.y = (Math.PI / planes) * i;
    group.add(mesh);
  }

  scene.add(group);
}

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

  group.rotation.y += 0.005;
}
body {
  margin: 0;
}
canvas {
  display: block;
}
<script src="https://cdn.jsdelivr.net/npm/three@0.121.1/build/three.min.js"></script>


推荐阅读