【转载】UE4 随记

1,832 阅读14分钟

版权声明:本文为CSDN博主「sh15285118586」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文 1 链接: blog.csdn.net/sh152851185…

原文 2 链接:blog.csdn.net/sh152851185…

原文 3 链接:blog.csdn.net/sh152851185…

原文 4 链接:blog.csdn.net/sh152851185…

第一部分

1. 理解 Shader 中 ViewSizeAndInvSize

视图尺寸尺寸 的倒数,比如视图的尺寸是 960*540 ,那么

ViewSizeAndInvSize.xy = float2(960, 540) 
ViewSizeAndInvSize.zw = float2(1/960, 1/540) 
float2 TexelSize = View.ViewSizeAndInvSize.zw;  ///< 将偏移量转换到UV空间

参考文档:www.it610.com/article/129…

2. SV_POSITIONSV_Target 区别

SV_POSITIONSV_Target 都是 语义绑定 (semantics binding) 。

SV_ 前缀的变量代表 System Value 的意思,在 DX10+ 的语义绑定中被使用代表特殊的意义。

SV_POSITION 在用法上和 POSITION 是一样的,区别SV_POSTION 一旦被作为 vertex 函数的输出语义,那么这个最终的顶点位置就被固定了,不得改变。DX10+ 推荐使用 SV_POSITION 作为 vertex 函数的输出和 fragment 函数的输入,而 vertex 函数的输入还是使用 POSITION。不过 DX10 以后的代码依旧兼容 POSITION 作为全程表达,估计编译器会自动判断并替换的吧。

SV_TargetDX10+ 用于 fragment 函数着色器颜色输出的语义。DX9 使用 COLOR 作为 fragment 函数输出语义,但是也有一些着色器语言使用 COLOR 来表示网格数据和顶点输出语义,效果和功能是一样的,没有什么区别,同时使用 COLOR 的话 DX10+ 也会兼容。

参考文档:www.jianshu.com/p/ea63577a0…

3. ViewResolvedView

未找到文档

第二部分

这篇 邹晓航 —— UE4菜鸟分析1 简单记录了一下 UE4 渲染流程,两种渲染器,然后走 BasePassRender ,第一阶段创建 Gbuffer,第二阶段做 Lighting

一:创建 GBuffer

1. 起始位置:PixelShaderOutputCommon.ush 中的 MainPS 函数。

  • 输入:FVertexFactoryInterpolantsVSToPSFBasePassInterpolantsVSToPSFMeshDecalInterpolantsSV_Position
  • 输出:out float4 OutTarget0 : SV_Target0 可用范围 0 到 7
  • 函数:根据不同参数,调用 shader。
#if PIXELSHADEROUTPUT_BASEPASS
	FPixelShaderInOut_MainPS(Interpolants, BasePassInterpolants, PixelShaderIn, PixelShaderOut);
#elif PIXELSHADEROUTPUT_MESHDECALPASS
	FPixelShaderInOut_MainPS(Interpolants, MeshDecalInterpolants, PixelShaderIn, PixelShaderOut);
#elif PIXELSHADEROUTPUT_INTERPOLANTS
	FPixelShaderInOut_MainPS(Interpolants, PixelShaderIn, PixelShaderOut);
#else
	FPixelShaderInOut_MainPS(PixelShaderIn, PixelShaderOut);
#endif
 
#if PIXELSHADEROUTPUT_MRT0
	OutTarget0 = PixelShaderOut.MRT[0];
#endif

里面涉及 FPixelShaderIn FPixelShaderOutCommon.ush

// see PixelShaderOutputCommon
struct FPixelShaderIn
{
	// read only
	float4 SvPosition;
 
	// Pixel Shader InCoverage, only usable if PIXELSHADEROUTPUT_COVERAGE is 1
	uint Coverage;
 
	//
	bool bIsFrontFace;
};
// see PixelShaderOutputCommon
struct FPixelShaderOut
{
	// [0..7], only usable if PIXELSHADEROUTPUT_MRT0, PIXELSHADEROUTPUT_MRT1, ... is 1
	float4 MRT[8];
 
	// Pixel Shader OutCoverage, only usable if PIXELSHADEROUTPUT_COVERAGE is 1
	uint Coverage;
 
	// Pixel Shader OutDepth
	float Depth;
};

2.分析 BasePass

#if PIXELSHADEROUTPUT_BASEPASS
	FPixelShaderInOut_MainPS(Interpolants, BasePassInterpolants, PixelShaderIn, PixelShaderOut);

在文件 BasePassPixelShader.usf 中,FPixelShaderInOut_MainPS 开始。

先分析:

FMaterialPixelParameters MaterialParameters = GetMaterialPixelParameters(Interpolants, In.SvPosition);

LocalVertexFactory.ush 文件内:

/** Converts from vertex factory specific interpolants to a FMaterialPixelParameters, which is used by material inputs. */
FMaterialPixelParameters GetMaterialPixelParameters(FVertexFactoryInterpolantsVSToPS Interpolants, float4 SvPosition)
{
	// GetMaterialPixelParameters is responsible for fully initializing the result
	FMaterialPixelParameters Result = MakeInitializedMaterialPixelParameters();
 
#if NUM_TEX_COORD_INTERPOLATORS
	UNROLL
	for( int CoordinateIndex = 0; CoordinateIndex < NUM_TEX_COORD_INTERPOLATORS; CoordinateIndex++ )
	{
		Result.TexCoords[CoordinateIndex] = GetUV(Interpolants, CoordinateIndex);
	}
#endif
 
#if USE_PARTICLE_SUBUVS
	// Output TexCoord0 for when previewing materials that use ParticleSubUV.
	Result.Particle.SubUVCoords[0] = GetUV(Interpolants, 0);
	Result.Particle.SubUVCoords[1] = GetUV(Interpolants, 0);
#endif	// USE_PARTICLE_SUBUVS
 
	half3 TangentToWorld0 = GetTangentToWorld0(Interpolants).xyz;
	half4 TangentToWorld2 = GetTangentToWorld2(Interpolants);
	Result.UnMirrored = TangentToWorld2.w;
 
	Result.VertexColor = GetColor(Interpolants);
 
	// Required for previewing materials that use ParticleColor
	Result.Particle.Color = half4(1,1,1,1);
#if USE_INSTANCING
	Result.PerInstanceParams = Interpolants.PerInstanceParams;
#endif
 
	Result.TangentToWorld = AssembleTangentToWorld( TangentToWorld0, TangentToWorld2 );
#if USE_WORLDVERTEXNORMAL_CENTER_INTERPOLATION
	Result.WorldVertexNormal_Center = Interpolants.TangentToWorld2_Center.xyz;
#endif
 
#if LIGHTMAP_UV_ACCESS
#if NEEDS_LIGHTMAP_COORDINATE
	#if (ES2_PROFILE || ES3_1_PROFILE)
		// Not supported in pixel shader
		Result.LightmapUVs = float2(0, 0);
	#else
		Result.LightmapUVs = Interpolants.LightMapCoordinate.xy;
	#endif	// ES2_PROFILE
#endif	// NEEDS_LIGHTMAP_COORDINATE
#endif	// LIGHTMAP_UV_ACCESS
 
	Result.TwoSidedSign = 1;
	Result.PrimitiveId = GetPrimitiveId(Interpolants);
 
	return Result;
}

再分析 CalcMaterialParametersEx()

#if USE_WORLD_POSITION_EXCLUDING_SHADER_OFFSETS
	{
		float4 ScreenPosition = SvPositionToResolvedScreenPosition(In.SvPosition);
		float3 TranslatedWorldPosition = SvPositionToResolvedTranslatedWorld(In.SvPosition);
		CalcMaterialParametersEx(MaterialParameters, PixelMaterialInputs, In.SvPosition, ScreenPosition, In.bIsFrontFace, TranslatedWorldPosition, BasePassInterpolants.PixelPositionExcludingWPO);
	}
