Search code examples
three.jsreact-three-fiber

Three Js : Different colors to different face of geometry


I am learning three js , I want to create geometry with each face have different color , Here I choose Isocahedron , I tried giving color to face but am getting transition of colors on each face instead I want a single color on each face

let g = new THREE.IcosahedronGeometry(8, 3)

const count = g.attributes.position.count;
const color = new THREE.Color();

                
g.setAttribute( 'color', new THREE.BufferAttribute( new Float32Array( count * 3 ), 3 ) );
const colors1 = g.attributes.color;
        
      
for ( let i = 0; i < count; i ++ ) {
    color.setHex( Math.random() * 0xffffff );
    colors1.setXYZ( i, color.r, color.g, color.b);
    }
        
let m =  new THREE.MeshLambertMaterial( {vertexColors: true,} );
let o = new THREE.Mesh(g, m);
scene.add(o);

enter image description here


Solution

  • The loop with setting of colors has to be something like this:

    for (let i = 0; i < (count / 3); i++) {
      color.setHex(Math.random() * 0xffffff);
      colors1.setXYZ(i * 3 + 0, color.r, color.g, color.b);
      colors1.setXYZ(i * 3 + 1, color.r, color.g, color.b);
      colors1.setXYZ(i * 3 + 2, color.r, color.g, color.b);
    }
    

    Example:

    body{
      overflow: hidden;
      margin: 0;
    }
    <script type="module">
    console.clear();
    
    import * as THREE from "https://cdn.skypack.dev/three@0.132.2";
    import {
      OrbitControls
    } from "https://cdn.skypack.dev/three@0.132.2/examples/jsm/controls/OrbitControls.js";
    
    let scene = new THREE.Scene();
    let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000);
    camera.position.set(0, 8, 13).setLength(10);
    camera.lookAt(scene.position);
    let renderer = new THREE.WebGLRenderer({
      antialias: true
    });
    renderer.setSize(innerWidth, innerHeight);
    renderer.setClearColor(0x404040);
    document.body.appendChild(renderer.domElement);
    
    let controls = new OrbitControls(camera, renderer.domElement);
    
    let light = new THREE.DirectionalLight(0xffffff, 1);
    light.position.setScalar(1);
    scene.add(light, new THREE.AmbientLight(0xffffff, 0.5));
    
    let g = new THREE.IcosahedronGeometry(5, 3)
    
    const count = g.attributes.position.count;
    const color = new THREE.Color();
    
    
    g.setAttribute('color', new THREE.BufferAttribute(new Float32Array(count * 3), 3));
    const colors1 = g.attributes.color;
    
    
    for (let i = 0; i < (count / 3); i++) {
      color.setHex(Math.random() * 0xffffff);
      colors1.setXYZ(i * 3 + 0, color.r, color.g, color.b);
      colors1.setXYZ(i * 3 + 1, color.r, color.g, color.b);
      colors1.setXYZ(i * 3 + 2, color.r, color.g, color.b);
    }
    
    let m = new THREE.MeshLambertMaterial({
      vertexColors: true,
    });
    let o = new THREE.Mesh(g, m);
    scene.add(o);
    
    renderer.setAnimationLoop(_ => {
      renderer.render(scene, camera);
    })
    
    </script>