版权声明:本文为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_POSITION 与 SV_Target 区别
SV_POSITION 和 SV_Target 都是 语义绑定 (semantics binding) 。
SV_ 前缀的变量代表 System Value 的意思,在 DX10+ 的语义绑定中被使用代表特殊的意义。
SV_POSITION 在用法上和 POSITION 是一样的,区别是 SV_POSTION 一旦被作为 vertex 函数的输出语义,那么这个最终的顶点位置就被固定了,不得改变。DX10+ 推荐使用 SV_POSITION 作为 vertex 函数的输出和 fragment 函数的输入,而 vertex 函数的输入还是使用 POSITION。不过 DX10 以后的代码依旧兼容 POSITION 作为全程表达,估计编译器会自动判断并替换的吧。
SV_Target 是 DX10+ 用于 fragment 函数着色器颜色输出的语义。DX9 使用 COLOR 作为 fragment 函数输出语义,但是也有一些着色器语言使用 COLOR 来表示网格数据和顶点输出语义,效果和功能是一样的,没有什么区别,同时使用 COLOR 的话 DX10+ 也会兼容。
参考文档:www.jianshu.com/p/ea63577a0…
3. View 和 ResolvedView
未找到文档
第二部分
这篇 邹晓航 —— UE4菜鸟分析1 简单记录了一下 UE4 渲染流程,两种渲染器,然后走 BasePassRender ,第一阶段创建 Gbuffer,第二阶段做 Lighting 。
一:创建 GBuffer
1. 起始位置:PixelShaderOutputCommon.ush 中的 MainPS 函数。
- 输入:
FVertexFactoryInterpolantsVSToPS、FBasePassInterpolantsVSToPS或FMeshDecalInterpolants和SV_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 FPixelShaderOut (Common.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,然后创建 SceneTexture ,ID 选择 CustomStencil ,如下图:
在材质编辑器下,点击 Window->Shader Code->HLSL Code, copy 对应代码,保存生成 custom.hsls 文件(名称随便命名,目的方便描述该文件)。
- HLSL code 是基于 MaterialTemplate.ush (Engine/Shader/Private)进行生成。
- 如何生成?目前没有深入研究,待后续更新(如果用到)。
对比 MaterialTemplate.ush 和 custom.hsls 文件。在 VSCode 中,左侧目录同时选中两个文件,右键,有 compare 功能,进行对比哪些是 custom.hsls 新增的。
实际对比,发现有大量的不同出现,然而我们在材质蓝图中,仅仅增加了一个 SceneTexture 函数,不应该有很多变化。没有深入分析原因,后面用到再研究。
本次研究的重点是如何获得 SceneTexture ,测试的 ID 是 CustomStencil 。而不是 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);
}
}
GetScreenSpaceData 在 DeferredShadingCommon.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;
}
回归到测试 ID 即 CustomStencil:
#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;
}