#else
	{
		float4 ScreenPosition = SvPositionToResolvedScreenPosition(In.SvPosition);
		float3 TranslatedWorldPosition = SvPositionToResolvedTranslatedWorld(In.SvPosition);
		CalcMaterialParametersEx(MaterialParameters, PixelMaterialInputs, In.SvPosition, ScreenPosition, In.bIsFrontFace, TranslatedWorldPosition, TranslatedWorldPosition);
	}
#endif

该函数在 MaterialTemplate.ush 中,MaterialTemplate 是材质的模板,场景的材质都会根据这个模板转换成 hlsl 。这个函数模板和实例化内容一样。

/** Initializes the subset of Parameters that was not set in GetMaterialPixelParameters. */
void CalcMaterialParametersEx(
	in out FMaterialPixelParameters Parameters,
	in out FPixelMaterialInputs PixelMaterialInputs,
	float4 SvPosition,
	float4 ScreenPosition,
	FIsFrontFace bIsFrontFace,
	float3 TranslatedWorldPosition,
	float3 TranslatedWorldPositionExcludingShaderOffsets)
{
	// Remove the pre view translation
	Parameters.WorldPosition_CamRelative = TranslatedWorldPosition.xyz;
	Parameters.AbsoluteWorldPosition = TranslatedWorldPosition.xyz - ResolvedView.PreViewTranslation.xyz;
 
	// If the material uses any non-offset world position expressions, calculate those parameters. If not, 
	// the variables will have been initialised to 0 earlier.
#if USE_WORLD_POSITION_EXCLUDING_SHADER_OFFSETS
	Parameters.WorldPosition_NoOffsets_CamRelative = TranslatedWorldPositionExcludingShaderOffsets;
	Parameters.WorldPosition_NoOffsets = TranslatedWorldPositionExcludingShaderOffsets - ResolvedView.PreViewTranslation.xyz;
#endif
 
	Parameters.SvPosition = SvPosition;
	Parameters.ScreenPosition = ScreenPosition;
 
#if COMPILER_GLSL_ES2
	// ES2 normalize isn't done accurately. This seems to fix it.
	// Originally this was normalize(normalize(TranslatedWorldPosition.xyz)) but tegra4 appears to optimize that out.
	Parameters.CameraVector = normalize(-0.01 * Parameters.WorldPosition_CamRelative.xyz);
#else
	#if !RAYHITGROUPSHADER
		// TranslatedWorldPosition is the world position translated to the camera position, which is just -CameraVector
		Parameters.CameraVector = normalize(-Parameters.WorldPosition_CamRelative.xyz);
	#else
		Parameters.CameraVector = -WorldRayDirection();
	#endif
#endif
 
	Parameters.LightVector = 0;
 
	Parameters.TwoSidedSign = 1.0f;
 
#if MATERIAL_TWOSIDED && HAS_PRIMITIVE_UNIFORM_BUFFER
    // #dxr: DirectX Raytracing's HitKind() intrinsic already accounts for negative scaling
    #if PIXELSHADER
	    Parameters.TwoSidedSign *= ResolvedView.CullingSign * GetPrimitiveData(Parameters.PrimitiveId).InvNonUniformScaleAndDeterminantSign.w;
    #endif
 
	#if !MATERIAL_TWOSIDED_SEPARATE_PASS
		Parameters.TwoSidedSign *= GetFloatFacingSign(bIsFrontFace);
	#endif
#endif
 
#if NUM_VIRTUALTEXTURE_SAMPLES || LIGHTMAP_VT_ENABLED
	InitializeVirtualTextureFeedback(Parameters.VirtualTextureFeedback, (uint2)SvPosition.xy, View.FrameNumber);
#endif
 
	// Now that we have all the pixel-related parameters setup, calculate the Material Input/Attributes and Normal
	CalcPixelMaterialInputs(Parameters, PixelMaterialInputs);
}

接着看:CalcPixelMaterialInputs,这个函数在模板和实例化是不同的。

模板内容如下:

void CalcPixelMaterialInputs(in out FMaterialPixelParameters Parameters, in out FPixelMaterialInputs PixelMaterialInputs)
{
	// Initial calculations (required for Normal)
%s
	// The Normal is a special case as it might have its own expressions and also be used to calculate other inputs, so perform the assignment here
%s
 
	// Note that here MaterialNormal can be in world space or tangent space
	float3 MaterialNormal = GetMaterialNormal(Parameters, PixelMaterialInputs);
 
#if MATERIAL_TANGENTSPACENORMAL
#if SIMPLE_FORWARD_SHADING
	Parameters.WorldNormal = float3(0, 0, 1);
#endif
 
#if FEATURE_LEVEL >= FEATURE_LEVEL_SM4
	// ES2 will rely on only the final normalize for performance
	MaterialNormal = normalize(MaterialNormal);
#endif
 
	// normalizing after the tangent space to world space conversion improves quality with sheared bases (UV layout to WS causes shrearing)
	// use full precision normalize to avoid overflows
	Parameters.WorldNormal = TransformTangentNormalToWorld(Parameters.TangentToWorld, MaterialNormal);
 
#else //MATERIAL_TANGENTSPACENORMAL
 
	Parameters.WorldNormal = normalize(MaterialNormal);
 
#endif //MATERIAL_TANGENTSPACENORMAL
 
#if MATERIAL_TANGENTSPACENORMAL
	// flip the normal for backfaces being rendered with a two-sided material
	Parameters.WorldNormal *= Parameters.TwoSidedSign;
#endif
 
	Parameters.ReflectionVector = ReflectionAboutCustomWorldNormal(Parameters, Parameters.WorldNormal, false);
 
#if !PARTICLE_SPRITE_FACTORY
	Parameters.Particle.MotionBlurFade = 1.0f;
#endif // !PARTICLE_SPRITE_FACTORY
 
	// Now the rest of the inputs
%s
}

实例化内容如下:

void CalcPixelMaterialInputs(in out FMaterialPixelParameters Parameters, in out FPixelMaterialInputs PixelMaterialInputs)
{
    // Initial calculations (required for Normal)
 
    // The Normal is a special case as it might have its own expressions and also be used to calculate other inputs, so perform the assignment here
    PixelMaterialInputs.Normal = MaterialFloat3(0.00000000,0.00000000,1.00000000);
 
 
    // Note that here MaterialNormal can be in world space or tangent space
    float3 MaterialNormal = GetMaterialNormal(Parameters, PixelMaterialInputs);
 
#if MATERIAL_TANGENTSPACENORMAL
#if SIMPLE_FORWARD_SHADING
    Parameters.WorldNormal = float3(0, 0, 1);
#endif
 
#if FEATURE_LEVEL >= FEATURE_LEVEL_SM4
    // Mobile will rely on only the final normalize for performance
    MaterialNormal = normalize(MaterialNormal);
#endif
 
    // normalizing after the tangent space to world space conversion improves quality with sheared bases (UV layout to WS causes shrearing)
    // use full precision normalize to avoid overflows
    Parameters.WorldNormal = TransformTangentNormalToWorld(Parameters.TangentToWorld, MaterialNormal);
 
#else //MATERIAL_TANGENTSPACENORMAL
 
    Parameters.WorldNormal = normalize(MaterialNormal);
 
#endif //MATERIAL_TANGENTSPACENORMAL
 
#if MATERIAL_TANGENTSPACENORMAL
    // flip the normal for backfaces being rendered with a two-sided material
    Parameters.WorldNormal *= Parameters.TwoSidedSign;
#endif
 
    Parameters.ReflectionVector = ReflectionAboutCustomWorldNormal(Parameters, Parameters.WorldNormal, false);
 
#if !PARTICLE_SPRITE_FACTORY
    Parameters.Particle.MotionBlurFade = 1.0f;
#endif // !PARTICLE_SPRITE_FACTORY
 
    // Now the rest of the inputs
    MaterialFloat4 Local0 = SceneTextureLookup(GetDefaultSceneTextureUV(Parameters, 25), 25, false);
    MaterialFloat3 Local1 = lerp(Local0.rgba.rgb,Material.VectorExpressions[1].rgb,MaterialFloat(Material.ScalarExpressions[0].x));
 
    PixelMaterialInputs.EmissiveColor = Local1;
    PixelMaterialInputs.Opacity = 1.00000000;
    PixelMaterialInputs.OpacityMask = 1.00000000;
    PixelMaterialInputs.BaseColor = MaterialFloat3(0.00000000,0.00000000,0.00000000);
    PixelMaterialInputs.Metallic = 0.00000000;
    PixelMaterialInputs.Specular = 0.50000000;
    PixelMaterialInputs.Roughness = 0.50000000;
    PixelMaterialInputs.Anisotropy = 0.00000000;
    PixelMaterialInputs.Tangent = MaterialFloat3(1.00000000,0.00000000,0.00000000);
    PixelMaterialInputs.Subsurface = 0;
    PixelMaterialInputs.AmbientOcclusion = 1.00000000;
    PixelMaterialInputs.Refraction = 0;
    PixelMaterialInputs.PixelDepthOffset = 0.00000000;
    PixelMaterialInputs.ShadingModel = 0;
 
#if MATERIAL_USES_ANISOTROPY
    Parameters.WorldTangent = CalculateAnisotropyTangent(Parameters, PixelMaterialInputs);
#else
    Parameters.WorldTangent = 0;
#endif
}

