Three.js 初体验

Three.js

  • 官网:https://threejs.org
  • 参考:
    • GitHub 地址 https://github.com/mrdoob/three.js
    • Stack Overflow https://stackoverflow.com/questions/tagged/three.js
    • Intro to WebGL with Three.js http://davidscottlyons.com/threejs-intro/
    • three.js 在线编辑器https://threejs.org/editor/
cnpm i --save three
cnpm i --save-dev @types/three
  • 引入控件
cnpm i --save three-orbitcontrols-ts (另一种方式: 用来支持鼠标的交互行为的库)
import { OrbitControls } from 'three-orbitcontrols-ts';

- 建议使用下面的方式
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import Stats from 'three/examples/jsm/libs/stats.module.js';
import { RoomEnvironment } from 'three/examples/jsm/environments/RoomEnvironment.js';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'

react 中使用

  1. 大概流程

    a. 创建一个场景实例 scene,是放置物体的空间
    b. 创建一个摄像机 camera,通过设置位置等去观察场景中的物体
    c. 创建一个渲染器 render,将渲染器的节点添加到容器中, 这一步很重要
    d. 创建控制器 controls。
    e. 配置灯光。
    f. 创建模型和材质。
    g. 添加动画。
    
  2. demo

    import React, { Component } from 'react';
    import * as THREE from 'three';
    import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
    
    export default class SimpleScene extends Component {
      private renderer: any;
      private scene: any;
      private camera: any;
      private mesh: any;
      private controls: any;
    
      componentDidMount() {
        this.init();
        this.animate();
      }
    
      init = () => {
        // 生成场景
        const scene = new THREE.Scene();
        this.scene = scene;
    
        // 设置相机
        const camera = new THREE.PerspectiveCamera(
          75,
          window.innerWidth / window.innerHeight,
          1,
          1000,
        );
        this.camera = camera;
    
        // 生成模型: 立方缓冲几何体(BoxGeometry)
        const geometry = new THREE.BoxGeometry(1, 1, 1);
        const material = new THREE.MeshBasicMaterial({
          color: 0x049ef4,
        });
        const mesh = new THREE.Mesh(geometry, material);
        this.mesh = mesh;
    
        scene.add(mesh);
        camera.position.set(3, 3, 3);
        camera.lookAt(mesh.position);
    
        // 设置灯光
        const pointLight = new THREE.PointLight(0xff0000, 1);
        pointLight.position.set(3, 2, 1);
        scene.add(pointLight);
    
        // 环境光会均匀的照亮场景中的所有物体
        const ambientLight = new THREE.AmbientLight(0xcccccc, 0.5);
        scene.add(ambientLight);
    
        // 渲染
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.render(scene, camera);
        this.renderer = renderer;
        const threeMain = document.getElementById('container');
        threeMain?.appendChild(renderer.domElement);
    
        // 添加控制器
        const controls = new OrbitControls(this.camera, this.renderer.domElement);
        controls.addEventListener('change', this.handleControl);
        this.controls = controls;
      };
    
      handleControl = () => {
        this.renderer.render(this.scene, this.camera);
      };
    
      // 添加动画,自己转动
      animate = () => {
        requestAnimationFrame(this.animate);
        this.mesh.rotation.y += 0.02;
        this.renderer.render(this.scene, this.camera);
      };
    
      componentWillUnmount() {
        // 移除所有的事件监听
        this.controls.dispose();
      }
    
      render() {
        return <div id="container"></div>;
      }
    }
    
    

学习案例demo,碰到的问题点

  1. 使用 GLTFLoader 将.glTF 文件加载到 three.js 中

    • err: Unexpected token < in JSON at position 0
      路径问题: new GLTFLoader() -> 改成:new GLTFLoader().setPath(‘/’);
    • err: Uncaught SyntaxError: Unexpected token ‘<’ (at
      需要指向公共路径问题
      - umirc.ts: publicPath: ‘/public/’,
      - const loader = new GLTFLoader().setPath(‘/public/’);
  2. threejs 没有渲染任何东西

    首先:注意调整后记得检查一致
    const container = document.getElementById('container');
    <div id="container" />
    
    
    其次:排查发现,
    放在外层函数的原因:此时dom节点加载还未
    - const container = document.getElementById('container');
    
    - 放在里面即可
    const initThree = () => {
      ...
      const container = document.getElementById('container');
      ...
    }
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值