three.js之加载模型、贴图

加载各种模型

<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 { TrackballControls } from "three/addons/controls/TrackballControls.js";
  import { GUI } from "three/addons/libs/lil-gui.module.min.js";
  import { initRenderer, initPerspectiveCamera, initAmbientLight, initSpotLight } from "./init.js";
  import { OBJLoader } from "three/addons/loaders/OBJLoader.js";
  import { MTLLoader } from "three/addons/loaders/MTLLoader.js";
  import { ColladaLoader } from "three/addons/loaders/ColladaLoader.js";
  import { STLLoader } from "three/addons/loaders/STLLoader.js";
  import { VTKLoader } from "three/addons/loaders/VTKLoader.js";
  import { PDBLoader } from "three/addons/loaders/PDBLoader.js";
  import { PLYLoader } from "three/addons/loaders/PLYLoader.js";
  import { VRMLLoader } from "three/addons/loaders/VRMLLoader.js";
  import { TDSLoader } from "three/addons/loaders/TDSLoader.js";
  import { ThreeMFLoader } from "three/addons/loaders/3MFLoader.js";
  import { AMFLoader } from "three/addons/loaders/AMFLoader.js";
  import { DRACOLoader } from "three/addons/loaders/DRACOLoader.js";
  import { GCodeLoader } from "three/addons/loaders/GCodeLoader.js";
  import { SVGLoader } from "three/addons/loaders/SVGLoader.js";
  import { FBXLoader } from "three/addons/loaders/FBXLoader.js";

  function init() {
    const gui = new GUI();

    const renderer = initRenderer("mainCanvas");

    let scene = new THREE.Scene();

    const camera = initPerspectiveCamera();
    scene.add(camera);

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

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

    let knot = createMesh(new THREE.TorusKnotGeometry(10, 1, 64, 8, 2, 3));
    scene.add(knot);

    const controls = setupControls();
    let step = 0;
    let loadedMesh;

    render();

    function render() {
      knot.rotation.y = step += 0.01;

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

    function setupControls() {
      const controls = new (function () {
        this.radius = knot.geometry.parameters.radius;
        this.tube = 0.3;
        this.radialSegments = knot.geometry.parameters.radialSegments;
        this.tubularSegments = knot.geometry.parameters.tubularSegments;
        this.p = knot.geometry.parameters.p;
        this.q = knot.geometry.parameters.q;

        this.redraw = function () {
          scene.remove(knot);
          knot = createMesh(
            new THREE.TorusKnotGeometry(controls.radius, controls.tube, Math.round(controls.radialSegments), Math.round(controls.tubularSegments), Math.round(controls.p), Math.round(controls.q))
          );
          scene.add(knot);
        };

        this.saveMesh = function () {
          const result = knot.toJSON();
          sessionStorage.setItem("mesh", JSON.stringify(result));
          console.log(sessionStorage.getItem("mesh"));
        };

        this.loadMesh = function () {
          scene.remove(loadedMesh);

          const json = sessionStorage.getItem("mesh");
          if (json) {
            const loadedGeometry = JSON.parse(json);
            const loader = new THREE.ObjectLoader();
            loadedMesh = loader.parse(loadedGeometry);
            loadedMesh.position.x -= 40;
            scene.add(loadedMesh);
          }
        };

        this.exportScene = function () {
          sessionStorage.setItem("scene", JSON.stringify(scene.toJSON()));
          console.log(sessionStorage.getItem("scene"));
        };

        this.clearScene = function () {
          scene = new THREE.Scene();
          scene.add(ambientLight);
          scene.add(spotLight);
        };

        this.importScene = function () {
          const json = sessionStorage.getItem("scene");

          if (json) {
            const loadedSceneAsJson = JSON.parse(json);
            const loader = new THREE.ObjectLoader();
            scene = loader.parse(loadedSceneAsJson);
          }
        };

        this.loadFromJson = function () {
          const loader = new THREE.ObjectLoader();
          loader.load("./models/lightmap/lightmap.json", function (obj) {
            computeSize(obj);
            console.log("obj scale", obj.scale);
            computeSize(scene);

            obj.scale.set(5, 5, 5);
            scene.add(obj);
          });
        };

        this.loadFromObj = function () {
          // OBJ加载器 用于加载 .obj 资源的加载器。
          // OBJ 文件格式是一种简单的数据格式, 这种格式以人类可读的形式来表示3D几何体,即每个顶点的位置、每个纹理坐标顶点的UV位置、顶点法线、 将使每个多边形定义为顶点列表的面以及纹理顶点。
          const loader = new OBJLoader();
          loader.load("./models/tree.obj", function (obj) {
            computeSize(obj);
            console.log("obj scale", obj.scale);
            computeSize(scene);

            obj.scale.set(20, 20, 20);
            scene.add(obj);
          });
        };

        this.loadFromObjMtl = function () {
          const mtlLoader = new MTLLoader();
          mtlLoader.load("./models/walt/WaltHead.mtl", function (materials) {
            materials.preload();

            const loader = new OBJLoader();
            loader.load("./models/walt/WaltHead.obj", function (obj) {
              computeSize(obj);
              console.log("obj scale", obj.scale);
              computeSize(scene);

              obj.scale.set(0.2, 0.2, 0.2);
              scene.add(obj);
            });
          });
        };

        this.loadFromCollada = function () {
          const loader = new ColladaLoader();
          loader.load("./models/collada/elf/elf.dae", function (res) {
            console.log(res);
            computeSize(res.scene);
            res.scene.scale.set(2, 2, 2);
            scene.add(res.scene);
          });
        };

        this.loadFromStl = function () {
          const loader = new STLLoader();
          loader.load("./models/stl/ascii/slotted_disk.stl", function (geometry) {
            const mat = new THREE.MeshStandardMaterial({
              color: 0xffffff,
              metalness: 1,
              roughness: 0.5,
            });
            const mesh = new THREE.Mesh(geometry, mat);
            mesh.rotation.x = -0.5 * Math.PI;
            mesh.scale.set(20, 20, 20);

            computeSize(mesh);
            computeSize(scene);

            scene.add(mesh);
          });
        };

        this.loadFromVtk = function () {
          const loader = new VTKLoader();
          loader.load("./models/vtk/liver.vtk", function (geometry) {
            const mat = new THREE.MeshNormalMaterial();

            geometry.center();
            geometry.computeVertexNormals();

            const mesh = new THREE.Mesh(geometry, mat);
            mesh.scale.set(0.3, 0.3, 0.3);

            computeSize(mesh);
            computeSize(scene);

            scene.add(mesh);
          });
        };

        this.loadFromPdb = function () {
          const loader = new PDBLoader();
          loader.load("./models/diamond.pdb", function (geometries) {
            const group = new THREE.Object3D();
            const geometryAtoms = geometries.geometryAtoms;

            for (let i = 0; i < geometryAtoms.attributes.position.count; i++) {
              const startPosition = new THREE.Vector3();
              startPosition.x = geometryAtoms.attributes.position.getX(i);
              startPosition.y = geometryAtoms.attributes.position.getY(i);
              startPosition.z = geometryAtoms.attributes.position.getZ(i);

              const color = new THREE.Color();
              color.r = geometryAtoms.attributes.color.getX(i);
              color.g = geometryAtoms.attributes.color.getY(i);
              color.b = geometryAtoms.attributes.color.getZ(i);

              const material = new THREE.MeshPhongMaterial({
                color: color,
              });

              const sphere = new THREE.SphereGeometry(0.2);
              const mesh = new THREE.Mesh(sphere, material);
              mesh.position.copy(startPosition);
              group.add(mesh);
            }

            const geometryBonds = geometries.geometryBonds;

            for (let j = 0; j < geometryBonds.attributes.position.count; j += 2) {
              const startPosition = new THREE.Vector3();
              startPosition.x = geometryBonds.attributes.position.getX(j);
              startPosition.y = geometryBonds.attributes.position.getY(j);
              startPosition.z = geometryBonds.attributes.position.getZ(j);

              const endPosition = new THREE.Vector3();
              endPosition.x = geometryBonds.attributes.position.getX(j + 1);
              endPosition.y = geometryBonds.attributes.position.getY(j + 1);
              endPosition.z = geometryBonds.attributes.position.getZ(j + 1);

              const path = new THREE.CatmullRomCurve3([startPosition, endPosition]);
              const tube = new THREE.TubeGeometry(path, 1, 0.04);
              const material = new THREE.MeshPhongMaterial({
                color: 0xcccccc,
              });
              const mesh = new THREE.Mesh(tube, material);
              group.add(mesh);
            }

            computeSize(scene);
            computeSize(group);
            group.scale.set(2, 2, 2);
            scene.add(group);
          });
        };

        this.loadFromPly = function () {
          const loader = new PLYLoader();
          loader.load("./models/ply/ascii/dolphins.ply", function (geometry) {
            const material = new THREE.PointsMaterial({
              color: 0xffffff,
              size: 1,
              opacity: 0.6,
              transparent: true,
              blending: THREE.AdditiveBlending,
              depthWrite: false,
              map: generateSprite(),
            });

            const group = new THREE.Points(geometry, material);
            group.scale.set(0.05, 0.05, 0.05);
            computeSize(scene);
            computeSize(group);
            scene.add(group);
          });
        };

        this.loadFromVrml = function () {
          const loader = new VRMLLoader();
          loader.load("./models/house.wrl", function (model) {
            computeSize(model);
            console.log;
            computeSize(scene);
            model.scale.set(2, 2, 2);
            scene.add(model);
          });
        };

        this.loadFromTds = function () {
          const loader = new TDSLoader();
          loader.load("./models/3ds/portalgun/portalgun.3ds", function (group) {
            computeSize(group);
            group.scale.set(20, 20, 20);
            scene.add(group);
          });
        };

        this.loadFrom3mf = function () {
          const loader = new ThreeMFLoader();
          loader.load("./models/truck.3mf", function (group) {
            computeSize(group);
            scene.add(group);
          });
        };

        this.loadFromAmf = function () {
          const loader = new AMFLoader();
          loader.load("./models/rook.amf", function (group) {
            computeSize(group);
            group.scale.set(5, 5, 5);
            scene.add(group);
          });
        };

        this.loadFromDrc = function () {
          // DRACOLoader 一个用于加载经过Draco压缩的图形库。
          // Draco是一个开源的库,主要用于压缩和解压缩三维模型及点云。 以客户端上解压缩为代价,显著减少压缩的图形。
          // 独立的Draco文件后缀为.drc,其中包含顶点坐标,法线,颜色和其他的属性,不包含材质,纹理,动画和节点结构。
          const loader = new DRACOLoader();
          loader.setDecoderPath("./js/jsm/libs/draco/");
          loader.setDecoderConfig({ type: "js" });
          loader.preload();

          loader.load("./models/bunny.drc", function (geometry) {
            geometry.computeVertexNormals();
            geometry.computeBoundingSphere();
            geometry.computeBoundingBox();

            const mesh = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial());
            computeSize(mesh);
            mesh.scale.set(100, 100, 100);
            scene.add(mesh);
          });
        };

        this.loadFromGcode = function () {
          const loader = new GCodeLoader();
          loader.load("./models/benchy.gcode", function (obj) {
            computeSize(obj);
            obj.scale.set(0.1, 0.1, 0.1);
            scene.add(obj);
          });
        };

        this.loadFromSvg = function () {
          // SVGLoader 用于加载.svg资源的加载器
          // 可伸缩向量图形是XML形式的矢量图形格式,用来描述二维矢量图形并支持交互和动画。
          const loader = new SVGLoader();

          loader.load("./models/tiger.svg", function (data) {
            const paths = data.paths;
            const group = new THREE.Group();
            group.scale.multiplyScalar(0.1);
            group.scale.y *= -1;
            for (let i = 0; i < paths.length; i++) {
              const path = paths[i];
              const material = new THREE.MeshBasicMaterial({
                color: path.color,
                side: THREE.DoubleSide,
                depthWrite: false,
              });
              const shapes = path.toShapes(true);
              for (let j = 0; j < shapes.length; j++) {
                const shape = shapes[j];
                const geometry = new THREE.ShapeGeometry(shape);
                const mesh = new THREE.Mesh(geometry, material);
                group.add(mesh);
              }
            }

            computeSize(group);
            scene.add(group);
          });
        };

        this.loadFromFbx = function () {
          const fbxloader = new FBXLoader();
          fbxloader.load("./models/Samba Dancing.fbx", function (obj) {
            console.log(obj);
            computeSize(obj);
            obj.scale.set(0.1, 0.1, 0.1);
            scene.add(obj);
          });
        };
      })();

      const ioGui = gui.addFolder("Save & Load");
      ioGui.add(controls, "exportScene");
      ioGui.add(controls, "clearScene");
      ioGui.add(controls, "importScene");
      ioGui.add(controls, "saveMesh");
      ioGui.add(controls, "loadMesh");
      ioGui.add(controls, "loadFromJson");
      ioGui.add(controls, "loadFromObj");
      ioGui.add(controls, "loadFromObjMtl");
      ioGui.add(controls, "loadFromCollada");
      ioGui.add(controls, "loadFromStl");
      ioGui.add(controls, "loadFromVtk");
      ioGui.add(controls, "loadFromPdb");
      ioGui.add(controls, "loadFromPly");
      ioGui.add(controls, "loadFromVrml");
      ioGui.add(controls, "loadFromTds");
      ioGui.add(controls, "loadFrom3mf");
      ioGui.add(controls, "loadFromAmf");
      ioGui.add(controls, "loadFromDrc");
      ioGui.add(controls, "loadFromGcode");
      ioGui.add(controls, "loadFromSvg");
      ioGui.add(controls, "loadFromFbx");

      const meshGui = gui.addFolder("mesh");
      meshGui.add(controls, "radius", 0, 40).onChange(controls.redraw);
      meshGui.add(controls, "tube", 0, 40).onChange(controls.redraw);
      meshGui.add(controls, "radialSegments", 1, 400).step(1).onChange(controls.redraw);
      meshGui.add(controls, "tubularSegments", 1, 20).step(1).onChange(controls.redraw);
      meshGui.add(controls, "p", 1, 10).step(1).onChange(controls.redraw);
      meshGui.add(controls, "q", 1, 15).step(1).onChange(controls.redraw);

      return controls;
    }
  }

  init();

  function createMesh(geom) {
    const meshMaterial = new THREE.MeshBasicMaterial({
      vertexColors: false,
      wireframe: true,
      wireframeLinewidth: 2,
      color: 0xaaaaaa,
    });
    meshMaterial.side = THREE.DoubleSide;

    const mesh = new THREE.Mesh(geom, meshMaterial);
    mesh.position.set(20, 0, 0);
    return mesh;
  }

  function computeSize(obj) {
    const cbox = new THREE.Box3().setFromObject(obj);
    const size = cbox.getSize(new THREE.Vector3());

    if (obj instanceof THREE.Scene) {
      console.log("scene size", size);
    } else {
      console.log("obj size", size);
    }
  }

  function generateSprite() {
    const canvas = document.createElement("canvas");
    canvas.width = 16;
    canvas.height = 16;
    const context = canvas.getContext("2d");

    const gradient = context.createRadialGradient(canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2);
    gradient.addColorStop(0, "rgba(255,255,255,1)");
    gradient.addColorStop(0.2, "rgba(0,255,255,1)");
    gradient.addColorStop(0.4, "rgba(0,0,64,1)");
    gradient.addColorStop(1, "rgba(0,0,0,1)");
    context.fillStyle = gradient;
    context.fillRect(0, 0, canvas.width, canvas.height);

    const texture = new THREE.Texture(canvas);
    texture.needsUpdate = true;
    return texture;
  }