二:Lighting

第三部分

1、蓝图材质转换 HLSL 代码

在蓝图中创建 Post Process Material,然后创建 SceneTextureID 选择 CustomStencil ,如下图:

image.png

在材质编辑器下,点击 Window->Shader Code->HLSL Code, copy 对应代码,保存生成 custom.hsls 文件(名称随便命名,目的方便描述该文件)。

  • HLSL code 是基于 MaterialTemplate.ush (Engine/Shader/Private)进行生成。
  • 如何生成?目前没有深入研究,待后续更新(如果用到)。

对比 MaterialTemplate.ushcustom.hsls 文件。在 VSCode 中,左侧目录同时选中两个文件,右键,有 compare 功能,进行对比哪些是 custom.hsls 新增的。

实际对比,发现有大量的不同出现,然而我们在材质蓝图中,仅仅增加了一个 SceneTexture 函数,不应该有很多变化。没有深入分析原因,后面用到再研究。

本次研究的重点是如何获得 SceneTexture ,测试的 IDCustomStencil 。而不是 Post Process Material 如何被使用,因此下面内容会围绕本次重点展开。

custom.hsls 中找出 Emissive Color 赋值出现的位置:

void CalcPixelMaterialInputs(in out FMaterialPixelParameters Parameters, in out FPixelMaterialInputs PixelMaterialInputs)

不研究 CalcPixelMaterialInputs 如何被使用,只研究里面的内容。

EmissiveColor 是有两个数值差值的出来。

  • Local0 是和 SceneTexture 相关,深入研究
  • Material.VectorExpression[1].rgb,不是重点,没有深入研究。

关键部分代码

MaterialFloat4 Local0 = SceneTextureLookup(GetDefaultSceneTextureUV(Parameters, 25), 25, false);
MaterialFloat3 Local1 = erp(Local0.rgba.rgb,Material.VectorExpressions[1].rgb,MaterialFloat(Material.ScalarExpressions[0].x));
PixelMaterialInputs.EmissiveColor = Local1;

SceneTextureLookup 函数介绍

/** Applies an offset to the scene texture lookup and decodes the HDR linear space color. */
float4 SceneTextureLookup(float2 UV, int SceneTextureIndex, bool bFiltered)
{
#if SCENE_TEXTURES_DISABLED
    return float4(0.0f, 0.0f, 0.0f, 0.0f);
#endif
 
    FScreenSpaceData ScreenSpaceData = GetScreenSpaceData(UV, false);
    switch(SceneTextureIndex)
    {
        // order needs to match to ESceneTextureId
 
        case PPI_SceneColor:
            return float4(CalcSceneColor(UV), 0);
        case PPI_SceneDepth:
            return ScreenSpaceData.GBuffer.Depth;
        case PPI_DiffuseColor:
            return float4(ScreenSpaceData.GBuffer.DiffuseColor, 0);
        case PPI_SpecularColor:
            return float4(ScreenSpaceData.GBuffer.SpecularColor, 0);
        case PPI_SubsurfaceColor:
            return IsSubsurfaceModel(ScreenSpaceData.GBuffer.ShadingModelID) ? float4( ExtractSubsurfaceColor(ScreenSpaceData.GBuffer), ScreenSpaceData.GBuffer.CustomData.a ) : ScreenSpaceData.GBuffer.CustomData;
        case PPI_BaseColor:
            return float4(ScreenSpaceData.GBuffer.BaseColor, 0);
        case PPI_Specular:
            return ScreenSpaceData.GBuffer.Specular;
        case PPI_Metallic:
            return ScreenSpaceData.GBuffer.Metallic;
        case PPI_WorldNormal:
            return float4(ScreenSpaceData.GBuffer.WorldNormal, 0);
        case PPI_SeparateTranslucency:
            return float4(1, 1, 1, 1);    // todo
        case PPI_Opacity:
            return ScreenSpaceData.GBuffer.CustomData.a;
        case PPI_Roughness:
            return ScreenSpaceData.GBuffer.Roughness;
        case PPI_MaterialAO:
            return ScreenSpaceData.GBuffer.GBufferAO;
        case PPI_CustomDepth:
            return ScreenSpaceData.GBuffer.CustomDepth;
#if POST_PROCESS_MATERIAL
        case PPI_PostProcessInput0:
            return Texture2DSample(PostProcessInput_0_Texture, bFiltered ? PostProcessInput_BilinearSampler : PostProcessInput_0_SharedSampler, UV);
        case PPI_PostProcessInput1:
            return Texture2DSample(PostProcessInput_1_Texture, bFiltered ? PostProcessInput_BilinearSampler : PostProcessInput_1_SharedSampler, UV);
        case PPI_PostProcessInput2:
            return Texture2DSample(PostProcessInput_2_Texture, bFiltered ? PostProcessInput_BilinearSampler : PostProcessInput_2_SharedSampler, UV);
        case PPI_PostProcessInput3:
            return Texture2DSample(PostProcessInput_3_Texture, bFiltered ? PostProcessInput_BilinearSampler : PostProcessInput_3_SharedSampler, UV);
        case PPI_PostProcessInput4:
            return Texture2DSample(PostProcessInput_4_Texture, bFiltered ? PostProcessInput_BilinearSampler : PostProcessInput_4_SharedSampler, UV);
#endif // __POST_PROCESS_COMMON__
        case PPI_DecalMask:
            return 0;  // material compiler will return an error
        case PPI_ShadingModelColor:
            return float4(GetShadingModelColor(ScreenSpaceData.GBuffer.ShadingModelID), 1);
        case PPI_ShadingModelID:
            return float4(ScreenSpaceData.GBuffer.ShadingModelID, 0, 0, 0);
        case PPI_AmbientOcclusion:
            return ScreenSpaceData.AmbientOcclusion;
        case PPI_CustomStencil:
            return ScreenSpaceData.GBuffer.CustomStencil;
        case PPI_StoredBaseColor:
            return float4(ScreenSpaceData.GBuffer.StoredBaseColor, 0);
        case PPI_StoredSpecular:
            return float4(ScreenSpaceData.GBuffer.StoredSpecular.rrr, 0);
#if POST_PROCESS_MATERIAL
        case PPI_Velocity:
            return float4(PostProcessVelocityLookup(ConvertToDeviceZ(ScreenSpaceData.GBuffer.Depth), UV), 0, 0);
#endif
        case PPI_WorldTangent:
            return float4(ScreenSpaceData.GBuffer.WorldTangent, 0);
        case PPI_Anisotropy:
            return ScreenSpaceData.GBuffer.Anisotropy;
        default:
            return float4(0, 0, 0, 0);
    }
}

GetScreenSpaceDataDeferredShadingCommon.ush 文件中。

