Three.js之相机、渲染器、光源、动画、性能监测

参考资料

  • 第一个3D案例—透视投影相机
  • 第一个3D案例—渲染器
  • Canvas画布布局和全屏

知识点

  • 透视投影相机PerspectiveCamera
  • WebGL渲染器WebGLRenderer
  • 辅助观察坐标系AxesHelper
  • 漫反射网格材质MeshLambertMaterial
  • 点光源PointLight
  • 点光源辅助观察PointLightHelper
  • 环境光AmbientLight
  • 平行光DirectionalLight
  • 平行光辅助观察DirectionalLightHelper
  • 相机控件OrbitControls
  • 请求动画帧window.requestAnimationFrame
  • canvas画布宽高度动态变化
  • 性能监控Stats

代码实现

  • 相机、渲染器、光

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Three.js</title>
    </head>
      <body>
      </body>
      <!-- 具体路径配置,你根据自己文件目录设置,我的是课件中源码形式 -->
      <script type="importmap">
        {
          "imports": {
            "three": "./js/three.module.js",
            "three/addons/": "../three.js/examples/jsm/"
          }
        }
      </script>
      <script type="module">
        import * as THREE from 'three';
        import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
    
        const width = 800
        const height = 500
    
        // 场景
        const scene = new THREE.Scene();
        // 几何体
        const geometry = new THREE.BoxGeometry(100, 100, 100);
        // 材质 
        // MeshBasicMaterial:不受光
        // MeshLambertMaterial:受光
        const material = new THREE.MeshLambertMaterial({
          color:0x0000ff,
        });
        // 网格模型:物体
        const mesh = new THREE.Mesh(geometry, material);
        mesh.position.set(0, 0, 0);
        scene.add(mesh);
    
        // 坐标系
        const axes = new THREE.AxesHelper(200);
        scene.add(axes);
    
        // // 点光源
        // const pointLight = new THREE.PointLight( 0xffffff, 1.0, 0, 0);
        // pointLight.position.set(-200, 200, 200 );
        // scene.add( pointLight );
    
        // // 辅助点光源
        // const pointLightHelper = new THREE.PointLightHelper( pointLight, 10 );
        // scene.add( pointLightHelper );
    
        // 环境光
        const ambientLight = new THREE.AmbientLight( 0xffffff, 0.2);
        scene.add( ambientLight );
    
        // 平行光
        const directionalLight = new THREE.DirectionalLight( 0xffffff, 1, 0, 0);
        // directionalLight.position.set(100, 0, 0);
        // directionalLight.position.set(0, 100, 0);
        // directionalLight.position.set(100, 100, 100);
        directionalLight.position.set(100, 60, 50);
        directionalLight.target = mesh;
        scene.add( directionalLight );
    
        // 辅助平行光
        const directionalLightHelper = new THREE.DirectionalLightHelper( directionalLight, 10 );
        scene.add( directionalLightHelper );
    
        // 相机
        const camera = new THREE.PerspectiveCamera(75, width/height, 0.1, 1000);
        camera.position.set(200, 200, 200);
        camera.lookAt(scene.position);
    
        // 渲染器
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(width, height);
        renderer.render(scene, camera);
        document.body.appendChild(renderer.domElement);
    
        // 控制器
        const controls = new OrbitControls(camera, renderer.domElement);
        controls.addEventListener('change', () => {
          renderer.render(scene, camera);
        });
      </script>
    </html>
    
  • 动画

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Three.js</title>
    </head>
      <body>
      </body>
      <!-- 具体路径配置,你根据自己文件目录设置,我的是课件中源码形式 -->
      <script type="importmap">
        {
          "imports": {
            "three": "./js/three.module.js",
            "three/addons/": "../three.js/examples/jsm/"
          }
        }
      </script>
      <script type="module">
        import * as THREE from 'three';
        import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
    
        const width = 800
        const height = 500
    
        // 场景
        const scene = new THREE.Scene();
        // 几何体
        const geometry = new THREE.BoxGeometry(100, 100, 100);
        // 材质
        const material = new THREE.MeshBasicMaterial({
          color: 0x00ff00,
          transparent: true,
          opacity: 0.5
        });
        // 网格模型:物体
        const mesh = new THREE.Mesh(geometry, material);
        mesh.position.set(0, 0, 0);
        scene.add(mesh);
    
        // 坐标系
        const axes = new THREE.AxesHelper(200);
        scene.add(axes);
    
        // 相机
        const camera = new THREE.PerspectiveCamera(75, width/height, 0.1, 1000);
        camera.position.set(200, 200, 200);
        camera.lookAt(scene.position);
    
        // 渲染器
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(width, height);
        renderer.render(scene, camera);
        document.body.appendChild(renderer.domElement);
    
        // 动画渲染
        // 跟踪时间
        var clock = new THREE.Clock();
        function render() {
          const spt = clock.getDelta() * 1000;
          console.log(' ~ file: animation.html:59 ~ render ~ spt:', spt)
          requestAnimationFrame(render);
          mesh.rotation.y += 0.01;
          renderer.render(scene, camera);
        }
    
        render();
    
        // 控制器
        const controls = new OrbitControls(camera, renderer.domElement);
        controls.addEventListener('change', () => {
          // 因为动画渲染了,所以这里可以省略
          // renderer.render(scene, camera);
        });
      </script>
    </html>
    
  • 画布动态变化

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Three.js</title>
      <style>
        body {
          margin: 0;
          overflow: hidden;
        }
      </style>
    </head>
      <body>
      </body>
      <!-- 具体路径配置,你根据自己文件目录设置,我的是课件中源码形式 -->
      <script type="importmap">
        {
          "imports": {
            "three": "./js/three.module.js"
          }
        }
      </script>
      <script type="module">
        import * as THREE from 'three';
    
        let width = window.innerWidth;
        let height = window.innerHeight;
    
        // 场景
        const scene = new THREE.Scene();
        // 几何体
        const geometry = new THREE.BoxGeometry(100, 100, 100);
        // 材质
        const material = new THREE.MeshBasicMaterial({
          color: 0x00ff00,
          transparent: true,
          opacity: 0.5
        });
        // 网格模型:物体
        const mesh = new THREE.Mesh(geometry, material);
        mesh.position.set(0, 0, 0);
        scene.add(mesh);
    
        // 坐标系
        const axes = new THREE.AxesHelper(200);
        scene.add(axes);
    
        // 相机
        const camera = new THREE.PerspectiveCamera(75, width/height, 0.1, 1000);
        camera.position.set(200, 200, 200);
        camera.lookAt(scene.position);
    
        // 渲染器
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(width, height);
        renderer.render(scene, camera);
        document.body.appendChild(renderer.domElement);
    
        // 填满浏览器
        window.onresize = function () {
          width = window.innerWidth;
          height = window.innerHeight;
          renderer.setSize(width, height);
          camera.aspect = width / height;
          camera.updateProjectionMatrix();
        }
      </script>
    </html>
    
  • 性能监控

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Three.js</title>
    </head>
      <body>
      </body>
      <!-- 具体路径配置,你根据自己文件目录设置,我的是课件中源码形式 -->
      <script type="importmap">
        {
          "imports": {
            "three": "./js/three.module.js",
            "three/addons/": "../three.js/examples/jsm/"
          }
        }
      </script>
      <script type="module">
        import * as THREE from 'three';
        import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
        import Stats from 'three/addons/libs/stats.module.js';
    
        const width = 800
        const height = 500
    
        // 场景
        const scene = new THREE.Scene();
        // 几何体
        const geometry = new THREE.BoxGeometry(100, 100, 100);
        // 材质
        const material = new THREE.MeshBasicMaterial({
          color: 0x00ff00,
          transparent: true,
          opacity: 0.5
        });
        // 网格模型:物体
        const mesh = new THREE.Mesh(geometry, material);
        mesh.position.set(0, 0, 0);
        scene.add(mesh);
    
        for (let i = 0; i < 1000; i++) {
          // 几何体
          const geometry = new THREE.BoxGeometry(5, 5, 5);
          // 材质
          const material = new THREE.MeshBasicMaterial({
            color: 0x00ff00,
            transparent: true,
            opacity: 0.5
          });
          // 网格模型:物体
          const mesh = new THREE.Mesh(geometry, material);
          mesh.position.set((Math.random() - 0.5) * 200, (Math.random() - 0.5) * 200, (Math.random() - 0.5) * 200);
          scene.add(mesh);
        }
    
        // 坐标系
        const axes = new THREE.AxesHelper(200);
        scene.add(axes);
    
        // 相机
        const camera = new THREE.PerspectiveCamera(75, width/height, 0.1, 1000);
        camera.position.set(200, 200, 200);
        camera.lookAt(scene.position);
    
        // 渲染器
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(width, height);
        renderer.render(scene, camera);
        document.body.appendChild(renderer.domElement);
    
        // 性能监控
        const stats = new Stats()
        document.body.appendChild(stats.domElement);
    
        // 动画渲染
        // 跟踪时间
        var clock = new THREE.Clock();
        function render() {
          stats.update()
          const spt = clock.getDelta() * 1000;
          requestAnimationFrame(render);
          mesh.rotation.y += 0.01;
          renderer.render(scene, camera);
        }
    
        render();
      </script>
    </html>
    

你可能感兴趣的:(Web3D,Web3D)