three.js之BufferGeometry

BufferGeometry缓冲几何体

<canvas id="mainCanvas"></canvas>
<script type="importmap">
  {
    "imports": {
      "three": "./js/build/three.module.js",
      "three/addons/": "./js/jsm/"
    }
  }
</script>
<script type="module">
  import * as THREE from "three";
  import { GUI } from "three/addons/libs/lil-gui.module.min.js";
  import { TrackballControls } from "three/addons/controls/TrackballControls.js";
  import { initRenderer, initPerspectiveCamera, initAmbientLight, initSpotLight, addPlane, addBox } from "./init.js";

  async function init() {
    const renderer = initRenderer("mainCanvas");

    const scene = new THREE.Scene();

    const camera = initPerspectiveCamera();
    camera.position.set(50, 0, 200);
    scene.add(camera);

    const ambientLight = initAmbientLight();
    scene.add(ambientLight);

    const spotLight = initSpotLight();
    scene.add(spotLight);

    const trackballControls = new TrackballControls(camera, renderer.domElement);
    const clock = new THREE.Clock();

    const axesHelper = new THREE.AxesHelper(150);
    scene.add(axesHelper);

    const material = new THREE.MeshLambertMaterial({
      color: 0xff0000,
      side: THREE.DoubleSide,
    });

    const material_v = new THREE.MeshBasicMaterial({
      vertexColors: true, //默认false,设置为true表示使用顶点颜色渲染
      side: THREE.DoubleSide,
    });

    const textureLoader = new THREE.TextureLoader();
    const texture = await textureLoader.load("./textures/uv/ash_uvgrid01.jpg");
    texture.colorSpace = THREE.SRGBColorSpace; //设置为SRGB颜色空间
    // 设置阵列模式
    // texture.wrapS = THREE.RepeatWrapping;
    // texture.wrapT = THREE.RepeatWrapping;
    // uv两个方向纹理重复数量
    // texture.repeat.set(2, 2);
    const material_t = new THREE.MeshLambertMaterial({
      map: texture,
      side: THREE.DoubleSide,
    });

    const vertices = new Float32Array([0, 0, 0, 30, 0, 0, 30, 30, 0, 0, 0, 0, 30, 30, 0, 0, 30, 0]);
    const vertices_norepeat = new Float32Array([0, 0, 0, 30, 0, 0, 30, 30, 0, 0, 30, 0]);

    {
      // 根据顶点坐标生成面
      const geometry = new THREE.BufferGeometry();
      geometry.attributes.position = new THREE.BufferAttribute(vertices, 3);
      const mesh = new THREE.Mesh(geometry, material);
      mesh.position.set(-40, -40, 0);
      scene.add(mesh);

      // 几何体顶点索引数据
      const geometry2 = new THREE.BufferGeometry();
      geometry2.attributes.position = new THREE.BufferAttribute(vertices_norepeat, 3);
      const indexes = new Uint16Array([0, 1, 2, 0, 2, 3]);
      geometry2.index = new THREE.BufferAttribute(indexes, 1);
      const material2 = material.clone();
      material2.color.set(0x00ff00);
      const mesh2 = new THREE.Mesh(geometry2, material2);
      mesh2.position.set(0, -40, 0);
      scene.add(mesh2);

      // 顶点法线数据 法线的就是平面的垂线,如果是光滑曲面,一点的法线就是该点切面的法线。每个顶点的法线数据和顶点位置数据一一对应
      const geometry3 = geometry.clone();
      const normals = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]);
      geometry3.attributes.normal = new THREE.BufferAttribute(normals, 3);
      const mesh3 = new THREE.Mesh(geometry3, material);
      mesh3.position.set(40, -40, 0);
      scene.add(mesh3);

      const geometry4 = geometry2.clone();
      const normals4 = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]);
      geometry4.attributes.normal = new THREE.BufferAttribute(normals, 3);
      const mesh4 = new THREE.Mesh(geometry4, material2);
      mesh4.position.set(80, -40, 0);
      scene.add(mesh4);
    }

    {
      // 顶点颜色:3个一组表示一个顶点的颜色数据RGB
      const geometry = new THREE.BufferGeometry();
      geometry.attributes.position = new THREE.BufferAttribute(vertices_norepeat, 3);
      const indexes = new Uint16Array([0, 1, 2, 0, 2, 3]);
      geometry.index = new THREE.BufferAttribute(indexes, 1);
      const colors = new Float32Array([1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1]);
      geometry.attributes.color = new THREE.BufferAttribute(colors, 3);
      const mesh = new THREE.Mesh(geometry, material_v);
      mesh.position.set(-40, 0, 0);
      scene.add(mesh);

      const geometry2 = new THREE.BufferGeometry();
      const pointsArr2 = [new THREE.Vector3(0, 0, 0), new THREE.Vector3(30, 0, 0), new THREE.Vector3(30, 30, 0)];
      geometry2.setFromPoints(pointsArr2);
      const pos = geometry2.attributes.position;
      const count = pos.count;
      const colorsArr2 = [];
      for (let i = 0; i < count; i++) {
        const percent = i / count;
        colorsArr2.push(percent, 0, 1 - percent);
      }
      const colors2 = new Float32Array(colorsArr2);
      geometry2.attributes.color = new THREE.BufferAttribute(colors2, 3);
      const mesh2 = new THREE.Mesh(geometry2, material_v);
      mesh2.position.set(0, 0, 0);
      scene.add(mesh2);

      const colorsArr3 = [];
      const c1 = new THREE.Color(0x00ffff);
      const c2 = new THREE.Color(0xffff00);
      for (let i = 0; i < count; i++) {
        const percent = i / count;
        const c = c1.clone().lerp(c2, percent);
        colorsArr3.push(c.r, c.g, c.b);
      }
      const colors3 = new Float32Array(colorsArr3);
      const geometry3 = geometry2.clone();
      geometry3.attributes.color = new THREE.BufferAttribute(colors3, 3);
      const mesh3 = new THREE.Mesh(geometry3, material_v);
      mesh3.position.set(40, 0, 0);
      scene.add(mesh3);
    }

    // 顶点uv坐标
    // 顶点uv坐标,是二维顶点坐标,顶点UV坐标geometry.attributes.uv和顶点位置坐标geometry.attributes.position是一一对应的。
    // 作用:纹理贴图上提取像素映射到网格模型Mesh的几何体表面上。
    {
      const geometry = new THREE.BufferGeometry();
      geometry.attributes.position = new THREE.BufferAttribute(vertices_norepeat, 3);
      const indexes = new Uint16Array([0, 1, 2, 0, 2, 3]);
      geometry.index = new THREE.BufferAttribute(indexes, 1);
      const mesh = new THREE.Mesh(geometry, material_t);
      mesh.position.set(-40, 40, 0);
      scene.add(mesh);

      const uvs2 = [0, 0, 1, 0, 1, 1, 0, 1];
      const geometry2 = geometry.clone();
      geometry2.attributes.uv = new THREE.BufferAttribute(new Float32Array(uvs2), 2);
      const mesh2 = new THREE.Mesh(geometry2, material_t);
      mesh2.position.set(0, 40, 0);
      scene.add(mesh2);

      const uvs3 = [0, 0, 1, 0, 0.5, 0.5, 0, 1];
      const geometry3 = geometry.clone();
      geometry3.attributes.uv = new THREE.BufferAttribute(new Float32Array(uvs3), 2);
      const mesh3 = new THREE.Mesh(geometry3, material_t);
      mesh3.position.set(40, 40, 0);
      scene.add(mesh3);
    }

    render();

    function render() {
      trackballControls.update(clock.getDelta());

      requestAnimationFrame(render);
      renderer.render(scene, camera);
    }
  }

  init();
</script>

posted @ 2024-07-15 10:15  carol2014  阅读(2)  评论(0编辑  收藏  举报