colorsthree.jsvertex-shadervertex-array

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


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


Solution

  • 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/three@0.141/build/three.min.js"></script>