• 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中使用场景的渲染结果作为纹理?
  • 相关阅读:
    DevExpress之Treelist应用
    空间参考及坐标转换
    ArcGIS API for JavaScript开发环境搭建及第一个实例demo
    SQL中字符串拼接
    Json.net实现方便的Json转C#(dynamic动态类型)对象
    第四章:C#如何生成JSON字符串提交给接口(服务器)
    第三章:C#如何生成JSON字符串?(序列化对象)
    第二章:C#如何解析JSON数据?(反序列化对象)
    Eucalyptus4.0 管理页面介绍
    Eucalyptus常用查询命令
  • 原文地址:https://www.cnblogs.com/charlee44/p/13168331.html
Copyright © 2020-2023  润新知