1、蓝图材质转换HLSL代码
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;
/** 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;
}
在相同文件内:
// @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));
}
在相同文件里:
/** 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;
}
回归到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