1. 程式人生 > >渲染系統中MRT和RTT的應用組合(WEBGL1 GLSL ES1實現)

渲染系統中MRT和RTT的應用組合(WEBGL1 GLSL ES1實現)

Demo: http://www.artvily.com/sample?sample=mrtgl1a

效果圖:

上圖是先實施了兩個目標輸出的MRT然後繪再使用這個MRT的輸出結果來制場景到一個RTT中最後又被一次繪製CUBE使用,之後輸出到螢幕。(其實MRT和RTT只是輸出目標是多個和一個的區別, 當然glsl程式碼也有區別)
我的渲染系統的設計思路是用 RTT/MRT控制物件來管理這個流程。
我的渲染系統相容(WebGL2 GLSL ES3) 使用方式一致,請見:https://blog.csdn.net/vily_lei/article/details/83152910
具體見下面程式碼(WebGL1 GLSL ES2):


// for control mrt
function MRTCtrObj()
{
    RTTDispObj3D.call( this );
    let m_texProxy = null;
    let m_texProxy2 = null;
    this.getTexture = function()
    {
        if(m_texProxy == null)
        {
            m_texProxy = new TextureProxy();
            m_texProxy.initializeBySize(Stage.stageWidth, Stage.stageHeight);
            m_texProxy.name = "m_texProxy0";
        }
        return m_texProxy;
    }
    this.getTexture2 = function()
    {
        if(m_texProxy2 == null)
        {
            m_texProxy2 = new TextureProxy();
            m_texProxy2.initializeBySize(Stage.stageWidth, Stage.stageHeight);
            m_texProxy2.name = "m_texProxy1";
        }
        return m_texProxy2;
    }
    this.renderBegin = function(renderer)
    {
        // mrt doing...
        renderer.setRenderToTexture(this.getTexture(), true, false, 0);
        renderer.setRenderToTexture(this.getTexture2(), true, false, 1);
    };
    this.renderEnd = function(renderer)
    {
    };
};
// for control rtt
function RTTCtrObj()
{
    RTTDispObj3D.call( this );
    var m_texProxy = null;
    this.getTexture = function()
    {
        if(m_texProxy == null)
        {
            m_texProxy = new TextureProxy();
            m_texProxy.initializeBySize(Stage.stageWidth, Stage.stageHeight);
            m_texProxy.name = "m_texProxy2";
        }
        return m_texProxy;
    }
    this.renderBegin = function(renderer)
    {
        // set RTT
        renderer.setRenderToTexture(this.getTexture(), true, false, 0);
    };
    this.renderEnd = function(renderer)
    {
        renderer.setRenderToBackBuffer();
    };
};
// main scene manager
function VoxSc3D()
{
    // Create a renderer
    let m_rsc = new RenderScene();
    // glgl code loader
    let m_codeLoader = new ResLoadQueue();
    let m_loadCode = true;
    let m_self = this;
    this.initialize = function(glCanvasNS)
    {
        setVersionToGL1();
        m_rsc.initialize(glCanvasNS);
        m_rsc.getRenderer().statusEnbled = true;
        //
        let arr = window.location.href.split("=");
        let baseUrl = "static/voxgl/engine2/samples/"+arr[1]+"/";
        m_codeLoader.loadByURL(baseUrl + "vcode.c");
        m_codeLoader.loadByURL(baseUrl + "fcode.c");
        m_codeLoader.loadByURL(baseUrl + "vcode2.c");
        m_codeLoader.loadByURL(baseUrl + "fcode2.c");
        m_codeLoader.loadByURL(baseUrl + "vcode3.c");
        m_codeLoader.loadByURL(baseUrl + "fcode3.c");
        m_codeLoader.loadByURL(baseUrl + "vcode4.c");
        m_codeLoader.loadByURL(baseUrl + "fcode4.c");
    };
    
    let codeArr = null;
    let act = null;
    let m_mrtTwoCtrObj = new MRTCtrObj();
    let m_rttCtrObj = new RTTCtrObj();
    //
    // loaded glsl code
    this.loadedCode = function()
    {
        codeArr = m_codeLoader.getCodes();
        let material = new MaterialBase();
        material.initialize({uniqueName:"sampleTest..",vshdCode:codeArr[0], fshdCode:codeArr[1]},["u_objMat","u_viewMat","u_projMat"],["a_vs","a_uvs"]);
        var purl = "static/voxgl/assets/ground_02.jpg";
        var purl2 = "static/voxgl/assets/flare_core_02.jpg";
        // create two textures
        let tex = TextureProxy.Create(purl,TextureFormat.RGBA,TextureFormat.RGBA);
        tex.mipmapEnabled = true;
        material.setTextureProxy(tex);
        //
        let tex2 = TextureProxy.Create(purl2,TextureFormat.RGBA,TextureFormat.RGBA);
        tex2.mipmapEnabled = true;
        tex.next = tex2;
        //
        let plane3D = new DispPlane3D();
        act = new DisplayRotationAction();
        act.setRotSpeedXYZ(0.0, 0.3, 0.0);
        plane3D.setAction( act );
        plane3D.setMaterial(material);
        plane3D.initializeXOZ(-260,-260,520,520,purl,TextureFormat.RGBA,true);
        plane3D.setXYZ(0,-50,0);
        m_rsc.addRDisp(plane3D);
        //
        var sph3D = new DispSphere3D();
        sph3D.setMaterial(material);
        act = new DisplayRotationAction();
        act.setRotSpeedXYZ(0.3, 0.0, 0.3);
        sph3D.setAction( act );
        sph3D.setMaterial(material);
        sph3D.initialize(80,15,15,purl,TextureFormat.RGBA,true);
        sph3D.setXYZ(0,60,-100);
        m_rsc.addRDisp(sph3D);
        //
        m_mrtTwoCtrObj = new MRTCtrObj();
        m_rsc.addRTTDisp(m_mrtTwoCtrObj);
        // use mrt output
        this.draw2();
        this.draw3();
        //
        m_rsc.addRTTDisp(m_rttCtrObj);
        this.draw4();        
    }
    this.draw2 = function()
    {
        var cube = new DispCube3D();
        act = new DisplayRotationAction();
        act.setRotSpeedXYZ(0.0, 0.3, 0.3);
        cube.setAction( act );
        material = new MaterialBase();
        material.initialize({uniqueName:"rttMaterial",vshdCode:codeArr[2], fshdCode:codeArr[3]},["u_objMat","u_viewMat","u_projMat"],["a_vs","a_uvs"]);
        let texProxy = m_mrtTwoCtrObj.getTexture2();
        texProxy.next = m_mrtTwoCtrObj.getTexture();
        material.setTextureProxy( texProxy );
        cube.setMaterial(material);
        cube.initialize(new Vector3D(-150,-150,-150),new Vector3D(150,150,150),"",TextureFormat.RGBA,true);
        cube.setXYZ(-200, 30, 0);
        m_rsc.addRDisp(cube);
    }
    this.draw3 = function()
    {
        var cube = new DispCube3D();
        act = new DisplayRotationAction();
        act.setRotSpeedXYZ(0.0, 0.3, 0.3);
        cube.setAction( act );
        material = new MaterialBase();
        material.initialize({uniqueName:"rttMaterial",vshdCode:codeArr[4], fshdCode:codeArr[5]},["u_objMat","u_viewMat","u_projMat"],["a_vs","a_uvs"]);
        material.setTextureProxy( m_mrtTwoCtrObj.getTexture() );
        cube.setMaterial(material);
        cube.initialize(new Vector3D(-150,-150,-150),new Vector3D(150,150,150),"",TextureFormat.RGBA,true);
        cube.setXYZ(200, 30, 0);
        m_rsc.addRDisp(cube);
    }
    this.draw4 = function()
    {
        let purl = "static/voxgl/assets/broken_iron.jpg";
        var cube = new DispCube3D();
        act = new DisplayRotationAction();
        act.setRotSpeedXYZ(0.0, 0.1, 0.1);
        cube.setAction( act );
        cube.cullFaceMode = CullFaceMode.FRONT;
        material = new MaterialBase();
        material.initialize({uniqueName:"rttMaterial",vshdCode:codeArr[6], fshdCode:codeArr[7]},["u_objMat","u_viewMat","u_projMat"],["a_vs","a_uvs"]);
        material.setTextureProxy( m_rttCtrObj.getTexture() );
        cube.setMaterial(material);
        cube.initialize(new Vector3D(-250,-250,-250),new Vector3D(250,250,250),"",TextureFormat.RGBA,true);
        cube.setXYZ(0, 30, 0);
        m_rsc.addRDisp(cube);
    }
    this.run = function()
    {
        // Wait loaded glsl shader's text.
        if(m_loadCode)
        {
            if(m_codeLoader.run())
            {
                m_loadCode = false;
                this.loadedCode();
            }
        }
        // Renderer run;
        m_rsc.run();    
    };
};