October3d55/M/LGUI/Shaders/Private/LGUIShader.usf

283 lines
9.8 KiB
Plaintext

// Copyright 2019-Present LexLiu. All Rights Reserved.
#include "/Engine/Private/Common.ush"
#include "/Engine/Private/GammaCorrectionCommon.ush"
#include "/Engine/Generated/Material.ush"
#include "LGUIShaderCommon.ush"
struct FLGUIBasePassInterpolants
{
float4 PixelPosition : TEXCOORD8; // xyz = world position, w = clip z
#if USE_WORLD_POSITION_EXCLUDING_SHADER_OFFSETS
float3 PixelPositionExcludingWPO : TEXCOORD9;
#endif
};
struct FLGUIBasePassVSToPS
{
FLGUIVertexFactoryInterpolantsVSToPS FactoryInterpolants;
FLGUIBasePassInterpolants BasePassInterpolants;
float4 Position : SV_POSITION;
};
FLGUIVertexFactoryInterpolantsVSToPS VertexFactoryGetInterpolantsVSToPS(float2 TexCoord0, float2 TexCoord1
, FMaterialVertexParameters VertexParameters
, HALF4_TYPE VertexColor
, half3x3 TangentToWorld
, float TangentToWorldSign
)
{
FLGUIVertexFactoryInterpolantsVSToPS Interpolants;
// Initialize the whole struct to 0
// Really only the last two components of the packed UVs have the opportunity to be uninitialized
Interpolants = (FLGUIVertexFactoryInterpolantsVSToPS) 0;
#if NUM_TEX_COORD_INTERPOLATORS
float2 CustomizedUVs[NUM_TEX_COORD_INTERPOLATORS];
GetMaterialCustomizedUVs(VertexParameters, CustomizedUVs);
GetCustomInterpolators(VertexParameters, CustomizedUVs);
UNROLL
for (int CoordinateIndex = 0; CoordinateIndex < NUM_TEX_COORD_INTERPOLATORS; CoordinateIndex++)
{
SetUV(Interpolants, CoordinateIndex, CustomizedUVs[CoordinateIndex]);
}
#endif
#if COMPILER_GLSL_ES3_1 && !MOBILE_EMULATION
VertexColor.rgba = VertexColor.bgra;
#endif
SetTangents(Interpolants, TangentToWorld[0], TangentToWorld[2], TangentToWorldSign);
SetColor(Interpolants, VertexColor);
return Interpolants;
}
/** Converts from vertex factory specific input to a FMaterialVertexParameters, which is used by vertex shader material inputs. */
FMaterialVertexParameters GetMaterialVertexParameters(HALF4_TYPE VertexColor, float3 WorldPosition, float2 UVs[4], half3x3 TangentToWorld)
{
FMaterialVertexParameters Result = (FMaterialVertexParameters) 0;
Result.WorldPosition = WorldPosition;
Result.VertexColor = VertexColor;
Result.TangentToWorld = TangentToWorld;
#if NUM_MATERIAL_TEXCOORDS_VERTEX
int MaxCount = min(NUM_MATERIAL_TEXCOORDS_VERTEX, 4);
UNROLL
for (int CoordinateIndex = 0; CoordinateIndex < MaxCount; CoordinateIndex++)
{
Result.TexCoords[CoordinateIndex] = UVs[CoordinateIndex].xy;
}
#endif
return Result;
}
float4 TransformLocalToTranslatedWorld(float3 LocalPosition, FDFMatrix LocalToWorld)
{
return DFTransformLocalToTranslatedWorld(LocalPosition, LocalToWorld, ResolvedView.PreViewTranslation);
}
void MainVS(
in float3 Position : ATTRIBUTE0,
in HALF4_TYPE Color : ATTRIBUTE1,
in float2 TextureCoord0 : ATTRIBUTE2,
in float2 TextureCoord1 : ATTRIBUTE3,
in float2 TextureCoord2 : ATTRIBUTE4,
in float2 TextureCoord3 : ATTRIBUTE5,
in HALF3_TYPE TangentX : ATTRIBUTE6,
// TangentZ.w contains sign of tangent basis determinant
in HALF4_TYPE TangentZ : ATTRIBUTE7,
out FLGUIBasePassVSToPS Output
)
{
ResolvedView = ResolveView();
FPrimitiveSceneData Primitive = GetPrimitiveDataFromUniformBuffer();
//float4 WorldPosition = mul(float4(Position, 1.0), GetPrimitiveData(Parameters.PrimitiveId).LocalToWorld);
float4 WorldPosition = TransformLocalToTranslatedWorld(Position, Primitive.LocalToWorld);
//float4 WorldPosition = float4(Position.xyz + ResolvedView.PreViewTranslation.xyz, 1.0);
float TangentSign;
half3x3 TangentToLocal = CalcTangentToLocal(TangentX, TangentZ, TangentSign);
half3x3 TangentToWorld = CalcTangentToWorld(TangentToLocal, DFDemote(Primitive.LocalToWorld), Primitive.InvNonUniformScale);
float TangentToWorldSign = TangentSign * GetPrimitive_DeterminantSign_FromFlags(Primitive.Flags);
float2 UVs[4];
UVs[0] = TextureCoord0;
UVs[1] = TextureCoord1;
UVs[2] = TextureCoord2;
UVs[3] = TextureCoord3;
FMaterialVertexParameters VertexParameters = GetMaterialVertexParameters(Color, WorldPosition.xyz, UVs, TangentToWorld);
HALF3_TYPE WorldPositionOffset = GetMaterialWorldPositionOffset(VertexParameters);
WorldPosition.xyz += WorldPositionOffset;
Output.Position = mul(WorldPosition, ResolvedView.TranslatedWorldToClip);
Output.BasePassInterpolants.PixelPosition = WorldPosition;
#if USE_WORLD_POSITION_EXCLUDING_SHADER_OFFSETS
Output.BasePassInterpolants.PixelPositionExcludingWPO = WorldPosition.xyz;
#endif
Output.FactoryInterpolants = VertexFactoryGetInterpolantsVSToPS(TextureCoord0, TextureCoord1
, VertexParameters
, Color
, TangentToWorld, TangentToWorldSign
);
Output.BasePassInterpolants.PixelPosition.w = Output.Position.w;
}
FMaterialPixelParameters GetMaterialPixelParameters(FLGUIVertexFactoryInterpolantsVSToPS 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
HALF3_TYPE TangentToWorld0 = GetTangentToWorld0(Interpolants).xyz;
HALF4_TYPE TangentToWorld2 = GetTangentToWorld2(Interpolants);
Result.UnMirrored = TangentToWorld2.w;
Result.VertexColor = GetColor(Interpolants);
Result.TangentToWorld = AssembleTangentToWorld(TangentToWorld0, TangentToWorld2);
return Result;
}
void ApplyPixelDepthOffsetForLGUIBasePass(inout FMaterialPixelParameters MaterialParameters, FPixelMaterialInputs PixelMaterialInputs, out float OutDepth)
{
float PixelDepthOffset = ApplyPixelDepthOffsetToMaterialParameters(MaterialParameters, PixelMaterialInputs, OutDepth);
}
/** Reference from Engine/Shader/Private/SlateElementPixelShader.usf */
/** Display gamma x:gamma curve adjustment, y:inverse gamma (1/GEngine->DisplayGamma), z:InvertAlpha, w:Contrast */
#define SOURCE_IN_LINEAR_SPACE 1
half3 GammaCorrect(half3 InColor, half4 GammaValues)
{
half3 CorrectedColor = InColor;
#if SOURCE_IN_LINEAR_SPACE
FLATTEN if (GammaValues.y != 1.0f)
{
CorrectedColor = ApplyGammaCorrection(CorrectedColor, GammaValues.x);
}
#endif
return CorrectedColor;
}
#if LGUI_BLEND_DEPTH
Texture2D _SceneDepthTex;
SamplerState _SceneDepthTexSampler;
float4 _SceneDepthTextureScaleOffset;
float _SceneDepthBlend;
#if LGUI_DEPTH_FADE
int _SceneDepthFade;
#endif
#endif
HALF4_TYPE _LGUIGammaValues;
void MainPS(
FLGUIVertexFactoryInterpolantsVSToPS Interpolants
, FLGUIBasePassInterpolants BasePassInterpolants
, in float4 SvPosition : SV_Position
OPTIONAL_IsFrontFace
, out HALF4_TYPE OutColor : SV_Target0
#if OUTPUT_PIXEL_DEPTH_OFFSET
, out float OutDepth : SV_Depth
#endif
)
{
ResolvedView = ResolveView();
FMaterialPixelParameters MaterialParameters = GetMaterialPixelParameters(Interpolants, SvPosition);
FPixelMaterialInputs PixelMaterialInputs;
{
float4 ScreenPosition = SvPositionToResolvedScreenPosition(SvPosition);
float3 WorldPosition = BasePassInterpolants.PixelPosition.xyz;
float3 WorldPositionExcludingWPO = BasePassInterpolants.PixelPosition.xyz;
#if USE_WORLD_POSITION_EXCLUDING_SHADER_OFFSETS
WorldPositionExcludingWPO = BasePassInterpolants.PixelPositionExcludingWPO;
#endif
CalcMaterialParametersEx(MaterialParameters, PixelMaterialInputs, SvPosition, ScreenPosition, bIsFrontFace, WorldPosition, WorldPositionExcludingWPO);
}
#if OUTPUT_PIXEL_DEPTH_OFFSET
ApplyPixelDepthOffsetForLGUIBasePass(MaterialParameters, PixelMaterialInputs, OutDepth);
#endif
#if SUBSTRATE_ENABLED
// UI element are always rendered with a unlit BSDF behind the scene
FSubstrateBSDF UnlitBSDF = PixelMaterialInputs.FrontMaterial.InlinedBSDF;
UnlitBSDF.SubstrateSanitizeBSDF();
HALF3_TYPE Color = BSDF_GETEMISSIVE(UnlitBSDF);
#if STRATA_USE_PREMULTALPHA_OVERRIDE // AlphaComposite - Premultiplied alpha blending
HALF_TYPE Coverage = GetMaterialOpacity(PixelMaterialInputs);
#else
HALF_TYPE Coverage = saturate(1.0f - UNLIT_TRANSMITTANCE(UnlitBSDF).x); // Unlit node transmittance is only generated from opacity
Color /= Coverage;//Restore color value because material node "Substrate UE4 Unlit Shading"
#endif
OutColor = HALF4_TYPE(Color, Coverage);
#else // SUBSTRATE_ENABLED
OutColor = HALF4_TYPE(GetMaterialEmissive(PixelMaterialInputs), GetMaterialOpacity(PixelMaterialInputs));
#endif // SUBSTRATE_ENABLED
// Gamma Correct
OutColor.rgb = GammaCorrect(OutColor.rgb, _LGUIGammaValues);
#if MATERIALBLENDING_MASKED
clip(GetMaterialMask(PixelMaterialInputs));
#endif
#if LGUI_BLEND_DEPTH
float PixelDepth = min(MaterialParameters.ScreenPosition.z / MaterialParameters.ScreenPosition.w, MaterialParameters.SvPosition.z);
float2 ScreenUV = MaterialParameters.ScreenPosition.xy / MaterialParameters.ScreenPosition.w;
ScreenUV = ScreenUV * 0.5f + float2(0.5f, 0.5f);
ScreenUV.y = 1.0f - ScreenUV.y;
#if LGUI_DEPTH_FADE
float DepthFadeValue = 0;
int SampleCount = 0;
int SampleSize = _SceneDepthFade;
ScreenUV = ScreenUV * _SceneDepthTextureScaleOffset.xy + _SceneDepthTextureScaleOffset.zw;
for (int w = -SampleSize; w <= SampleSize; w++)
{
for (int h = -SampleSize; h <= SampleSize; h++)
{
float ExistDepth = _SceneDepthTex.Sample(_SceneDepthTexSampler, ScreenUV + float2(w, h) * ResolvedView.ViewSizeAndInvSize.zw).x;
DepthFadeValue += step(ExistDepth, PixelDepth);
SampleCount++;
}
}
DepthFadeValue /= SampleCount;
DepthFadeValue = smoothstep(0, 1, DepthFadeValue);
#else
float ExistDepth = _SceneDepthTex.Sample(_SceneDepthTexSampler, ScreenUV * _SceneDepthTextureScaleOffset.xy + _SceneDepthTextureScaleOffset.zw).x;
float DepthFadeValue = step(ExistDepth, PixelDepth);
#endif
OutColor.a = lerp(_SceneDepthBlend * OutColor.a, OutColor.a, DepthFadeValue);
#endif
}