Three.js.Почему эта текстура RGBA не меняет непрозрачность связанного материала? - PullRequest
1 голос
/ 16 апреля 2019

В three.js я создаю материал, который использует текстуру для контроля прозрачности. Текстура создана из холста. Холст рисуется с помощью fillStyle от rgba. Альфа меняется по всему холсту. Эффект, которого я добиваюсь, заключается в изменении прозрачности объекта, к которому прикреплен материал. Этого не происходит. Объект остается непрозрачным.

Код:

tubeTexture = new THREE.Texture(canvas);
tubeTexture.center.set(0.5, 0.5);
tubeTexture.rotation = Math.PI/2.0;

// turn off any filtering to create sharp edges when highlighting
// tube section based on colorRamp highlighting.
tubeTexture.minFilter = tubeTexture.magFilter = THREE.NearestFilter;

// let tubeMaterial = new THREE.MeshBasicMaterial({ map: tubeTexture });
let tubeMaterial = new THREE.MeshPhongMaterial({ map: tubeTexture });
tubeMaterial.side = THREE.DoubleSide;
tubeMaterial.transparent = true;

// let tubeMaterial = sceneManager.stickMaterial.clone();
const tubeMesh = new THREE.Mesh(tubeGeometry, tubeMaterial);

Чего мне не хватает?

1 Ответ

1 голос
/ 17 апреля 2019

Кажется, у меня работает

'use strict';

/* global THREE */

function main() {
  const canvas = document.querySelector('#c');
  const renderer = new THREE.WebGLRenderer({
    canvas: canvas
  });

  const fov = 75;
  const aspect = 2; // the canvas default
  const near = 0.1;
  const far = 5;
  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  camera.position.z = 2;

  const scene = new THREE.Scene();
  scene.background = new THREE.Color('white');

  {
    const color = 0xFFFFFF;
    const intensity = 1;
    const light = new THREE.DirectionalLight(color, intensity);
    light.position.set(-1, 2, 4);
    scene.add(light);
  }

  const boxWidth = 1;
  const boxHeight = 1;
  const boxDepth = 1;
  const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);
  
  const ctx = document.createElement('canvas').getContext('2d');
  ctx.canvas.width = 256;
  ctx.canvas.height = 256;
  ctx.fillStyle = 'rgba(255, 255, 255, 0.25)';
  ctx.beginPath();
  ctx.arc(128, 128, 120, 0, Math.PI * 2);
  ctx.fill();
  ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';
  ctx.beginPath();
  ctx.arc(128, 128, 64, 0, Math.PI * 2);
  ctx.fill();
  ctx.fillStyle = 'rgba(255, 255, 255, 1.0)';
  ctx.beginPath();
  ctx.arc(128, 128, 32, 0, Math.PI * 2);
  ctx.fill();
  
  const texture = new THREE.CanvasTexture(ctx.canvas);
  
  const root = new THREE.Object3D();
  scene.add(root);

  function makeInstance(geometry, color, x) {
    const material = new THREE.MeshPhongMaterial({
      color,
      map: texture,
      transparent: true,
      side: THREE.DoubleSide,
      alphaTest: 0.1,
    });

    const cube = new THREE.Mesh(geometry, material);
    root.add(cube);

    cube.position.x = x;

    return cube;
  }

  const cubes = [
    makeInstance(geometry, 0x44aa88, 0),
    makeInstance(geometry, 0x8844aa, -2),
    makeInstance(geometry, 0xaa8844, 2),
  ];

  function resizeRendererToDisplaySize(renderer) {
    const canvas = renderer.domElement;
    const width = canvas.clientWidth;
    const height = canvas.clientHeight;
    const needResize = canvas.width !== width || canvas.height !== height;
    if (needResize) {
      renderer.setSize(width, height, false);
    }
    return needResize;
  }

  function render(time) {
    time *= 0.001;

    if (resizeRendererToDisplaySize(renderer)) {
      const canvas = renderer.domElement;
      camera.aspect = canvas.clientWidth / canvas.clientHeight;
      camera.updateProjectionMatrix();
    }

    root.rotation.y = time * .2;

    cubes.forEach((cube, ndx) => {
      const speed = 1 + ndx * .1;
      const rot = time * speed;
      cube.rotation.x = rot;
      cube.rotation.y = rot;
    });

    renderer.render(scene, camera);

    requestAnimationFrame(render);
  }

  requestAnimationFrame(render);
}

main();
body {
  margin: 0;
}

#c {
  width: 100vw;
  height: 100vh;
  display: block;
}
<canvas id="c"></canvas>

<script src="https://threejsfundamentals.org/threejs/resources/threejs/r103/three.min.js"></script>

Конечно, есть нормальные проблемы, связанные с прозрачностью и сортировкой. Объект не будет постоянно прозрачным для самого себя, только для других объектов.

...