</script>

加载贴图

<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 { DDSLoader } from "three/addons/loaders/DDSLoader.js";
  import { PVRLoader } from "three/addons/loaders/PVRLoader.js";
  import { TGALoader } from "three/addons/loaders/TGALoader.js";
  import { KTXLoader } from "three/addons/loaders/KTXLoader.js";
  import { EXRLoader } from "three/addons/loaders/EXRLoader.js";
  import { RGBELoader } from "three/addons/loaders/RGBELoader.js";
  import { initRenderer, initPerspectiveCamera, initAmbientLight, initSpotLight, addPlane, addMaterialSettings, addSpecificMaterialSettings } from "./init.js";

  function init() {
    const gui = new GUI();

    const renderer = initRenderer("mainCanvas");

    let scene = new THREE.Scene();

    const camera = initPerspectiveCamera();
    scene.add(camera);

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

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

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

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

    const groundPlane = addPlane({ width: 200, height: 200 });
    groundPlane.position.set(0, -10, 0);
    scene.add(groundPlane);

    const textureLoader = new THREE.TextureLoader();

    let meshs = addGeometrys([
      textureLoader.load("./textures/general/metal-rust.jpg"),
      textureLoader.load("./textures/general/floor-wood.jpg"),
      textureLoader.load("./textures/general/brick-wall.jpg"),
    ]);
    const controls = setupControls();
    const clock = new THREE.Clock();

    render();

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

      for (let i in meshs) {
        if (i == 0) {
          meshs[i].rotation.x += 0.01;
        } else if (i == meshs.length - 1) {
          meshs[i].rotation.z += 0.01;
        } else {
          meshs[i].rotation.y += 0.01;
        }
      }

      let cubeCamera = null;
      scene.traverse(function (obj) {
        if (obj instanceof THREE.CubeCamera) {
          cubeCamera = obj;
        }
      });
      if (cubeCamera != null) {
        meshs[0].visible = false;
        cubeCamera.update(renderer, scene);
        meshs[1].visible = true;
      }

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

    function addGeometrys(textures) {
      const geoms = [new THREE.IcosahedronGeometry(8, 0), new THREE.SphereGeometry(5, 20, 20), new THREE.BoxGeometry(10, 10, 10)];
      const meshs = [];
      if (textures.length == 3) {
        for (let i in textures) {
          //map : Texture 颜色贴图。可以选择包括一个alpha通道,通常与.transparent 或.alphaTest。默认为null。 纹理贴图颜色由漫反射颜色.color调节。
          const mat = new THREE.MeshStandardMaterial({
            map: textures[i],
            metalness: 0.2,
            roughness: 0.07,
          });
          const mesh = new THREE.Mesh(geoms[i], mat);
          mesh.castShadow = true;
          scene.add(mesh);
          meshs.push(mesh);
        }
      } else if (textures.length == 1) {
        for (let i in geoms) {
          const mat = new THREE.MeshStandardMaterial({
            map: textures[0],
            metalness: 0.2,
            roughness: 0.07,
          });
          const mesh = new THREE.Mesh(geoms[i], mat);
          mesh.castShadow = true;
          scene.add(mesh);
          meshs.push(mesh);
        }
      } else if (textures.length == 0) {
        for (let i in geoms) {
          const mat = new THREE.MeshStandardMaterial({
            color: 0x00ffff,
            metalness: 0.2,
            roughness: 0.07,
          });
          const mesh = new THREE.Mesh(geoms[i], mat);
          mesh.castShadow = true;
          scene.add(mesh);
          meshs.push(mesh);
        }
      }

      for (let i in meshs) {
        if (i == 0) {
          meshs[i].position.x = -20;
        } else if (i == meshs.length - 1) {
          meshs[i].position.x = 20;
        }
      }

      return meshs;
    }

    function setupControls() {
      const controls = new (function () {
        this.clearScene = function () {
          scene = new THREE.Scene();
          scene.add(ambientLight);
          scene.add(spotLight);
          scene.add(groundPlane);
        };

        this.loadDds = function () {
          for (let i in meshs) {
            scene.remove(meshs[i]);
          }

          const textureLoader = new DDSLoader();
          const texture = textureLoader.load("./textures/dds/test-dxt1.dds");
          meshs = addGeometrys([texture]);
        };

        this.loadPvr = function () {
          for (let i in meshs) {
            scene.remove(meshs[i]);
          }

          console.log("pvrtc", renderer.extensions.get("WEBGL_compressed_texture_pvrtc"));
          const textureLoader = new PVRLoader();
          const texture = textureLoader.load("./textures/pvr/tex_base.pvr"); //显示纯黑色,似乎贴图未加载
          meshs = addGeometrys([texture]);
        };

        this.loadTga = function () {
          for (let i in meshs) {
            scene.remove(meshs[i]);
          }

          const textureLoader = new TGALoader();
          meshs = addGeometrys([textureLoader.load("./textures/tga/dried_grass.tga"), textureLoader.load("./textures/tga/grass.tga"), textureLoader.load("./textures/tga/moss.tga")]);
        };

        this.loadKtx = function () {
          for (let i in meshs) {
            scene.remove(meshs[i]);
          }

          const textureLoader = new KTXLoader();
          const format = determineFormat();
          console.log(format);
          let texture;
          switch (format) {
            case "astc":
              texture = textureLoader.load("./textures/ktx/disturb_ASTC4x4.ktx");
              break;
            case "etc1":
              texture = textureLoader.load("./textures/ktx/disturb_ETC1.ktx");
              break;
            case "s3tc":
              texture = textureLoader.load("./textures/ktx/disturb_BC1.ktx");
              break;
            case "pvrtc":
              texture = textureLoader.load("./textures/ktx/disturb_PVR2bpp.ktx");
              break;
          }
          meshs = addGeometrys([texture]);
        };

        this.loadExr = function () {
          for (let i in meshs) {
            scene.remove(meshs[i]);
          }

          const textureLoader = new EXRLoader();
          const texture = textureLoader.load("./textures/exr/Rec709.exr");
          meshs = addGeometrys([texture]);
        };

        this.loadRgbe = function () {
          for (let i in meshs) {
            scene.remove(meshs[i]);
          }

          const textureLoader = new RGBELoader();
          textureLoader.load("./textures/hdr/dani_cathedral_oBBC.hdr", function (texture) {
            texture.flipY = true;
            meshs = addGeometrys([texture]);
          });
        };

        this.loadBumpmap = function () {
          for (let i in meshs) {
            scene.remove(meshs[i]);
          }

          // 用于创建凹凸贴图的纹理。黑色和白色值映射到与光照相关的感知深度。
          // 凹凸实际上不会影响对象的几何形状,只影响光照。如果定义了法线贴图,则将忽略该贴图。
          // bumpScale : Float 凹凸贴图会对材质产生多大影响。典型范围是0-1。默认值为1。
          const texture = textureLoader.load("./textures/stone/stone.jpg");
          meshs = addGeometrys([texture]);
          meshs[2].material.bumpMap = textureLoader.load("./textures/stone/stone-bump.jpg"); //凸凹贴图
          meshs[2].material.bumpScale = 1;
        };

        this.loadNormalmap = function () {
          for (let i in meshs) {
            scene.remove(meshs[i]);
          }

          // 用于创建法线贴图的纹理。RGB值会影响每个像素片段的曲面法线,并更改颜色照亮的方式。
          // 法线贴图不会改变曲面的实际形状,只会改变光照。
          // normalScale : Vector2 法线贴图对材质的影响程度。典型范围是0-1。默认值是Vector2设置为(1,1)
          const texture = textureLoader.load("./textures/general/plaster.jpg");
          meshs = addGeometrys([texture]);
          meshs[2].material.normalMap = textureLoader.load("./textures/general/plaster-normal.jpg"); //法线贴图
        };

        this.loadDisplacementMap = function () {
          for (let i in meshs) {
            scene.remove(meshs[i]);
          }

          // 位移贴图会影响网格顶点的位置,与仅影响材质的光照和阴影的其他贴图不同,移位的顶点可以投射阴影,阻挡其他对象,以及充当真实的几何体。
          // 位移纹理是指:网格的所有顶点被映射为图像中每个像素的值(白色是最高的),并且被重定位。
          // displacementScale : Float 位移贴图对网格的影响程度(黑色是无位移,白色是最大位移)。如果没有设置位移贴图,则不会应用此值。默认值为1。
          // displacementBias : Float 位移贴图在网格顶点上的偏移量。如果没有设置位移贴图,则不会应用此值。默认值为0。
          const texture = textureLoader.load("./textures/w_c.jpg");
          meshs = addGeometrys([texture]);
          meshs[1].material.displacementMap = textureLoader.load("./textures/w_d.png"); //位移贴图
        };

        this.loadAoMap = function () {
          for (let i in meshs) {
            scene.remove(meshs[i]);
          }

          // aoMap : Texture 该纹理的红色通道用作环境遮挡贴图。默认值为null。aoMap需要第二组UV。
          // aoMapIntensity : Float 环境遮挡效果的强度。默认值为1。零是不遮挡效果。
          meshs = addGeometrys([]);
          meshs[2].material.aoMap = textureLoader.load("./textures/ambient.png");
          meshs[2].material.aoMapIntensity = 1;
        };

        this.loadLightMap = function () {
          for (let i in meshs) {
            scene.remove(meshs[i]);
          }

          // lightMap : Texture 光照贴图。默认值为null。lightMap需要第二组UV。
          // lightMapIntensity : Float 烘焙光的强度。默认值为1。
          meshs = addGeometrys([]);
          meshs[2].material.lightMap = textureLoader.load("./textures/lightmap/lightmap.png");
        };

        this.loadMetalRoughnessMap = function () {
          for (let i in meshs) {
            scene.remove(meshs[i]);
          }
          scene.remove(groundPlane);

          const urls = [
            "./textures/cubemap/colloseum/right.png",
            "./textures/cubemap/colloseum/left.png",
            "./textures/cubemap/colloseum/top.png",
            "./textures/cubemap/colloseum/bottom.png",
            "./textures/cubemap/colloseum/front.png",
            "./textures/cubemap/colloseum/back.png",
          ];
          const cubeLoader = new THREE.CubeTextureLoader();
          //背景
          scene.background = cubeLoader.load(urls);

          meshs = addGeometrys([]);
          // metalnessMap : Texture 该纹理的蓝色通道用于改变材质的金属度。
          meshs[0].material.metalnessMap = textureLoader.load("./textures/engraved/roughness-map.jpg");
          // roughnessMap : Texture 该纹理的绿色通道用于改变材质的粗糙度。
          meshs[2].material.roughnessMap = textureLoader.load("./textures/engraved/roughness-map.jpg");
        };

        this.loadAlphaMap = function () {
          for (let i in meshs) {
            scene.remove(meshs[i]);
          }

          // alphaMap: Texture alpha贴图是一张灰度纹理,用于控制整个表面的不透明度。(黑色:完全透明;白色:完全不透明)
          // alphaTest: Float 设置运行alphaTest时要使用的alpha值。如果不透明度低于此值,则不会渲染材质。默认值为0。
          meshs = addGeometrys([]);
          meshs[0].material.alphaMap = textureLoader.load("./textures/alpha/partial-transparency.png");
          meshs[0].material.alphaTest = 0.5;
        };

        this.loadEmissiveMap = function () {
          for (let i in meshs) {
            scene.remove(meshs[i]);
          }

          // emissive : Color 材质的放射(光)颜色,基本上是不受其他光照影响的固有颜色。默认为黑色。
          // emissiveMap : Texture 设置放射(发光)贴图。默认值为null。放射贴图颜色由放射颜色和强度所调节。 如果你有一个放射贴图,请务必将放射颜色设置为黑色以外的其他颜色。
          // emissiveIntensity : Float 放射光强度。调节发光颜色。默认为1。
          const material = new THREE.MeshStandardMaterial({
            emissive: 0xffffff,
            emissiveMap: textureLoader.load("./textures/emissive/lava.png"),
            normalMap: textureLoader.load("./textures/emissive/lava-normals.png"),
            metalnessMap: textureLoader.load("./textures/emissive/lava-smoothness.png"),
            metalness: 1,
            roughness: 0.4,
            normalScale: new THREE.Vector2(4, 4),
          });
          meshs = addGeometrys([]);
          meshs[0].material = material;
          meshs[1].material = material;
        };

        this.loadSpecularMap = function () {
          for (let i in meshs) {
            scene.remove(meshs[i]);
          }

          // specularMap : Texture 镜面反射贴图值会影响镜面高光以及环境贴图对表面的影响程度。默认值为null。
          const material = new THREE.MeshPhongMaterial({
            map: textureLoader.load("./textures/earth/Earth.png"),
            normalMap: textureLoader.load("./textures/earth/EarthNormal.png"),
            specularMap: textureLoader.load("./textures/earth/EarthSpec.png"),
            normalScale: new THREE.Vector2(6, 6),
          });
          meshs = addGeometrys([]);
          meshs[0].material = material;
          meshs[1].material = material;
        };
      })();
      gui.add(spotLight, "intensity", 0, 30, 1).name("聚光源强度");
      gui.add(controls, "clearScene");
      gui.add(controls, "loadDds");
      gui.add(controls, "loadPvr");
      gui.add(controls, "loadTga");
      gui.add(controls, "loadKtx");
      gui.add(controls, "loadExr");
      gui.add(controls, "loadRgbe");

      const obj = {
        bumpScale: 1,
        normalScaleX: 1,
        normalScaleY: 1,
        displacementScale: 1,
        displacementBias: 0,
        aoMapIntensity: 1,
        lightMapIntensity: 1,
        emissiveIntensity: 1,
      };
      const gui_map = gui.addFolder("map");
      gui_map.add(controls, "loadBumpmap");
      gui_map.add(obj, "bumpScale", 0, 1).onChange(function (e) {
        meshs[2].material.bumpScale = e;
      });
      gui_map.add(controls, "loadNormalmap");
      gui_map.add(obj, "normalScaleX", -3, 3).onChange(function (e) {
        meshs[2].material.normalScale.set(obj.normalScaleX, obj.normalScaleY);
      });
      gui_map.add(obj, "normalScaleY", -3, 3).onChange(function (e) {
        meshs[2].material.normalScale.set(obj.normalScaleX, obj.normalScaleY);
      });
      gui_map.add(controls, "loadDisplacementMap");
      gui_map.add(obj, "displacementScale", -5, 5).onChange(function (e) {
        meshs[1].material.displacementScale = e;
      });
      gui_map.add(obj, "displacementBias", -5, 5).onChange(function (e) {
        meshs[1].material.displacementBias = e;
      });
      gui_map.add(controls, "loadAoMap");
      gui_map.add(obj, "aoMapIntensity", 0, 5).onChange(function (e) {
        meshs[2].material.aoMapIntensity = e;
      });
      gui_map.add(controls, "loadLightMap");
      gui_map.add(obj, "lightMapIntensity", 0, 5).onChange(function (e) {
        meshs[2].material.lightMapIntensity = e;
      });
      gui_map.add(controls, "loadMetalRoughnessMap");
      gui_map.add(controls, "loadAlphaMap");
      gui_map.add(controls, "loadEmissiveMap");
      gui_map.add(obj, "emissiveIntensity", 0, 5, 0.5).onChange(function (e) {
        meshs[0].material.emissiveIntensity = e;
      });
      gui_map.add(controls, "loadSpecularMap");

      return controls;
    }

    function determineFormat() {
      if (renderer.extensions.get("WEBGL_compressed_texture_astc") !== null) return "astc";
      if (renderer.extensions.get("WEBGL_compressed_texture_etc1") !== null) return "etc1";
      if (renderer.extensions.get("WEBGL_compressed_texture_s3tc") !== null) return "s3tc";
      if (renderer.extensions.get("WEBGL_compressed_texture_pvrtc") !== null) return "pvrtc";
    }
  }

  init();
</script>

 

posted @ 2024-05-23 16:50  carol2014  阅读(94)  评论(0编辑  收藏  举报