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

624 Views Asked by At

I am using three.js and I want to create geometry 16x16 size. I want that each segment is different color and some of them is transparent. What is the best solution for this problem? Should i render each pixel as a single plane geometry? Or there is possible way to change single segment color/transparency.

Desired result

1

There are 1 best solutions below

0
On BEST ANSWER

I suggest you an instance of PlaneGeometry, transform it to a so called non-indexed geometry and then add an additional color buffer attribute. Full example:

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/[email protected]/build/three.min.js"></script>