three.js中幀緩存的使用

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();
}

其運行的結果如下:
imglink1

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);

所以最裏層的部分就是緩存場景繪製面,也就是灰色的。而這個緩存場景是通過同一個渲染器繪製的,也就是緩存場景剩餘的部分,就會是渲染器的背景色,也就是白色了。

3. 參考

  1. Quick Tip: How to Render to a Texture in Three.js
  2. 如何在ThreeJS中使用場景的渲染結果作爲紋理?
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章