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, addPlane, addBox, addSphere } from "./init.js";

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

    const renderer = initRenderer("mainCanvas");

    const scene = new THREE.Scene();

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

    const ambientLight = initAmbientLight();
    scene.add(ambientLight);
    gui.add(ambientLight, "intensity", 0, 100).name("AmbientLight光源强度");

    const spotLight = initSpotLight();
    scene.add(spotLight);
    // spotLight.shadow.mapSize = new THREE.Vector2(1024, 1024);
    // spotLight.shadow.camera.far = 130;
    // spotLight.shadow.camera.near = 40;
    gui.add(spotLight.position, "x", -50, 100).name("SpotLight光源位置x");
    gui.add(spotLight.position, "y", 0, 100).name("SpotLight光源位置y");
    gui.add(spotLight.position, "z", -50, 100).name("SpotLight光源位置z");
    gui.add(spotLight, "intensity", 0, 100).name("SpotLight光源强度");
    gui.add(spotLight, "angle", 0, 2 * Math.PI).name("SpotLight光源照射范围的角度");
    gui.add(spotLight, "distance", 0, 5000).name("SpotLight光源照射的最大距离");
    gui.add(spotLight, "decay", 0, 10).name("SpotLight光源沿着光照距离的衰退量");

    createTree(scene);
    createHouse(scene);
    createGroundPlane(scene);
    createBoundingWall(scene);

    const plane = addPlane();
    plane.position.set(15, 0, 0);
    scene.add(plane);

    const cube = addBox({ color: 0xff0000 });
    cube.position.set(-4, 2, 0);
    scene.add(cube);

    const sphere = addSphere({ color: 0x7777ff });
    sphere.position.set(20, 5, 0);
    scene.add(sphere);

    render();

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

  function createBoundingWall(scene) {
    const wallLeft = new THREE.BoxGeometry(70, 2, 2);
    const wallRight = new THREE.BoxGeometry(70, 2, 2);
    const wallTop = new THREE.BoxGeometry(2, 2, 50);
    const wallBottom = new THREE.BoxGeometry(2, 2, 50);

    const wallMaterial = new THREE.MeshLambertMaterial({
      color: 0xa0522d,
    });

    const wallLeftMesh = new THREE.Mesh(wallLeft, wallMaterial);
    const wallRightMesh = new THREE.Mesh(wallRight, wallMaterial);
    const wallTopMesh = new THREE.Mesh(wallTop, wallMaterial);
    const wallBottomMesh = new THREE.Mesh(wallBottom, wallMaterial);

    wallLeftMesh.position.set(15, 1, -25);
    wallRightMesh.position.set(15, 1, 25);
    wallTopMesh.position.set(-19, 1, 0);
    wallBottomMesh.position.set(49, 1, 0);

    scene.add(wallLeftMesh);
    scene.add(wallRightMesh);
    scene.add(wallBottomMesh);
    scene.add(wallTopMesh);
  }

  function createGroundPlane(scene) {
    const planeGeometry = new THREE.PlaneGeometry(70, 50);
    const planeMaterial = new THREE.MeshLambertMaterial({
      color: 0x9acd32,
    });
    const plane = new THREE.Mesh(planeGeometry, planeMaterial);
    plane.receiveShadow = true;

    plane.rotation.x = -0.5 * Math.PI;
    plane.position.set(15, 0, 0);

    scene.add(plane);
  }

  function createHouse(scene) {
    const roof = new THREE.ConeGeometry(5, 4);
    const base = new THREE.CylinderGeometry(5, 5, 6);

    const roofMesh = new THREE.Mesh(
      roof,
      new THREE.MeshLambertMaterial({
        color: 0x8b7213,
      })
    );
    const baseMesh = new THREE.Mesh(
      base,
      new THREE.MeshLambertMaterial({
        color: 0xffe4c4,
      })
    );

    roofMesh.position.set(25, 8, 0);
    baseMesh.position.set(25, 3, 0);

    roofMesh.receiveShadow = true;
    baseMesh.receiveShadow = true;
    roofMesh.castShadow = true;
    baseMesh.castShadow = true;

    scene.add(roofMesh);
    scene.add(baseMesh);
  }

  function createTree(scene) {
    const trunk = new THREE.BoxGeometry(1, 8, 1);
    const leaves = new THREE.SphereGeometry(4);

    const trunkMesh = new THREE.Mesh(
      trunk,
      new THREE.MeshLambertMaterial({
        color: 0x8b4513,
      })
    );
    const leavesMesh = new THREE.Mesh(
      leaves,
      new THREE.MeshLambertMaterial({
        color: 0x00ff00,
      })
    );

    trunkMesh.position.set(-10, 4, 0);
    leavesMesh.position.set(-10, 12, 0);

    trunkMesh.castShadow = true;
    trunkMesh.receiveShadow = true;
    leavesMesh.castShadow = true;
    leavesMesh.receiveShadow = true;

    scene.add(trunkMesh);
    scene.add(leavesMesh);
  }

  init();
</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 { initRenderer, initPerspectiveCamera, initAmbientLight, initSpotLight } from "./init.js";

  const renderer = initRenderer("mainCanvas");

  const scene = new THREE.Scene();

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

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

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

  const path = new THREE.CatmullRomCurve3([
    new THREE.Vector3(-5, 2, 9),
    new THREE.Vector3(-1, 4, 4),
    new THREE.Vector3(0, 0, 0),
    new THREE.Vector3(6, -6, 0),
    new THREE.Vector3(9, -4, 6),
    new THREE.Vector3(12, 3, 3),
  ]);
  // 三维样条曲线作为TubeGeometry参数生成管道
  const geometry = new THREE.TubeGeometry(path, 100, 5, 30);
  const texLoader = new THREE.TextureLoader();
  //纹理贴图
  texLoader.load("../images/square.jpg", (texture) => {
    //UV坐标U方向阵列模式
    texture.wrapS = THREE.RepeatWrapping;
    // 纹理沿着管道方向阵列(UV坐标U方向)
    texture.repeat.x = 100;
    const material = new THREE.MeshBasicMaterial({
      map: texture,
      side: THREE.DoubleSide,
    });
    const mesh = new THREE.Mesh(geometry, material);
    scene.add(mesh);
  });

  let i = 0;
  render();

  function render() {
    const pointsArr = path.getSpacedPoints(500);
    if (i < pointsArr.length - 1) {
      camera.position.copy(pointsArr[i]);
      camera.lookAt(pointsArr[i + 1]);
      i += 1;
    } else {
      i = 0;
    }
    renderer.render(scene, camera);
    requestAnimationFrame(render);
  }
</script>

 

posted @   carol2014  阅读(84)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示