当前位置:   article > 正文

unity渲染场景流程_unity 渲染流程 详解

unity 渲染流程 详解

unity渲染场景流程

大概流程

渲染管线使用物体队列调用多个渲染通道->渲染通道遍历物体队列调用Shader中的某个Pass->Pass中通过Shader执行物体渲染过程

为了区分,把 RenderPipeline 称为 渲染管线, ShaderPipeline 称为着色管线,RenderPass 称为渲染通道,ShaderPass 称为着色通道
  • 1
  • 2
  • 3

渲染管线的大致流程

	//	这个就是渲染管线,不同的管线有不同的实现代码,这里描述的是内置渲染管线
	void 	Pipeline:Render(RenderContext context)
	{
   
		for (var camera in camearas)
		{
   
			Render(context,camera);
		}
	}
	
	void 	Pipeline:Render(RenderContext context,Camera camera)
	{
   
		CullResult cull = CullResults.Cull(context);//	剔除掉不会渲染的物体
		
		context.SetupCameraProperties(camera);		//	设置矩阵及其他属性
		
		var buffer = new CommandBuffer();			//	创建命令缓冲
		buffer.ClearRenderTarget();					//	清除渲染目标
		context.ExecuteCommandBuffer(buffer);		//	执行命令缓冲,没有立即执行,只是拷贝到内部缓冲区
		buffer.Release();
		
		//	现在主流有2种渲染路径:前向渲染和延迟渲染
		//		不同的渲染路径会使用不同的 shader 代码,因此在立项时就要确定好采用哪种渲染路径
		//		一般手机用前向渲染,通用性更好,PC或VR等性能好的用延迟渲染,具有更好的光影表现
		//	参考  教程\图形学\渲染管线\延迟渲染 VS 前向渲染.pdf
		//	参考  Unity User Manual (2019.4 LTS)/图形/Render pipelines/内置渲染管线/Extending the Built-in Render Pipeline with Command Buffers
		//	不同的路径有不同实现代码,通过组合不同的物体队列和着色通道来渲染物体
		//	
		if ( m_useForward )
		{
   
			//	前向渲染
			//	渲染不透明物体然后渲染透明物体
			
			//	指定使用材质上的哪个Pass,物体材质上可以有多个 SubShader 代表不同的显卡平台,每个SubShader上有多个Pass
			//	每个Pass代表不同参数下如何渲染物体,当我们渲染一个队列的物体时要指定用哪个Pass
			
			//	初始化所有灯光
			setupFirstLight();	
				
			//	渲染不透明物体
			{
   
				//	前向渲染当重要光源超过1个时会用到多个Pass
				//	第1次设置第1个重要光源和其他不重要光源,然后调用材质中的 ForwardBase Pass
				var drawSettings = new DrawRendererSettings(camera, new ShaderPassName("ForwardBase"));
				
				//	指定排序方式,不透明物体按离摄像机从近到远排序,这样远的物体如果被覆盖,在深度测试时就被pass掉,提高效率
				drawSettings.sorting.flags = SortFlags.CommandOpaque;		
				//	drawSettings.SetOverrideMaterial(errMaterial);	//	可以通过该函数覆盖所有物体渲染时的材质
				//	指定不透明物体队列
				var filterSettings = new FilterRenderersSettings(){
   renderQueueRange=RenderQueueRange.opaque};	
				//	使用 ForwardBase 着色器通道渲染不透明物体,FrameDebugger中看到的是 A ForwardBase, B ForwardBase
				conext.DrawRenderers(cull.visibleRenderers, ref drawSettings, filterSettings);	
				
				//	然后对剩下的重要光源每次设置1个,然后调用材质中的 ForwardAdd Pass ,
				//		为什么使用不同的Pass 呢,因为第1次Pass还有其它光源
				//	后面的Pass有点不一样,是设置好所有Pass,然后再遍历物体
				for ( int i=1; i<m_importLights.Length; i++ )
				{
   
					drawSettings.SetShaderPassName(i-1,new ShaderPassName("ForwardAdd"));
				}
				//	设置好所有Pass后再一次性遍历,所以在 FrameDebugger中看到的是 A ForwardAdd, A ForwardAdd, B ForwardAdd, B ForwardAdd
				conext.DrawRenderers(cull.visibleRenderers, ref drawSettings, filterSettings);
			}
			
			contex.DrawSkyBox();	//	画天空盒,没有立即执行,只是提交了个命令到内部缓冲区
			
			//	渲染半透明物体
			{
   
				//	透明物体队列物体按离摄像头从远到近排序,这样才能正确显示
				drawSettings.sorting.flags 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/102784
推荐阅读
相关标签
  

闽ICP备14008679号