平面几何,每段颜色不同,部分透明

Plane geometry, each segment different color, some of them transparent

我正在使用 three.js,我想创建 16x16 尺寸的几何图形。我希望每一段都是不同的颜色,其中一些是透明的。这个问题的最佳解决方案是什么? 我应该将每个像素渲染为一个平面几何体吗?或者有可能改变单个段 color/transparency.

Desired result

我建议您使用 PlaneGeometry 的实例,将其转换为所谓的 non-indexed 几何体,然后添加一个额外的颜色缓冲属性。完整示例:

let camera, scene, renderer;

init();
render();

function init() {

  camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10);
  camera.position.z = 1;

  scene = new THREE.Scene();
  
  // background

  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  canvas.width = canvas.height = 128;
  ctx.fillStyle = '#ddd';
  ctx.fillRect(0, 0, 128, 128);
  ctx.fillStyle = '#555';
  ctx.fillRect(0, 0, 64, 64);
  ctx.fillStyle = '#999';
  ctx.fillRect(32, 32, 32, 32);
  ctx.fillStyle = '#555';
  ctx.fillRect(64, 64, 64, 64);
  ctx.fillStyle = '#777';
  ctx.fillRect(96, 96, 32, 32);

  mapBg = new THREE.CanvasTexture(canvas);
  mapBg.wrapS = mapBg.wrapT = THREE.RepeatWrapping;
  mapBg.repeat.set(64, 32);

  scene.background = mapBg;
  
  // plane mesh

  const geometry = new THREE.PlaneGeometry(1, 1, 10, 10).toNonIndexed();

  const positionAttribute = geometry.getAttribute('position');

  const colors = [];
  const color = new THREE.Color();

  for (let i = 0; i < positionAttribute.count; i += 6) {

    color.setRGB(Math.random(), Math.random(), Math.random());
    const alpha = Math.random();

    colors.push(color.r, color.g, color.b, alpha);
    colors.push(color.r, color.g, color.b, alpha);
    colors.push(color.r, color.g, color.b, alpha);

    colors.push(color.r, color.g, color.b, alpha);
    colors.push(color.r, color.g, color.b, alpha);
    colors.push(color.r, color.g, color.b, alpha);

  }

  geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 4));

  const material = new THREE.MeshBasicMaterial({
    vertexColors: true,
    transparent: true
  });

  const mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);
  
  //

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

}

function render() {

  renderer.render(scene, camera);

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