来个甜甜圈 | 大帅老猿threejs特训

160 阅读2分钟

1. 创建场景三大件

/**
 * 创建场景和相机以及渲染器
 */
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(
    // 广角
    75,
    // 压缩比
    window.innerWidth / window.innerHeight,
    // 场景得近距离锥体
    0.01,
    // 场景得远距离锥体
    10
)

const renderer = new THREE.WebGLRenderer({
    // 抗锯齿(开启就会消耗更多得性能)
    a

// 设置渲染器大小
renderer.setSize(window.innerWidth,window.innerHeight)

// 将渲染器添加到dom
document.body.appendChild(renderer.domElement)ntialias: true
})

2. 创建灯光和几何体

/**
 * 创建灯光
 */
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5)
scene.add(ambientLight)

/**
 * 创建几何体 (用几何体测试我们得场景搭建完得效果是否成功	 )
 */
const boxGeometry =new  THREE.BoxGeometry(1,1,1)
const boxMaterial = new THREE.MeshBasicMaterial({
	color: 0x00ff00
})
const boxMesh = new THREE.Mesh(boxGeometry,boxMaterial)

scene.add(boxMesh)

3. 创建渲染帧动画

/**
 * 创建关键帧动画
 */
function animate () {
	requestAnimationFrame(animate)

	renderer.render(scene,camera)
}

animate()

4. 设置相机位置及交互控件

// 放置相机位置,要不然是在盒子里面,一片黑
camera.position.set(0,0,2)

// 创建控制 (就可以使用鼠标开始交互了)
const controls = new OrbitControls(camera,renderer.domElement)

function animate () {
  // ....
  controls.update()
}

5. 加载甜甜圈和下落动画

/**
 * 加载甜甜圈
 */
let mixer;
new GLTFLoader().load('../resources/models/donuts.glb', (gltf) => {
	// 注意要取到scene这层,要不然报错了
	// 后续如果需要加载模型某个图层对应得name也在scene得children里面
	scene.add(gltf.scene)

	// traverse 遍历所有层级得节点(拓展)
	// gltf.scene.traverse((child) => {
	// 	// 接收阴影
	// 	child.receiveShadow = true

	// 	// 投射阴影
	// 	child.castShadow = true
	// })

	// AnimationMixer相当于一个剪辑组
	mixer = new THREE.AnimationMixer(gltf.scene)
	// clips相当于剪辑得每一帧
	const clips = gltf.animations
	clips.forEach((clip) => {
		// 然后剪辑组里得每一帧都放到专门得播放容器进行调度播放
		const action = mixer.clipAction(clip)
		action.loop = THREE.LoopOnce
		action.play()
		// 停在最后一帧
		action.clampWhenFinished = true
	})
})

function animate () {
  // ....
  if (mixer) {
    // 记得要加上动画播放得帧更新
		// 有一定延时得播放
		mixer.update(0.02)
	}
}

6. 给甜甜圈加点光

// 环境光
const directionLight = new THREE.DirectionalLight(0xffffff, 0.2)
scene.add(directionLight)

/**
 * 添加hdr光照
 */
new RGBELoader().load('../resources/sky.hdr', (texture) => {
	texture.mapping = THREE.EquirectangularReflectionMapping
	scene.environment = texture
	renderer.outputEncoding = THREE.sRGBEncoding
	renderer.render(scene, camera)
})

这样一个下落得甜甜圈就完成了!

7. 有意思得点

  1. 一个是在跟着视频学的时候,发现在给three传参得时候,就算传得参数和他参数要求得类型不同,也不会报错,这种时候出现问题或者加载失败,就只能一个个回退盘查了
  2. 初始化得时候,最好创建个盒子验证下是否相机三要素都完成了渲染和显示
  3. 播放动画要记得添加到帧动画执行里,然后播放动画得使用需要使用三要素(自己用土话注释了一遍,不知道对不对哈哈)
  4. 加上灯光和光照色泽得时候,在调试这个参数得时候,很有那种拟真得感觉!

加入猿创营 (v:dashuailaoyuan),一起交流学习