314 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			314 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
# 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);
 | 
						||
}
 | 
						||
``` |