BlueRoseNote/03-UnrealEngine/Rendering/RenderingPipeline/Yivanlee 添加Pass与GBuffer笔记.md

314 lines
11 KiB
Markdown
Raw Permalink Normal View History

2023-06-29 11:55:02 +08:00
# Yivanlee 添加Pass与GBuffer笔记
### 给BaseScalability.ini 添加渲染质量命令行
```ini
[EffectsQuality@0]
[EffectsQuality@1]
r.ToonDataMaterials=0
[EffectsQuality@2]
[EffectsQuality@3]
[EffectsQuality@Cine]
r.ToonDataMaterials=1
```
### 增加bUsesToonData选项
1. MaterialRelevance.h的FMaterialRelevance
2. HLSLMaterialTranslator.h与HLSLMaterialTranslator.cpp的FHLSLMaterialTranslator类
3. MaterialInterface.cpp的UMaterialInterface::GetRelevance_Internal
4. PrimitiveSceneInfo.cpp的FBatchingSPDI.DrawMesh()
5. SceneCore.h的FStaticMeshBatchRelevance类
### 定义Stat宏
RenderCore.cpp与RenderCore.h里定义ToonDataPass渲染Stat。
```c#
//h
DECLARE_CYCLE_STAT_EXTERN(TEXT("ToonData pass drawing"), STAT_ToonDataPassDrawTime, STATGROUP_SceneRendering, RENDERCORE_API);
//cpp
DEFINE_STAT(STAT_ToonDataPassDrawTime);
```
BasePassRendering.cpp里定义渲染状态宏。
```c#
DECLARE_CYCLE_STAT(TEXT("ToonDataPass"), STAT_CLM_ToonDataPass, STATGROUP_CommandListMarkers);
DECLARE_CYCLE_STAT(TEXT("AfterToonDataPass"), STAT_CLM_AfterToonDataPass, STATGROUP_CommandListMarkers);
```
### 添加渲染用的RT
SceneRenderTargets.h与SceneRenderTargets.cpp
```c++
//h
TRefCountPtr<IPooledRenderTarget> ToonBufferA;
//cpp
FSceneRenderTargets::FSceneRenderTargets(const FViewInfo& View, const FSceneRenderTargets& SnapshotSource)
: LightAccumulation(GRenderTargetPool.MakeSnapshot(SnapshotSource.LightAccumulation))
···
, ToonBufferA(GRenderTargetPool.MakeSnapshot(SnapshotSource.ToonBufferA))
```
修改SetupSceneTextureUniformParameters(),在GBuffer代码段中增加`SceneTextureParameters.ToonBufferATexture = bCanReadGBufferUniforms && EnumHasAnyFlags(SetupMode, ESceneTextureSetupMode::GBufferF) && SceneContext.ToonBufferA ? GetRDG(SceneContext.ToonBufferA) : BlackDefault2D;`
在SceneTextureParameters.h与SceneTextureParameters.cpp中将新增加的RT添加到FSceneTextureParameters中并且在GetSceneTextureParameters中注册RT,并在另一个同名函数中添加`Parameters.ToonBufferATexture = (*SceneTextureUniformBuffer)->ToonBufferATexture;`
在FSceneTextureUniformParameters中添加`SHADER_PARAMETER_RDG_TEXTURE(Texture2D, ToonBufferATexture)`
### 添加SceneVisibility中的ToonDataPass定义
在SceneVisibility.h中的MarkRelevant()添加
```c#
if (StaticMeshRelevance.bUseToonData)
{
DrawCommandPacket.AddCommandsForMesh(PrimitiveIndex, PrimitiveSceneInfo, StaticMeshRelevance, StaticMesh, Scene, bCanCache, EMeshPass::ToonDataPass);
}
```
在ComputeDynamicMeshRelevance()中添加
```c#
if (ViewRelevance.bUsesToonData)
{
PassMask.Set(EMeshPass::ToonDataPass);
View.NumVisibleDynamicMeshElements[EMeshPass::ToonDataPass] += NumElements;
}
```
#### 修改DecodeGBufferData()以及相关函数
- 修改RayTracingDeferredShadingCommon.ush的DecodeGBufferData()
- 修改DeferredShadingCommon.ush中的FGBufferData添加ToonDataA变量并修改DecodeGBufferData()、GetGBufferDataUint()、GetGBufferData()、
- 修改SceneTextureParameters.ush中的ToonData变量声明`Texture2D ToonBufferATexture;``#define ToonBufferATextureSampler GlobalPointClampedSampler`以及`GetGBufferDataFromSceneTextures()`;SceneTexturesCommon.ush中的`#define SceneTexturesStruct_ToonBufferATextureSampler SceneTexturesStruct.PointClampSampler`
### 增加ToonDataPass MeshDrawPass已实现增加GBuffer
- 在MeshPassProcessor.h增加ToonDataPass MeshDrawPass定义。
- 在DeferredShadingRenderer.h添加渲染函数声明。
- 在新添加的ToonDataRendering.h与ToonDataRendering.cpp中添加MeshDrawPass声明与定义。
- 在ToonDataPassShader.usf中实现
```
// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
AnisotropyPassShader.usf: Outputs Anisotropy and World Tangent to GBufferF
=============================================================================*/
#include "Common.ush"
#include "/Engine/Generated/Material.ush"
#include "/Engine/Generated/VertexFactory.ush"
#include "DeferredShadingCommon.ush"
struct FToonDataPassVSToPS
{
float4 Position : SV_POSITION;
FVertexFactoryInterpolantsVSToPS Interps;
#if USE_WORLD_POSITION_EXCLUDING_SHADER_OFFSETS
float3 PixelPositionExcludingWPO : TEXCOORD7;
#endif
};
#if USING_TESSELLATION
struct FAnisotropyPassVSToDS
{
FVertexFactoryInterpolantsVSToDS FactoryInterpolants;
float4 Position : VS_To_DS_Position;
#if USE_WORLD_POSITION_EXCLUDING_SHADER_OFFSETS
float3 PixelPositionExcludingWPO : TEXCOORD7;
#endif
OPTIONAL_VertexID_VS_To_DS
};
#define FVertexOutput FAnisotropyPassVSToDS
#define VertexFactoryGetInterpolants VertexFactoryGetInterpolantsVSToDS
#else
#define FVertexOutput FToonDataPassVSToPS
#define VertexFactoryGetInterpolants VertexFactoryGetInterpolantsVSToPS
#endif
#if USING_TESSELLATION
#define FPassSpecificVSToDS FAnisotropyPassVSToDS
#define FPassSpecificVSToPS FToonDataPassVSToPS
FAnisotropyPassVSToDS PassInterpolate(FAnisotropyPassVSToDS a, float aInterp, FAnisotropyPassVSToDS b, float bInterp)
{
FAnisotropyPassVSToDS O;
O.FactoryInterpolants = VertexFactoryInterpolate(a.FactoryInterpolants, aInterp, b.FactoryInterpolants, bInterp);
#if USE_WORLD_POSITION_EXCLUDING_SHADER_OFFSETS
TESSELLATION_INTERPOLATE_MEMBER(PixelPositionExcludingWPO);
#endif
return O;
}
FToonDataPassVSToPS PassFinalizeTessellationOutput(FAnisotropyPassVSToDS Interpolants, float4 WorldPosition, FMaterialTessellationParameters MaterialParameters)
{
FToonDataPassVSToPS O;
O.Interps = VertexFactoryAssignInterpolants(Interpolants.FactoryInterpolants);
O.Position = mul(WorldPosition, ResolvedView.TranslatedWorldToClip);
#if USE_WORLD_POSITION_EXCLUDING_SHADER_OFFSETS
O.PixelPositionExcludingWPO = Interpolants.PixelPositionExcludingWPO;
#endif
return O;
}
#include "Tessellation.ush"
#endif
/*=============================================================================
* Vertex Shader
*============================================================================*/
void MainVertexShader(
FVertexFactoryInput Input,
OPTIONAL_VertexID
out FVertexOutput Output
#if USE_GLOBAL_CLIP_PLANE && !USING_TESSELLATION
, out float OutGlobalClipPlaneDistance : SV_ClipDistance
#endif
#if INSTANCED_STEREO
, uint InstanceId : SV_InstanceID
#if !MULTI_VIEW
, out float OutClipDistance : SV_ClipDistance1
#else
, out uint ViewportIndex : SV_ViewPortArrayIndex
#endif
#endif
)
{
#if INSTANCED_STEREO
const uint EyeIndex = GetEyeIndex(InstanceId);
ResolvedView = ResolveView(EyeIndex);
#if !MULTI_VIEW
OutClipDistance = 0.0;
#else
ViewportIndex = EyeIndex;
#endif
#else
uint EyeIndex = 0;
ResolvedView = ResolveView();
#endif
FVertexFactoryIntermediates VFIntermediates = GetVertexFactoryIntermediates(Input);
float4 WorldPos = VertexFactoryGetWorldPosition(Input, VFIntermediates);
float4 WorldPositionExcludingWPO = WorldPos;
float3x3 TangentToLocal = VertexFactoryGetTangentToLocal(Input, VFIntermediates);
FMaterialVertexParameters VertexParameters = GetMaterialVertexParameters(Input, VFIntermediates, WorldPos.xyz, TangentToLocal);
// Isolate instructions used for world position offset
// As these cause the optimizer to generate different position calculating instructions in each pass, resulting in self-z-fighting.
// This is only necessary for shaders used in passes that have depth testing enabled.
{
WorldPos.xyz += GetMaterialWorldPositionOffset(VertexParameters);
}
#if USING_TESSELLATION
// Transformation is done in Domain shader when tessellating
Output.Position = WorldPos;
#else
{
float4 RasterizedWorldPosition = VertexFactoryGetRasterizedWorldPosition(Input, VFIntermediates, WorldPos);
#if ODS_CAPTURE
float3 ODS = OffsetODS(RasterizedWorldPosition.xyz, ResolvedView.TranslatedWorldCameraOrigin.xyz, ResolvedView.StereoIPD);
Output.Position = INVARIANT(mul(float4(RasterizedWorldPosition.xyz + ODS, 1.0), ResolvedView.TranslatedWorldToClip));
#else
Output.Position = INVARIANT(mul(RasterizedWorldPosition, ResolvedView.TranslatedWorldToClip));
#endif
}
#if INSTANCED_STEREO && !MULTI_VIEW
BRANCH
if (IsInstancedStereo())
{
// Clip at the center of the screen
OutClipDistance = dot(Output.Position, EyeClipEdge[EyeIndex]);
// Scale to the width of a single eye viewport
Output.Position.x *= 0.5 * ResolvedView.HMDEyePaddingOffset;
// Shift to the eye viewport
Output.Position.x += (EyeOffsetScale[EyeIndex] * Output.Position.w) * (1.0f - 0.5 * ResolvedView.HMDEyePaddingOffset);
}
#elif XBOXONE_BIAS_HACK
// XB1 needs a bias in the opposite direction to fix FORT-40853
// XBOXONE_BIAS_HACK is defined only in a custom node in a particular material
// This should be removed with a future shader compiler update
Output.Position.z -= 0.0001 * Output.Position.w;
#endif
#if USE_GLOBAL_CLIP_PLANE
OutGlobalClipPlaneDistance = dot(ResolvedView.GlobalClippingPlane, float4(WorldPos.xyz - ResolvedView.PreViewTranslation.xyz, 1));
#endif
#endif
#if USING_TESSELLATION
Output.FactoryInterpolants = VertexFactoryGetInterpolants( Input, VFIntermediates, VertexParameters );
#else
Output.Interps = VertexFactoryGetInterpolants(Input, VFIntermediates, VertexParameters);
#endif // #if USING_TESSELLATION
#if INSTANCED_STEREO
#if USING_TESSELLATION
Output.Interps.InterpolantsVSToPS.EyeIndex = EyeIndex;
#else
Output.Interps.EyeIndex = EyeIndex;
#endif
#endif
#if USE_WORLD_POSITION_EXCLUDING_SHADER_OFFSETS
Output.PixelPositionExcludingWPO = WorldPositionExcludingWPO.xyz;
#endif
OutputVertexID( Output );
}
/*=============================================================================
* Pixel Shader
*============================================================================*/
void MainPixelShader(
in INPUT_POSITION_QUALIFIERS float4 SvPosition : SV_Position,
FVertexFactoryInterpolantsVSToPS Input
#if USE_WORLD_POSITION_EXCLUDING_SHADER_OFFSETS
, float3 PixelPositionExcludingWPO : TEXCOORD7
#endif
OPTIONAL_IsFrontFace
OPTIONAL_OutDepthConservative
, out float4 ToonBufferA : SV_Target0
#if MATERIALBLENDING_MASKED_USING_COVERAGE
, out uint OutCoverage : SV_Coverage
#endif
)
{
#if INSTANCED_STEREO
ResolvedView = ResolveView(Input.EyeIndex);
#else
ResolvedView = ResolveView();
#endif
// Manual clipping here (alpha-test, etc)
FMaterialPixelParameters MaterialParameters = GetMaterialPixelParameters(Input, SvPosition);
FPixelMaterialInputs PixelMaterialInputs;
#if USE_WORLD_POSITION_EXCLUDING_SHADER_OFFSETS
float4 ScreenPosition = SvPositionToResolvedScreenPosition(SvPosition);
float3 TranslatedWorldPosition = SvPositionToResolvedTranslatedWorld(SvPosition);
CalcMaterialParametersEx(MaterialParameters, PixelMaterialInputs, SvPosition, ScreenPosition, bIsFrontFace, TranslatedWorldPosition, PixelPositionExcludingWPO);
#else
CalcMaterialParameters(MaterialParameters, PixelMaterialInputs, SvPosition, bIsFrontFace);
#endif
#if OUTPUT_PIXEL_DEPTH_OFFSET
ApplyPixelDepthOffsetToMaterialParameters(MaterialParameters, PixelMaterialInputs, OutDepth);
#endif
#if MATERIALBLENDING_MASKED_USING_COVERAGE
OutCoverage = DiscardMaterialWithPixelCoverage(MaterialParameters, PixelMaterialInputs);
#endif
//float Anisotropy = GetMaterialAnisotropy(PixelMaterialInputs);
//float3 WorldTangent = MaterialParameters.WorldTangent;
ToonBufferA = float4(0.2, 0.1, 0.8, 1.0);
}
```