// @param UV - UV space in the GBuffer textures (BufferSize resolution)
FScreenSpaceData GetScreenSpaceData(float2 UV, bool bGetNormalizedNormal = true)
{
	FScreenSpaceData Out;
 
	Out.GBuffer = GetGBufferData(UV, bGetNormalizedNormal);
	float4 ScreenSpaceAO = Texture2DSampleLevel(SceneTexturesStruct.ScreenSpaceAOTexture, SceneTexturesStruct.ScreenSpaceAOTextureSampler, UV, 0);
 
	Out.AmbientOcclusion = ScreenSpaceAO.r;
 
	return Out;
}

在相同文件内 GetGBufferData

// @param UV - UV space in the GBuffer textures (BufferSize resolution)
FGBufferData GetGBufferData(float2 UV, bool bGetNormalizedNormal = true)
{
#if 0 //METAL_MRT_PROFILE
	// @todo metal mrt: The deferred renderer isn't keeping these in tiled memory all the time - we don't know when this makes sense
	// versus just sampling a bound resolved texture
	float4 GBufferA = FramebufferFetchMRT(1);
	float4 GBufferB = FramebufferFetchMRT(2);
	float4 GBufferC = FramebufferFetchMRT(3);
	float4 GBufferD = FramebufferFetchMRT(4);
	// @todo metal mrt: We can't framebuffer fetch the depth, can we jam it in somewhere?
	float CustomNativeDepth = 0.5;
	#if ALLOW_STATIC_LIGHTING
		float4 GBufferE = FramebufferFetchMRT(5);
	#else
		float4 GBufferE = 1;
	#endif
#else	
	float4 GBufferA = Texture2DSampleLevel(SceneTexturesStruct.GBufferATexture, SceneTexturesStruct.GBufferATextureSampler, UV, 0);
	float4 GBufferB = Texture2DSampleLevel(SceneTexturesStruct.GBufferBTexture, SceneTexturesStruct.GBufferBTextureSampler, UV, 0);
	float4 GBufferC = Texture2DSampleLevel(SceneTexturesStruct.GBufferCTexture, SceneTexturesStruct.GBufferCTextureSampler, UV, 0);
	float4 GBufferD = Texture2DSampleLevel(SceneTexturesStruct.GBufferDTexture, SceneTexturesStruct.GBufferDTextureSampler, UV, 0);
	float CustomNativeDepth = Texture2DSampleLevel(SceneTexturesStruct.CustomDepthTexture, SceneTexturesStruct.CustomDepthTextureSampler, UV, 0).r;
 
#if FEATURE_LEVEL >= FEATURE_LEVEL_SM4
	int2 IntUV = (int2)trunc(UV * View.BufferSizeAndInvSize.xy);
	uint CustomStencil = SceneTexturesStruct.CustomStencilTexture.Load(int3(IntUV, 0)) STENCIL_COMPONENT_SWIZZLE;
#else
	uint CustomStencil = 0;
#endif
 
	#if ALLOW_STATIC_LIGHTING
		float4 GBufferE = Texture2DSampleLevel(SceneTexturesStruct.GBufferETexture, SceneTexturesStruct.GBufferETextureSampler, UV, 0);
	#else
		float4 GBufferE = 1;
	#endif
 
	#if WRITES_VELOCITY_TO_GBUFFER
		float4 GBufferVelocity = Texture2DSampleLevel(SceneTexturesStruct.GBufferVelocityTexture, SceneTexturesStruct.GBufferVelocityTextureSampler, UV, 0);
	#else
		float4 GBufferVelocity = 0;
	#endif
#endif
 
	float SceneDepth = CalcSceneDepth(UV);
	
	return DecodeGBufferData(GBufferA, GBufferB, GBufferC, GBufferD, GBufferE, GBufferVelocity, CustomNativeDepth, CustomStencil, SceneDepth, bGetNormalizedNormal, CheckerFromSceneColorUV(UV));
}

在相同文件里 DecodeGBufferData

/** Populates FGBufferData */
// @param bChecker High frequency Checkerboard pattern computed with one of the CheckerFrom.. functions, todo: profile if float 0/1 would be better (need to make sure it's 100% the same)
FGBufferData DecodeGBufferData(
	float4 InGBufferA,
	float4 InGBufferB,
	float4 InGBufferC,
	float4 InGBufferD,
	float4 InGBufferE,
	float4 InGBufferVelocity,
	float CustomNativeDepth,
	uint CustomStencil,
	float SceneDepth,
	bool bGetNormalizedNormal,
	bool bChecker)
{
	FGBufferData GBuffer;
 
	GBuffer.WorldNormal = DecodeNormal( InGBufferA.xyz );
	if(bGetNormalizedNormal)
	{
		GBuffer.WorldNormal = normalize(GBuffer.WorldNormal);
	}
 
	GBuffer.PerObjectGBufferData = InGBufferA.a;  
	GBuffer.Metallic	= InGBufferB.r;
	GBuffer.Specular	= InGBufferB.g;
	GBuffer.Roughness	= InGBufferB.b;
	// Note: must match GetShadingModelId standalone function logic
	// Also Note: SimpleElementPixelShader directly sets SV_Target2 ( GBufferB ) to indicate unlit.
	// An update there will be required if this layout changes.
	GBuffer.ShadingModelID = DecodeShadingModelId(InGBufferB.a);
	GBuffer.SelectiveOutputMask = DecodeSelectiveOutputMask(InGBufferB.a);
 
	GBuffer.BaseColor = DecodeBaseColor(InGBufferC.rgb);
 
#if ALLOW_STATIC_LIGHTING
	GBuffer.GBufferAO = 1;
	GBuffer.IndirectIrradiance = DecodeIndirectIrradiance(InGBufferC.a);
#else
	GBuffer.GBufferAO = InGBufferC.a;
	GBuffer.IndirectIrradiance = 1;
#endif
 
	GBuffer.CustomData = !(GBuffer.SelectiveOutputMask & SKIP_CUSTOMDATA_MASK) ? InGBufferD : 0;
 
	GBuffer.PrecomputedShadowFactors = !(GBuffer.SelectiveOutputMask & SKIP_PRECSHADOW_MASK) ? InGBufferE :  ((GBuffer.SelectiveOutputMask & ZERO_PRECSHADOW_MASK) ? 0 :  1);
	GBuffer.CustomDepth = ConvertFromDeviceZ(CustomNativeDepth);
	GBuffer.CustomStencil = CustomStencil;
	GBuffer.Depth = SceneDepth;
 
	GBuffer.StoredBaseColor = GBuffer.BaseColor;
	GBuffer.StoredMetallic = GBuffer.Metallic;
	GBuffer.StoredSpecular = GBuffer.Specular;
 
	FLATTEN
	if( GBuffer.ShadingModelID == SHADINGMODELID_EYE )
	{
		GBuffer.Metallic = 0.0;
#if IRIS_NORMAL
		GBuffer.Specular = 0.25;
#endif
	}
 
	// derived from BaseColor, Metalness, Specular
	{
		GBuffer.SpecularColor = ComputeF0(GBuffer.Specular, GBuffer.BaseColor, GBuffer.Metallic);
 
		if (UseSubsurfaceProfile(GBuffer.ShadingModelID))
		{
			AdjustBaseColorAndSpecularColorForSubsurfaceProfileLighting(GBuffer.BaseColor, GBuffer.SpecularColor, GBuffer.Specular, bChecker);
		}
 
		GBuffer.DiffuseColor = GBuffer.BaseColor - GBuffer.BaseColor * GBuffer.Metallic;
 
		#if USE_DEVELOPMENT_SHADERS
		{
			// this feature is only needed for development/editor - we can compile it out for a shipping build (see r.CompileShadersForDevelopment cvar help)
			GBuffer.DiffuseColor = GBuffer.DiffuseColor * View.DiffuseOverrideParameter.www + View.DiffuseOverrideParameter.xyz;
			GBuffer.SpecularColor = GBuffer.SpecularColor * View.SpecularOverrideParameter.w + View.SpecularOverrideParameter.xyz;
		}
		#endif //USE_DEVELOPMENT_SHADERS
	}
 
	GBuffer.Velocity = !(GBuffer.SelectiveOutputMask & SKIP_VELOCITY_MASK) ? InGBufferVelocity : 0;
 
	return GBuffer;
}

