1. 概述
在網上查閱了一下three.js關於幀緩存的使用,感覺很多都是關於three.js中後處理通道的使用的。後處理通道確實使用FBO實現的,但其實我就是想獲取某個時刻的渲染結果作爲紋理,沒必要在動態渲染中進行後處理。真正實現這個功能的是WebGLRenderTarget這個類,這是一個渲染目標的緩衝區,可以裝載到WebGLRenderer中進行渲染,再從WebGLRenderTarget獲取紋理對象。
2. 示例
2.1. 代碼
廢話不多說,直接給出代碼:
'use strict';
function init() {
var scene = new THREE.Scene();
scene.background = new THREE.Color(0x000000); //場景的背景色
// create a camera, which defines where we're looking at.
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
// position and point the camera to the center of the scene
camera.position.set(0, 0, 60); //相機的位置
camera.up.set(0, 1, 0); //相機以哪個方向爲上方
camera.lookAt(new THREE.Vector3(0, 0, 0)); //相機看向哪個座標
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xffffff, 1); //渲染器的背景色
document.body.appendChild(renderer.domElement);
//緩存場景
var bufferScene = new THREE.Scene();
//渲染目標緩衝區
var bufferTexture = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight);
// create the ground plane
var fboGeometry = new THREE.PlaneGeometry(60, 30);
var fboMaterial = new THREE.MeshBasicMaterial({
color: 0xAAAAAA
});
var fboPlane = new THREE.Mesh(fboGeometry, fboMaterial);
// add the plane to the scene
bufferScene.add(fboPlane);
//渲染到目標緩衝區
renderer.setRenderTarget(bufferTexture);
renderer.render(bufferScene, camera);
//渲染到屏幕
renderer.setRenderTarget(null);
// create the ground plane
var planeGeometry = new THREE.PlaneGeometry(60, 30);
var planeMaterial = new THREE.MeshBasicMaterial({
map: bufferTexture.texture //獲取渲染目標緩衝區中的紋理
});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
scene.add(plane);
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
render();
}
其運行的結果如下:
2.2. 解析
渲染的結果出現了三個顏色部分:黑色區域,白色區域,以及灰色區域。對照代碼來說,渲染器的清空色(背景色)是白色的:
renderer.setClearColor(0xffffff, 1); //渲染器的背景色
但是由於給當前的場景根節點設置背景色爲黑色:
scene.background = new THREE.Color(0x000000); //場景的背景色
所以最外層的部分是黑色。
場景根節點中繪製了一個面:
// create the ground plane
var planeGeometry = new THREE.PlaneGeometry(60, 30);
var planeMaterial = new THREE.MeshBasicMaterial({
map: bufferTexture.texture //獲取渲染目標緩衝區中的紋理
});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
scene.add(plane);
這個面的材質紋理來自於自定義的喧嚷目標緩衝區,並且預先通過渲染器將緩存場景渲染到這個緩衝區中:
//緩存場景
var bufferScene = new THREE.Scene();
//渲染目標緩衝區
var bufferTexture = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight);
//...
//渲染到目標緩衝區
renderer.setRenderTarget(bufferTexture);
renderer.render(bufferScene, camera);
//渲染到屏幕
renderer.setRenderTarget(null);
在緩存場景中,通過同一個相機,也繪製了一個面,這個面的材質顏色是灰色的:
// create the ground plane
var fboGeometry = new THREE.PlaneGeometry(60, 30);
var fboMaterial = new THREE.MeshBasicMaterial({
color: 0xAAAAAA
});
var fboPlane = new THREE.Mesh(fboGeometry, fboMaterial);
// add the plane to the scene
bufferScene.add(fboPlane);
所以最裏層的部分就是緩存場景繪製面,也就是灰色的。而這個緩存場景是通過同一個渲染器繪製的,也就是緩存場景剩餘的部分,就會是渲染器的背景色,也就是白色了。