Demo:http://www.artvily.com/sample?sample=mrtgl2
上图是先实施了两个目标输出的MRT然后绘再使用这个MRT的输出结果来制场景到一个RTT中最后又被一次绘制CUBE使用,之后输出到屏幕。(其实MRT和RTT只是输出目标是多个和一个的区别, 当然glsl代码也有区别)
我的渲染系统的设计思路是用 RTT/MRT控制对象来管理这个流程。
我的渲染系统兼容(WebGL1 GLSL ES2) 使用方式一致,请见:https://blog.csdn.net/vily_lei/article/details/83152742
具体见下面代码(WebGL2 GLSL ES3):
// 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)
{
setVersionToGL2();
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();
};
};