CommandBuffer文档
CommandBuffer为渲染命令缓冲区,保存了渲染命令列表。当我们将一些渲染指令添加到CommandBuffer后,可以实现对渲染流程的控制,将这些指令在我们想要的时机进行执行。command buffer设置渲染目标或绘制给定网格,可以设置在摄像机渲染期间的不同点执行
CommandBuffer是一个高阶的3D渲染功能,用来拓展LayaAir引擎渲染管线的渲染效果。在实现毛玻璃(玻璃透明模糊感)、轮廓透视描边或者边缘光效、沙滩脚印、景深等等效果时非常好用,懂的人都明白,CommandBuffer非常强大,也是3A级大作经常用到的渲染功能,并且不会有额外的功能损耗,甚至某些效果比其它方案更省性能,是一种小游戏平台中也可以用来加强3D渲染效果的渲染扩展功能
2.使用步骤
Section titled “2.使用步骤”1.创建好CommandBuffer后,添加渲染指令给CommandBuffer
Section titled “1.创建好CommandBuffer后,添加渲染指令给CommandBuffer”添加代码接口如下:
var buf:CommandBuffer = new CommandBuffer();buf.setRenderTarget(renderTexture);buf.drawRender(renders[i],materials[i],0);2.需要将CBuffer绑定到Camera的渲染事件中,目前laya支持的Camera事件如下:
Section titled “2.需要将CBuffer绑定到Camera的渲染事件中,目前laya支持的Camera事件如下:”BeforeForwardOpaque = 0,//在渲染非透明物体之前BeforeSkyBox = 2,//在渲染天空盒之前BeforeTransparent = 4,//在渲染透明物体之BeforeImageEffect = 6,//在后期处理之前AfterEveryThing = 8,//所有渲染之后添加CommandBuffer到相机事件的接口如下:
this.camera.addCommandBuffer(this.cameraEventFlag,this.commandBuffer);删除CommandBuffer的接口如下:
this.camera.removeCommandBuffer(this.cameraEventFlag,this.commandBuffer);CommandBuffer是一个渲染指令集,组成这个渲染指令集的是一个一个的独立的渲染指令
setShaderData//设置shader数据,可以设置shader中的texture vector number等 setGlobalShaderData//设置全局数据,可以用于所有的shaderblitScreenQuad//通过全屏四边形将源纹理渲染到目标渲染纹理指令。blitScreenQuadByMaterial//通过全屏四边形将源纹理渲染到目标渲染纹理指令setRenderTarget//设置指令渲染目标,调用后,所有的渲染都会渲染到方法绑定的图片上clearRenderTarget//清理绑定的渲染纹理drawMesh//渲染一个MeshdrawRender//渲染一个Render可以组合不同的渲染指令然后放入不同的渲染流程,下面具体分析官方示例来更好的理解一下CommandBuffer的用法。
3.使用示例
Section titled “3.使用示例”3.1.BlurryGlass示例(毛玻璃示例)
Section titled “3.1.BlurryGlass示例(毛玻璃示例)”
毛玻璃属于透明材质,后面的三个胶囊体都是非透明材质,所以我们需要每帧将毛玻璃模型后面的所有渲染物体全部拿出,进行模糊,再将图片按屏幕uv采样到毛玻璃上面,便可以实现这样的效果
createCommandBuffer(camera:Camera){ //当需要在渲染透明物体之前拿到摄像机渲染结果,所以调用下面的属性true camera.enableBuiltInRenderTexture = true; //创建CommandBuffer var buf:CommandBuffer = new CommandBuffer(); //创建需要模糊使用的屏幕RenderTexture var viewPort:Viewport = camera.viewport; //创建新的RenderTexture var renderTexture = RenderTexture.createFromPool(viewPort.width,viewPort.height,RenderTextureFormat.R8G8B8,RenderTextureDepthFormat.DEPTHSTENCIL_NONE); this.texture = renderTexture; //将当前渲染的结果拷贝到创建好的RenderTexturebuf.blitScreenTriangle(null,renderTexture); //获得模糊shader var shader:Shader3D = Shader3D.find("blurEffect"); //设置模糊参数var shaderValue:ShaderData = new ShaderData(); //down Sample level设置降采样等级 var downSampleFactor:number = 4; var downSampleWidth:number = viewPort.width/downSampleFactor; var downSampleheigh:number = viewPort.height/downSampleFactor; //设置模糊材质参数 var texSize:Vector4 = new Vector4(1.0/viewPort.width,1.0/viewPort.height,viewPort.width,downSampleheigh); shaderValue.setNumber(BlurEffect.SHADERVALUE_DOWNSAMPLEVALUE,1); shaderValue.setVector(BlurEffect.SHADERVALUE_TEXELSIZE,texSize); //创建降采样RenderTexture1 var downRenderTexture = RenderTexture.createFromPool(downSampleWidth,downSampleheigh,RenderTextureFormat.R8G8B8,RenderTextureDepthFormat.DEPTHSTENCIL_NONE); //降采样命令流 buf.blitScreenTriangle(renderTexture,downRenderTexture,null,shader,shaderValue,0); //创建降采样RenderTexture2 var blurTexture:RenderTexture = RenderTexture.createFromPool(downSampleWidth,downSampleheigh,RenderTextureFormat.R8G8B8,RenderTextureDepthFormat.DEPTHSTENCIL_NONE); blurTexture.filterMode = FilterMode.Bilinear; //Horizontal blur buf.blitScreenTriangle(downRenderTexture,blurTexture,null,shader,shaderValue,1); //vertical blur buf.blitScreenTriangle(blurTexture,downRenderTexture,null,shader,shaderValue,2); //Horizontal blur buf.blitScreenTriangle(downRenderTexture,blurTexture,null,shader,shaderValue,1); //vertical blur buf.blitScreenTriangle(blurTexture,downRenderTexture,null,shader,shaderValue,2); //至此 模糊图片已经生成在downRenderTexture中 //设置全局uniform变量 var globalUniformNameID:number = Shader3D.propertyNameToID("u_screenTexture"); //将全局变量u_screenTexture赋值为模糊图片 buf.setGlobalTexture(globalUniformNameID,downRenderTexture); //将commandBuffer加入渲染流程 camera.addCommandBuffer(CameraEventFlags.BeforeTransparent,buf); //回收用过的RenderTexture RenderTexture.recoverToPool(downRenderTexture); RenderTexture.recoverToPool(blurTexture); return; }3.2.OutLine示例(轮廓线描边)
Section titled “3.2.OutLine示例(轮廓线描边)”
在渲染完成之后,绑定另外一个黑色的Rendertexture,重新画好粒子,Box,猴子为纯红色,再将图片模糊,模糊图片颜色减去没模糊的图片,就能得到渲染边框,最后将渲染边框重新加到渲染好的画布上面,便可实现轮廓效果
createDrawMeshCommandBuffer(camera:Camera,renders:BaseRender[],materials:Material[]):CommandBuffer{ var buf:CommandBuffer = new CommandBuffer(); //当需要在流程中拿摄像机渲染效果的时候 设置true camera.enableBuiltInRenderTexture = true; //创建和屏幕一样大的Rendertexture var viewPort:Viewport = camera.viewport; var renderTexture = RenderTexture.createFromPool(viewPort.width,viewPort.height,RenderTextureFormat.R8G8B8A8,RenderTextureDepthFormat.DEPTHSTENCIL_NONE); //将RenderTexture设置为渲染目标 buf.setRenderTarget(renderTexture); //清楚渲染目标的颜色为黑色,不清理深度 buf.clearRenderTarget(true,false,new Vector4(0,0,0,0)); //将传入的Render渲染到纹理上 for(var i = 0,n = renders.length;i<n;i++){ buf.drawRender(renders[i],materials[i],0); } //创建新的RenderTexture var subRendertexture = RenderTexture.createFromPool(viewPort.width,viewPort.height,RenderTextureFormat.R8G8B8A8,RenderTextureDepthFormat.DEPTHSTENCIL_NONE); //将renderTexture的结果复制到subRenderTexture buf.blitScreenQuad(renderTexture,subRendertexture); //设置模糊的参数 var downSampleFactor:number = 2; var downSampleWidth:number = viewPort.width/downSampleFactor; var downSampleheigh:number = viewPort.height/downSampleFactor; var texSize:Vector4 = new Vector4(1.0/viewPort.width,1.0/viewPort.height,viewPort.width,downSampleheigh); //创建模糊材质 var blurMaterial:BlurMaterial = new BlurMaterial(texSize,1); //创建降采样RenderTexture1 var downRenderTexture = RenderTexture.createFromPool(downSampleWidth,downSampleheigh,RenderTextureFormat.R8G8B8,RenderTextureDepthFormat.DEPTHSTENCIL_NONE); //降采样 使用blurMaterial材质的0SubShader将Rendertexture渲染到DownRendertexture buf.blitScreenQuadByMaterial(renderTexture,downRenderTexture,null,blurMaterial,0); //创建降采样RenderTexture2 var blurTexture:RenderTexture = RenderTexture.createFromPool(downSampleWidth,downSampleheigh,RenderTextureFormat.R8G8B8,RenderTextureDepthFormat.DEPTHSTENCIL_NONE); blurTexture.filterMode = FilterMode.Bilinear; //Horizontal blur 使用blurMaterial材质的1SubShader buf.blitScreenQuadByMaterial(downRenderTexture,blurTexture,null,blurMaterial,1); //vertical blur 使用blurMaterial材质的2SubShader buf.blitScreenQuadByMaterial(blurTexture,downRenderTexture,null,blurMaterial,2); //Horizontal blur 使用blurMaterial材质的1SubShader buf.blitScreenQuadByMaterial(downRenderTexture,blurTexture,null,blurMaterial,1); //vertical blur 使用blurMaterial材质的2SubShader buf.blitScreenQuadByMaterial(blurTexture,downRenderTexture,null,blurMaterial,2); //在命令流里面插入设置图片命令流,在调用的时候会设置blurMaterial的图片数据 buf.setShaderDataTexture(blurMaterial._shaderValues,BlurMaterial.SHADERVALUE_SOURCETEXTURE0,downRenderTexture); buf.setShaderDataTexture(blurMaterial._shaderValues,BlurMaterial.ShADERVALUE_SOURCETEXTURE1,subRendertexture); //caculate edge计算边缘图片 buf.blitScreenQuadByMaterial(blurTexture,renderTexture,null,blurMaterial,3); //重新传入图片 buf.setShaderDataTexture(blurMaterial._shaderValues,BlurMaterial.SHADERVALUE_SOURCETEXTURE0,renderTexture); //将camera渲染结果复制到subRendertexture,使用blurMaterial的4通道shader buf.blitScreenQuadByMaterial(null,subRendertexture,null,blurMaterial,4); //将subRenderTexture重新赋值到camera的渲染结果上面 buf.blitScreenQuadByMaterial(subRendertexture,null); return buf; }