RenderTarget 介绍
在渲染的时候调用 renderer.render(scene, camera, renderTarget, forceClear)
方法,render
方法有四个参数,我们平时使用只传前两个参数,第一个参数是要绘制的场景,第二个参数是指定相机,相机照射的区域会转换成 2D 绘制到屏幕,而我们今天要讲的就是使用第三个参数,不让渲染的内容直接绘制到屏幕,而是存放到 renderTarget
里。RenderTarget 是一个缓冲区,用来记录渲染后的像素,而不是直接绘制到屏幕上,因此我们可以在绘制屏幕之前做一些处理,以满足特殊的需求。
把 RenderTarget 作为贴图使用
首先创建两个场景:一个 RTScene
场景,用来渲染 RenderTarget 贴图、另一个 Scene
场景,用来渲染最终显示到屏幕上的,并调用 RTScene
场景作为贴图。
创建一个尺寸为 300×300 大小的 RenderTarget 存放 RTScene 的渲染结果
1 | const RT_SIZE = 300; |
创建相机
1 | const Camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 ); |
创建 RTScene,并向 RTScene 场景添加灯光、环面
1 | // 创建场景 |
创建 Scene,并向 Scene 场景添加灯光、立方体,立方体使用 RTScene 作为贴图
1 | const Scene = new THREE.Scene(); |
创建 Renderer
1 | const Renderer = new THREE.WebGLRenderer( { |
场景设置完毕接下来我们就可以渲染场景了,注意这两个 render
的顺序,第一个的结果要给第二个使用,所以不能写反了
1 | Renderer.render(RTScene, Camera, RenderTarget); // 离屏渲染并存放到 RenderTarget 里 |
如果场景有动画则需要使用 requestAnimationFrame
马不停蹄的进行渲染
1 | animation(); |
实例 Demo
把 RenderTarget 画到 2D Canvas 上
我们可以使用 Renderer.readRenderTargetPixels(renderTarget, x, y, width, height, buffer)
方法读取离屏渲染的像素数据到一个 Uint8Array(length)
实例里,x
、y
可以限制读取的起点,width
、height
为读取的宽高。
新建一个画布,通过 canvas.getContext('2d')
方法获取 2D 的对象,此对象有个 ctx.putImageData(imagedata, dx, dy)
可以让画布绘制 ImageData(data, width, height)
实例类型的矩形像素,data
为 Uint8ClampedArray(length)
实例,width
、height
为图片的宽和高(必须保证 Uint8ClampedArray
的 length = 4 * width * height
才不会报错)。
指定 canvas 元素,并获取 2D 对象
1 | const preview = document.getElementById('preview'); |
创建 buffer 用来存放 RenderTarget 的像素数据,实例化 Uint8ClampedArray
以便创建 ImageData
时使用。在处理图片像素中与 Uint8Array
相比 Uint8ClampedArray
更安全,因为 Uint8ClampedArray
能保证写入的值在 0-255 之间,当写入的值小于 0 时会自动改为 0,当大于 255 时会自动改为 255。
1 | const buffer = new Uint8Array(RT_SIZE * RT_SIZE * 4); |
1 | Renderer.readRenderTargetPixels(RenderTarget, 0, 0, RT_SIZE, RT_SIZE, buffer); // 读取像素到 buffer |
实例 Demo
小结
至此结束,完整代码请查看例子,感谢阅读。