回归到测试 IDCustomStencil

#if FEATURE_LEVEL >= FEATURE_LEVEL_SM4
	int2 IntUV = (int2)trunc(UV * View.BufferSizeAndInvSize.xy);
	uint CustomStencil = SceneTexturesStruct.CustomStencilTexture.Load(int3(IntUV, 0)) STENCIL_COMPONENT_SWIZZLE;
#else
	uint CustomStencil = 0;
#endif

第四部分

UE4 PixelFormat

Epic Games\UE_4.24\Engine\Source\Runtime\CoreUObject\Public\UObject\NoExportTypes.h

/**
 * Describes the format of a each pixel in a graphics buffer.
 * @warning: When you update this, you must add an entry to GPixelFormats(see RenderUtils.cpp)
 * @warning: When you update this, you must add an entries to PixelFormat.h, usually just copy the generated section on the header into EPixelFormat
 * @warning: The *Tools DLLs will also need to be recompiled if the ordering is changed, but should not need code changes.
 */
UENUM()
enum EPixelFormat
{
	PF_Unknown,
	PF_A32B32G32R32F,
	/** UNORM (0..1), corresponds to FColor.  Unpacks as rgba in the shader. */
	PF_B8G8R8A8,
	/** UNORM red (0..1) */
	PF_G8,
	PF_G16,
	PF_DXT1,
	PF_DXT3,
	PF_DXT5,
	PF_UYVY,
	/** Same as PF_FloatR11G11B10 */
	PF_FloatRGB,
	/** RGBA 16 bit signed FP format.  Use FFloat16Color on the CPU. */
	PF_FloatRGBA,
	/** A depth+stencil format with platform-specific implementation, for use with render targets. */
	PF_DepthStencil,
	/** A depth format with platform-specific implementation, for use with render targets. */
	PF_ShadowDepth,
	PF_R32_FLOAT,
	PF_G16R16,
	PF_G16R16F,
	PF_G16R16F_FILTER,
	PF_G32R32F,
	PF_A2B10G10R10,
	PF_A16B16G16R16,
	PF_D24,
	PF_R16F,
	PF_R16F_FILTER,
	PF_BC5,
	/** SNORM red, green (-1..1). Not supported on all RHI e.g. Metal */
	PF_V8U8,
	PF_A1,
	/** A low precision floating point format, unsigned.  Use FFloat3Packed on the CPU. */
	PF_FloatR11G11B10,
	PF_A8,
	PF_R32_UINT,
	PF_R32_SINT,
	PF_PVRTC2,
	PF_PVRTC4,
	PF_R16_UINT,
	PF_R16_SINT,
	PF_R16G16B16A16_UINT,
	PF_R16G16B16A16_SINT,
	PF_R5G6B5_UNORM,
	PF_R8G8B8A8,
	/** Only used for legacy loading; do NOT use! */
	PF_A8R8G8B8,
	/** High precision single channel block compressed, equivalent to a single channel BC5, 8 bytes per 4x4 block. */
	PF_BC4,
	/** UNORM red, green (0..1). */
	PF_R8G8,
	/** ATITC format. */
	PF_ATC_RGB,
	/** ATITC format. */
	PF_ATC_RGBA_E,
	/** ATITC format. */
	PF_ATC_RGBA_I,
	/** Used for creating SRVs to alias a DepthStencil buffer to read Stencil.  Don't use for creating textures. */
	PF_X24_G8,
	PF_ETC1,
	PF_ETC2_RGB,
	PF_ETC2_RGBA,
	PF_R32G32B32A32_UINT,
	PF_R16G16_UINT,
	/** 8.00 bpp */
	PF_ASTC_4x4,
	/** 3.56 bpp */
	PF_ASTC_6x6,
	/** 2.00 bpp */
	PF_ASTC_8x8,
	/** 1.28 bpp */
	PF_ASTC_10x10,
	/** 0.89 bpp */
	PF_ASTC_12x12,
	PF_BC6H,
	PF_BC7,
	PF_R8_UINT,
	PF_L8,
	PF_XGXR8,
	PF_R8G8B8A8_UINT,
	/** SNORM (-1..1), corresponds to FFixedRGBASigned8. */
	PF_R8G8B8A8_SNORM,
	PF_R16G16B16A16_UNORM,
	PF_R16G16B16A16_SNORM,
	PF_PLATFORM_HDR_0,
	PF_PLATFORM_HDR_1,
	PF_PLATFORM_HDR_2,
	PF_NV12,
	PF_R32G32_UINT,
	PF_MAX,
};

Epic Games\UE_4.24\Engine\Source\Runtime\RenderCore\Private\RenderUtils.cpp

