精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

電子發燒友App

硬聲App

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示
創作
電子發燒友網>電子資料下載>人工智能>URP渲染管線初步解析

URP渲染管線初步解析

2021-01-21 | pdf | 170.47KB | 次下載 | 2積分

資料介紹

URP渲染管線初步解析

LWRP現在在unity2019已經成為默認的管線了,并更名為URP(通用渲染管線),替代了原來的builtin管線,以下是應用階段的渲染流程順序。


步驟分析

URP整個渲染的主入口在UniversalRenderPipeline,他繼承的RenderPipeline,是rsp的渲染流程關鍵類

PipelineSettings:這里會獲取UniversalRenderPipelineAsset(也就是我們外部傳入的管線的參數

ScriptableRenderer:srp渲染器,需要把UniversalRenderPipelineAsset傳給他。他是渲染核心,他會收集所有當前幀要渲染的pass,以及他會擁有渲染相關的燈光和后處理等執行方法。

PerFrameBuffer:每幀設置的緩存數據

_GlossyEnvironmentColor:主要用于PBR這塊的全局光照的顏色,在Lighting.hlsl的GlossyEnvironmentReflection,可以看到他主要是全局光照的高光部分顏色。

_SubtractiveShadowColor:主要用在除了主光源外的lightmap計算的陰影顏色。在SubtractDirectMainLightFromLightmap里使用。

PerCameraBuffer:每幀攝像機的緩存數據

_InvCameraViewProj:視圖空間到投影空間的轉置矩陣,如果用原始矩陣乘以反向矩陣結果為identity矩陣。如果一些矩陣以一個特定的方式變換向量,反向矩陣可以將他們變換回去。例如worldToLoclaMatrix和localToWorldMatrix是互逆的。

_ScaledScreenParams:屏幕縮放參數

antiAliasing:從asset中獲取msaaSampleCount

Shader.globalRenderPipeline = " UniversalPipeline ";設置全局管線為UniversalPipeline

lightsDelegate:全局光照的回調

執行到Render中執行具體渲染流程:

SetupPerFrameShaderConstants:設置全局光照的數據,設置PerFrameBuffer中的_GlossyEnvironmentColor和_SubtractiveShadowColor。

其中_GlossyEnvironmentColor是通過球形諧波方程決定顏色的,最后要轉到當前顏色空間(gamma空間或線性空間)

_SubtractiveShadowColor則是直接賦值具體的除去主光源后的陰影顏色,只是也有最后轉到當前顏色空間的轉換。

對當前Render給過來當前有哪些相機渲染的數據來進行每個相機的渲染RenderSingleCamera。
每個相機中的渲染步驟如下:

CullResults.GetCullingParameters:獲取相機下的裁剪參數,如果返回false說明沒有聶榮,不需要渲染這個相機。如果需要考慮到類似vr等情況需要區分左右眼的攝像機時需要把stereoAware設置為true。

CommandBuffer cmd = CommandBufferPool.Get(k_RenderCameraTag):這里從命令緩存池中獲取一個gl命令緩存,CommandBuffer主要用于收集一系列gl指令,然后之后執行。

ProfilingSample是對指定名字做性能采樣。

InitializeCameraData:初始化攝像機數據。

cameraData.msaaSamples:如果數量大于1說明需要多重采樣。

cameraData.isSceneViewCamera:這個是查看當前要渲染的是否在unity的scene視圖。

cameraData.isOffscreenRender:屏幕外渲染,如果攝像機的targettexture存在并且不是scene視圖則這個為true。

cameraData.isStereoEnabled:就是左右眼做區別的攝像機,用于vr等

cameraData.isHdrEnabled:是否支持hdr,也就是高動態范圍圖像,就是可以在高光情況下能看清一些光照細節,提高細節渲染。

cameraData.postProcessLayer:后處理

cameraData.postProcessEnabled:是否開啟后處理

cameraData.renderScale:渲染縮放比例

cameraData.opaqueTextureDownsampling:降采樣

cameraData.isDefaultViewport:如果是正常的(0,0,1,1)則是默認的

cameraData.maxShadowDistance:最大陰影范圍

cameraData.requiresDepthTexture:是否啟用深度紋理

cameraData.requiresOpaqueTexture:是否保存非透明顏色信息

cameraData.defaultOpaqueSortFlags:默認的非透明渲染順序

SetupPerCameraShaderConstants

PerCameraBuffer._ScaledScreenParams:是一個vector4,包括相機像素的長寬和紋素

PerCameraBuffer._InvCameraViewProj:設置攝像機視角的逆矩陣,通過GL.GetGPUProjectionMatrix獲取到當前gpu正確坐標系的投影矩陣,再跟camera.worldToCameraMatrix視圖矩陣相乘得到視圖到投影的矩陣,再用Matrix4x4.Inverse獲取逆矩陣。

cullingParameters.shadowDistance:設置陰影距離,這里會根據攝像機最遠渲染距離來獲得最遠可達到的距離。

ScriptableRenderContext.ExecuteCommandBuffer(cmd):執行命令緩存

cmd.Clear();清除緩存數據

CullResults.Cull:根據裁剪的參數cullingParameters和context指定的渲染指令得到裁剪的燈光,物體等。

InitializeRenderingData:初始化渲染相關數據

GetMainLight:獲取主光源,如果是直線光并且mainLightRenderingMode不為LightRenderingMode.PerPixel就是主光源。

mainLightCastShadows:如果可見光存在而且陰影設置存在則為true。

additionalLightsCastShadows:如果additionalLightsRenderingMode是LightRenderingMode.PerPixel并且可見光存在并且lightType是LightType.Spot且陰影存在則為true。

InitializeLightData:初始化燈光數據,這里設置了mainLightIndex(也就是GetMainLight獲取的),設置additionalLightsCount獲取疊加光源的數量,maxPerObjectAdditionalLightsCount最大疊加光源數量,shadeAdditionalLightsPerVertex就是是否是疊加光源,visibleLights可視光源,supportsMixedLighting支持混合光源。

InitializeShadowData:初始化陰影數據,如果有多光源會添加LWRPAdditionalLightData到光源的gameobject上,m_ShadowBiasData會設置陰影偏移和陰影發現偏移,主要用于解決自陰影的問題。

supportsMainLightShadows支持主光源陰影 。

mainLightShadowCascadesCount是陰影的級聯個數,(mainLightShadowmapWidth、mainLightShadowmapHeight)主光源陰影貼圖的寬高。

mainLightShadowCascadesSplit是陰影的級聯分割,supportsAdditionalLightShadows是否支持多光源陰影。

additionalLightsShadowmapWidth、additionalLightsShadowmapHeight是多光源陰影貼圖的寬和高都是additionalLightsShadowmapResolution。

supportsSoftShadows支持軟陰影。

supportsDynamicBatching:是否支持動態批處理,這個是lwrp的動態批處理。

設置完渲染數據后就是開始設置渲染的順序了:

renderer.Clear():再設置之前需要清理renderer的數據,不然前一幀渲染的dc是不會清掉的,dc就會越來越高。

setupToUse.Setup(renderer, ref renderingData):默認lwrp是用DefaultRendererSetup來設置的,當然你也可以實現IRendererSetup然后傳入Render來自己實現。

DefaultRendererSetup:lwrp默認會有一系列渲染過程。會再Setup中確定渲染的先后。

SetupPerObjectLightIndices設置每個對象光照信息。

CreateRenderTextureDescriptor創建rt數據信息。

GetCameraClearFlag獲取當前攝像機清理方式,lwrp對這層做了一些處理,主要是對深度剔除做了一些選項

如果是渲染到紋理則用CreateLightweightRenderTexturesPass這個pass執行一次渲染。

如果有渲染前要執行的pass要實現IBeforeRender接口,并且可以多個pass。

如果支持主光源陰影投放則執行MainLightShadowCasterPass的pass。

如果支持多光源陰影投放則執行AdditionalLightsShadowCasterPass。

之后執行SetupForwardRenderingPass,這個pass是必然執行的,設置攝像機到context里。

如果支持深度貼圖獲取的話會執行DepthOnlyPass(requiresDepthPrepass決定是否執行他),這里會用一個rt保存深度貼圖新消息。

如果支持屏幕空間陰影獲取,則會執行ScreenSpaceShadowResolvePass,這里會用一個rt記錄屏幕空間中的陰影貼圖。

然后執行SetupLightweightConstanstPass,主要設置主光源和其他光源的顏色,位置以及其他屬性。如果不設置則會是默認顏色和位置等信息。

然后執行RenderOpaqueForwardPass,這個pass定義了兩個pass名,LightweightForward和SRPDefaultUnlit。然后再Execute申請cmd來做不透明渲染。

如果支持后處理則會執行OpaquePostProcessPass,里面是申請一個臨時rt做相關不透明的后處理。

如果是相機是天空盒清除方式的話并且天空盒不是空的話則執行DrawSkyboxPass,里面會繪制天空盒。

如果需要天空盒處理之后執行的話需要繼承IAfterSkyboxPass實現相關pass。

如果是支持深度貼圖的話并且沒有執行requiresDepthPrepass的話(就是前面執行DepthOnlyPass的判斷)則會執行CopyDepthPass,這里主要是拷貝深度貼圖到全局變量_CameraDepthAttachment中,shader可以直接獲取這個變量(如果有開深度貼圖獲取)

如果開啟了接收不透明貼圖的話則執行CopyColorPass,這里主要是把不透明渲染后的顏色輸出到臨時rt中。

然后執行RenderTransparentForwardPass,透明渲染方式。

如果支持后處理則執行TransparentPostProcessPass,也是一樣申請一個臨時rt做相關透明渲染的后處理。如果不需要并且不支持屏幕外渲染并且不是渲染到紋理的則要執行FinalBlitPass,這里主要設置貼圖到全局變量_BlitTex,然后把顏色blit到內置rt中。

然后如果攝像機有IAfterRender的mono則會執行pass中的GetPassToEnqueue方法。

最后還會有一個EndXRRenderingPass的渲染,這個是支持立體攝像機的情況下執行的,主要是停止立體攝像機渲染。

然后再到外面renderer.Execute(context, ref renderingData);也就是把所有pass都執行一次。(前面只是加入到列表中,并沒有執行每個pass的execute)

最后需要context.Submit來提交渲染,這時相應的gpu才會根據cmd來執行所有的pass。

源碼分析

渲染前階段:

根據渲染資產初始化渲染管線

      public UniversalRenderPipeline(UniversalRenderPipelineAsset asset)              {            SetSupportedRenderingFeatures();    //設置渲染支持功能            //PerFrameBuffer類中的參數指定            PerFrameBuffer._GlossyEnvironmentColor = Shader.PropertyToID("_GlossyEnvironmentColor");            PerFrameBuffer._SubtractiveShadowColor = Shader.PropertyToID("_SubtractiveShadowColor");            PerFrameBuffer._Time = Shader.PropertyToID("_Time");                    PerFrameBuffer._SinTime = Shader.PropertyToID("_SinTime");            PerFrameBuffer._CosTime = Shader.PropertyToID("_CosTime");            PerFrameBuffer.unity_DeltaTime = Shader.PropertyToID("unity_DeltaTime");            PerFrameBuffer._TimeParameters = Shader.PropertyToID("_TimeParameters");            PerCameraBuffer._InvCameraViewProj = Shader.PropertyToID("_InvCameraViewProj");            PerCameraBuffer._ScreenParams = Shader.PropertyToID("_ScreenParams");            PerCameraBuffer._ScaledScreenParams = Shader.PropertyToID("_ScaledScreenParams");            PerCameraBuffer._WorldSpaceCameraPos = Shader.PropertyToID("_WorldSpaceCameraPos");            // Let engine know we have MSAA on for cases where we support MSAA backbuffer            if (QualitySettings.antiAliasing != asset.msaaSampleCount)      //設置多重采樣抗鋸齒                QualitySettings.antiAliasing = asset.msaaSampleCount;            // For compatibility reasons we also match old LightweightPipeline tag.            Shader.globalRenderPipeline = "UniversalPipeline,LightweightPipeline";  //設置渲染管線            Lightmapping.SetDelegate(lightsDelegate);             CameraCaptureBridge.enabled = true;            RenderingUtils.ClearSystemInfoCache();        }

渲染階段

1. 開始幀渲染

BeginFrameRendering(renderContext, cameras);    //開始幀渲染

2. 判斷色彩空間是否為線性空間

GraphicsSettings.lightsUseLinearIntensity = (QualitySettings.activeColorSpace == ColorSpace.Linear);    //色彩空間是否是線性空間

3. 設置資產中的Batcher

GraphicsSettings.useScriptableRenderPipelineBatching = asset.useSRPBatcher; //設置資產中的Batcher

4. 設置每幀shader參數

SetupPerFrameShaderConstants(); //設置幀著色器常量

5. 排序相機

SortCameras(cameras);   //排序相機

6. 遍歷相機/開始相機渲染/渲染單個相機/結束相機渲染

foreach (Camera camera in cameras)      //遍歷相機{   BeginCameraRendering(renderContext, camera);    //開始相機渲染   #if VISUAL_EFFECT_GRAPH_0_0_1_OR_NEWER                //It should be called before culling to prepare material. When there isn't any VisualEffect component, this method has no effect.         VFX.VFXManager.PrepareCamera(camera);	#endif         RenderSingleCamera(renderContext, camera);  //渲染單個相機         EndCameraRendering(renderContext, camera);  //結束相機渲染 }

7. 結束幀渲染

EndFrameRendering(renderContext, cameras);  //結束幀渲染

渲染單個相機流程(RenderSingleCamera)


源碼分析

1. 初始化剔除參數

if (!camera.TryGetCullingParameters(IsStereoEnabled(camera), out var cullingParameters))    //初始化剔除參數return;

2. 獲取UniversalAdditionCameraData

UniversalAdditionalCameraData additionalCameraData = null;if (camera.cameraType == CameraType.Game || camera.cameraType == CameraType.VR)camera.gameObject.TryGetComponent(out additionalCameraData);

3. 初始化CameraData,InitializeCameraData方法

InitializeCameraData(settings, camera, additionalCameraData, out var cameraData);

4. 設置每個相機的shader參數

SetupPerCameraShaderConstants(cameraData);

SetupPerCameraShaderConstants方法:

//設置每個相機的shader參數static void SetupPerCameraShaderConstants(CameraData cameraData){   Camera camera = cameraData.camera;   float scaledCameraWidth = (float)cameraData.camera.pixelWidth * cameraData.renderScale;   float scaledCameraHeight = (float)cameraData.camera.pixelHeight * cameraData.renderScale;   Shader.SetGlobalVector(PerCameraBuffer._ScaledScreenParams, new Vector4(scaledCameraWidth, scaledCameraHeight, 1.0f + 1.0f / scaledCameraWidth, 1.0f + 1.0f / scaledCameraHeight));   Shader.SetGlobalVector(PerCameraBuffer._WorldSpaceCameraPos, camera.transform.position);   float cameraWidth = (float)cameraData.camera.pixelWidth;   float cameraHeight = (float)cameraData.camera.pixelHeight;   Shader.SetGlobalVector(PerCameraBuffer._ScreenParams, new Vector4(cameraWidth, cameraHeight, 1.0f + 1.0f / cameraWidth, 1.0f + 1.0f / cameraHeight));  Matrix4x4 projMatrix = GL.GetGPUProjectionMatrix(camera.projectionMatrix, false);  Matrix4x4 viewMatrix = camera.worldToCameraMatrix;  Matrix4x4 viewProjMatrix = projMatrix * viewMatrix;  Matrix4x4 invViewProjMatrix = Matrix4x4.Inverse(viewProjMatrix);  Shader.SetGlobalMatrix(PerCameraBuffer._InvCameraViewProj, invViewProjMatrix);        }

5. 獲取ScriptableRenderer

ScriptableRenderer renderer = (additionalCameraData != null) ? additionalCameraData.scriptableRenderer : settings.scriptableRenderer;

6. 填充剔除參數、CameraData

renderer.SetupCullingParameters(ref cullingParameters, ref cameraData);

7. 性能采樣

context.ExecuteCommandBuffer(cmd);

8. 編輯器模式下Scene相機額外顯示UI

#if UNITY_EDITOR// Emit scene view UI       編輯器模式下Scene相機額外顯示UIif (cameraData.isSceneViewCamera)ScriptableRenderContext.EmitWorldGeometryForSceneView(camer);#endif

9. 剔除

var cullResults = context.Cull(ref cullingParameters);      //剔除

10. 根據管線設置、CameraData、剔除結果,初始化渲染數據RenderingData

InitializeRenderingData(settings, ref cameraData, ref cullResults, out var renderingData);

11. 使用ScriptableRenderer根據RenderingData,Setup并Exute渲染上下文

renderer.Setup(context, ref renderingData);renderer.Execute(context, ref renderingData);

12. 釋放CommandBufferPool

CommandBufferPool.Release(cmd);

13. 提交渲染上下文

context.Submit();


原文鏈接:

來源:電子創新網

下載該資料的人也在下載 下載該資料的人還在閱讀
更多 >

評論

查看更多

下載排行

本周

  1. 1HFSS電磁仿真設計應用詳解PDF電子教程免費下載
  2. 24.30 MB   |  128次下載  |  1 積分
  3. 2雷達的基本分類方法
  4. 1.25 MB   |  4次下載  |  4 積分
  5. 3電感技術講解
  6. 827.73 KB  |  2次下載  |  免費
  7. 4從 MSP430? MCU 到 MSPM0 MCU 的遷移指南
  8. 1.17MB   |  2次下載  |  免費
  9. 5有源低通濾波器設計應用說明
  10. 1.12MB   |  2次下載  |  免費
  11. 6RA-Eco-RA2E1-48PIN-V1.0開發板資料
  12. 35.59 MB  |  2次下載  |  免費
  13. 7面向熱插拔應用的 I2C 解決方案
  14. 685.57KB   |  1次下載  |  免費
  15. 8愛普生有源晶體振蕩器SG3225EEN應用于儲能NPC、新能源
  16. 317.46 KB  |  1次下載  |  免費

本月

  1. 12024年工控與通信行業上游發展趨勢和熱點解讀
  2. 2.61 MB   |  763次下載  |  免費
  3. 2HFSS電磁仿真設計應用詳解PDF電子教程免費下載
  4. 24.30 MB   |  128次下載  |  1 積分
  5. 3繼電保護原理
  6. 2.80 MB   |  36次下載  |  免費
  7. 4正激、反激、推挽、全橋、半橋區別和特點
  8. 0.91 MB   |  32次下載  |  1 積分
  9. 5labview實現DBC在界面加載配置
  10. 0.57 MB   |  21次下載  |  5 積分
  11. 6在設計中使用MOSFET瞬態熱阻抗曲線
  12. 1.57MB   |  15次下載  |  免費
  13. 7GBT 4706.1-2024家用和類似用途電器的安全第1部分:通用要求
  14. 7.43 MB   |  14次下載  |  免費
  15. 8AD18學習筆記
  16. 14.47 MB   |  8次下載  |  2 積分

總榜

  1. 1matlab軟件下載入口
  2. 未知  |  935113次下載  |  10 積分
  3. 2開源硬件-PMP21529.1-4 開關降壓/升壓雙向直流/直流轉換器 PCB layout 設計
  4. 1.48MB  |  420061次下載  |  10 積分
  5. 3Altium DXP2002下載入口
  6. 未知  |  233084次下載  |  10 積分
  7. 4電路仿真軟件multisim 10.0免費下載
  8. 340992  |  191360次下載  |  10 積分
  9. 5十天學會AVR單片機與C語言視頻教程 下載
  10. 158M  |  183329次下載  |  10 積分
  11. 6labview8.5下載
  12. 未知  |  81578次下載  |  10 積分
  13. 7Keil工具MDK-Arm免費下載
  14. 0.02 MB  |  73804次下載  |  10 積分
  15. 8LabVIEW 8.6下載
  16. 未知  |  65985次下載  |  10 積分