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
小结
至此结束,完整代码请查看例子,感谢阅读。