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);
所以最里層的部分就是緩存場景繪制面,也就是灰色的。而這個緩存場景是通過同一個渲染器繪制的,也就是緩存場景剩余的部分,就會是渲染器的背景色,也就是白色了。