unity 获取深度图(drawcall不翻倍)
原文地址:https://blog.csdn.net/SnoopyNa2Co3/article/details/114090245
深度圖基礎
深度圖里存放了[0,1]范圍的非線性分布的深度值,這些深度值來自NDC坐標。
在延遲渲染中,深度值默認已經渲染到G-buffer;
https://www.jianshu.com/p/80a932d1f11e這里已經有詳細說明
沒優化前深度圖獲取
在C#中設置Camera.main.depthTextureMode = DepthTextureMode.Depth;
在Shader中聲明_CameraDepthTexture
原理:Unity在背后利用Shader Replacement將RenderType為Opaque、渲染隊列小于等于2500并且有ShadowCaster Pass的物體的深度值渲染到深度圖中。所以drawcall翻倍
深度圖獲取優化
使用接口m_Camera.SetTargetBuffers設置depthbuffer
然后depthbuffer輸出導一張rendertexture,這張圖就是我們要的深度圖,shader里面聲明全局圖片,我定義為_DepthTex
然后shader直接聲明_DepthTex就可以使用
通過Blit處理rendertexture避免多次渲染
下面是代碼
using UnityEngine; using UnityEngine.Rendering; /// <summary> /// Pieken 2020 /// </summary> public class RenderMgr : MonoBehaviour {/// <summary>/// 當前攝像機/// </summary>private Camera m_Camera;/// <summary>/// 抗鋸齒材質球(后處理用)/// </summary>public Material ssaa;/// <summary>/// 在天空盒渲染之后保存的圖片id(就是特效渲染之前)/// </summary>private static int m_AfterSkyboxTexId = Shader.PropertyToID("_AfterSkyboxTex");/// <summary>/// 深度圖id/// </summary>private static int m_DepthTexId = Shader.PropertyToID("_DepthTex");/// <summary>/// 在天空盒渲染之后保存的圖片(就是特效渲染之前)/// </summary>public RenderTexture m_AfterSkyboxTex;/// <summary>/// 用于存儲深度/// </summary>public RenderTexture m_depthBufferTex;/// <summary>/// 深度圖/// </summary>public RenderTexture m_DepthTex;/// <summary>/// 當前攝像機渲染最終的圖片/// </summary>private RenderTexture m_CameraRenderTex;/// <summary>/// 在渲染天空盒之后的commandbuff指令/// </summary>private CommandBuffer m_AfterSkyboxCommandBuffer;/// <summary>/// 處理深度圖的commandbuff指令/// </summary>private CommandBuffer m_DepthBuffer;private void Start(){m_Camera = GetComponent<Camera>();Init();}private void Init(){//屏幕渲染圖m_CameraRenderTex = RenderTexture.GetTemporary(Screen.width, Screen.height, 0, RenderTextureFormat.Default, RenderTextureReadWrite.Default);//存儲深度m_depthBufferTex = new RenderTexture(Screen.width, Screen.height, 24, RenderTextureFormat.Depth);m_depthBufferTex.name = "DepthBuffer";//深度圖m_DepthTex = new RenderTexture(Screen.width, Screen.height, 0, RenderTextureFormat.RHalf);m_DepthTex.name = "DepthTex";//添加處理深度圖commandbufferm_DepthBuffer = new CommandBuffer();m_DepthBuffer.name = "CommandBuffer_DepthBuffer";//把depthbuffer寫入m_DepthTex的colorbuffer//把depthbuffer合成一張rt和自帶的是重新渲染一張rt效果一樣//我這里定義rt全局id為_DepthTex,shader直接獲取這個就可以使用自定義深度圖m_DepthBuffer.Blit(m_depthBufferTex.depthBuffer, m_DepthTex.colorBuffer);m_Camera.AddCommandBuffer(CameraEvent.AfterForwardOpaque, m_DepthBuffer);//設置shader全局深度圖Shader.SetGlobalTexture(m_DepthTexId, m_DepthTex);//半透渲染前的commandbufferm_AfterSkyboxTex = new RenderTexture(Screen.width, Screen.height, 0, RenderTextureFormat.Default);m_AfterSkyboxTex.name = "AfterSkyboxTex";m_AfterSkyboxCommandBuffer = new CommandBuffer();m_AfterSkyboxCommandBuffer.name = "AfterSkyBox_CommandBuffer";//buffer之類把當前渲染出來的圖片保存到m_AfterSkyboxTexm_AfterSkyboxCommandBuffer.Blit(BuiltinRenderTextureType.CurrentActive, m_AfterSkyboxTex);//設置攝像機觸發commandbuffer時機m_Camera.AddCommandBuffer(CameraEvent.AfterSkybox, m_AfterSkyboxCommandBuffer);//設置shader全局圖片,方便給扭曲效果用Shader.SetGlobalTexture(m_AfterSkyboxTexId, m_AfterSkyboxTex);}private void OnPreRender(){m_Camera.SetTargetBuffers(m_CameraRenderTex.colorBuffer, m_depthBufferTex.depthBuffer);}private void OnPostRender(){//開始處理后處理,ssaa是抗鋸齒后處理Graphics.Blit(m_CameraRenderTex, null as RenderTexture, ssaa);} }
注意:m_Camera.SetTargetBuffers用的rendertexture必須抗鋸齒一樣,由于depthbuff不能用抗鋸齒,所以colorbuffer也不能用抗鋸齒
,只能通過后處理來處理抗鋸齒(上面代碼有用后處理抗鋸齒)
使用版本unity 2018.4.23 ,這個優化用于舊項目優化,新項目建議使用更新版本使用urp
鏈接:https://pan.baidu.com/s/1jXROoypDy4BooeXDIunqFQ?
提取碼:9c0b?
總結
以上是生活随笔為你收集整理的unity 获取深度图(drawcall不翻倍)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Camera2实现二维码扫描功能(qrc
- 下一篇: 中国厨房机器人市场现状及未来发展趋势