FPixelFormatInfo	GPixelFormats[PF_MAX] =
{
	// Name						BlockSizeX	BlockSizeY	BlockSizeZ	BlockBytes	NumComponents	PlatformFormat	Supported		UnrealFormat
 
	{ TEXT("unknown"),			0,			0,			0,			0,			0,				0,				0,				PF_Unknown			},
	{ TEXT("A32B32G32R32F"),	1,			1,			1,			16,			4,				0,				1,				PF_A32B32G32R32F	},
	{ TEXT("B8G8R8A8"),			1,			1,			1,			4,			4,				0,				1,				PF_B8G8R8A8			},
	{ TEXT("G8"),				1,			1,			1,			1,			1,				0,				1,				PF_G8				},
	{ TEXT("G16"),				1,			1,			1,			2,			1,				0,				1,				PF_G16				},
	{ TEXT("DXT1"),				4,			4,			1,			8,			3,				0,				1,				PF_DXT1				},
	{ TEXT("DXT3"),				4,			4,			1,			16,			4,				0,				1,				PF_DXT3				},
	{ TEXT("DXT5"),				4,			4,			1,			16,			4,				0,				1,				PF_DXT5				},
	{ TEXT("UYVY"),				2,			1,			1,			4,			4,				0,				0,				PF_UYVY				},
	{ TEXT("FloatRGB"),			1,			1,			1,			4,			3,				0,				1,				PF_FloatRGB			},
	{ TEXT("FloatRGBA"),		1,			1,			1,			8,			4,				0,				1,				PF_FloatRGBA		},
	{ TEXT("DepthStencil"),		1,			1,			1,			4,			1,				0,				0,				PF_DepthStencil		},
	{ TEXT("ShadowDepth"),		1,			1,			1,			4,			1,				0,				0,				PF_ShadowDepth		},
	{ TEXT("R32_FLOAT"),		1,			1,			1,			4,			1,				0,				1,				PF_R32_FLOAT		},
	{ TEXT("G16R16"),			1,			1,			1,			4,			2,				0,				1,				PF_G16R16			},
	{ TEXT("G16R16F"),			1,			1,			1,			4,			2,				0,				1,				PF_G16R16F			},
	{ TEXT("G16R16F_FILTER"),	1,			1,			1,			4,			2,				0,				1,				PF_G16R16F_FILTER	},
	{ TEXT("G32R32F"),			1,			1,			1,			8,			2,				0,				1,				PF_G32R32F			},
	{ TEXT("A2B10G10R10"),      1,          1,          1,          4,          4,              0,              1,				PF_A2B10G10R10		},
	{ TEXT("A16B16G16R16"),		1,			1,			1,			8,			4,				0,				1,				PF_A16B16G16R16		},
	{ TEXT("D24"),				1,			1,			1,			4,			1,				0,				1,				PF_D24				},
	{ TEXT("PF_R16F"),			1,			1,			1,			2,			1,				0,				1,				PF_R16F				},
	{ TEXT("PF_R16F_FILTER"),	1,			1,			1,			2,			1,				0,				1,				PF_R16F_FILTER		},
	{ TEXT("BC5"),				4,			4,			1,			16,			2,				0,				1,				PF_BC5				},
	{ TEXT("V8U8"),				1,			1,			1,			2,			2,				0,				1,				PF_V8U8				},
	{ TEXT("A1"),				1,			1,			1,			1,			1,				0,				0,				PF_A1				},
	{ TEXT("FloatR11G11B10"),	1,			1,			1,			4,			3,				0,				0,				PF_FloatR11G11B10	},
	{ TEXT("A8"),				1,			1,			1,			1,			1,				0,				1,				PF_A8				},	
	{ TEXT("R32_UINT"),			1,			1,			1,			4,			1,				0,				1,				PF_R32_UINT			},
	{ TEXT("R32_SINT"),			1,			1,			1,			4,			1,				0,				1,				PF_R32_SINT			},
 
	// IOS Support
	{ TEXT("PVRTC2"),			8,			4,			1,			8,			4,				0,				0,				PF_PVRTC2			},
	{ TEXT("PVRTC4"),			4,			4,			1,			8,			4,				0,				0,				PF_PVRTC4			},
 
	{ TEXT("R16_UINT"),			1,			1,			1,			2,			1,				0,				1,				PF_R16_UINT			},
	{ TEXT("R16_SINT"),			1,			1,			1,			2,			1,				0,				1,				PF_R16_SINT			},
	{ TEXT("R16G16B16A16_UINT"),1,			1,			1,			8,			4,				0,				1,				PF_R16G16B16A16_UINT},
	{ TEXT("R16G16B16A16_SINT"),1,			1,			1,			8,			4,				0,				1,				PF_R16G16B16A16_SINT},
	{ TEXT("R5G6B5_UNORM"),     1,          1,          1,          2,          3,              0,              1,              PF_R5G6B5_UNORM		},
	{ TEXT("R8G8B8A8"),			1,			1,			1,			4,			4,				0,				1,				PF_R8G8B8A8			},
	{ TEXT("A8R8G8B8"),			1,			1,			1,			4,			4,				0,				1,				PF_A8R8G8B8			},
	{ TEXT("BC4"),				4,			4,			1,			8,			1,				0,				1,				PF_BC4				},
	{ TEXT("R8G8"),				1,			1,			1,			2,			2,				0,				1,				PF_R8G8				},
 
	{ TEXT("ATC_RGB"),			4,			4,			1,			8,			3,				0,				0,				PF_ATC_RGB			},
	{ TEXT("ATC_RGBA_E"),		4,			4,			1,			16,			4,				0,				0,				PF_ATC_RGBA_E		},
	{ TEXT("ATC_RGBA_I"),		4,			4,			1,			16,			4,				0,				0,				PF_ATC_RGBA_I		},
	{ TEXT("X24_G8"),			1,			1,			1,			1,			1,				0,				0,				PF_X24_G8			},
	{ TEXT("ETC1"),				4,			4,			1,			8,			3,				0,				0,				PF_ETC1				},
	{ TEXT("ETC2_RGB"),			4,			4,			1,			8,			3,				0,				0,				PF_ETC2_RGB			},
	{ TEXT("ETC2_RGBA"),		4,			4,			1,			16,			4,				0,				0,				PF_ETC2_RGBA		},
	{ TEXT("PF_R32G32B32A32_UINT"),1,		1,			1,			16,			4,				0,				1,				PF_R32G32B32A32_UINT},
	{ TEXT("PF_R16G16_UINT"),	1,			1,			1,			4,			4,				0,				1,				PF_R16G16_UINT},
 
	// ASTC support
	{ TEXT("ASTC_4x4"),			4,			4,			1,			16,			4,				0,				0,				PF_ASTC_4x4			},
	{ TEXT("ASTC_6x6"),			6,			6,			1,			16,			4,				0,				0,				PF_ASTC_6x6			},
	{ TEXT("ASTC_8x8"),			8,			8,			1,			16,			4,				0,				0,				PF_ASTC_8x8			},
	{ TEXT("ASTC_10x10"),		10,			10,			1,			16,			4,				0,				0,				PF_ASTC_10x10		},
	{ TEXT("ASTC_12x12"),		12,			12,			1,			16,			4,				0,				0,				PF_ASTC_12x12		},
 
	{ TEXT("BC6H"),				4,			4,			1,			16,			3,				0,				1,				PF_BC6H				},
	{ TEXT("BC7"),				4,			4,			1,			16,			4,				0,				1,				PF_BC7				},
	{ TEXT("R8_UINT"),			1,			1,			1,			1,			1,				0,				1,				PF_R8_UINT			},
	{ TEXT("L8"),				1,			1,			1,			1,			1,				0,				0,				PF_L8				},
	{ TEXT("XGXR8"),			1,			1,			1,			4,			4,				0,				1,				PF_XGXR8 			},
	{ TEXT("R8G8B8A8_UINT"),	1,			1,			1,			4,			4,				0,				1,				PF_R8G8B8A8_UINT	},
	{ TEXT("R8G8B8A8_SNORM"),	1,			1,			1,			4,			4,				0,				1,				PF_R8G8B8A8_SNORM	},
 
	{ TEXT("R16G16B16A16_UINT"),1,			1,			1,			8,			4,				0,				1,				PF_R16G16B16A16_UNORM },
	{ TEXT("R16G16B16A16_SINT"),1,			1,			1,			8,			4,				0,				1,				PF_R16G16B16A16_SNORM },
	{ TEXT("PLATFORM_HDR_0"),	0,			0,			0,			0,			0,				0,				0,				PF_PLATFORM_HDR_0   },
	{ TEXT("PLATFORM_HDR_1"),	0,			0,			0,			0,			0,				0,				0,				PF_PLATFORM_HDR_1   },
	{ TEXT("PLATFORM_HDR_2"),	0,			0,			0,			0,			0,				0,				0,				PF_PLATFORM_HDR_2   },
 
	// NV12 contains 2 textures: R8 luminance plane followed by R8G8 1/4 size chrominance plane.
	// BlockSize/BlockBytes/NumComponents values don't make much sense for this format, so set them all to one.
	{ TEXT("NV12"),				1,			1,			1,			1,			1,				0,				0,				PF_NV12             },
 
	{ TEXT("PF_R32G32_UINT"),   1,   		1,			1,			8,			2,				0,				1,				PF_R32G32_UINT      },
};

D3D11Device.cpp

// Initialize the platform pixel format map.
GPixelFormats[PF_Unknown].PlatformFormat = DXGI_FORMAT_UNKNOWN;
GPixelFormats[PF_A32B32G32R32F].PlatformFormat = DXGI_FORMAT_R32G32B32A32_FLOAT;
GPixelFormats[PF_B8G8R8A8].PlatformFormat = DXGI_FORMAT_B8G8R8A8_TYPELESS;
GPixelFormats[PF_G8].PlatformFormat = DXGI_FORMAT_R8_UNORM;
GPixelFormats[PF_G16].PlatformFormat = DXGI_FORMAT_R16_UNORM;
GPixelFormats[PF_DXT1].PlatformFormat = DXGI_FORMAT_BC1_TYPELESS;
GPixelFormats[PF_DXT3].PlatformFormat = DXGI_FORMAT_BC2_TYPELESS;
GPixelFormats[PF_DXT5].PlatformFormat = DXGI_FORMAT_BC3_TYPELESS;
GPixelFormats[PF_BC4].PlatformFormat = DXGI_FORMAT_BC4_UNORM;
GPixelFormats[PF_UYVY].PlatformFormat = DXGI_FORMAT_UNKNOWN; // TODO: Not supported in D3D11
if (CVarD3D11UseD24.GetValueOnAnyThread())
{
    GPixelFormats[PF_DepthStencil].PlatformFormat = DXGI_FORMAT_R24G8_TYPELESS;
    GPixelFormats[PF_DepthStencil].BlockBytes = 4;
    GPixelFormats[PF_X24_G8].PlatformFormat = DXGI_FORMAT_X24_TYPELESS_G8_UINT;
    GPixelFormats[PF_X24_G8].BlockBytes = 4;
}
else
{
    GPixelFormats[PF_DepthStencil].PlatformFormat = DXGI_FORMAT_R32G8X24_TYPELESS;
    GPixelFormats[PF_DepthStencil].BlockBytes = 5;
    GPixelFormats[PF_X24_G8].PlatformFormat = DXGI_FORMAT_X32_TYPELESS_G8X24_UINT;
    GPixelFormats[PF_X24_G8].BlockBytes = 5;
}
GPixelFormats[PF_DepthStencil].Supported = true;
GPixelFormats[PF_X24_G8].Supported = true;
GPixelFormats[PF_ShadowDepth].PlatformFormat = DXGI_FORMAT_R16_TYPELESS;
GPixelFormats[PF_ShadowDepth].BlockBytes = 2;
GPixelFormats[PF_ShadowDepth].Supported = true;
GPixelFormats[PF_R32_FLOAT].PlatformFormat = DXGI_FORMAT_R32_FLOAT;
GPixelFormats[PF_G16R16].PlatformFormat = DXGI_FORMAT_R16G16_UNORM;
GPixelFormats[PF_G16R16F].PlatformFormat = DXGI_FORMAT_R16G16_FLOAT;
GPixelFormats[PF_G16R16F_FILTER].PlatformFormat = DXGI_FORMAT_R16G16_FLOAT;
GPixelFormats[PF_G32R32F].PlatformFormat = DXGI_FORMAT_R32G32_FLOAT;
GPixelFormats[PF_A2B10G10R10].PlatformFormat = DXGI_FORMAT_R10G10B10A2_UNORM;
GPixelFormats[PF_A16B16G16R16].PlatformFormat = DXGI_FORMAT_R16G16B16A16_UNORM;
GPixelFormats[PF_D24].PlatformFormat = DXGI_FORMAT_R24G8_TYPELESS;
GPixelFormats[PF_R16F].PlatformFormat = DXGI_FORMAT_R16_FLOAT;
GPixelFormats[PF_R16F_FILTER].PlatformFormat = DXGI_FORMAT_R16_FLOAT;

