Нема описа
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GBufferPass.cs 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. using System;
  2. using UnityEngine.Experimental.GlobalIllumination;
  3. using UnityEngine.Experimental.Rendering;
  4. using UnityEngine.Profiling;
  5. using Unity.Collections;
  6. using UnityEngine.Rendering.RenderGraphModule;
  7. namespace UnityEngine.Rendering.Universal.Internal
  8. {
  9. // Render all tiled-based deferred lights.
  10. internal class GBufferPass : ScriptableRenderPass
  11. {
  12. internal static readonly int s_CameraNormalsTextureID = Shader.PropertyToID("_CameraNormalsTexture");
  13. static ShaderTagId s_ShaderTagLit = new ShaderTagId("Lit");
  14. static ShaderTagId s_ShaderTagSimpleLit = new ShaderTagId("SimpleLit");
  15. static ShaderTagId s_ShaderTagUnlit = new ShaderTagId("Unlit");
  16. static ShaderTagId s_ShaderTagComplexLit = new ShaderTagId("ComplexLit");
  17. static ShaderTagId s_ShaderTagUniversalGBuffer = new ShaderTagId("UniversalGBuffer");
  18. static ShaderTagId s_ShaderTagUniversalMaterialType = new ShaderTagId("UniversalMaterialType");
  19. DeferredLights m_DeferredLights;
  20. static ShaderTagId[] s_ShaderTagValues;
  21. static RenderStateBlock[] s_RenderStateBlocks;
  22. FilteringSettings m_FilteringSettings;
  23. RenderStateBlock m_RenderStateBlock;
  24. private PassData m_PassData;
  25. public GBufferPass(RenderPassEvent evt, RenderQueueRange renderQueueRange, LayerMask layerMask, StencilState stencilState, int stencilReference, DeferredLights deferredLights)
  26. {
  27. base.profilingSampler = new ProfilingSampler("Draw GBuffer");
  28. base.renderPassEvent = evt;
  29. m_PassData = new PassData();
  30. m_DeferredLights = deferredLights;
  31. m_FilteringSettings = new FilteringSettings(renderQueueRange, layerMask);
  32. m_RenderStateBlock = new RenderStateBlock(RenderStateMask.Nothing);
  33. m_RenderStateBlock.stencilState = stencilState;
  34. m_RenderStateBlock.stencilReference = stencilReference;
  35. m_RenderStateBlock.mask = RenderStateMask.Stencil;
  36. if (s_ShaderTagValues == null)
  37. {
  38. s_ShaderTagValues = new ShaderTagId[5];
  39. s_ShaderTagValues[0] = s_ShaderTagLit;
  40. s_ShaderTagValues[1] = s_ShaderTagSimpleLit;
  41. s_ShaderTagValues[2] = s_ShaderTagUnlit;
  42. s_ShaderTagValues[3] = s_ShaderTagComplexLit;
  43. s_ShaderTagValues[4] = new ShaderTagId(); // Special catch all case for materials where UniversalMaterialType is not defined or the tag value doesn't match anything we know.
  44. }
  45. if (s_RenderStateBlocks == null)
  46. {
  47. s_RenderStateBlocks = new RenderStateBlock[5];
  48. s_RenderStateBlocks[0] = DeferredLights.OverwriteStencil(m_RenderStateBlock, (int)StencilUsage.MaterialMask, (int)StencilUsage.MaterialLit);
  49. s_RenderStateBlocks[1] = DeferredLights.OverwriteStencil(m_RenderStateBlock, (int)StencilUsage.MaterialMask, (int)StencilUsage.MaterialSimpleLit);
  50. s_RenderStateBlocks[2] = DeferredLights.OverwriteStencil(m_RenderStateBlock, (int)StencilUsage.MaterialMask, (int)StencilUsage.MaterialUnlit);
  51. s_RenderStateBlocks[3] = DeferredLights.OverwriteStencil(m_RenderStateBlock, (int)StencilUsage.MaterialMask, (int)StencilUsage.MaterialUnlit); // Fill GBuffer, but skip lighting pass for ComplexLit
  52. s_RenderStateBlocks[4] = s_RenderStateBlocks[0];
  53. }
  54. }
  55. public void Dispose()
  56. {
  57. m_DeferredLights?.ReleaseGbufferResources();
  58. }
  59. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  60. public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
  61. {
  62. RTHandle[] gbufferAttachments = m_DeferredLights.GbufferAttachments;
  63. if (cmd != null)
  64. {
  65. var allocateGbufferDepth = true;
  66. if (m_DeferredLights.UseFramebufferFetch && (m_DeferredLights.DepthCopyTexture != null && m_DeferredLights.DepthCopyTexture.rt != null))
  67. {
  68. m_DeferredLights.GbufferAttachments[m_DeferredLights.GbufferDepthIndex] = m_DeferredLights.DepthCopyTexture;
  69. allocateGbufferDepth = false;
  70. }
  71. // Create and declare the render targets used in the pass
  72. for (int i = 0; i < gbufferAttachments.Length; ++i)
  73. {
  74. // Lighting buffer has already been declared with line ConfigureCameraTarget(m_ActiveCameraColorAttachment.Identifier(), ...) in DeferredRenderer.Setup
  75. if (i == m_DeferredLights.GBufferLightingIndex)
  76. continue;
  77. // Normal buffer may have already been created if there was a depthNormal prepass before.
  78. // DepthNormal prepass is needed for forward-only materials when SSAO is generated between gbuffer and deferred lighting pass.
  79. if (i == m_DeferredLights.GBufferNormalSmoothnessIndex && m_DeferredLights.HasNormalPrepass)
  80. continue;
  81. if (i == m_DeferredLights.GbufferDepthIndex && !allocateGbufferDepth)
  82. continue;
  83. // No need to setup temporaryRTs if we are using input attachments as they will be Memoryless
  84. if (m_DeferredLights.UseFramebufferFetch && (i != m_DeferredLights.GbufferDepthIndex && !m_DeferredLights.HasDepthPrepass))
  85. continue;
  86. m_DeferredLights.ReAllocateGBufferIfNeeded(cameraTextureDescriptor, i);
  87. cmd.SetGlobalTexture(m_DeferredLights.GbufferAttachments[i].name, m_DeferredLights.GbufferAttachments[i].nameID);
  88. }
  89. }
  90. if (m_DeferredLights.UseFramebufferFetch)
  91. m_DeferredLights.UpdateDeferredInputAttachments();
  92. // Disable obsolete warning for internal usage
  93. #pragma warning disable CS0618
  94. ConfigureTarget(m_DeferredLights.GbufferAttachments, m_DeferredLights.DepthAttachment, m_DeferredLights.GbufferFormats);
  95. // We must explicitly specify we don't want any clear to avoid unwanted side-effects.
  96. // ScriptableRenderer will implicitly force a clear the first time the camera color/depth targets are bound.
  97. ConfigureClear(ClearFlag.None, Color.black);
  98. #pragma warning restore CS0618
  99. }
  100. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  101. public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
  102. {
  103. ContextContainer frameData = renderingData.frameData;
  104. UniversalRenderingData universalRenderingData = frameData.Get<UniversalRenderingData>();
  105. UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
  106. UniversalLightData lightData = frameData.Get<UniversalLightData>();
  107. m_PassData.deferredLights = m_DeferredLights;
  108. InitRendererLists(ref m_PassData, context, default(RenderGraph), universalRenderingData, cameraData, lightData, false);
  109. var cmd = renderingData.commandBuffer;
  110. using (new ProfilingScope(cmd, profilingSampler))
  111. {
  112. #if UNITY_EDITOR
  113. // Need to clear the bounded targets to get scene-view filtering working.
  114. if (CoreUtils.IsSceneFilteringEnabled() && cameraData.camera.sceneViewFilterMode == Camera.SceneViewFilterMode.ShowFiltered)
  115. cmd.ClearRenderTarget(RTClearFlags.Color, Color.clear);
  116. #endif
  117. ExecutePass(CommandBufferHelpers.GetRasterCommandBuffer(cmd), m_PassData, m_PassData.rendererList, m_PassData.objectsWithErrorRendererList);
  118. // If any sub-system needs camera normal texture, make it available.
  119. // Input attachments will only be used when this is not needed so safe to skip in that case
  120. if (!m_DeferredLights.UseFramebufferFetch)
  121. renderingData.commandBuffer.SetGlobalTexture(s_CameraNormalsTextureID, m_DeferredLights.GbufferAttachments[m_DeferredLights.GBufferNormalSmoothnessIndex]);
  122. }
  123. }
  124. static void ExecutePass(RasterCommandBuffer cmd, PassData data, RendererList rendererList, RendererList errorRendererList)
  125. {
  126. bool usesRenderingLayers = data.deferredLights.UseRenderingLayers && !data.deferredLights.HasRenderingLayerPrepass;
  127. if (usesRenderingLayers)
  128. cmd.SetKeyword(ShaderGlobalKeywords.WriteRenderingLayers, true);
  129. if (data.deferredLights.IsOverlay)
  130. data.deferredLights.ClearStencilPartial(cmd);
  131. cmd.DrawRendererList(rendererList);
  132. // Render objects that did not match any shader pass with error shader
  133. RenderingUtils.DrawRendererListObjectsWithError(cmd, ref errorRendererList);
  134. // Clean up
  135. if (usesRenderingLayers)
  136. cmd.SetKeyword(ShaderGlobalKeywords.WriteRenderingLayers, false);
  137. }
  138. /// <summary>
  139. /// Shared pass data
  140. /// </summary>
  141. private class PassData
  142. {
  143. internal TextureHandle[] gbuffer;
  144. internal TextureHandle depth;
  145. internal DeferredLights deferredLights;
  146. internal RendererListHandle rendererListHdl;
  147. internal RendererListHandle objectsWithErrorRendererListHdl;
  148. // Required for code sharing purpose between RG and non-RG.
  149. internal RendererList rendererList;
  150. internal RendererList objectsWithErrorRendererList;
  151. }
  152. private void InitRendererLists( ref PassData passData, ScriptableRenderContext context, RenderGraph renderGraph, UniversalRenderingData renderingData, UniversalCameraData cameraData, UniversalLightData lightData, bool useRenderGraph)
  153. {
  154. // User can stack several scriptable renderers during rendering but deferred renderer should only lit pixels added by this gbuffer pass.
  155. // If we detect we are in such case (camera is in overlay mode), we clear the highest bits of stencil we have control of and use them to
  156. // mark what pixel to shade during deferred pass. Gbuffer will always mark pixels using their material types.
  157. ShaderTagId lightModeTag = s_ShaderTagUniversalGBuffer;
  158. var drawingSettings = CreateDrawingSettings(lightModeTag, renderingData, cameraData, lightData, cameraData.defaultOpaqueSortFlags);
  159. var filterSettings = m_FilteringSettings;
  160. NativeArray<ShaderTagId> tagValues = new NativeArray<ShaderTagId>(s_ShaderTagValues, Allocator.Temp);
  161. NativeArray<RenderStateBlock> stateBlocks = new NativeArray<RenderStateBlock>(s_RenderStateBlocks, Allocator.Temp);
  162. var param = new RendererListParams(renderingData.cullResults, drawingSettings, filterSettings)
  163. {
  164. tagValues = tagValues,
  165. stateBlocks = stateBlocks,
  166. tagName = s_ShaderTagUniversalMaterialType,
  167. isPassTagName = false
  168. };
  169. if (useRenderGraph)
  170. {
  171. passData.rendererListHdl = renderGraph.CreateRendererList(param);
  172. }
  173. else
  174. {
  175. passData.rendererList = context.CreateRendererList(ref param);
  176. }
  177. tagValues.Dispose();
  178. stateBlocks.Dispose();
  179. if (useRenderGraph)
  180. {
  181. RenderingUtils.CreateRendererListObjectsWithError(renderGraph, ref renderingData.cullResults, cameraData.camera, filterSettings, SortingCriteria.None, ref passData.objectsWithErrorRendererListHdl);
  182. }
  183. else
  184. {
  185. RenderingUtils.CreateRendererListObjectsWithError(context, ref renderingData.cullResults, cameraData.camera, filterSettings, SortingCriteria.None, ref passData.objectsWithErrorRendererList);
  186. }
  187. }
  188. internal void Render(RenderGraph renderGraph, ContextContainer frameData, TextureHandle cameraColor, TextureHandle cameraDepth)
  189. {
  190. UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();
  191. UniversalRenderingData renderingData = frameData.Get<UniversalRenderingData>();
  192. UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
  193. UniversalLightData lightData = frameData.Get<UniversalLightData>();
  194. TextureHandle[] gbuffer;
  195. using (var builder = renderGraph.AddRasterRenderPass<PassData>(profilingSampler.name, out var passData,profilingSampler))
  196. {
  197. // Note: This code is pretty confusing as passData.gbuffer[i] and gbuffer[i] actually point to the same array but seem to be mixed in this code.
  198. passData.gbuffer = gbuffer = m_DeferredLights.GbufferTextureHandles;
  199. for (int i = 0; i < m_DeferredLights.GBufferSliceCount; i++)
  200. {
  201. var gbufferSlice = cameraData.cameraTargetDescriptor;
  202. gbufferSlice.depthBufferBits = 0; // make sure no depth surface is actually created
  203. gbufferSlice.stencilFormat = GraphicsFormat.None;
  204. if (i == m_DeferredLights.GBufferNormalSmoothnessIndex && m_DeferredLights.HasNormalPrepass)
  205. gbuffer[i] = resourceData.cameraNormalsTexture;
  206. else if (m_DeferredLights.UseRenderingLayers && i == m_DeferredLights.GBufferRenderingLayers && !m_DeferredLights.UseLightLayers)
  207. gbuffer[i] = resourceData.renderingLayersTexture;
  208. else if (i != m_DeferredLights.GBufferLightingIndex)
  209. {
  210. gbufferSlice.graphicsFormat = m_DeferredLights.GetGBufferFormat(i);
  211. gbuffer[i] = UniversalRenderer.CreateRenderGraphTexture(renderGraph, gbufferSlice, DeferredLights.k_GBufferNames[i], true);
  212. }
  213. else
  214. gbuffer[i] = cameraColor;
  215. // Note: We don't store the returned handle here it is a versioned handle.
  216. // In general it should be fine to use unversioned handles anyway especially unversioned resources
  217. // should be registered in the frame data
  218. builder.SetRenderAttachment(gbuffer[i], i, AccessFlags.Write);
  219. }
  220. RenderGraphUtils.UseDBufferIfValid(builder, resourceData);
  221. resourceData.gBuffer = gbuffer;
  222. passData.depth = cameraDepth;
  223. builder.SetRenderAttachmentDepth(cameraDepth, AccessFlags.Write);
  224. passData.deferredLights = m_DeferredLights;
  225. InitRendererLists(ref passData, default(ScriptableRenderContext), renderGraph, renderingData, cameraData, lightData, true);
  226. builder.UseRendererList(passData.rendererListHdl);
  227. builder.UseRendererList(passData.objectsWithErrorRendererListHdl);
  228. builder.AllowPassCulling(false);
  229. builder.AllowGlobalStateModification(true);
  230. builder.SetRenderFunc((PassData data, RasterGraphContext context) =>
  231. {
  232. ExecutePass(context.cmd, data, data.rendererListHdl, data.objectsWithErrorRendererListHdl);
  233. });
  234. }
  235. }
  236. }
  237. }