// 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 }