GPixelFormats[PF_FloatRGB].PlatformFormat = DXGI_FORMAT_R11G11B10_FLOAT;
GPixelFormats[PF_FloatRGB].BlockBytes = 4;
GPixelFormats[PF_FloatRGBA].PlatformFormat = DXGI_FORMAT_R16G16B16A16_FLOAT;
GPixelFormats[PF_FloatRGBA].BlockBytes = 8;

GPixelFormats[PF_FloatR11G11B10].PlatformFormat = DXGI_FORMAT_R11G11B10_FLOAT;
GPixelFormats[PF_FloatR11G11B10].BlockBytes = 4;
GPixelFormats[PF_FloatR11G11B10].Supported = true;

GPixelFormats[PF_V8U8].PlatformFormat = DXGI_FORMAT_R8G8_SNORM;
GPixelFormats[PF_BC5].PlatformFormat = DXGI_FORMAT_BC5_UNORM;
GPixelFormats[PF_A1].PlatformFormat = DXGI_FORMAT_R1_UNORM; // Not supported for rendering.
GPixelFormats[PF_A8].PlatformFormat = DXGI_FORMAT_A8_UNORM;
GPixelFormats[PF_R32_UINT].PlatformFormat = DXGI_FORMAT_R32_UINT;
GPixelFormats[PF_R32_SINT].PlatformFormat = DXGI_FORMAT_R32_SINT;

GPixelFormats[PF_R16_UINT].PlatformFormat = DXGI_FORMAT_R16_UINT;
GPixelFormats[PF_R16_SINT].PlatformFormat = DXGI_FORMAT_R16_SINT;
GPixelFormats[PF_R16G16B16A16_UINT].PlatformFormat = DXGI_FORMAT_R16G16B16A16_UINT;
GPixelFormats[PF_R16G16B16A16_SINT].PlatformFormat = DXGI_FORMAT_R16G16B16A16_SINT;

GPixelFormats[PF_R5G6B5_UNORM].PlatformFormat = DXGI_FORMAT_B5G6R5_UNORM;
GPixelFormats[PF_R8G8B8A8].PlatformFormat = DXGI_FORMAT_R8G8B8A8_TYPELESS;
GPixelFormats[PF_R8G8B8A8_UINT].PlatformFormat = DXGI_FORMAT_R8G8B8A8_UINT;
GPixelFormats[PF_R8G8B8A8_SNORM].PlatformFormat = DXGI_FORMAT_R8G8B8A8_SNORM;
GPixelFormats[PF_R8G8].PlatformFormat = DXGI_FORMAT_R8G8_UNORM;
GPixelFormats[PF_R32G32B32A32_UINT].PlatformFormat = DXGI_FORMAT_R32G32B32A32_UINT;
GPixelFormats[PF_R16G16_UINT].PlatformFormat = DXGI_FORMAT_R16G16_UINT;
GPixelFormats[PF_R32G32_UINT].PlatformFormat = DXGI_FORMAT_R32G32_UINT;

GPixelFormats[PF_BC6H].PlatformFormat = DXGI_FORMAT_BC6H_UF16;
GPixelFormats[PF_BC7].PlatformFormat = DXGI_FORMAT_BC7_TYPELESS;
GPixelFormats[PF_R8_UINT].PlatformFormat = DXGI_FORMAT_R8_UINT;

GPixelFormats[PF_R16G16B16A16_UNORM].PlatformFormat = DXGI_FORMAT_R16G16B16A16_UNORM;
GPixelFormats[PF_R16G16B16A16_SNORM].PlatformFormat = DXGI_FORMAT_R16G16B16A16_SNORM;

GPixelFormats[PF_NV12].PlatformFormat = DXGI_FORMAT_NV12;
GPixelFormats[PF_NV12].Supported = true;

