11 KiB
		
	
	
	
	
	
	
	
			
		
		
	
	Yivanlee 添加Pass与GBuffer笔记
给BaseScalability.ini 添加渲染质量命令行
[EffectsQuality@0]
[EffectsQuality@1]
r.ToonDataMaterials=0
[EffectsQuality@2]
[EffectsQuality@3]
[EffectsQuality@Cine]
r.ToonDataMaterials=1
增加bUsesToonData选项
- MaterialRelevance.h的FMaterialRelevance
 - HLSLMaterialTranslator.h与HLSLMaterialTranslator.cpp的FHLSLMaterialTranslator类
 - MaterialInterface.cpp的UMaterialInterface::GetRelevance_Internal
 - PrimitiveSceneInfo.cpp的FBatchingSPDI.DrawMesh()
 - SceneCore.h的FStaticMeshBatchRelevance类
 
定义Stat宏
RenderCore.cpp与RenderCore.h里定义ToonDataPass渲染Stat。
//h
DECLARE_CYCLE_STAT_EXTERN(TEXT("ToonData pass drawing"), STAT_ToonDataPassDrawTime, STATGROUP_SceneRendering, RENDERCORE_API);
//cpp
DEFINE_STAT(STAT_ToonDataPassDrawTime);
BasePassRendering.cpp里定义渲染状态宏。
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
//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()添加
if (StaticMeshRelevance.bUseToonData)
{
    DrawCommandPacket.AddCommandsForMesh(PrimitiveIndex, PrimitiveSceneInfo, StaticMeshRelevance, StaticMesh, Scene, bCanCache, EMeshPass::ToonDataPass);
}
在ComputeDynamicMeshRelevance()中添加
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);
}