「这是我参与2022首次更文挑战的第15天,活动详情查看:2022首次更文挑战」
WebGLRenderTarget
WebGLRenderTarget
是一个渲染器。用于在缓存中为场景绘制像素。- 简单理解就是在缓存创建一张图片,我们可以把这张图片当成纹理在几何体上使用。
使用
- 基础代码环境,展示一个几何体。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>学习</title>
</head>
<body>
<canvas id="c2d" class="c2d" width="1000" height="500"></canvas>
<script type="module">
import * as THREE from 'https://threejs.org/build/three.module.js'
import { OrbitControls } from 'https://threejsfundamentals.org/threejs/resources/threejs/r132/examples/jsm/controls/OrbitControls.js'
const canvas = document.querySelector('#c2d')
// 渲染器
const renderer = new THREE.WebGLRenderer({ canvas })
const fov = 40 // 视野范围
const aspect = 2 // 相机默认值 画布的宽高比
const near = 0.1 // 近平面
const far = 1000 // 远平面
// 透视投影相机
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far)
camera.position.set(10, 20, 20)
camera.lookAt(0, 0, 0)
// 控制相机
const controls = new OrbitControls(camera, canvas)
controls.update()
// 场景
const scene = new THREE.Scene()
{
// 光源
const color = 0xffffff
const intensity = 1
const light = new THREE.DirectionalLight(color, intensity)
light.position.set(-1, 2, 4)
scene.add(light)
}
// 立体
const boxWidth = 6
const boxHeight = 6
const boxDepth = 6
const boxGeometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth)
// 材质
const material = new THREE.MeshPhongMaterial({ color: 0x00ff00 })
const mesh = new THREE.Mesh(boxGeometry, material)
scene.add(mesh)
// 渲染
function render(time) {
time *= 0.001
mesh.rotation.y = time
mesh.rotation.x = time
renderer.render(scene, camera)
requestAnimationFrame(render)
}
requestAnimationFrame(render)
</script>
</body>
</html>
- 创建渲染器。
const rtWidth = 512;
const rtHeight = 512;
const renderTarget = new THREE.WebGLRenderTarget(rtWidth, rtHeight);
...
const canvas = document.querySelector('#c2d')
...
- 使用渲染器就需要一个
Camera
(相机) 和一个Scene
(场景)。 - 这里使用的相机比例(
rtAspect
)是几何体面的比例,不是画布的比例。
const rtFov = 75
const rtAspect = rtWidth / rtHeight
const rtNear = 0.1
const rtFar = 5
const rtCamera = new THREE.PerspectiveCamera(rtFov, rtAspect, rtNear, rtFar)
rtCamera.position.z = 2
const rtScene = new THREE.Scene()
rtScene.background = new THREE.Color('white')
- 有了场景,需要展示的纹理就和普通的绘制是一样的。
- 添加几何体。
// 几何体
const rtBox = 1
const rtGeometry = new THREE.BoxGeometry(rtBox, rtBox, rtBox)
const rtMaterial = new THREE.MeshBasicMaterial({ color: 0x44aa88 })
const rtCube = new THREE.Mesh(rtGeometry, rtMaterial)
rtScene.add(rtCube)
- 在几何体中使用缓存画面。
// 材质
const material = new THREE.MeshPhongMaterial({
// color: 0x00ff00
map: renderTarget.texture
})
- 渲染时,我们首先渲染目标的场景(
rtScene
),在渲染要在画布上展示的场景。
function render(time) {
renderer.setRenderTarget(renderTarget)
renderer.render(rtScene, rtCamera)
renderer.setRenderTarget(null)
}
- 几何体的表面就是我们绘制的缓存场景。
- 既然是缓存渲染器,我们也可以为纹理添加动画。
function render(time) {
rtCube.rotation.y = time
rtCube.rotation.x = time
}
总结
WebGLRenderTarget
可以用在各种各样的物体上,比如在开发中绘制镜子反射场景,这一类物体就需要。需要注意,WebGLRenderTarget
会创建两个纹理。 颜色纹理和深度、模版纹理。如果你不需要深度或者模版纹理,设置depthBuffer: false,stencilBuffer: false
。