typedef enum DXGI_FORMAT
{
   DXGI_FORMAT_UNKNOWN	                    = 0,
   DXGI_FORMAT_R32G32B32A32_TYPELESS       = 1,
   DXGI_FORMAT_R32G32B32A32_FLOAT          = 2,
   DXGI_FORMAT_R32G32B32A32_UINT           = 3,
   DXGI_FORMAT_R32G32B32A32_SINT           = 4,
   DXGI_FORMAT_R32G32B32_TYPELESS          = 5,
   DXGI_FORMAT_R32G32B32_FLOAT             = 6,
   DXGI_FORMAT_R32G32B32_UINT              = 7,
   DXGI_FORMAT_R32G32B32_SINT              = 8,
   DXGI_FORMAT_R16G16B16A16_TYPELESS       = 9,
   DXGI_FORMAT_R16G16B16A16_FLOAT          = 10,
   DXGI_FORMAT_R16G16B16A16_UNORM          = 11,
   DXGI_FORMAT_R16G16B16A16_UINT           = 12,
   DXGI_FORMAT_R16G16B16A16_SNORM          = 13,
   DXGI_FORMAT_R16G16B16A16_SINT           = 14,
   DXGI_FORMAT_R32G32_TYPELESS             = 15,
   DXGI_FORMAT_R32G32_FLOAT                = 16,
   DXGI_FORMAT_R32G32_UINT                 = 17,
   DXGI_FORMAT_R32G32_SINT                 = 18,
   DXGI_FORMAT_R32G8X24_TYPELESS           = 19,
   DXGI_FORMAT_D32_FLOAT_S8X24_UINT        = 20,
   DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS    = 21,
   DXGI_FORMAT_X32_TYPELESS_G8X24_UINT     = 22,
   DXGI_FORMAT_R10G10B10A2_TYPELESS        = 23,
   DXGI_FORMAT_R10G10B10A2_UNORM           = 24,
   DXGI_FORMAT_R10G10B10A2_UINT            = 25,
   DXGI_FORMAT_R11G11B10_FLOAT             = 26,
   DXGI_FORMAT_R8G8B8A8_TYPELESS           = 27,
   DXGI_FORMAT_R8G8B8A8_UNORM              = 28,
   DXGI_FORMAT_R8G8B8A8_UNORM_SRGB         = 29,
   DXGI_FORMAT_R8G8B8A8_UINT               = 30,
   DXGI_FORMAT_R8G8B8A8_SNORM              = 31,
   DXGI_FORMAT_R8G8B8A8_SINT               = 32,
   DXGI_FORMAT_R16G16_TYPELESS             = 33,
   DXGI_FORMAT_R16G16_FLOAT                = 34,
   DXGI_FORMAT_R16G16_UNORM                = 35,
   DXGI_FORMAT_R16G16_UINT                 = 36,
   DXGI_FORMAT_R16G16_SNORM                = 37,
   DXGI_FORMAT_R16G16_SINT                 = 38,
   DXGI_FORMAT_R32_TYPELESS                = 39,
   DXGI_FORMAT_D32_FLOAT                   = 40,
   DXGI_FORMAT_R32_FLOAT                   = 41,
   DXGI_FORMAT_R32_UINT                    = 42,
   DXGI_FORMAT_R32_SINT                    = 43,
   DXGI_FORMAT_R24G8_TYPELESS              = 44,
   DXGI_FORMAT_D24_UNORM_S8_UINT           = 45,
   DXGI_FORMAT_R24_UNORM_X8_TYPELESS       = 46,
   DXGI_FORMAT_X24_TYPELESS_G8_UINT        = 47,
   DXGI_FORMAT_R8G8_TYPELESS               = 48,
   DXGI_FORMAT_R8G8_UNORM                  = 49,
   DXGI_FORMAT_R8G8_UINT                   = 50,
   DXGI_FORMAT_R8G8_SNORM                  = 51,
   DXGI_FORMAT_R8G8_SINT                   = 52,
   DXGI_FORMAT_R16_TYPELESS                = 53,
   DXGI_FORMAT_R16_FLOAT                   = 54,
   DXGI_FORMAT_D16_UNORM                   = 55,
   DXGI_FORMAT_R16_UNORM                   = 56,
   DXGI_FORMAT_R16_UINT                    = 57,
   DXGI_FORMAT_R16_SNORM                   = 58,
   DXGI_FORMAT_R16_SINT                    = 59,
   DXGI_FORMAT_R8_TYPELESS                 = 60,
   DXGI_FORMAT_R8_UNORM                    = 61,
   DXGI_FORMAT_R8_UINT                     = 62,
   DXGI_FORMAT_R8_SNORM                    = 63,
   DXGI_FORMAT_R8_SINT                     = 64,
   DXGI_FORMAT_A8_UNORM                    = 65,
   DXGI_FORMAT_R1_UNORM                    = 66,
   DXGI_FORMAT_R9G9B9E5_SHAREDEXP          = 67,
   DXGI_FORMAT_R8G8_B8G8_UNORM             = 68,
   DXGI_FORMAT_G8R8_G8B8_UNORM             = 69,
   DXGI_FORMAT_BC1_TYPELESS                = 70,
   DXGI_FORMAT_BC1_UNORM                   = 71,
   DXGI_FORMAT_BC1_UNORM_SRGB              = 72,
   DXGI_FORMAT_BC2_TYPELESS                = 73,
   DXGI_FORMAT_BC2_UNORM                   = 74,
   DXGI_FORMAT_BC2_UNORM_SRGB              = 75,
   DXGI_FORMAT_BC3_TYPELESS                = 76,
   DXGI_FORMAT_BC3_UNORM                   = 77,
   DXGI_FORMAT_BC3_UNORM_SRGB              = 78,
   DXGI_FORMAT_BC4_TYPELESS                = 79,
   DXGI_FORMAT_BC4_UNORM                   = 80,
   DXGI_FORMAT_BC4_SNORM                   = 81,
   DXGI_FORMAT_BC5_TYPELESS                = 82,
   DXGI_FORMAT_BC5_UNORM                   = 83,
   DXGI_FORMAT_BC5_SNORM                   = 84,
   DXGI_FORMAT_B5G6R5_UNORM                = 85,
   DXGI_FORMAT_B5G5R5A1_UNORM              = 86,
   DXGI_FORMAT_B8G8R8A8_UNORM              = 87,
   DXGI_FORMAT_B8G8R8X8_UNORM              = 88,
   DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM  = 89,
   DXGI_FORMAT_B8G8R8A8_TYPELESS           = 90,
   DXGI_FORMAT_B8G8R8A8_UNORM_SRGB         = 91,
   DXGI_FORMAT_B8G8R8X8_TYPELESS           = 92,
   DXGI_FORMAT_B8G8R8X8_UNORM_SRGB         = 93,
   DXGI_FORMAT_BC6H_TYPELESS               = 94,
   DXGI_FORMAT_BC6H_UF16                   = 95,
   DXGI_FORMAT_BC6H_SF16                   = 96,
   DXGI_FORMAT_BC7_TYPELESS                = 97,
   DXGI_FORMAT_BC7_UNORM                   = 98,
   DXGI_FORMAT_BC7_UNORM_SRGB              = 99,
   DXGI_FORMAT_AYUV                        = 100,
   DXGI_FORMAT_Y410                        = 101,
   DXGI_FORMAT_Y416                        = 102,
   DXGI_FORMAT_NV12                        = 103,
   DXGI_FORMAT_P010                        = 104,
   DXGI_FORMAT_P016                        = 105,
   DXGI_FORMAT_420_OPAQUE                  = 106,
   DXGI_FORMAT_YUY2                        = 107,
   DXGI_FORMAT_Y210                        = 108,
   DXGI_FORMAT_Y216                        = 109,
   DXGI_FORMAT_NV11                        = 110,
   DXGI_FORMAT_AI44                        = 111,
   DXGI_FORMAT_IA44                        = 112,
   DXGI_FORMAT_P8                          = 113,
   DXGI_FORMAT_A8P8                        = 114,
   DXGI_FORMAT_B4G4R4A4_UNORM              = 115,

   DXGI_FORMAT_P208                        = 130,
   DXGI_FORMAT_V208                        = 131,
   DXGI_FORMAT_V408                        = 132,


   DXGI_FORMAT_FORCE_UINT                  = 0xffffffff
} DXGI_FORMAT;

D3D11RHIPrimitive.h

/** Find an appropriate DXGI format for the input format and SRGB setting. */
inline DXGI_FORMAT FindShaderResourceDXGIFormat(DXGI_FORMAT InFormat,bool bSRGB)
{
	if(bSRGB)
	{
		switch(InFormat)
		{
		case DXGI_FORMAT_B8G8R8A8_TYPELESS:    return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
		case DXGI_FORMAT_R8G8B8A8_TYPELESS:    return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
		case DXGI_FORMAT_BC1_TYPELESS:         return DXGI_FORMAT_BC1_UNORM_SRGB;
		case DXGI_FORMAT_BC2_TYPELESS:         return DXGI_FORMAT_BC2_UNORM_SRGB;
		case DXGI_FORMAT_BC3_TYPELESS:         return DXGI_FORMAT_BC3_UNORM_SRGB;
		case DXGI_FORMAT_BC7_TYPELESS:         return DXGI_FORMAT_BC7_UNORM_SRGB;
		};
	}
	else
	{
		switch(InFormat)
		{
		case DXGI_FORMAT_B8G8R8A8_TYPELESS: return DXGI_FORMAT_B8G8R8A8_UNORM;
		case DXGI_FORMAT_R8G8B8A8_TYPELESS: return DXGI_FORMAT_R8G8B8A8_UNORM;
		case DXGI_FORMAT_BC1_TYPELESS:      return DXGI_FORMAT_BC1_UNORM;
		case DXGI_FORMAT_BC2_TYPELESS:      return DXGI_FORMAT_BC2_UNORM;
		case DXGI_FORMAT_BC3_TYPELESS:      return DXGI_FORMAT_BC3_UNORM;
		case DXGI_FORMAT_BC7_TYPELESS:      return DXGI_FORMAT_BC7_UNORM;
		};
	}
	switch(InFormat)
	{
		case DXGI_FORMAT_R24G8_TYPELESS: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
		case DXGI_FORMAT_R32_TYPELESS: return DXGI_FORMAT_R32_FLOAT;
		case DXGI_FORMAT_R16_TYPELESS: return DXGI_FORMAT_R16_UNORM;
		// Changing Depth Buffers to 32 bit on Dingo as D24S8 is actually implemented as a 32 bit buffer in the hardware
		case DXGI_FORMAT_R32G8X24_TYPELESS: return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; 
	}
	return InFormat;
}