three.js InstancedBufferAttribute InstancedBufferGeometry InstancedMesh 介绍

154 阅读1分钟

InstancedBufferAttribute 是什么能够做什么

  • InstancedBufferAttribute 主要用来渲染大量重复几何体的技术
  • InstancedBufferGeometry 与 InstancedBufferAttribute 配合使用能够在新建一个几体的的情况下,渲染大量的几何休
  • 通过 ShaderMaterial 材质 设置几何体的各种属性

InstancedBufferGeometry 是新建的几何体的对象

InstancedMesh 是新建的网格对象

代码示例


    


    const renderer = new THREE.WebGLRenderer();
    renderer.setSize( width, height );
    DOMEl.appendChild( renderer.domElement );
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera( 45, width / height, 1, 2000 );
    camera.position.set( 0, 300, 800 );
    camera.lookAt( 0, 0, 0 );

    const geometry = new THREE.BoxGeometry(1, 1, 1);
    const count = 1000; // Number of instances

    // 创建一个包含1000个实例的 InstancedBufferGeometry
    const instancedGeometry = new THREE.InstancedBufferGeometry().copy(geometry);

    // 创建每个实例的偏移属性(例如位置的偏移)
    const offsets = [];
    for (let i = 0; i < count; i++) {
        offsets.push(Math.random() * 10 - 5); // x
        offsets.push(Math.random() * 10 - 5); // y
        offsets.push(Math.random() * 10 - 5); // z
    }

    // 将偏移属性添加到几何体中
    instancedGeometry.setAttribute('offset', new THREE.InstancedBufferAttribute(new Float32Array(offsets), 3));

    // 创建材质并传递自定义着色器,处理偏移属性
    const material = new THREE.ShaderMaterial({
    vertexShader: `
        attribute vec3 offset;
        void main() {
        vec3 pos = position + offset;
        gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
        }
    `,
    fragmentShader: `
        void main() {
        gl_FragColor = vec4(1.0, 0.5, 0.2, 1.0);
        }
    `,
    });

    // 创建网格并添加到场景 
    const mesh = new THREE.InstancedMesh(instancedGeometry, material, count);
    scene.add(mesh);

    renderer.render(scene, camera);

需要特别注意的几个点 InstancedMesh 上下文对象网格 InstancedBufferGeometry 上下文对象几何体 InstancedBufferAttribute 上下文对象Buffer数据 这几个是成套的