更新于 

Start - 开始ThreeJs之旅

Rendering and viewing a 3D object

要组成一个3D画面,需要3个主要元素:

  • 场景 Scene

    Store and keep track of all the objects we want to render and all the lights we want to use

    1
    const scene = new THREE.Scene()
  • 相机 Camera

    Defines what we’ll see when we render a scene

    1
    const camera = new THREE.PerspectiveCamera( 45, window.innerWidth/window.innerHeight, 0.1, 1000 )
  • 渲染器 Renderer

    Calculating what the scene object will look like

    1
    2
    3
    const renderer = new THREE.WebGLRenderer()
    renderer.setClearColor(new THREE.Color(0x000000))
    renderer.setSize(window.innerWidth, window.innerHeight)
Renderers

ThreeJs提供多种渲染器:

  • WebGLRenderer
  • CanvasRenderer
  • SVGRenderer
  • CssRenderer
AxesHelper 坐标辅助器

a helpful debugging tool

1
2
const axes = new THREE.AxesHepler(5)
scene.add(axes)

Materials, lights, and shadows

Light

加入光源

  • spotLight 聚光灯
  • spotLightHepler 聚光灯辅助线
1
2
3
4
5
6
let spotLight = new THREE.SpotLight(0xaa00aa)
spotLight.position.set( 1.5, 0.7, 1.5 );
spotLight.intensity = 7
scene.add(spotLight)
const spotLightHelper = new THREE.SpotLightHelper( spotLight );
scene.add( spotLightHelper );
Material

threeJs中有些材质是不受光线影响的,如MeshBasicMaterial
想要创建受光照作用的材质,可以使用其他材质,如:

  • MeshLambertMaterial
  • MeshPhongMaterial
Shadow

由于渲染shadow会耗费大量CPU资源,因此默认是disabled的,
需要三步开启shadow:

  1. 开启指定投射阴影物和被投射阴影物的阴影投射属性 castShadow/receiveShadow
    1
    2
    3
    4
    // 投射阴影物体
    cube.castShadow = true
    // 被投射阴影物体
    plan.receiveShadow = true
  2. 开启指定光源的阴影投射属性 castShadow
    1
    spotLight.castShadow = true
  3. 开启渲染器Renderer的阴影贴图shadowMap
    1
    renderer.shadowMap.enabled = true
添加阴影之后的效果
添加阴影之后的效果
Stats 性能检测插件

Stats能够检测当前屏幕的fps值
fps : frame per second

1
2
3
4
5
6
7
8
import Stats from 'three/examples/jsm/libs/stats.module'
const stats = new Stats()
document.body.appendChild(stats.domElement)
function animate(){
requestAnimationFrame(animate)
stats.update() // 更新状态监控器
renderer.render(scene,camera)
}

Animations

requestAnimationFrame
1
2
requestAnimationFrame(nextFrameFun)
function nextFrameFun(){}

requestAnimationFrame相当于告诉浏览器绘制下一帧时调用的函数,
threeJs中的更新函数一般在requestAnimationFrame指定的函数中调用

1
2
3
4
5
6
function animation(){
requestAnimationFrame(animation)
controls.upadte() // 更新轨道控制器
stats.update() // 更新帧监听器
renderer.render(scene,camera) // 渲染器重渲染
}

GUI

dat.gui

lil-gui提供快速编辑渲染参数的工具插件

Resize

resize

需要在window的resize事件时做下面两步

1
2
3
4
5
6
window.addEventListener('resize',resize)
function resize(){
camera.aspect = window.innerWidth/window.innerHeight // 修改宽高比值
camera.updateProjectionMatrix() // 更新视图矩阵
renderer.setSize(window.innerWidth,window.innerHeight) // 更新渲染器宽高
}
render result
render result