渲染系統中MRT和RTT的應用組合(WEBGL1 GLSL ES1實現)
阿新 • • 發佈:2018-11-09
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(); }; };