Merge branch 'master' of http://blueroses.top:8888/BlueRose/BlueRoseNotes
This commit is contained in:
commit
07d78fe48c
@ -132,6 +132,7 @@ rating: ⭐⭐⭐
|
|||||||
1. ![[星穹铁道中下巴阴影处理.png]]
|
1. ![[星穹铁道中下巴阴影处理.png]]
|
||||||
2. [ ] ToonSDFShadow
|
2. [ ] ToonSDFShadow
|
||||||
1. [ ] TODO: SDF贴图工具?
|
1. [ ] TODO: SDF贴图工具?
|
||||||
|
3. [ ] ShadowPass https://zhuanlan.zhihu.com/p/619718145
|
||||||
19. [ ] LookDev场景
|
19. [ ] LookDev场景
|
||||||
1. [ ] https://zhuanlan.zhihu.com/p/394608910
|
1. [ ] https://zhuanlan.zhihu.com/p/394608910
|
||||||
20. [ ] 考虑往GBuffer中添加更多数据(考虑Velocity以及SingleLayerWater)
|
20. [ ] 考虑往GBuffer中添加更多数据(考虑Velocity以及SingleLayerWater)
|
||||||
@ -144,12 +145,14 @@ rating: ⭐⭐⭐
|
|||||||
1. 【二次元人物眼睛如何变形?】 https://www.bilibili.com/video/BV14M4m1y71A/?share_source=copy_web&vd_source=fe8142e8e12816535feaeabd6f6cdc8e
|
1. 【二次元人物眼睛如何变形?】 https://www.bilibili.com/video/BV14M4m1y71A/?share_source=copy_web&vd_source=fe8142e8e12816535feaeabd6f6cdc8e
|
||||||
1. 原视频 https://www.youtube.com/watch?v=euIyX9v8rvw
|
1. 原视频 https://www.youtube.com/watch?v=euIyX9v8rvw
|
||||||
2. 眼睛建模 https://youtu.be/s2_7Q2IIvNY?si=fWiYjqcLFXzdeQ-B&t=126
|
2. 眼睛建模 https://youtu.be/s2_7Q2IIvNY?si=fWiYjqcLFXzdeQ-B&t=126
|
||||||
25. DX11问题修复
|
25. 尝试实现Forward+
|
||||||
|
1. BasePass https://zhuanlan.zhihu.com/p/618698467
|
||||||
|
26. DX11问题修复
|
||||||
1. [x] ToonOutline SceneColorTexture为空的问题。 **DX11限制,必须CopyTexture**
|
1. [x] ToonOutline SceneColorTexture为空的问题。 **DX11限制,必须CopyTexture**
|
||||||
26. 卡通渲染针对TAA的优化思路 https://zhuanlan.zhihu.com/p/678876237
|
27. 卡通渲染针对TAA的优化思路 https://zhuanlan.zhihu.com/p/678876237
|
||||||
1. https://www.bilibili.com/video/BV1BK411v7FY/?spm_id_from=333.788&vd_source=ea6df38502a795b7533aa33b78bf1159
|
1. https://www.bilibili.com/video/BV1BK411v7FY/?spm_id_from=333.788&vd_source=ea6df38502a795b7533aa33b78bf1159
|
||||||
2. https://zhuanlan.zhihu.com/p/20786650
|
2. https://zhuanlan.zhihu.com/p/20786650
|
||||||
27. [ ] Unreal Engine 5.4 Scene Extension https://zhuanlan.zhihu.com/p/706268007
|
28. [ ] Unreal Engine 5.4 Scene Extension https://zhuanlan.zhihu.com/p/706268007
|
||||||
1. [ ] 通过SceneExtension改进ToonObjectID,这样可以减少对应ToonBuffer的精度来存其他数据。
|
1. [ ] 通过SceneExtension改进ToonObjectID,这样可以减少对应ToonBuffer的精度来存其他数据。
|
||||||
2. [ ] https://www.bilibili.com/video/BV1fM4m1U7Tp/
|
2. [ ] https://www.bilibili.com/video/BV1fM4m1U7Tp/
|
||||||
|
|
||||||
|
378
03-UnrealEngine/卡通渲染相关资料/渲染功能/ShaderModel/BasePass C++.md
Normal file
378
03-UnrealEngine/卡通渲染相关资料/渲染功能/ShaderModel/BasePass C++.md
Normal file
@ -0,0 +1,378 @@
|
|||||||
|
---
|
||||||
|
title: Untitled
|
||||||
|
date: 2024-09-26 18:41:24
|
||||||
|
excerpt:
|
||||||
|
tags:
|
||||||
|
rating: ⭐
|
||||||
|
---
|
||||||
|
# RenderBasePass()
|
||||||
|
传入RenderBasePass()的DepthStencil逻辑如下:
|
||||||
|
```c++
|
||||||
|
const FExclusiveDepthStencil::Type BasePassDepthStencilAccess =
|
||||||
|
bAllowReadOnlyDepthBasePass
|
||||||
|
? FExclusiveDepthStencil::DepthRead_StencilWrite
|
||||||
|
: FExclusiveDepthStencil::DepthWrite_StencilWrite;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
FDeferredShadingSceneRenderer::RenderBasePass() =>
|
||||||
|
FDeferredShadingSceneRenderer::RenderBasePassInternal() =>
|
||||||
|
|
||||||
|
|
||||||
|
FBasePassMeshProcessor::TryAddMeshBatch =>
|
||||||
|
|
||||||
|
## 大致流程
|
||||||
|
1. 创建MRT并绑定、取得深度缓存。
|
||||||
|
```c++
|
||||||
|
const FExclusiveDepthStencil ExclusiveDepthStencil(BasePassDepthStencilAccess);
|
||||||
|
|
||||||
|
TStaticArray<FTextureRenderTargetBinding, MaxSimultaneousRenderTargets> BasePassTextures;
|
||||||
|
uint32 BasePassTextureCount = SceneTextures.GetGBufferRenderTargets(BasePassTextures);
|
||||||
|
Strata::AppendStrataMRTs(*this, BasePassTextureCount, BasePassTextures);
|
||||||
|
TArrayView<FTextureRenderTargetBinding> BasePassTexturesView = MakeArrayView(BasePassTextures.GetData(), BasePassTextureCount);
|
||||||
|
FRDGTextureRef BasePassDepthTexture = SceneTextures.Depth.Target;
|
||||||
|
```
|
||||||
|
2. GBuffer Clear
|
||||||
|
```c++
|
||||||
|
GraphBuilder.AddPass(RDG_EVENT_NAME("GBufferClear"), PassParameters, ERDGPassFlags::Raster,
|
||||||
|
[PassParameters, ColorLoadAction, SceneColorClearValue](FRHICommandList& RHICmdList)
|
||||||
|
{
|
||||||
|
// If no fast-clear action was used, we need to do an MRT shader clear.
|
||||||
|
if (ColorLoadAction == ERenderTargetLoadAction::ENoAction)
|
||||||
|
{
|
||||||
|
const FRenderTargetBindingSlots& RenderTargets = PassParameters->RenderTargets;
|
||||||
|
FLinearColor ClearColors[MaxSimultaneousRenderTargets];
|
||||||
|
FRHITexture* Textures[MaxSimultaneousRenderTargets];
|
||||||
|
int32 TextureIndex = 0;
|
||||||
|
|
||||||
|
RenderTargets.Enumerate([&](const FRenderTargetBinding& RenderTarget)
|
||||||
|
{
|
||||||
|
FRHITexture* TextureRHI = RenderTarget.GetTexture()->GetRHI();
|
||||||
|
ClearColors[TextureIndex] = TextureIndex == 0 ? SceneColorClearValue : TextureRHI->GetClearColor();
|
||||||
|
Textures[TextureIndex] = TextureRHI;
|
||||||
|
++TextureIndex;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Clear color only; depth-stencil is fast cleared.
|
||||||
|
DrawClearQuadMRT(RHICmdList, true, TextureIndex, ClearColors, false, 0, false, 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
3. RenderTargetBindingSlots
|
||||||
|
```c++
|
||||||
|
// Render targets bindings should remain constant at this point.
|
||||||
|
FRenderTargetBindingSlots BasePassRenderTargets = GetRenderTargetBindings(ERenderTargetLoadAction::ELoad, BasePassTexturesView);
|
||||||
|
BasePassRenderTargets.DepthStencil = FDepthStencilBinding(BasePassDepthTexture, ERenderTargetLoadAction::ELoad, ERenderTargetLoadAction::ELoad, ExclusiveDepthStencil);
|
||||||
|
```
|
||||||
|
4. RenderBasePassInternal()
|
||||||
|
5. RenderAnisotropyPass()
|
||||||
|
|
||||||
|
# MeshDraw
|
||||||
|
## RenderBasePassInternal()
|
||||||
|
RenderNaniteBasePass()为一个Lambda,最终调用**Nanite::DrawBasePass()** 渲染Nanite物体的BasePass。其他相关渲染代码如下:
|
||||||
|
```c++
|
||||||
|
SCOPE_CYCLE_COUNTER(STAT_BasePassDrawTime);
|
||||||
|
RDG_EVENT_SCOPE(GraphBuilder, "BasePass");
|
||||||
|
RDG_GPU_STAT_SCOPE(GraphBuilder, Basepass);
|
||||||
|
|
||||||
|
const bool bDrawSceneViewsInOneNanitePass = Views.Num() > 1 && Nanite::ShouldDrawSceneViewsInOneNanitePass(Views[0]);
|
||||||
|
if (bParallelBasePass)//并行渲染模式
|
||||||
|
{
|
||||||
|
RDG_WAIT_FOR_TASKS_CONDITIONAL(GraphBuilder, IsBasePassWaitForTasksEnabled());
|
||||||
|
|
||||||
|
for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ++ViewIndex)
|
||||||
|
{
|
||||||
|
FViewInfo& View = Views[ViewIndex];
|
||||||
|
RDG_GPU_MASK_SCOPE(GraphBuilder, View.GPUMask);
|
||||||
|
RDG_EVENT_SCOPE_CONDITIONAL(GraphBuilder, Views.Num() > 1, "View%d", ViewIndex);
|
||||||
|
View.BeginRenderView();
|
||||||
|
|
||||||
|
const bool bLumenGIEnabled = GetViewPipelineState(View).DiffuseIndirectMethod == EDiffuseIndirectMethod::Lumen;
|
||||||
|
|
||||||
|
FMeshPassProcessorRenderState DrawRenderState;
|
||||||
|
SetupBasePassState(BasePassDepthStencilAccess, ViewFamily.EngineShowFlags.ShaderComplexity, DrawRenderState);
|
||||||
|
|
||||||
|
FOpaqueBasePassParameters* PassParameters = GraphBuilder.AllocParameters<FOpaqueBasePassParameters>();
|
||||||
|
PassParameters->View = View.GetShaderParameters();
|
||||||
|
PassParameters->ReflectionCapture = View.ReflectionCaptureUniformBuffer;
|
||||||
|
PassParameters->BasePass = CreateOpaqueBasePassUniformBuffer(GraphBuilder, View, ViewIndex, ForwardBasePassTextures, DBufferTextures, bLumenGIEnabled);
|
||||||
|
PassParameters->RenderTargets = BasePassRenderTargets;
|
||||||
|
PassParameters->RenderTargets.ShadingRateTexture = GVRSImageManager.GetVariableRateShadingImage(GraphBuilder, View, FVariableRateShadingImageManager::EVRSPassType::BasePass);
|
||||||
|
|
||||||
|
const bool bShouldRenderView = View.ShouldRenderView();
|
||||||
|
if (bShouldRenderView)
|
||||||
|
{
|
||||||
|
View.ParallelMeshDrawCommandPasses[EMeshPass::BasePass].BuildRenderingCommands(GraphBuilder, Scene->GPUScene, PassParameters->InstanceCullingDrawParams);
|
||||||
|
|
||||||
|
GraphBuilder.AddPass(
|
||||||
|
RDG_EVENT_NAME("BasePassParallel"),
|
||||||
|
PassParameters,
|
||||||
|
ERDGPassFlags::Raster | ERDGPassFlags::SkipRenderPass,
|
||||||
|
[this, &View, PassParameters](const FRDGPass* InPass, FRHICommandListImmediate& RHICmdList)
|
||||||
|
{
|
||||||
|
FRDGParallelCommandListSet ParallelCommandListSet(InPass, RHICmdList, GET_STATID(STAT_CLP_BasePass), View, FParallelCommandListBindings(PassParameters));
|
||||||
|
View.ParallelMeshDrawCommandPasses[EMeshPass::BasePass].DispatchDraw(&ParallelCommandListSet, RHICmdList, &PassParameters->InstanceCullingDrawParams);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool bShouldRenderViewForNanite = bNaniteEnabled && (!bDrawSceneViewsInOneNanitePass || ViewIndex == 0); // when bDrawSceneViewsInOneNanitePass, the first view should cover all the other atlased ones
|
||||||
|
if (bShouldRenderViewForNanite)
|
||||||
|
{
|
||||||
|
// Should always have a full Z prepass with Nanite
|
||||||
|
check(ShouldRenderPrePass());
|
||||||
|
//渲染Nanite物体BasePass
|
||||||
|
RenderNaniteBasePass(View, ViewIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
//渲染编辑器相关的图元物体
|
||||||
|
RenderEditorPrimitives(GraphBuilder, PassParameters, View, DrawRenderState, InstanceCullingManager);
|
||||||
|
|
||||||
|
//渲染大气
|
||||||
|
if (bShouldRenderView && View.Family->EngineShowFlags.Atmosphere)
|
||||||
|
{
|
||||||
|
FOpaqueBasePassParameters* SkyPassPassParameters = GraphBuilder.AllocParameters<FOpaqueBasePassParameters>();
|
||||||
|
SkyPassPassParameters->BasePass = PassParameters->BasePass;
|
||||||
|
SkyPassPassParameters->RenderTargets = BasePassRenderTargets;
|
||||||
|
SkyPassPassParameters->View = View.GetShaderParameters();
|
||||||
|
SkyPassPassParameters->ReflectionCapture = View.ReflectionCaptureUniformBuffer;
|
||||||
|
|
||||||
|
View.ParallelMeshDrawCommandPasses[EMeshPass::SkyPass].BuildRenderingCommands(GraphBuilder, Scene->GPUScene, SkyPassPassParameters->InstanceCullingDrawParams);
|
||||||
|
|
||||||
|
GraphBuilder.AddPass(
|
||||||
|
RDG_EVENT_NAME("SkyPassParallel"),
|
||||||
|
SkyPassPassParameters,
|
||||||
|
ERDGPassFlags::Raster | ERDGPassFlags::SkipRenderPass,
|
||||||
|
[this, &View, SkyPassPassParameters](const FRDGPass* InPass, FRHICommandListImmediate& RHICmdList)
|
||||||
|
{
|
||||||
|
FRDGParallelCommandListSet ParallelCommandListSet(InPass, RHICmdList, GET_STATID(STAT_CLP_BasePass), View, FParallelCommandListBindings(SkyPassPassParameters));
|
||||||
|
View.ParallelMeshDrawCommandPasses[EMeshPass::SkyPass].DispatchDraw(&ParallelCommandListSet, RHICmdList, &SkyPassPassParameters->InstanceCullingDrawParams);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ++ViewIndex)
|
||||||
|
{
|
||||||
|
FViewInfo& View = Views[ViewIndex];
|
||||||
|
RDG_GPU_MASK_SCOPE(GraphBuilder, View.GPUMask);
|
||||||
|
RDG_EVENT_SCOPE_CONDITIONAL(GraphBuilder, Views.Num() > 1, "View%d", ViewIndex);
|
||||||
|
View.BeginRenderView();
|
||||||
|
|
||||||
|
const bool bLumenGIEnabled = GetViewPipelineState(View).DiffuseIndirectMethod == EDiffuseIndirectMethod::Lumen;
|
||||||
|
|
||||||
|
FMeshPassProcessorRenderState DrawRenderState;
|
||||||
|
SetupBasePassState(BasePassDepthStencilAccess, ViewFamily.EngineShowFlags.ShaderComplexity, DrawRenderState);
|
||||||
|
|
||||||
|
FOpaqueBasePassParameters* PassParameters = GraphBuilder.AllocParameters<FOpaqueBasePassParameters>();
|
||||||
|
PassParameters->View = View.GetShaderParameters();
|
||||||
|
PassParameters->ReflectionCapture = View.ReflectionCaptureUniformBuffer;
|
||||||
|
PassParameters->BasePass = CreateOpaqueBasePassUniformBuffer(GraphBuilder, View, ViewIndex, ForwardBasePassTextures, DBufferTextures, bLumenGIEnabled);
|
||||||
|
PassParameters->RenderTargets = BasePassRenderTargets;
|
||||||
|
PassParameters->RenderTargets.ShadingRateTexture = GVRSImageManager.GetVariableRateShadingImage(GraphBuilder, View, FVariableRateShadingImageManager::EVRSPassType::BasePass);
|
||||||
|
|
||||||
|
const bool bShouldRenderView = View.ShouldRenderView();
|
||||||
|
if (bShouldRenderView)
|
||||||
|
{
|
||||||
|
View.ParallelMeshDrawCommandPasses[EMeshPass::BasePass].BuildRenderingCommands(GraphBuilder, Scene->GPUScene, PassParameters->InstanceCullingDrawParams);
|
||||||
|
|
||||||
|
GraphBuilder.AddPass(
|
||||||
|
RDG_EVENT_NAME("BasePass"),
|
||||||
|
PassParameters,
|
||||||
|
ERDGPassFlags::Raster,
|
||||||
|
[this, &View, PassParameters](FRHICommandList& RHICmdList)
|
||||||
|
{
|
||||||
|
SetStereoViewport(RHICmdList, View, 1.0f);
|
||||||
|
View.ParallelMeshDrawCommandPasses[EMeshPass::BasePass].DispatchDraw(nullptr, RHICmdList, &PassParameters->InstanceCullingDrawParams);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool bShouldRenderViewForNanite = bNaniteEnabled && (!bDrawSceneViewsInOneNanitePass || ViewIndex == 0); // when bDrawSceneViewsInOneNanitePass, the first view should cover all the other atlased ones
|
||||||
|
if (bShouldRenderViewForNanite)
|
||||||
|
{
|
||||||
|
// Should always have a full Z prepass with Nanite
|
||||||
|
check(ShouldRenderPrePass());
|
||||||
|
|
||||||
|
RenderNaniteBasePass(View, ViewIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderEditorPrimitives(GraphBuilder, PassParameters, View, DrawRenderState, InstanceCullingManager);
|
||||||
|
|
||||||
|
if (bShouldRenderView && View.Family->EngineShowFlags.Atmosphere)
|
||||||
|
{
|
||||||
|
FOpaqueBasePassParameters* SkyPassParameters = GraphBuilder.AllocParameters<FOpaqueBasePassParameters>();
|
||||||
|
SkyPassParameters->BasePass = PassParameters->BasePass;
|
||||||
|
SkyPassParameters->RenderTargets = BasePassRenderTargets;
|
||||||
|
SkyPassParameters->View = View.GetShaderParameters();
|
||||||
|
SkyPassParameters->ReflectionCapture = View.ReflectionCaptureUniformBuffer;
|
||||||
|
|
||||||
|
View.ParallelMeshDrawCommandPasses[EMeshPass::SkyPass].BuildRenderingCommands(GraphBuilder, Scene->GPUScene, SkyPassParameters->InstanceCullingDrawParams);
|
||||||
|
|
||||||
|
GraphBuilder.AddPass(
|
||||||
|
RDG_EVENT_NAME("SkyPass"),
|
||||||
|
SkyPassParameters,
|
||||||
|
ERDGPassFlags::Raster,
|
||||||
|
[this, &View, SkyPassParameters](FRHICommandList& RHICmdList)
|
||||||
|
{
|
||||||
|
SetStereoViewport(RHICmdList, View, 1.0f);
|
||||||
|
View.ParallelMeshDrawCommandPasses[EMeshPass::SkyPass].DispatchDraw(nullptr, RHICmdList, &SkyPassParameters->InstanceCullingDrawParams);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### SetDepthStencilStateForBasePass()
|
||||||
|
```c++
|
||||||
|
void SetDepthStencilStateForBasePass(
|
||||||
|
FMeshPassProcessorRenderState& DrawRenderState,
|
||||||
|
ERHIFeatureLevel::Type FeatureLevel,
|
||||||
|
bool bDitheredLODTransition,
|
||||||
|
const FMaterial& MaterialResource,
|
||||||
|
bool bEnableReceiveDecalOutput,
|
||||||
|
bool bForceEnableStencilDitherState)
|
||||||
|
{
|
||||||
|
const bool bMaskedInEarlyPass = (MaterialResource.IsMasked() || bDitheredLODTransition) && MaskedInEarlyPass(GShaderPlatformForFeatureLevel[FeatureLevel]);
|
||||||
|
if (bEnableReceiveDecalOutput)
|
||||||
|
{
|
||||||
|
if (bMaskedInEarlyPass)
|
||||||
|
{
|
||||||
|
SetDepthStencilStateForBasePass_Internal<false, CF_Equal>(DrawRenderState, FeatureLevel);
|
||||||
|
}
|
||||||
|
else if (DrawRenderState.GetDepthStencilAccess() & FExclusiveDepthStencil::DepthWrite)
|
||||||
|
{
|
||||||
|
SetDepthStencilStateForBasePass_Internal<true, CF_GreaterEqual>(DrawRenderState, FeatureLevel);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetDepthStencilStateForBasePass_Internal<false, CF_GreaterEqual>(DrawRenderState, FeatureLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (bMaskedInEarlyPass)
|
||||||
|
{
|
||||||
|
DrawRenderState.SetDepthStencilState(TStaticDepthStencilState<false, CF_Equal>::GetRHI());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bForceEnableStencilDitherState)
|
||||||
|
{
|
||||||
|
SetDepthStencilStateForBasePass_Internal<false, CF_Equal>(DrawRenderState, FeatureLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
## AnisotropyPass
|
||||||
|
Anisotropy的RT设置:
|
||||||
|
- RenderTarget:SceneTextures.GBufferF。
|
||||||
|
- DepthStencil:SceneTextures.Depth.Target。**ERenderTargetLoadAction::ELoad**、**FExclusiveDepthStencil::DepthRead_StencilNop**
|
||||||
|
|
||||||
|
### 管线状态
|
||||||
|
在FAnisotropyMeshProcessor::CollectPSOInitializers()中:
|
||||||
|
```c++
|
||||||
|
ETextureCreateFlags GBufferFCreateFlags;
|
||||||
|
EPixelFormat GBufferFPixelFormat = FSceneTextures::GetGBufferFFormatAndCreateFlags(GBufferFCreateFlags);
|
||||||
|
AddRenderTargetInfo(GBufferFPixelFormat, GBufferFCreateFlags, RenderTargetsInfo);
|
||||||
|
SetupDepthStencilInfo(PF_DepthStencil, SceneTexturesConfig.DepthCreateFlags, ERenderTargetLoadAction::ELoad,
|
||||||
|
ERenderTargetLoadAction::ELoad, FExclusiveDepthStencil::DepthRead_StencilNop, RenderTargetsInfo);
|
||||||
|
```
|
||||||
|
|
||||||
|
```c++
|
||||||
|
void SetupDepthStencilInfo(
|
||||||
|
EPixelFormat DepthStencilFormat,
|
||||||
|
ETextureCreateFlags DepthStencilCreateFlags,
|
||||||
|
ERenderTargetLoadAction DepthTargetLoadAction,
|
||||||
|
ERenderTargetLoadAction StencilTargetLoadAction,
|
||||||
|
FExclusiveDepthStencil DepthStencilAccess,
|
||||||
|
FGraphicsPipelineRenderTargetsInfo& RenderTargetsInfo)
|
||||||
|
{
|
||||||
|
// Setup depth stencil state
|
||||||
|
RenderTargetsInfo.DepthStencilTargetFormat = DepthStencilFormat;
|
||||||
|
RenderTargetsInfo.DepthStencilTargetFlag = DepthStencilCreateFlags;
|
||||||
|
|
||||||
|
RenderTargetsInfo.DepthTargetLoadAction = DepthTargetLoadAction;
|
||||||
|
RenderTargetsInfo.StencilTargetLoadAction = StencilTargetLoadAction;
|
||||||
|
RenderTargetsInfo.DepthStencilAccess = DepthStencilAccess;
|
||||||
|
|
||||||
|
const ERenderTargetStoreAction StoreAction = EnumHasAnyFlags(RenderTargetsInfo.DepthStencilTargetFlag, TexCreate_Memoryless) ? ERenderTargetStoreAction::ENoAction : ERenderTargetStoreAction::EStore;
|
||||||
|
RenderTargetsInfo.DepthTargetStoreAction = RenderTargetsInfo.DepthStencilAccess.IsUsingDepth() ? StoreAction : ERenderTargetStoreAction::ENoAction;
|
||||||
|
RenderTargetsInfo.StencilTargetStoreAction = RenderTargetsInfo.DepthStencilAccess.IsUsingStencil() ? StoreAction : ERenderTargetStoreAction::ENoAction;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### ParallelRendering
|
||||||
|
AnisotropyPass支持并行渲染,并行渲染的判断逻辑为
|
||||||
|
```c++
|
||||||
|
const bool bEnableParallelBasePasses = GRHICommandList.UseParallelAlgorithms() && CVarParallelBasePass.GetValueOnRenderThread();
|
||||||
|
```
|
||||||
|
看得出判断条件是:
|
||||||
|
1. 显卡是否支持并行渲染。
|
||||||
|
2. CVar(r.ParallelBasePass)是否开启并行渲染。
|
||||||
|
|
||||||
|
从AnisotropyPass可以看得出并行渲染与一般渲染的差别在于:
|
||||||
|
1. FRenderTargetBinding绑定时的ERenderTargetLoadAction不同,**并行为ELoad**;**普通渲染为EClear**。
|
||||||
|
2. 调用AddPass添加了**ERDGPassFlags::SkipRenderPass**标记。
|
||||||
|
3. 并行渲染会在AddPass中构建**FRDGParallelCommandListSet ParallelCommandListSet**,并作为传入**DispatchDraw**;普通渲染传递nullptr。
|
||||||
|
4. 普通渲染会额外调用**SetStereoViewport(RHICmdList, View);**,本质是调用RHICmdList.SetViewport来设置View。
|
||||||
|
|
||||||
|
### Code
|
||||||
|
```c++
|
||||||
|
RDG_CSV_STAT_EXCLUSIVE_SCOPE(GraphBuilder, RenderAnisotropyPass);
|
||||||
|
SCOPED_NAMED_EVENT(FDeferredShadingSceneRenderer_RenderAnisotropyPass, FColor::Emerald);
|
||||||
|
SCOPE_CYCLE_COUNTER(STAT_AnisotropyPassDrawTime);
|
||||||
|
RDG_GPU_STAT_SCOPE(GraphBuilder, RenderAnisotropyPass);
|
||||||
|
|
||||||
|
for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++)
|
||||||
|
{
|
||||||
|
FViewInfo& View = Views[ViewIndex];
|
||||||
|
|
||||||
|
if (View.ShouldRenderView())
|
||||||
|
{
|
||||||
|
FParallelMeshDrawCommandPass& ParallelMeshPass = View.ParallelMeshDrawCommandPasses[EMeshPass::AnisotropyPass];
|
||||||
|
|
||||||
|
if (!ParallelMeshPass.HasAnyDraw())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
View.BeginRenderView();
|
||||||
|
|
||||||
|
auto* PassParameters = GraphBuilder.AllocParameters<FAnisotropyPassParameters>();
|
||||||
|
PassParameters->View = View.GetShaderParameters();
|
||||||
|
PassParameters->RenderTargets.DepthStencil = FDepthStencilBinding(SceneTextures.Depth.Target, ERenderTargetLoadAction::ELoad, FExclusiveDepthStencil::DepthRead_StencilNop);
|
||||||
|
|
||||||
|
ParallelMeshPass.BuildRenderingCommands(GraphBuilder, Scene->GPUScene, PassParameters->InstanceCullingDrawParams);
|
||||||
|
if (bDoParallelPass)
|
||||||
|
{
|
||||||
|
AddClearRenderTargetPass(GraphBuilder, SceneTextures.GBufferF);
|
||||||
|
|
||||||
|
PassParameters->RenderTargets[0] = FRenderTargetBinding(SceneTextures.GBufferF, ERenderTargetLoadAction::ELoad);
|
||||||
|
|
||||||
|
GraphBuilder.AddPass(
|
||||||
|
RDG_EVENT_NAME("AnisotropyPassParallel"),
|
||||||
|
PassParameters,
|
||||||
|
ERDGPassFlags::Raster | ERDGPassFlags::SkipRenderPass,
|
||||||
|
[this, &View, &ParallelMeshPass, PassParameters](const FRDGPass* InPass, FRHICommandListImmediate& RHICmdList)
|
||||||
|
{
|
||||||
|
FRDGParallelCommandListSet ParallelCommandListSet(InPass, RHICmdList, GET_STATID(STAT_CLP_AnisotropyPass), View, FParallelCommandListBindings(PassParameters));
|
||||||
|
|
||||||
|
ParallelMeshPass.DispatchDraw(&ParallelCommandListSet, RHICmdList, &PassParameters->InstanceCullingDrawParams);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PassParameters->RenderTargets[0] = FRenderTargetBinding(SceneTextures.GBufferF, ERenderTargetLoadAction::EClear);
|
||||||
|
|
||||||
|
GraphBuilder.AddPass(
|
||||||
|
RDG_EVENT_NAME("AnisotropyPass"),
|
||||||
|
PassParameters,
|
||||||
|
ERDGPassFlags::Raster,
|
||||||
|
[this, &View, &ParallelMeshPass, PassParameters](FRHICommandList& RHICmdList)
|
||||||
|
{
|
||||||
|
SetStereoViewport(RHICmdList, View);
|
||||||
|
|
||||||
|
ParallelMeshPass.DispatchDraw(nullptr, RHICmdList, &PassParameters->InstanceCullingDrawParams);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
@ -32,6 +32,7 @@ OutGBufferD = GBuffer.CustomData
|
|||||||
OutGBufferE = GBuffer.PrecomputedShadowFactors (GBT_Unorm_8_8_8_8)
|
OutGBufferE = GBuffer.PrecomputedShadowFactors (GBT_Unorm_8_8_8_8)
|
||||||
TargetVelocity / OutGBufferF = velocity / tangent (默认不开启 带有深度<开启Lumen与距离场 或者 开启光线追踪> GBC_Raw_Float_16_16_16_16 不带深度 GBC_Raw_Float_16_16)
|
TargetVelocity / OutGBufferF = velocity / tangent (默认不开启 带有深度<开启Lumen与距离场 或者 开启光线追踪> GBC_Raw_Float_16_16_16_16 不带深度 GBC_Raw_Float_16_16)
|
||||||
TargetSeparatedMainDirLight = SingleLayerWater相关 (有SingleLayerWater才会开启 GBC_Raw_Float_11_11_10)
|
TargetSeparatedMainDirLight = SingleLayerWater相关 (有SingleLayerWater才会开启 GBC_Raw_Float_11_11_10)
|
||||||
|
OutGBufferF = Anisotropy
|
||||||
|
|
||||||
// 0..1, 2 bits, use CastContactShadow(GBuffer) or HasDynamicIndirectShadowCasterRepresentation(GBuffer) to extract
|
// 0..1, 2 bits, use CastContactShadow(GBuffer) or HasDynamicIndirectShadowCasterRepresentation(GBuffer) to extract
|
||||||
half PerObjectGBufferData;
|
half PerObjectGBufferData;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user