229 lines
8.2 KiB
Plaintext
229 lines
8.2 KiB
Plaintext
|
|
// Copyright 2019-Present LexLiu. All Rights Reserved.
|
||
|
|
|
||
|
|
#include "/Engine/Private/Common.ush"
|
||
|
|
#include "/Engine/Generated/Material.ush"
|
||
|
|
#include "LGUIHudVertexFactory.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 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 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, FLWCMatrix LocalToWorld)
|
||
|
|
{
|
||
|
|
FLWCVector3 WorldPosition = LWCMultiply(LocalPosition, LocalToWorld);
|
||
|
|
FLWCVector3 TranslatedWorldPosition = LWCAdd(WorldPosition, ResolvedView.PreViewTranslation);
|
||
|
|
return float4(LWCToFloat(TranslatedWorldPosition), 1.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
void MainVS(
|
||
|
|
in float3 Position : ATTRIBUTE0,
|
||
|
|
in half4 Color : ATTRIBUTE1,
|
||
|
|
in float2 TextureCoord0 : ATTRIBUTE2,
|
||
|
|
in float2 TextureCoord1 : ATTRIBUTE3,
|
||
|
|
in float2 TextureCoord2 : ATTRIBUTE4,
|
||
|
|
in float2 TextureCoord3 : ATTRIBUTE5,
|
||
|
|
in half3 TangentX : ATTRIBUTE6,
|
||
|
|
// TangentZ.w contains sign of tangent basis determinant
|
||
|
|
in half4 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, LWCToFloat3x3(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 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 TangentToWorld0 = GetTangentToWorld0(Interpolants).xyz;
|
||
|
|
half4 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);
|
||
|
|
}
|
||
|
|
|
||
|
|
#if LGUI_BLEND_DEPTH
|
||
|
|
Texture2D _SceneDepthTex;
|
||
|
|
SamplerState _SceneDepthTexSampler;
|
||
|
|
float4 _SceneDepthTextureScaleOffset;
|
||
|
|
float _SceneDepthBlend;
|
||
|
|
#if LGUI_DEPTH_FADE
|
||
|
|
float _SceneDepthFade;
|
||
|
|
#endif
|
||
|
|
#endif
|
||
|
|
float _ColorCorrectionValueForHDR;
|
||
|
|
|
||
|
|
void MainPS(
|
||
|
|
FLGUIVertexFactoryInterpolantsVSToPS Interpolants
|
||
|
|
, FLGUIBasePassInterpolants BasePassInterpolants
|
||
|
|
, in float4 SvPosition : SV_Position
|
||
|
|
OPTIONAL_IsFrontFace
|
||
|
|
, out half4 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
|
||
|
|
|
||
|
|
OutColor = half4(GetMaterialEmissive(PixelMaterialInputs).rgb, GetMaterialOpacity(PixelMaterialInputs));
|
||
|
|
OutColor.rgb = pow(OutColor.rgb, _ColorCorrectionValueForHDR);
|
||
|
|
|
||
|
|
#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;
|
||
|
|
float ExistDepth = _SceneDepthTex.Sample(_SceneDepthTexSampler, ScreenUV * _SceneDepthTextureScaleOffset.xy + _SceneDepthTextureScaleOffset.zw).x;
|
||
|
|
#if LGUI_DEPTH_FADE
|
||
|
|
float DepthFadeValue = smoothstep(0, 1, saturate((PixelDepth - ExistDepth) / (_SceneDepthFade * ExistDepth * ExistDepth)));//if without the "ExistDepth * ExistDepth" then the fade distance will be affect by camera distance.
|
||
|
|
#else
|
||
|
|
float DepthFadeValue = step(ExistDepth, PixelDepth);
|
||
|
|
#endif
|
||
|
|
OutColor.a = lerp(_SceneDepthBlend * OutColor.a, OutColor.a, DepthFadeValue);
|
||
|
|
#endif
|
||
|
|
}
|