-
Notifications
You must be signed in to change notification settings - Fork 872
Expand file tree
/
Copy pathHDRenderPipeline.RenderGraph.cs
More file actions
2108 lines (1784 loc) · 118 KB
/
HDRenderPipeline.RenderGraph.cs
File metadata and controls
2108 lines (1784 loc) · 118 KB
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
using System;
using System.Collections.Generic;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.RenderGraphModule;
using UnityEngine.VFX;
using UnityEngine.Rendering.RendererUtils;
// Resove the ambiguity in the RendererList name (pick the in-engine version)
using RendererList = UnityEngine.Rendering.RendererList;
using RendererListDesc = UnityEngine.Rendering.RendererUtils.RendererListDesc;
namespace UnityEngine.Rendering.HighDefinition
{
public partial class HDRenderPipeline
{
// Needed only because of custom pass. See comment at ResolveMSAAColor.
TextureHandle m_NonMSAAColorBuffer;
// Used when the user wants to override the internal rendering format for the AOVs.
internal bool m_ShouldOverrideColorBufferFormat = false;
GraphicsFormat m_AOVGraphicsFormat = GraphicsFormat.None;
// Property used for transparent motion vector color mask - depends on presence of virtual texturing or not
int colorMaskTransparentVel;
int colorMaskAdditionalTarget;
void RecordRenderGraph(RenderRequest renderRequest,
AOVRequestData aovRequest,
List<RTHandle> aovBuffers,
List<RTHandle> aovCustomPassBuffers,
ScriptableRenderContext renderContext,
CommandBuffer commandBuffer)
{
using (new ProfilingScope(commandBuffer, ProfilingSampler.Get(HDProfileId.RecordRenderGraph)))
{
var hdCamera = renderRequest.hdCamera;
var camera = hdCamera.camera;
var cullingResults = renderRequest.cullingResults.cullingResults;
var customPassCullingResults = renderRequest.cullingResults.customPassCullingResults ?? cullingResults;
bool msaa = hdCamera.msaaEnabled;
var target = renderRequest.target;
//Set resolution group for the entire frame
SetCurrentResolutionGroup(m_RenderGraph, hdCamera, ResolutionGroup.BeforeDynamicResUpscale);
// Caution: We require sun light here as some skies use the sun light to render, it means that UpdateSkyEnvironment must be called after PrepareLightsForGPU.
// TODO: Try to arrange code so we can trigger this call earlier and use async compute here to run sky convolution during other passes (once we move convolution shader to compute).
if (!m_CurrentDebugDisplaySettings.IsMatcapViewEnabled(hdCamera))
m_SkyManager.UpdateEnvironment(m_RenderGraph, hdCamera, GetMainLight(), m_CurrentDebugDisplaySettings);
// We need to initialize the MipChainInfo here, so it will be available to any render graph pass that wants to use it during setup
// Be careful, ComputePackedMipChainInfo needs the render texture size and not the viewport size. Otherwise it would compute the wrong size.
hdCamera.depthBufferMipChainInfo.ComputePackedMipChainInfo(RTHandles.rtHandleProperties.currentRenderTargetSize);
// Bind the depth pyramid offset info for the HDSceneDepth node in ShaderGraph. This can be used by users in custom passes.
commandBuffer.SetGlobalBuffer(HDShaderIDs._DepthPyramidMipLevelOffsets, hdCamera.depthBufferMipChainInfo.GetOffsetBufferData(m_DepthPyramidMipLevelOffsetsBuffer));
#if UNITY_EDITOR
var showGizmos = camera.cameraType == CameraType.Game
|| camera.cameraType == CameraType.SceneView;
#endif
// Set the default color buffer format for full screen debug rendering
GraphicsFormat fullScreenDebugFormat = GraphicsFormat.R16G16B16A16_SFloat;
if (aovRequest.isValid && aovRequest.overrideRenderFormat)
{
// If we are going to output AOVs, then override the debug format from the user-provided buffers
aovRequest.OverrideBufferFormatForAOVs(ref fullScreenDebugFormat, aovBuffers);
// Also override the internal rendering format (this would affect all calls to GetColorBufferFormat)
m_ShouldOverrideColorBufferFormat = true;
m_AOVGraphicsFormat = (GraphicsFormat)m_Asset.currentPlatformRenderPipelineSettings.colorBufferFormat;
aovRequest.OverrideBufferFormatForAOVs(ref m_AOVGraphicsFormat, aovBuffers);
}
else
{
m_ShouldOverrideColorBufferFormat = false;
}
UpdateParentExposure(m_RenderGraph, hdCamera);
TextureHandle backBuffer = m_RenderGraph.ImportBackbuffer(target.id);
TextureHandle colorBuffer = CreateColorBuffer(m_RenderGraph, hdCamera, msaa, true);
m_NonMSAAColorBuffer = CreateColorBuffer(m_RenderGraph, hdCamera, false);
TextureHandle currentColorPyramid = m_RenderGraph.ImportTexture(hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ColorBufferMipChain));
TextureHandle rayCountTexture = RayCountManager.CreateRayCountTexture(m_RenderGraph);
#if ENABLE_VIRTUALTEXTURES
TextureHandle vtFeedbackBuffer = VTBufferManager.CreateVTFeedbackBuffer(m_RenderGraph, hdCamera.msaaSamples);
bool resolveVirtualTextureFeedback = true;
#else
TextureHandle vtFeedbackBuffer = TextureHandle.nullHandle;
#endif
// Evaluate the ray tracing acceleration structure debug views
EvaluateRTASDebugView(m_RenderGraph, hdCamera);
LightingBuffers lightingBuffers = new LightingBuffers();
lightingBuffers.diffuseLightingBuffer = CreateDiffuseLightingBuffer(m_RenderGraph, hdCamera.msaaSamples);
lightingBuffers.sssBuffer = CreateSSSBuffer(m_RenderGraph, hdCamera, hdCamera.msaaSamples);
var prepassOutput = RenderPrepass(m_RenderGraph, colorBuffer, lightingBuffers.sssBuffer, vtFeedbackBuffer, cullingResults, customPassCullingResults, hdCamera, aovRequest, aovBuffers);
// Need this during debug render at the end outside of the main loop scope.
// Once render graph move is implemented, we can probably remove the branch and this.
ShadowResult shadowResult = new ShadowResult();
BuildGPULightListOutput gpuLightListOutput = new BuildGPULightListOutput();
TextureHandle uiBuffer = m_RenderGraph.defaultResources.blackTextureXR;
TextureHandle sunOcclusionTexture = m_RenderGraph.defaultResources.whiteTexture;
// Volume components
PathTracing pathTracing = hdCamera.volumeStack.GetComponent<PathTracing>();
if (m_CurrentDebugDisplaySettings.IsDebugDisplayEnabled() && m_CurrentDebugDisplaySettings.IsFullScreenDebugPassEnabled())
{
// Stop Single Pass is after post process.
StartXRSinglePass(m_RenderGraph, hdCamera);
RenderFullScreenDebug(m_RenderGraph, colorBuffer, prepassOutput.depthBuffer, cullingResults, hdCamera);
#if ENABLE_VIRTUALTEXTURES
resolveVirtualTextureFeedback = false; // Could be handled but not needed for fullscreen debug pass currently
#endif
}
else if (m_CurrentDebugDisplaySettings.IsDebugMaterialDisplayEnabled() || m_CurrentDebugDisplaySettings.IsMaterialValidationEnabled() || CoreUtils.IsSceneLightingDisabled(hdCamera.camera))
{
gpuLightListOutput = BuildGPULightList(m_RenderGraph, hdCamera, m_TileAndClusterData, m_TotalLightCount, ref m_ShaderVariablesLightListCB, prepassOutput.depthBuffer, prepassOutput.stencilBuffer, prepassOutput.gbuffer);
// For alpha output in AOVs or debug views, in case we have a shadow matte material, we need to render the shadow maps
if (m_CurrentDebugDisplaySettings.data.materialDebugSettings.debugViewMaterialCommonValue == Attributes.MaterialSharedProperty.Alpha)
RenderShadows(m_RenderGraph, hdCamera, cullingResults, ref shadowResult);
else
HDShadowManager.BindDefaultShadowGlobalResources(m_RenderGraph);
// Stop Single Pass is after post process.
StartXRSinglePass(m_RenderGraph, hdCamera);
colorBuffer = RenderDebugViewMaterial(m_RenderGraph, cullingResults, hdCamera, gpuLightListOutput, prepassOutput.dbuffer, prepassOutput.gbuffer, prepassOutput.depthBuffer, vtFeedbackBuffer);
colorBuffer = ResolveMSAAColor(m_RenderGraph, hdCamera, colorBuffer);
}
else if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) && pathTracing.enable.value && hdCamera.camera.cameraType != CameraType.Preview && GetRayTracingState() && GetRayTracingClusterState())
{
//// We only request the light cluster if we are gonna use it for debug mode
//if (FullScreenDebugMode.LightCluster == m_CurrentDebugDisplaySettings.data.fullScreenDebugMode && GetRayTracingClusterState())
//{
// HDRaytracingLightCluster lightCluster = RequestLightCluster();
// lightCluster.EvaluateClusterDebugView(cmd, hdCamera);
//}
if (hdCamera.viewCount == 1)
{
colorBuffer = RenderPathTracing(m_RenderGraph, hdCamera, colorBuffer);
}
else
{
Debug.LogWarning("Path Tracing is not supported with XR single-pass rendering.");
}
#if ENABLE_VIRTUALTEXTURES
resolveVirtualTextureFeedback = false;
#endif
}
else
{
gpuLightListOutput = BuildGPULightList(m_RenderGraph, hdCamera, m_TileAndClusterData, m_TotalLightCount, ref m_ShaderVariablesLightListCB, prepassOutput.depthBuffer, prepassOutput.stencilBuffer, prepassOutput.gbuffer);
// Evaluate the history validation buffer that may be required by temporal accumulation based effects
TextureHandle historyValidationTexture = EvaluateHistoryValidationBuffer(m_RenderGraph, hdCamera, prepassOutput.depthBuffer, prepassOutput.resolvedNormalBuffer, prepassOutput.resolvedMotionVectorsBuffer);
lightingBuffers.ambientOcclusionBuffer = RenderAmbientOcclusion(m_RenderGraph, hdCamera, prepassOutput.depthBuffer, prepassOutput.depthPyramidTexture, prepassOutput.resolvedNormalBuffer, prepassOutput.resolvedMotionVectorsBuffer, historyValidationTexture, hdCamera.depthBufferMipChainInfo, m_ShaderVariablesRayTracingCB, rayCountTexture);
lightingBuffers.contactShadowsBuffer = RenderContactShadows(m_RenderGraph, hdCamera, msaa ? prepassOutput.depthValuesMSAA : prepassOutput.depthPyramidTexture, gpuLightListOutput, hdCamera.depthBufferMipChainInfo.mipLevelOffsets[1].y);
var volumetricDensityBuffer = ClearAndHeightFogVoxelizationPass(m_RenderGraph, hdCamera);
RenderShadows(m_RenderGraph, hdCamera, cullingResults, ref shadowResult);
StartXRSinglePass(m_RenderGraph, hdCamera);
// Evaluate the clear coat mask texture based on the lit shader mode
var clearCoatMask = hdCamera.frameSettings.litShaderMode == LitShaderMode.Deferred ? prepassOutput.gbuffer.mrt[2] : m_RenderGraph.defaultResources.blackTextureXR;
lightingBuffers.ssrLightingBuffer = RenderSSR(m_RenderGraph, hdCamera, ref prepassOutput, clearCoatMask, rayCountTexture, m_SkyManager.GetSkyReflection(hdCamera), transparent: false);
lightingBuffers.ssgiLightingBuffer = RenderScreenSpaceIndirectDiffuse(hdCamera, prepassOutput, rayCountTexture, historyValidationTexture, gpuLightListOutput.lightList);
if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) && GetRayTracingClusterState())
{
HDRaytracingLightCluster lightCluster = RequestLightCluster();
lightCluster.EvaluateClusterDebugView(m_RenderGraph, hdCamera, prepassOutput.depthBuffer, prepassOutput.depthPyramidTexture);
}
lightingBuffers.screenspaceShadowBuffer = RenderScreenSpaceShadows(m_RenderGraph, hdCamera, prepassOutput, prepassOutput.depthBuffer, prepassOutput.normalBuffer, prepassOutput.motionVectorsBuffer, historyValidationTexture, rayCountTexture);
var maxZMask = GenerateMaxZPass(m_RenderGraph, hdCamera, prepassOutput.depthPyramidTexture, hdCamera.depthBufferMipChainInfo);
volumetricDensityBuffer = FogVolumeVoxelizationPass(m_RenderGraph, hdCamera, volumetricDensityBuffer, m_VisibleVolumeBoundsBuffer);
var volumetricLighting = VolumetricLightingPass(m_RenderGraph, hdCamera, prepassOutput.depthPyramidTexture, volumetricDensityBuffer, maxZMask, gpuLightListOutput.bigTileLightList, shadowResult);
var deferredLightingOutput = RenderDeferredLighting(m_RenderGraph, hdCamera, colorBuffer, prepassOutput.depthBuffer, prepassOutput.depthPyramidTexture, lightingBuffers, prepassOutput.gbuffer, shadowResult, gpuLightListOutput);
ApplyCameraMipBias(hdCamera);
RenderForwardOpaque(m_RenderGraph, hdCamera, colorBuffer, lightingBuffers, gpuLightListOutput, prepassOutput, vtFeedbackBuffer, shadowResult, cullingResults);
ResetCameraMipBias(hdCamera);
if (aovRequest.isValid)
aovRequest.PushCameraTexture(m_RenderGraph, AOVBuffers.Normals, hdCamera, prepassOutput.resolvedNormalBuffer, aovBuffers);
RenderSubsurfaceScattering(m_RenderGraph, hdCamera, colorBuffer, historyValidationTexture, ref lightingBuffers, ref prepassOutput);
var depthTexture = msaa ? prepassOutput.depthAsColor : prepassOutput.depthPyramidTexture;
RenderSky(m_RenderGraph, hdCamera, colorBuffer, volumetricLighting, prepassOutput.depthBuffer, depthTexture);
RenderCustomPass(m_RenderGraph, hdCamera, colorBuffer, prepassOutput, customPassCullingResults, cullingResults, CustomPassInjectionPoint.AfterOpaqueAndSky, aovRequest, aovCustomPassBuffers);
DoUserAfterOpaqueAndSky(m_RenderGraph, hdCamera, colorBuffer, prepassOutput.resolvedDepthBuffer, prepassOutput.resolvedNormalBuffer, prepassOutput.resolvedMotionVectorsBuffer);
m_SkyManager.RenderOpaqueAtmosphericScattering(m_RenderGraph, hdCamera, colorBuffer, depthTexture, volumetricLighting, prepassOutput.depthBuffer);
sunOcclusionTexture = RenderVolumetricClouds(m_RenderGraph, hdCamera, colorBuffer, prepassOutput.depthPyramidTexture, prepassOutput.motionVectorsBuffer, volumetricLighting, maxZMask);
// Send all the geometry graphics buffer to client systems if required (must be done after the pyramid and before the transparent depth pre-pass)
SendGeometryGraphicsBuffers(m_RenderGraph, prepassOutput.normalBuffer, prepassOutput.depthPyramidTexture, hdCamera);
// No need for old stencil values here since from transparent on different features are tagged
ClearStencilBuffer(m_RenderGraph, hdCamera, prepassOutput.depthBuffer);
colorBuffer = RenderTransparency(m_RenderGraph, hdCamera, colorBuffer, prepassOutput.resolvedNormalBuffer, vtFeedbackBuffer, currentColorPyramid, volumetricLighting, rayCountTexture, m_SkyManager.GetSkyReflection(hdCamera), gpuLightListOutput, ref prepassOutput,
shadowResult, cullingResults, customPassCullingResults, aovRequest, aovCustomPassBuffers);
uiBuffer = RenderTransparentUI(m_RenderGraph, hdCamera);
if (NeedMotionVectorForTransparent(hdCamera.frameSettings))
{
prepassOutput.resolvedMotionVectorsBuffer = ResolveMotionVector(m_RenderGraph, hdCamera, prepassOutput.motionVectorsBuffer);
}
// We push the motion vector debug texture here as transparent object can overwrite the motion vector texture content.
if (m_Asset.currentPlatformRenderPipelineSettings.supportMotionVectors)
PushFullScreenDebugTexture(m_RenderGraph, prepassOutput.resolvedMotionVectorsBuffer, FullScreenDebugMode.MotionVectors, fullScreenDebugFormat);
// Transparent objects may write to the depth and motion vectors buffers.
if (aovRequest.isValid)
{
aovRequest.PushCameraTexture(m_RenderGraph, AOVBuffers.DepthStencil, hdCamera, prepassOutput.resolvedDepthBuffer, aovBuffers);
if (m_Asset.currentPlatformRenderPipelineSettings.supportMotionVectors)
aovRequest.PushCameraTexture(m_RenderGraph, AOVBuffers.MotionVectors, hdCamera, prepassOutput.resolvedMotionVectorsBuffer, aovBuffers);
}
var distortionRendererList = m_RenderGraph.CreateRendererList(CreateTransparentRendererListDesc(cullingResults, hdCamera.camera, HDShaderPassNames.s_DistortionVectorsName));
// This final Gaussian pyramid can be reused by SSR, so disable it only if there is no distortion
if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.Distortion) && hdCamera.frameSettings.IsEnabled(FrameSettingsField.RoughDistortion))
{
TextureHandle distortionColorPyramid = m_RenderGraph.CreateTexture(
new TextureDesc(Vector2.one, true, true)
{
colorFormat = GetColorBufferFormat(),
enableRandomWrite = true,
useMipMap = true,
autoGenerateMips = false,
name = "DistortionColorBufferMipChain"
});
GenerateColorPyramid(m_RenderGraph, hdCamera, colorBuffer, distortionColorPyramid, FullScreenDebugMode.PreRefractionColorPyramid, distortionRendererList);
currentColorPyramid = distortionColorPyramid;
// The color pyramid for distortion is not an history, so it need to be sampled appropriate RT handle scale. Thus we need to update it
var newScale = new Vector4(RTHandles.rtHandleProperties.rtHandleScale.x, RTHandles.rtHandleProperties.rtHandleScale.y, 0, 0);
m_ShaderVariablesGlobalCB._ColorPyramidUvScaleAndLimitCurrentFrame = newScale;
PushGlobalCameraParams(m_RenderGraph, hdCamera);
}
using (new RenderGraphProfilingScope(m_RenderGraph, ProfilingSampler.Get(HDProfileId.Distortion)))
{
var distortionBuffer = AccumulateDistortion(m_RenderGraph, hdCamera, prepassOutput.resolvedDepthBuffer, distortionRendererList);
RenderDistortion(m_RenderGraph, hdCamera, colorBuffer, prepassOutput.resolvedDepthBuffer, currentColorPyramid, distortionBuffer, distortionRendererList);
}
PushFullScreenDebugTexture(m_RenderGraph, colorBuffer, FullScreenDebugMode.NanTracker, fullScreenDebugFormat);
PushFullScreenDebugTexture(m_RenderGraph, colorBuffer, FullScreenDebugMode.WorldSpacePosition, fullScreenDebugFormat);
PushFullScreenLightingDebugTexture(m_RenderGraph, colorBuffer, fullScreenDebugFormat);
bool accumulateInPost = m_PostProcessEnabled && m_DepthOfField.IsActive();
if (!accumulateInPost && m_SubFrameManager.isRecording && m_SubFrameManager.subFrameCount > 1)
{
RenderAccumulation(m_RenderGraph, hdCamera, colorBuffer, colorBuffer, null, false);
}
// Render gizmos that should be affected by post processes
RenderGizmos(m_RenderGraph, hdCamera, GizmoSubset.PreImageEffects);
}
#if ENABLE_VIRTUALTEXTURES
//Check debug data to see if user disabled streaming.
if (HDDebugDisplaySettings.Instance != null && HDDebugDisplaySettings.Instance.vtSettings.data.debugDisableResolving)
resolveVirtualTextureFeedback = false;
// Note: This pass rely on availability of vtFeedbackBuffer buffer (i.e it need to be write before we read it here)
// We don't write it when FullScreenDebug mode or path tracer.
if (resolveVirtualTextureFeedback)
{
hdCamera.ResolveVirtualTextureFeedback(m_RenderGraph, vtFeedbackBuffer);
PushFullScreenVTFeedbackDebugTexture(m_RenderGraph, vtFeedbackBuffer, msaa);
}
#endif
// At this point, the color buffer has been filled by either debug views are regular rendering so we can push it here.
var colorPickerTexture = PushColorPickerDebugTexture(m_RenderGraph, colorBuffer);
RenderCustomPass(m_RenderGraph, hdCamera, colorBuffer, prepassOutput, customPassCullingResults, cullingResults, CustomPassInjectionPoint.BeforePostProcess, aovRequest, aovCustomPassBuffers);
if (aovRequest.isValid)
{
aovRequest.PushCameraTexture(m_RenderGraph, AOVBuffers.Color, hdCamera, colorBuffer, aovBuffers);
}
bool postProcessIsFinalPass = HDUtils.PostProcessIsFinalPass(hdCamera, aovRequest);
TextureHandle afterPostProcessBuffer = RenderAfterPostProcessObjects(m_RenderGraph, hdCamera, pathTracing, cullingResults, prepassOutput);
var postProcessTargetFace = postProcessIsFinalPass ? target.face : CubemapFace.Unknown;
TextureHandle postProcessDest = RenderPostProcess(m_RenderGraph, prepassOutput, colorBuffer, backBuffer, uiBuffer, afterPostProcessBuffer, sunOcclusionTexture, cullingResults, hdCamera, postProcessTargetFace, postProcessIsFinalPass);
var xyMapping = GenerateDebugHDRxyMapping(m_RenderGraph, hdCamera, postProcessDest);
GenerateDebugImageHistogram(m_RenderGraph, hdCamera, postProcessDest);
PushFullScreenExposureDebugTexture(m_RenderGraph, postProcessDest, fullScreenDebugFormat);
PushFullScreenHDRDebugTexture(m_RenderGraph, postProcessDest, fullScreenDebugFormat);
ResetCameraSizeForAfterPostProcess(m_RenderGraph, hdCamera, commandBuffer);
RenderCustomPass(m_RenderGraph, hdCamera, postProcessDest, prepassOutput, customPassCullingResults, cullingResults, CustomPassInjectionPoint.AfterPostProcess, aovRequest, aovCustomPassBuffers);
CopyXRDepth(m_RenderGraph, hdCamera, prepassOutput.resolvedDepthBuffer, backBuffer);
// In developer build, we always render post process in an intermediate buffer at (0,0) in which we will then render debug.
// Because of this, we need another blit here to the final render target at the right viewport.
if (!postProcessIsFinalPass)
{
hdCamera.ExecuteCaptureActions(m_RenderGraph, postProcessDest);
postProcessDest = RenderDebug(m_RenderGraph,
hdCamera,
postProcessDest,
prepassOutput.resolvedDepthBuffer,
prepassOutput.depthPyramidTexture,
colorPickerTexture,
rayCountTexture,
xyMapping,
gpuLightListOutput,
shadowResult,
cullingResults,
fullScreenDebugFormat);
StopXRSinglePass(m_RenderGraph, hdCamera);
for (int viewIndex = 0; viewIndex < hdCamera.viewCount; ++viewIndex)
{
BlitFinalCameraTexture(m_RenderGraph, hdCamera, postProcessDest, backBuffer, uiBuffer, afterPostProcessBuffer, viewIndex, HDROutputActiveForCameraType(hdCamera), target.face);
}
if (aovRequest.isValid)
aovRequest.PushCameraTexture(m_RenderGraph, AOVBuffers.Output, hdCamera, postProcessDest, aovBuffers);
}
// This code is only for planar reflections. Given that the depth texture cannot be shared currently with the other depth copy that we do
// we need to do this separately.
for (int viewIndex = 0; viewIndex < hdCamera.viewCount; ++viewIndex)
{
if (target.targetDepth != null)
{
BlitFinalCameraTexture(m_RenderGraph, hdCamera, prepassOutput.resolvedDepthBuffer, m_RenderGraph.ImportTexture(target.targetDepth), uiBuffer, afterPostProcessBuffer, viewIndex, outputsToHDR: false, cubemapFace: target.face);
}
}
SendColorGraphicsBuffer(m_RenderGraph, hdCamera);
SetFinalTarget(m_RenderGraph, hdCamera, prepassOutput.resolvedDepthBuffer, backBuffer, target.face);
RenderWireOverlay(m_RenderGraph, hdCamera, backBuffer);
RenderGizmos(m_RenderGraph, hdCamera, GizmoSubset.PostImageEffects);
// Stop XR single pass before rendering screenspace UI
StopXRSinglePass(m_RenderGraph, hdCamera);
RenderScreenSpaceOverlayUI(m_RenderGraph, hdCamera, backBuffer);
}
}
void ExecuteWithRenderGraph(RenderRequest renderRequest,
AOVRequestData aovRequest,
List<RTHandle> aovBuffers,
List<RTHandle> aovCustomPassBuffers,
ScriptableRenderContext renderContext,
CommandBuffer commandBuffer)
{
using (m_RenderGraph.RecordAndExecute(new RenderGraphParameters
{
executionName = renderRequest.hdCamera.name,
currentFrameIndex = m_FrameCount,
rendererListCulling = m_GlobalSettings.rendererListCulling,
scriptableRenderContext = renderContext,
commandBuffer = commandBuffer
}))
{
RecordRenderGraph(
renderRequest, aovRequest, aovBuffers,
aovCustomPassBuffers, renderContext, commandBuffer);
}
if (aovRequest.isValid)
{
// aovRequest.Execute don't go through render graph for now
using (new ProfilingScope(commandBuffer, ProfilingSampler.Get(HDProfileId.AOVExecute)))
{
aovRequest.Execute(commandBuffer, aovBuffers, aovCustomPassBuffers, RenderOutputProperties.From(renderRequest.hdCamera));
}
}
}
class FinalBlitPassData
{
public bool flip;
public int srcTexArraySlice;
public int dstTexArraySlice;
public Rect viewport;
public Material blitMaterial;
public Vector4 hdrOutputParmeters;
public bool applyAfterPP;
public CubemapFace cubemapFace;
public TextureHandle uiTexture;
public TextureHandle afterPostProcessTexture;
public TextureHandle source;
public TextureHandle destination;
public ColorGamut colorGamut;
}
void BlitFinalCameraTexture(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle source, TextureHandle destination, TextureHandle uiTexture, TextureHandle afterPostProcessTexture, int viewIndex, bool outputsToHDR, CubemapFace cubemapFace)
{
using (var builder = renderGraph.AddRenderPass<FinalBlitPassData>("Final Blit (Dev Build Only)", out var passData))
{
if (hdCamera.xr.enabled)
{
passData.viewport = hdCamera.xr.GetViewport(viewIndex);
passData.srcTexArraySlice = viewIndex;
passData.dstTexArraySlice = hdCamera.xr.GetTextureArraySlice(viewIndex);
}
else
{
passData.viewport = hdCamera.finalViewport;
passData.srcTexArraySlice = -1;
passData.dstTexArraySlice = -1;
}
passData.flip = hdCamera.flipYMode == HDAdditionalCameraData.FlipYMode.ForceFlipY || hdCamera.isMainGameView;
passData.blitMaterial = HDUtils.GetBlitMaterial(TextureXR.useTexArray ? TextureDimension.Tex2DArray : TextureDimension.Tex2D, singleSlice: passData.srcTexArraySlice >= 0);
passData.source = builder.ReadTexture(source);
passData.afterPostProcessTexture = builder.ReadTexture(afterPostProcessTexture);
passData.destination = builder.WriteTexture(destination);
passData.applyAfterPP = false;
passData.cubemapFace = cubemapFace;
passData.colorGamut = outputsToHDR ? HDRDisplayColorGamutForCamera(hdCamera) : ColorGamut.sRGB;
if (outputsToHDR)
{
// Pick the right material based off XR rendering using texture arrays and if we are dealing with a single slice at the moment or processing all slices automatically.
passData.blitMaterial = (TextureXR.useTexArray && passData.srcTexArraySlice >= 0) ? m_FinalBlitWithOETFTexArraySingleSlice : m_FinalBlitWithOETF;
GetHDROutputParameters(HDRDisplayInformationForCamera(hdCamera), HDRDisplayColorGamutForCamera(hdCamera), m_Tonemapping, out passData.hdrOutputParmeters, out var unused);
passData.uiTexture = builder.ReadTexture(uiTexture);
passData.applyAfterPP = hdCamera.frameSettings.IsEnabled(FrameSettingsField.AfterPostprocess) && !NeedHDRDebugMode(m_CurrentDebugDisplaySettings);
}
else
{
passData.hdrOutputParmeters = new Vector4(-1.0f, -1.0f, -1.0f, -1.0f);
}
builder.SetRenderFunc(
(FinalBlitPassData data, RenderGraphContext context) =>
{
var propertyBlock = context.renderGraphPool.GetTempMaterialPropertyBlock();
RTHandle sourceTexture = data.source;
// We are in HDR mode so the final blit is different
if (data.hdrOutputParmeters.x >= 0)
{
data.blitMaterial.SetInt(HDShaderIDs._NeedsFlip, data.flip ? 1 : 0);
propertyBlock.SetTexture(HDShaderIDs._UITexture, data.uiTexture);
propertyBlock.SetTexture(HDShaderIDs._InputTexture, sourceTexture);
propertyBlock.SetVector(HDShaderIDs._HDROutputParams, data.hdrOutputParmeters);
propertyBlock.SetInt(HDShaderIDs._BlitTexArraySlice, data.srcTexArraySlice);
HDROutputUtils.ConfigureHDROutput(data.blitMaterial, data.colorGamut, HDROutputUtils.Operation.ColorEncoding);
if (data.applyAfterPP)
{
data.blitMaterial.EnableKeyword("APPLY_AFTER_POST");
data.blitMaterial.SetTexture(HDShaderIDs._AfterPostProcessTexture, data.afterPostProcessTexture);
}
else
{
data.blitMaterial.DisableKeyword("APPLY_AFTER_POST");
data.blitMaterial.SetTexture(HDShaderIDs._AfterPostProcessTexture, TextureXR.GetBlackTexture());
}
}
else
{
// Here we can't use the viewport scale provided in hdCamera. The reason is that this scale is for internal rendering before post process with dynamic resolution factored in.
// Here the input texture is already at the viewport size but may be smaller than the RT itself (because of the RTHandle system) so we compute the scale specifically here.
var scaleBias = new Vector4((float)data.viewport.width / sourceTexture.rt.width, (float)data.viewport.height / sourceTexture.rt.height, 0.0f, 0.0f);
if (data.flip)
{
scaleBias.w = scaleBias.y;
scaleBias.y *= -1;
}
propertyBlock.SetTexture(HDShaderIDs._BlitTexture, sourceTexture);
propertyBlock.SetVector(HDShaderIDs._BlitScaleBias, scaleBias);
propertyBlock.SetFloat(HDShaderIDs._BlitMipLevel, 0);
propertyBlock.SetInt(HDShaderIDs._BlitTexArraySlice, data.srcTexArraySlice);
}
HDUtils.DrawFullScreen(context.cmd, data.viewport, data.blitMaterial, data.destination, data.cubemapFace, propertyBlock, 0, data.dstTexArraySlice);
});
}
}
class UpdateParentExposureData
{
public HDCamera.ExposureTextures textures;
}
void UpdateParentExposure(RenderGraph renderGraph, HDCamera hdCamera)
{
var exposures = hdCamera.currentExposureTextures;
if (exposures.useCurrentCamera)
return;
using (var builder = renderGraph.AddRenderPass<UpdateParentExposureData>("UpdateParentExposures", out var passData))
{
passData.textures = exposures;
builder.SetRenderFunc(
(UpdateParentExposureData data, RenderGraphContext context) =>
{
if (data.textures.useFetchedExposure)
{
Color clearCol = new Color(data.textures.fetchedGpuExposure, ColorUtils.ConvertExposureToEV100(data.textures.fetchedGpuExposure), 0.0f, 0.0f);
context.cmd.SetRenderTarget(data.textures.current);
context.cmd.ClearRenderTarget(false, true, clearCol);
}
else
{
context.cmd.CopyTexture(data.textures.parent, data.textures.current);
}
});
}
}
void ApplyCameraMipBias(HDCamera hdCamera)
{
float globalMaterialMipBias = 0.0f;
if (m_CurrentDebugDisplaySettings != null && m_CurrentDebugDisplaySettings.data.UseDebugGlobalMipBiasOverride())
{
globalMaterialMipBias = m_CurrentDebugDisplaySettings.data.GetDebugGlobalMipBiasOverride();
}
else
{
globalMaterialMipBias = hdCamera.globalMipBias;
}
PushCameraGlobalMipBiasPass(m_RenderGraph, hdCamera, globalMaterialMipBias);
}
void ResetCameraMipBias(HDCamera hdCamera) => PushCameraGlobalMipBiasPass(m_RenderGraph, hdCamera, 0.0f);
class PushCameraGlobalMipBiasData
{
public HDCamera hdCamera;
public float mipBias;
public ShaderVariablesGlobal globalCB;
public ShaderVariablesXR xrCB;
}
void PushCameraGlobalMipBiasPass(RenderGraph renderGraph, HDCamera hdCamera, float mipBias)
{
if (!ShaderConfig.s_GlobalMipBias)
return;
using (var builder = renderGraph.AddRenderPass<PushCameraGlobalMipBiasData>("Push Global Camera Mip Bias", out var passData))
{
passData.hdCamera = hdCamera;
passData.mipBias = mipBias;
passData.globalCB = m_ShaderVariablesGlobalCB;
passData.xrCB = m_ShaderVariablesXRCB;
builder.SetRenderFunc(
(PushCameraGlobalMipBiasData data, RenderGraphContext context) =>
{
data.hdCamera.globalMipBias = data.mipBias;
data.hdCamera.UpdateShaderVariablesGlobalCB(ref data.globalCB);
ConstantBuffer.PushGlobal(context.cmd, data.globalCB, HDShaderIDs._ShaderVariablesGlobal);
data.hdCamera.UpdateShaderVariablesXRCB(ref data.xrCB);
ConstantBuffer.PushGlobal(context.cmd, data.xrCB, HDShaderIDs._ShaderVariablesXR);
});
}
}
class SetFinalTargetPassData
{
public bool copyDepth;
public Material copyDepthMaterial;
public TextureHandle finalTarget;
public CubemapFace finalTargetFace;
public Rect finalViewport;
public TextureHandle depthBuffer;
public bool flipY;
}
void SetFinalTarget(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle depthBuffer, TextureHandle finalTarget, CubemapFace finalTargetFace)
{
using (var builder = renderGraph.AddRenderPass<SetFinalTargetPassData>("Set Final Target", out var passData))
{
// Due to our RT handle system we don't write into the backbuffer depth buffer (as our depth buffer can be bigger than the one provided)
// So we need to do a copy of the corresponding part of RT depth buffer in the target depth buffer in various situation:
// - RenderTexture (camera.targetTexture != null) has a depth buffer (camera.targetTexture.depth != 0)
// - We are rendering into the main game view (i.e not a RenderTexture camera.cameraType == CameraType.Game && hdCamera.camera.targetTexture == null) in the editor for allowing usage of Debug.DrawLine and Debug.Ray.
// - We draw Gizmo/Icons in the editor (hdCamera.camera.targetTexture != null && camera.targetTexture.depth != 0 - The Scene view has a targetTexture and a depth texture)
// TODO: If at some point we get proper render target aliasing, we will be able to use the provided depth texture directly with our RT handle system
// Note: Debug.DrawLine and Debug.Ray only work in editor, not in player
passData.copyDepth = hdCamera.camera.targetTexture != null && hdCamera.camera.targetTexture.depth != 0;
#if UNITY_EDITOR
passData.copyDepth = passData.copyDepth || hdCamera.isMainGameView; // Specific case of Debug.DrawLine and Debug.Ray
#endif
passData.copyDepth = passData.copyDepth && !hdCamera.xr.enabled;
passData.finalTarget = builder.WriteTexture(finalTarget);
passData.finalTargetFace = finalTargetFace;
passData.finalViewport = hdCamera.finalViewport;
if (passData.copyDepth)
{
passData.depthBuffer = builder.ReadTexture(depthBuffer);
passData.flipY = hdCamera.isMainGameView || hdCamera.flipYMode == HDAdditionalCameraData.FlipYMode.ForceFlipY;
passData.copyDepthMaterial = m_CopyDepth;
}
builder.SetRenderFunc(
(SetFinalTargetPassData data, RenderGraphContext ctx) =>
{
// We need to make sure the viewport is correctly set for the editor rendering. It might have been changed by debug overlay rendering just before.
ctx.cmd.SetRenderTarget(data.finalTarget, 0, data.finalTargetFace);
ctx.cmd.SetViewport(data.finalViewport);
if (data.copyDepth)
{
using (new ProfilingScope(ctx.cmd, ProfilingSampler.Get(HDProfileId.CopyDepthInTargetTexture)))
{
var mpb = ctx.renderGraphPool.GetTempMaterialPropertyBlock();
RTHandle depth = data.depthBuffer;
// Depth buffer can be invalid if no opaque has been rendered before.
if (depth != null)
{
mpb.SetTexture(HDShaderIDs._InputDepth, depth);
// When we are Main Game View we need to flip the depth buffer ourselves as we are after postprocess / blit that have already flipped the screen
mpb.SetInt("_FlipY", data.flipY ? 1 : 0);
mpb.SetVector(HDShaderIDs._BlitScaleBias, new Vector4(1.0f, 1.0f, 0.0f, 0.0f));
CoreUtils.DrawFullScreen(ctx.cmd, data.copyDepthMaterial, mpb);
}
}
}
});
}
}
class CopyXRDepthPassData
{
public Material copyDepth;
public Rect viewport;
public TextureHandle depthBuffer;
public TextureHandle output;
public float dynamicResolutionScale;
}
void CopyXRDepth(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle depthBuffer, TextureHandle output)
{
// Copy and rescale depth buffer for XR devices
if (hdCamera.xr.enabled && hdCamera.xr.copyDepth)
{
using (var builder = renderGraph.AddRenderPass<CopyXRDepthPassData>("Copy XR Depth", out var passData, ProfilingSampler.Get(HDProfileId.XRDepthCopy)))
{
passData.copyDepth = m_CopyDepth;
passData.viewport = hdCamera.finalViewport;
passData.depthBuffer = builder.ReadTexture(depthBuffer);
passData.output = builder.WriteTexture(output);
passData.dynamicResolutionScale = DynamicResolutionHandler.instance.GetCurrentScale();
builder.SetRenderFunc(
(CopyXRDepthPassData data, RenderGraphContext ctx) =>
{
var mpb = ctx.renderGraphPool.GetTempMaterialPropertyBlock();
mpb.SetTexture(HDShaderIDs._InputDepth, data.depthBuffer);
mpb.SetVector(HDShaderIDs._BlitScaleBias, new Vector4(data.dynamicResolutionScale, data.dynamicResolutionScale, 0.0f, 0.0f));
mpb.SetInt("_FlipY", 1);
ctx.cmd.SetRenderTarget(data.output, 0, CubemapFace.Unknown, -1);
ctx.cmd.SetViewport(data.viewport);
CoreUtils.DrawFullScreen(ctx.cmd, data.copyDepth, mpb);
});
}
}
}
class ForwardPassData
{
public RendererListHandle rendererList;
public ComputeBufferHandle lightListTile;
public ComputeBufferHandle lightListCluster;
public ComputeBufferHandle perVoxelOffset;
public ComputeBufferHandle perTileLogBaseTweak;
public FrameSettings frameSettings;
}
class ForwardOpaquePassData : ForwardPassData
{
public DBufferOutput dbuffer;
public LightingBuffers lightingBuffers;
public bool enableDecals;
}
class ForwardTransparentPassData : ForwardPassData
{
public bool decalsEnabled;
public bool renderMotionVecForTransparent;
public int colorMaskTransparentVel;
public TextureHandle colorPyramid;
public TextureHandle transparentSSRLighting;
public TextureHandle volumetricLighting;
public TextureHandle depthPyramidTexture;
public TextureHandle normalBuffer;
}
void PrepareCommonForwardPassData(
RenderGraph renderGraph,
RenderGraphBuilder builder,
ForwardPassData data,
bool opaque,
FrameSettings frameSettings,
RendererListDesc rendererListDesc,
in BuildGPULightListOutput lightLists,
ShadowResult shadowResult)
{
bool useFptl = frameSettings.IsEnabled(FrameSettingsField.FPTLForForwardOpaque) && opaque;
data.frameSettings = frameSettings;
data.lightListTile = builder.ReadComputeBuffer(lightLists.lightList);
data.lightListCluster = builder.ReadComputeBuffer(lightLists.perVoxelLightLists);
if (!useFptl)
{
data.perVoxelOffset = builder.ReadComputeBuffer(lightLists.perVoxelOffset);
if (lightLists.perTileLogBaseTweak.IsValid())
data.perTileLogBaseTweak = builder.ReadComputeBuffer(lightLists.perTileLogBaseTweak);
}
else
{
data.perVoxelOffset = ComputeBufferHandle.nullHandle;
data.perTileLogBaseTweak = ComputeBufferHandle.nullHandle;
}
data.rendererList = builder.UseRendererList(renderGraph.CreateRendererList(rendererListDesc));
HDShadowManager.ReadShadowResult(shadowResult, builder);
}
static void BindGlobalLightListBuffers(ForwardPassData data, RenderGraphContext ctx)
{
ctx.cmd.SetGlobalBuffer(HDShaderIDs.g_vLightListTile, data.lightListTile);
ctx.cmd.SetGlobalBuffer(HDShaderIDs.g_vLightListCluster, data.lightListCluster);
// Next two are only for cluster rendering. PerTileLogBaseTweak is only when using depth buffer so can be invalid as well.
if (data.perVoxelOffset.IsValid())
ctx.cmd.SetGlobalBuffer(HDShaderIDs.g_vLayeredOffsetsBuffer, data.perVoxelOffset);
if (data.perTileLogBaseTweak.IsValid())
ctx.cmd.SetGlobalBuffer(HDShaderIDs.g_logBaseBuffer, data.perTileLogBaseTweak);
}
RendererListDesc PrepareForwardOpaqueRendererList(CullingResults cullResults, HDCamera hdCamera)
{
var passNames = hdCamera.frameSettings.litShaderMode == LitShaderMode.Forward
? m_ForwardAndForwardOnlyPassNames
: m_ForwardOnlyPassNames;
return CreateOpaqueRendererListDesc(cullResults, hdCamera.camera, passNames, m_CurrentRendererConfigurationBakedLighting);
}
RendererListDesc PrepareForwardTransparentRendererList(CullingResults cullResults, HDCamera hdCamera, bool preRefraction)
{
RenderQueueRange transparentRange;
if (preRefraction)
{
transparentRange = HDRenderQueue.k_RenderQueue_PreRefraction;
}
else if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.LowResTransparent))
{
transparentRange = HDRenderQueue.k_RenderQueue_Transparent;
}
else // Low res transparent disabled
{
transparentRange = HDRenderQueue.k_RenderQueue_TransparentWithLowRes;
}
if (!hdCamera.frameSettings.IsEnabled(FrameSettingsField.Refraction))
{
if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.LowResTransparent))
transparentRange = HDRenderQueue.k_RenderQueue_AllTransparent;
else
transparentRange = HDRenderQueue.k_RenderQueue_AllTransparentWithLowRes;
}
if (NeedMotionVectorForTransparent(hdCamera.frameSettings))
{
m_CurrentRendererConfigurationBakedLighting |= PerObjectData.MotionVectors; // This will enable the flag for low res transparent as well
}
var passNames = m_Asset.currentPlatformRenderPipelineSettings.supportTransparentBackface ? m_AllTransparentPassNames : m_TransparentNoBackfaceNames;
return CreateTransparentRendererListDesc(cullResults, hdCamera.camera, passNames, m_CurrentRendererConfigurationBakedLighting, transparentRange);
}
static internal void RenderForwardRendererList(FrameSettings frameSettings,
RendererList rendererList,
bool opaque,
ScriptableRenderContext renderContext,
CommandBuffer cmd)
{
// Note: SHADOWS_SHADOWMASK keyword is enabled in HDRenderPipeline.cs ConfigureForShadowMask
bool useFptl = opaque && frameSettings.IsEnabled(FrameSettingsField.FPTLForForwardOpaque);
// say that we want to use tile/cluster light loop
CoreUtils.SetKeyword(cmd, "USE_FPTL_LIGHTLIST", useFptl);
CoreUtils.SetKeyword(cmd, "USE_CLUSTERED_LIGHTLIST", !useFptl);
if (opaque)
DrawOpaqueRendererList(renderContext, cmd, frameSettings, rendererList);
else
DrawTransparentRendererList(renderContext, cmd, frameSettings, rendererList);
}
// Guidelines: In deferred by default there is no opaque in forward. However it is possible to force an opaque material to render in forward
// by using the pass "ForwardOnly". In this case the .shader should not have "Forward" but only a "ForwardOnly" pass.
// It must also have a "DepthForwardOnly" and no "DepthOnly" pass as forward material (either deferred or forward only rendering) have always a depth pass.
// The RenderForward pass will render the appropriate pass depends on the engine settings. In case of forward only rendering, both "Forward" pass and "ForwardOnly" pass
// material will be render for both transparent and opaque. In case of deferred, both path are used for transparent but only "ForwardOnly" is use for opaque.
// (Thus why "Forward" and "ForwardOnly" are exclusive, else they will render two times"
void RenderForwardOpaque(RenderGraph renderGraph,
HDCamera hdCamera,
TextureHandle colorBuffer,
in LightingBuffers lightingBuffers,
in BuildGPULightListOutput lightLists,
in PrepassOutput prepassOutput,
TextureHandle vtFeedbackBuffer,
ShadowResult shadowResult,
CullingResults cullResults)
{
if (!hdCamera.frameSettings.IsEnabled(FrameSettingsField.OpaqueObjects))
return;
bool debugDisplay = m_CurrentDebugDisplaySettings.IsDebugDisplayEnabled();
using (var builder = renderGraph.AddRenderPass<ForwardOpaquePassData>(debugDisplay ? "Forward (+ Emissive) Opaque Debug" : "Forward (+ Emissive) Opaque",
out var passData,
debugDisplay ? ProfilingSampler.Get(HDProfileId.ForwardOpaqueDebug) : ProfilingSampler.Get(HDProfileId.ForwardOpaque)))
{
PrepareCommonForwardPassData(renderGraph, builder, passData, true, hdCamera.frameSettings, PrepareForwardOpaqueRendererList(cullResults, hdCamera), lightLists, shadowResult);
int index = 0;
builder.UseColorBuffer(colorBuffer, index++);
#if ENABLE_VIRTUALTEXTURES
builder.UseColorBuffer(vtFeedbackBuffer, index++);
#endif
// In case of forward SSS we will bind all the required target. It is up to the shader to write into it or not.
if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.SubsurfaceScattering))
{
builder.UseColorBuffer(lightingBuffers.diffuseLightingBuffer, index++);
builder.UseColorBuffer(lightingBuffers.sssBuffer, index++);
}
builder.UseDepthBuffer(prepassOutput.depthBuffer, DepthAccess.ReadWrite);
builder.AllowRendererListCulling(false);
passData.enableDecals = hdCamera.frameSettings.IsEnabled(FrameSettingsField.Decals) && DecalSystem.instance.HasAnyForwardEmissive();
passData.dbuffer = ReadDBuffer(prepassOutput.dbuffer, builder);
passData.lightingBuffers = ReadLightingBuffers(lightingBuffers, builder);
// Texture has been bound globally during prepass, warn rendergraph that we may use it here
if (passData.enableDecals && hdCamera.frameSettings.IsEnabled(FrameSettingsField.DecalLayers))
builder.ReadTexture(prepassOutput.renderingLayersBuffer);
builder.SetRenderFunc(
(ForwardOpaquePassData data, RenderGraphContext context) =>
{
BindGlobalLightListBuffers(data, context);
BindDBufferGlobalData(data.dbuffer, context);
BindGlobalLightingBuffers(data.lightingBuffers, context.cmd);
RenderForwardRendererList(data.frameSettings, data.rendererList, true, context.renderContext, context.cmd);
// TODO : what will happen with render list? maybe we will not be able to skip this pass because of decal emissive projector, in this case
// we may need to move this part out?
if (data.enableDecals)
DecalSystem.instance.RenderForwardEmissive(context.cmd);
});
}
}
// This is use to Display legacy shader with an error shader
[System.Diagnostics.Conditional("DEVELOPMENT_BUILD"), System.Diagnostics.Conditional("UNITY_EDITOR")]
void RenderForwardError(RenderGraph renderGraph,
HDCamera hdCamera,
TextureHandle colorBuffer,
TextureHandle depthStencilBuffer,
CullingResults cullResults)
{
if (!hdCamera.frameSettings.IsEnabled(FrameSettingsField.TransparentObjects) &&
!hdCamera.frameSettings.IsEnabled(FrameSettingsField.OpaqueObjects))
{
return;
}
using (var builder = renderGraph.AddRenderPass<ForwardPassData>("Forward Error", out var passData, ProfilingSampler.Get(HDProfileId.RenderForwardError)))
{
builder.UseColorBuffer(colorBuffer, 0);
builder.UseDepthBuffer(depthStencilBuffer, DepthAccess.ReadWrite);
passData.rendererList = builder.UseRendererList(renderGraph.CreateRendererList(
CreateOpaqueRendererListDesc(cullResults, hdCamera.camera, m_ForwardErrorPassNames, renderQueueRange: RenderQueueRange.all, overrideMaterial: m_ErrorMaterial)));
builder.SetRenderFunc(
(ForwardPassData data, RenderGraphContext context) =>
{
CoreUtils.DrawRendererList(context.renderContext, context.cmd, data.rendererList);
});
}
}
class RenderOffscreenUIData
{
public Camera camera;
public FrameSettings frameSettings;
public Rect viewport;
}
TextureHandle CreateOffscreenUIBuffer(RenderGraph renderGraph, MSAASamples msaaSamples, Rect viewport)
{
return renderGraph.CreateTexture(new TextureDesc((int)viewport.width, (int)viewport.height, false, true)
{ colorFormat = GraphicsFormat.R8G8B8A8_SRGB, clearBuffer = false, msaaSamples = msaaSamples, name = "UI Buffer" });
}
TextureHandle RenderTransparentUI(RenderGraph renderGraph, HDCamera hdCamera)
{
var output = renderGraph.defaultResources.blackTextureXR;
if (HDROutputActiveForCameraType(hdCamera) && SupportedRenderingFeatures.active.rendersUIOverlay && !NeedHDRDebugMode(m_CurrentDebugDisplaySettings))
{
using (var builder = renderGraph.AddRenderPass<RenderOffscreenUIData>("UI Rendering", out var passData, ProfilingSampler.Get(HDProfileId.OffscreenUIRendering)))
{
// We cannot use rendererlist here because of the path tracing denoiser which will make it invalid due to multiple rendering per frame
output = builder.UseColorBuffer(CreateOffscreenUIBuffer(renderGraph, hdCamera.msaaSamples, hdCamera.finalViewport), 0);
passData.camera = hdCamera.camera;
passData.frameSettings = hdCamera.frameSettings;
passData.viewport = new Rect(0.0f, 0.0f, hdCamera.finalViewport.width, hdCamera.finalViewport.height);
builder.SetRenderFunc((RenderOffscreenUIData data, RenderGraphContext context) =>
{
context.cmd.SetViewport(data.viewport);
context.cmd.ClearRenderTarget(false, true, Color.clear);
context.renderContext.ExecuteCommandBuffer(context.cmd);
context.cmd.Clear();
if (data.camera.targetTexture == null)
context.renderContext.DrawUIOverlay(data.camera);
});
}
}
return output;
}
class AfterPostProcessPassData
{
public ShaderVariablesGlobal globalCB;
public HDCamera hdCamera;
public RendererListHandle opaqueAfterPostprocessRL;
public RendererListHandle transparentAfterPostprocessRL;
}
TextureHandle RenderAfterPostProcessObjects(RenderGraph renderGraph, HDCamera hdCamera, PathTracing pathTracing, CullingResults cullResults, in PrepassOutput prepassOutput)
{
if (!hdCamera.frameSettings.IsEnabled(FrameSettingsField.AfterPostprocess))
return renderGraph.defaultResources.blackTextureXR;
#if UNITY_64 && ENABLE_UNITY_DENOISING_PLUGIN && (UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN)
// For now disable this pass when path tracing is ON and denoising is active (the denoiser flushes the command buffer for syncing and invalidates the recorded RendererLists)
if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing)