Files
UnrealEngineUWP/Engine/Shaders/Private/MobileBasePassPixelShader.usf
robert srinivasiah 63aa8dcb98 Pass SV_ViewID to VIEW_ID as uint, no more casting to float
The uint->float cast was a hack to support old devices with bad drivers. Now it's interfering with mobile preview in DX12, so time to get rid of these hacks.

#jira UE-151332
#rb Arciel.Rekman, Dmitriy.Dyomin
#preflight 6282d76dc57a894cf6a0f3b4

[CL 20238182 by robert srinivasiah in ue5-main branch]
2022-05-16 23:33:20 -04:00

571 lines
23 KiB
Plaintext

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
MobileBasePassPixelShader.usf: Base pass pixel shader used with forward shading
=============================================================================*/
#include "Common.ush"
// Reroute MobileSceneTextures uniform buffer references to the base pass uniform buffer
#define MobileSceneTextures MobileBasePass.SceneTextures
#define EyeAdaptationStruct MobileBasePass
#define ForwardLightData MobileBasePass.Forward
#define ReflectionStruct MobileBasePass.ReflectionsParameters
#ifndef MOBILE_QL_FORCE_DISABLE_PREINTEGRATEDGF
#define MOBILE_QL_FORCE_DISABLE_PREINTEGRATEDGF 0
#endif
#define FORWARDSHADING_USE_HQ_ENV_BRDF (MATERIAL_USE_PREINTEGRATED_GF && !MOBILE_QL_FORCE_DISABLE_PREINTEGRATEDGF)
//use preintegrated GF lut for simple IBL
#if FORWARDSHADING_USE_HQ_ENV_BRDF
#define PreIntegratedGF MobileBasePass.PreIntegratedGFTexture
#define PreIntegratedGFSampler MobileBasePass.PreIntegratedGFSampler
#endif
#define APPLY_AO 0
#if (MATERIALBLENDING_MASKED || MATERIALBLENDING_SOLID)
#if ENABLE_AMBIENT_OCCLUSION && !MATERIAL_SHADINGMODEL_UNLIT
#undef APPLY_AO
#define APPLY_AO 1
#endif
#endif
#if APPLY_AO
#define AmbientOcclusionTexture MobileBasePass.AmbientOcclusionTexture
#define AmbientOcclusionSampler MobileBasePass.AmbientOcclusionSampler
#define AmbientOcclusionStaticFraction MobileBasePass.AmbientOcclusionStaticFraction
#endif
#if MATERIAL_SHADINGMODEL_SINGLELAYERWATER
#define SIMPLE_SINGLE_LAYER_WATER 1
#endif
#ifndef PROJECT_MOBILE_ENABLE_MOVABLE_SPOTLIGHT_SHADOWS
#define PROJECT_MOBILE_ENABLE_MOVABLE_SPOTLIGHT_SHADOWS 0
#endif
#ifndef MOBILE_QL_FORCE_FULLY_ROUGH
#define MOBILE_QL_FORCE_FULLY_ROUGH 0
#endif
#ifndef MOBILE_QL_FORCE_NONMETAL
#define MOBILE_QL_FORCE_NONMETAL 0
#endif
#ifndef MOBILE_QL_DISABLE_MATERIAL_NORMAL
#define MOBILE_QL_DISABLE_MATERIAL_NORMAL 0
#endif
#define FULLY_ROUGH (MATERIAL_FULLY_ROUGH || MOBILE_QL_FORCE_FULLY_ROUGH)
#define NONMETAL (MATERIAL_NONMETAL || MOBILE_QL_FORCE_NONMETAL)
#define FORCE_VERTEX_NORMAL (MOBILE_QL_DISABLE_MATERIAL_NORMAL)
#define SUPPORT_SPOTLIGHTS_SHADOW (MATERIALBLENDING_SOLID || MATERIALBLENDING_MASKED) && PROJECT_MOBILE_ENABLE_MOVABLE_SPOTLIGHT_SHADOWS
#define DEFERRED_SHADING_PATH (MOBILE_DEFERRED_SHADING && ((MATERIALBLENDING_SOLID || MATERIALBLENDING_MASKED) && !MATERIAL_SHADINGMODEL_SINGLELAYERWATER))
// SceneDepthAux always enabled for IOS, on other platforms only enabled when in forward and MobileHDR=true
#define USE_SCENE_DEPTH_AUX ((METAL_PROFILE || (!DEFERRED_SHADING_PATH && OUTPUT_MOBILE_HDR) || (DEFERRED_SHADING_PATH && USE_GLES_FBF_DEFERRED)) && (MATERIALBLENDING_SOLID || MATERIALBLENDING_MASKED) && !COMPILER_SWITCH)
#if DEFERRED_SHADING_PATH && MOBILE_EXTENDED_GBUFFER
#define SV_TargetDepthAux SV_Target5
#elif DEFERRED_SHADING_PATH
#define SV_TargetDepthAux SV_Target4
#else
#define SV_TargetDepthAux SV_Target1
#endif
#define TRANSLUCENCY_NON_DIRECTIONAL (MATERIALBLENDING_ANY_TRANSLUCENT && (TRANSLUCENCY_LIGHTING_VOLUMETRIC_NONDIRECTIONAL || TRANSLUCENCY_LIGHTING_VOLUMETRIC_PERVERTEX_NONDIRECTIONAL) && !MATERIAL_SHADINGMODEL_SINGLELAYERWATER)
#include "SHCommon.ush"
#include "/Engine/Generated/Material.ush"
#include "MobileBasePassCommon.ush"
#include "/Engine/Generated/VertexFactory.ush"
#include "LightmapCommon.ush"
#include "MobileLightingCommon.ush"
#include "ShadingModelsMaterial.ush"
#if MATERIAL_SHADINGMODEL_SINGLELAYERWATER
#include "SingleLayerWaterShading.ush"
#endif
half3 FrameBufferBlendOp(half4 Source)
{
half4 Dest = half4 (0,0,0,0);
#if MATERIALBLENDING_SOLID
return Source.rgb;
#elif MATERIALBLENDING_MASKED
return Source.rgb;
// AlphaComposite will set both MATERIALBLENDING_TRANSLUCENT and MATERIALBLENDING_ALPHACOMPOSITE defines
// so ensure MATERIALBLENDING_ALPHACOMPOSITE gets first in line
#elif MATERIALBLENDING_ALPHACOMPOSITE
return Source.rgb + (Dest.rgb*(1.0 - Source.a));
// AlphaHoldout will set both MATERIALBLENDING_TRANSLUCENT and MATERIALBLENDING_ALPHAHOLDOUT defines
// so ensure MATERIALBLENDING_ALPHAHOLDOUT gets first in line
#elif MATERIALBLENDING_ALPHAHOLDOUT
return (Dest.rgb*(1.0 - Source.a));
#elif MATERIALBLENDING_TRANSLUCENT
return (Source.rgb*Source.a) + (Dest.rgb*(1.0 - Source.a));
#elif MATERIALBLENDING_ADDITIVE
return Source.rgb + Dest.rgb;
#elif MATERIALBLENDING_MODULATE
return Source.rgb * Dest.rgb;
#endif
}
void ApplyPixelDepthOffsetForMobileBasePass(inout FMaterialPixelParameters MaterialParameters, FPixelMaterialInputs PixelMaterialInputs, out float OutDepth)
{
float PixelDepthOffset = ApplyPixelDepthOffsetToMaterialParameters(MaterialParameters, PixelMaterialInputs, OutDepth);
}
// Force early depth_stencil for non-masked material that use VT feedback
#if (NUM_VIRTUALTEXTURE_SAMPLES || LIGHTMAP_VT_ENABLED) && !(MATERIALBLENDING_MASKED || USE_DITHERED_LOD_TRANSITION || OUTPUT_PIXEL_DEPTH_OFFSET)
#define PIXELSHADER_EARLYDEPTHSTENCIL EARLYDEPTHSTENCIL
#else
#define PIXELSHADER_EARLYDEPTHSTENCIL
#endif
void ComputeIndirect(VTPageTableResult LightmapVTPageTableResult, FVertexFactoryInterpolantsVSToPS Interpolants, float3 DiffuseDir, half3 DiffuseColorForIndirect, half MaterialAO, out half IndirectIrradiance, inout FMobileLightAccumulator MobileLightAccumulator)
{
//To keep IndirectLightingCache conherence with PC, initialize the IndirectIrradiance to zero.
IndirectIrradiance = 0;
half3 IndirectColor = 0;
// Indirect Diffuse
#if LQ_TEXTURE_LIGHTMAP
float2 LightmapUV0, LightmapUV1;
uint LightmapDataIndex;
GetLightMapCoordinates(Interpolants, LightmapUV0, LightmapUV1, LightmapDataIndex);
half4 LightmapColor = GetLightMapColorLQ(LightmapVTPageTableResult, LightmapUV0, LightmapUV1, LightmapDataIndex, DiffuseDir);
IndirectColor += LightmapColor.rgb * DiffuseColorForIndirect * View.IndirectLightingColorScale;
IndirectIrradiance = LightmapColor.a;
#elif CACHED_POINT_INDIRECT_LIGHTING
#if MATERIALBLENDING_MASKED || MATERIALBLENDING_SOLID
// Take the normal into account for opaque
FThreeBandSHVectorRGB PointIndirectLighting;
PointIndirectLighting.R.V0 = IndirectLightingCache.IndirectLightingSHCoefficients0[0];
PointIndirectLighting.R.V1 = IndirectLightingCache.IndirectLightingSHCoefficients1[0];
PointIndirectLighting.R.V2 = IndirectLightingCache.IndirectLightingSHCoefficients2[0];
PointIndirectLighting.G.V0 = IndirectLightingCache.IndirectLightingSHCoefficients0[1];
PointIndirectLighting.G.V1 = IndirectLightingCache.IndirectLightingSHCoefficients1[1];
PointIndirectLighting.G.V2 = IndirectLightingCache.IndirectLightingSHCoefficients2[1];
PointIndirectLighting.B.V0 = IndirectLightingCache.IndirectLightingSHCoefficients0[2];
PointIndirectLighting.B.V1 = IndirectLightingCache.IndirectLightingSHCoefficients1[2];
PointIndirectLighting.B.V2 = IndirectLightingCache.IndirectLightingSHCoefficients2[2];
FThreeBandSHVector DiffuseTransferSH = CalcDiffuseTransferSH3(DiffuseDir, 1);
// Compute diffuse lighting which takes the normal into account
half3 DiffuseGI = max(half3(0, 0, 0), DotSH3(PointIndirectLighting, DiffuseTransferSH));
IndirectIrradiance = Luminance(DiffuseGI);
IndirectColor += DiffuseColorForIndirect * DiffuseGI * View.IndirectLightingColorScale;
#else
// Non-directional for translucency
// Ambient terms packed in xyz
// Already divided by PI and SH ambient on CPU
half3 PointIndirectLighting = IndirectLightingCache.IndirectLightingSHSingleCoefficient.rgb;
half3 DiffuseGI = PointIndirectLighting;
IndirectIrradiance = Luminance(DiffuseGI);
IndirectColor += DiffuseColorForIndirect * DiffuseGI * View.IndirectLightingColorScale;
#endif
#endif
IndirectIrradiance *= MaterialAO;
MobileLightAccumulator_Add(MobileLightAccumulator, IndirectColor, 0.0f, MaterialAO);
}
PIXELSHADER_EARLYDEPTHSTENCIL
void Main(
FVertexFactoryInterpolantsVSToPS Interpolants
, FMobileBasePassInterpolantsVSToPS BasePassInterpolants
, in float4 SvPosition : SV_Position
OPTIONAL_IsFrontFace
#if DEFERRED_SHADING_PATH
#if USE_GLES_FBF_DEFERRED
, out HALF4_TYPE OutProxy : SV_Target0
#else
, out HALF4_TYPE OutColor : SV_Target0
#endif
, out HALF4_TYPE OutGBufferA : SV_Target1
, out HALF4_TYPE OutGBufferB : SV_Target2
, out HALF4_TYPE OutGBufferC : SV_Target3
#if MOBILE_EXTENDED_GBUFFER
, out HALF4_TYPE OutGBufferD : SV_Target4
#endif
#else
, out HALF4_TYPE OutColor : SV_Target0
#endif
#if USE_SCENE_DEPTH_AUX
, out float OutSceneDepthAux : SV_TargetDepthAux
#endif
#if OUTPUT_PIXEL_DEPTH_OFFSET
, out float OutDepth : SV_Depth
#endif
)
{
#if DEFERRED_SHADING_PATH
#if USE_GLES_FBF_DEFERRED
half4 OutColor;
#endif
#if !MOBILE_EXTENDED_GBUFFER
half4 OutGBufferD;
#endif
#endif
#if MOBILE_MULTI_VIEW
ResolvedView = ResolveView(BasePassInterpolants.MultiViewId);
#else
ResolvedView = ResolveView();
#endif
#if USE_GLOBAL_CLIP_PLANE
clip(BasePassInterpolants.OutClipDistance);
#endif
#if PACK_INTERPOLANTS
float4 PackedInterpolants[NUM_VF_PACKED_INTERPOLANTS];
VertexFactoryUnpackInterpolants(Interpolants, PackedInterpolants);
#endif
#if COMPILER_GLSL_ES3_1 && !OUTPUT_MOBILE_HDR && !MOBILE_EMULATION
// LDR Mobile needs screen vertical flipped
SvPosition.y = ResolvedView.BufferSizeAndInvSize.y - SvPosition.y - 1;
#endif
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 FORCE_VERTEX_NORMAL
// Quality level override of material's normal calculation, can be used to avoid normal map reads etc.
MaterialParameters.WorldNormal = MaterialParameters.TangentToWorld[2];
MaterialParameters.ReflectionVector = ReflectionAboutCustomWorldNormal(MaterialParameters, MaterialParameters.WorldNormal, false);
#endif
}
#if OUTPUT_PIXEL_DEPTH_OFFSET
ApplyPixelDepthOffsetForMobileBasePass(MaterialParameters, PixelMaterialInputs, OutDepth);
#endif
#if !EARLY_Z_PASS_ONLY_MATERIAL_MASKING
//Clip if the blend mode requires it.
GetMaterialCoverageAndClipping(MaterialParameters, PixelMaterialInputs);
#endif
// Store the results in local variables and reuse instead of calling the functions multiple times.
half3 BaseColor = GetMaterialBaseColor(PixelMaterialInputs);
half Metallic = GetMaterialMetallic(PixelMaterialInputs);
half Specular = GetMaterialSpecular(PixelMaterialInputs);
// The smallest normalized value that can be represented in IEEE 754 (FP16) is 2^-24 = 5.96e-8.
// The code will make the following computation involving roughness: 1.0 / Roughness^4.
// Therefore to prevent division by zero on devices that do not support denormals, Roughness^4
// must be >= 5.96e-8. We will clamp to 0.015625 because 0.015625^4 = 5.96e-8.
//
// Note that we also clamp to 1.0 to match the deferred renderer on PC where the roughness is
// stored in an 8-bit value and thus automatically clamped at 1.0.
half Roughness = max(0.015625f, GetMaterialRoughness(PixelMaterialInputs));
half Anisotropy = GetMaterialAnisotropy(PixelMaterialInputs);
uint ShadingModelID = GetMaterialShadingModel(PixelMaterialInputs);
half Opacity = GetMaterialOpacity(PixelMaterialInputs);
half MaterialAO = GetMaterialAmbientOcclusion(PixelMaterialInputs);
// If we don't use this shading model the color should be black (don't generate shader code for unused data, don't do indirectlighting cache lighting with this color).
float3 SubsurfaceColor = 0;
// 0..1, SubsurfaceProfileId = int(x * 255)
float SubsurfaceProfile = 0;
#if (MATERIAL_SHADINGMODEL_SUBSURFACE || MATERIAL_SHADINGMODEL_PREINTEGRATED_SKIN || MATERIAL_SHADINGMODEL_SUBSURFACE_PROFILE) && MOBILE_SHADINGMODEL_SUPPORT
half4 SubsurfaceData = GetMaterialSubsurfaceData(PixelMaterialInputs);
SubsurfaceColor = SubsurfaceData.rgb * ResolvedView.DiffuseOverrideParameter.w + ResolvedView.DiffuseOverrideParameter.xyz;
SubsurfaceProfile = SubsurfaceData.a;
#endif
#if APPLY_AO
half4 GatheredAmbientOcclusion = Texture2DSample(AmbientOcclusionTexture, AmbientOcclusionSampler, SvPositionToBufferUV(SvPosition));
MaterialAO *= GatheredAmbientOcclusion.r;
#endif
FGBufferData GBuffer = (FGBufferData)0;
GBuffer.GBufferAO = MaterialAO;
GBuffer.Depth = MaterialParameters.ScreenPosition.w;
SetGBufferForShadingModel(
GBuffer,
MaterialParameters,
Opacity,
BaseColor,
Metallic,
Specular,
Roughness,
Anisotropy,
SubsurfaceColor,
SubsurfaceProfile,
0.0f,
ShadingModelID
);
GBuffer.Roughness = max(0.015625f, GBuffer.Roughness);
FMobileShadingModelContext ShadingModelContext = (FMobileShadingModelContext)0;
ShadingModelContext.Opacity = Opacity;
#if MATERIAL_SHADINGMODEL_THIN_TRANSLUCENT
float TopMaterialCoverage = ShadingModelContext.Opacity;
// Adjust Opacity
{
float3 TransmittanceColor = GetThinTranslucentMaterialOutput0(MaterialParameters);
float Transmittance = dot(TransmittanceColor, float3(1.0f,1.0f,1.0f)/3.0f);
// We can't use the NoV from the shading models because it uses saturate(), whereas we are using abs().
// The length through the surface is the same for both front and back faces.
float NoV = abs(dot(MaterialParameters.WorldNormal, MaterialParameters.CameraVector));
float PathLength = rcp(max(NoV, 1e-5f));
float NegativeAbsorptionCoefficient = log(Transmittance);
// Material Modulation is how much of the background light goes through the surface
float MaterialModulation = exp(NegativeAbsorptionCoefficient * PathLength);
// The alpha of the material in translucent mode is one minus the amount that it is modulating the background by.
float MaterialOpacity = 1.0f - MaterialModulation;
ShadingModelContext.Opacity = 1.0f - (1.0f - TopMaterialCoverage) * (1.0f - MaterialOpacity);
}
GBuffer.BaseColor *= TopMaterialCoverage;
#endif
#if MATERIAL_SHADINGMODEL_SUBSURFACE_PROFILE && MOBILE_SHADINGMODEL_SUPPORT
if (GBuffer.ShadingModelID == SHADINGMODELID_SUBSURFACE_PROFILE)
{
#if MATERIAL_SUBSURFACE_PROFILE_USE_CURVATURE
GBuffer.CustomData.g = GetMaterialCustomData0(MaterialParameters);
#else
GBuffer.CustomData.g = CalculateCurvature(GBuffer.WorldNormal, MaterialParameters.WorldPosition_CamRelative);
#endif
GBuffer.CustomData.g = max(saturate(GBuffer.CustomData.g), 0.001f);
}
#endif
InitShadingModelContext(ShadingModelContext, GBuffer, MaterialParameters.CameraVector);
VTPageTableResult LightmapVTPageTableResult = (VTPageTableResult)0.0f;
#if LIGHTMAP_VT_ENABLED
{
float2 LightmapUV0, LightmapUV1;
uint LightmapDataIndex;
GetLightMapCoordinates(Interpolants, LightmapUV0, LightmapUV1, LightmapDataIndex);
LightmapVTPageTableResult = LightmapGetVTSampleInfo(LightmapUV0, LightmapDataIndex, SvPosition.xy);
}
#endif
#if LIGHTMAP_VT_ENABLED
// This must occur after CalcMaterialParameters(), which is required to initialize the VT feedback mechanism
// Lightmap request is always the first VT sample in the shader
StoreVirtualTextureFeedback(MaterialParameters.VirtualTextureFeedback, 0, LightmapVTPageTableResult.PackedRequest);
#endif
FMobileLightAccumulator MobileLightAccumulator = (FMobileLightAccumulator)0;
half IndirectIrradiance;
half3 IndirectColor;
half3 DiffuseColorForIndirect = ShadingModelContext.DiffuseColor;
#if (MATERIAL_SHADINGMODEL_SUBSURFACE || MATERIAL_SHADINGMODEL_PREINTEGRATED_SKIN) && MOBILE_SHADINGMODEL_SUPPORT
if (GBuffer.ShadingModelID == SHADINGMODELID_SUBSURFACE || GBuffer.ShadingModelID == SHADINGMODELID_PREINTEGRATED_SKIN)
{
DiffuseColorForIndirect += ShadingModelContext.SubsurfaceColor;
}
#endif
// Apply MaterialAO since we don't have the DiffuseIndirectComposite pass on mobile deferred.
ComputeIndirect(LightmapVTPageTableResult, Interpolants, ShadingModelContext.DiffuseDir, DiffuseColorForIndirect, MaterialAO, IndirectIrradiance, MobileLightAccumulator);
half Shadow = GetPrimaryPrecomputedShadowMask(LightmapVTPageTableResult, Interpolants, MaterialParameters).r;
#if DEFERRED_SHADING_PATH
GBuffer.IndirectIrradiance = IndirectIrradiance;
GBuffer.PrecomputedShadowFactors.r = Shadow;
MobileEncodeGBuffer(GBuffer, OutGBufferA, OutGBufferB, OutGBufferC, OutGBufferD);
#else
half4 DynamicShadowFactors = 1.0f;
half NoL = 0.0f;
// Directional light
AccumulateDirectionalLighting(GBuffer, ShadingModelContext, MaterialParameters.CameraVector, MaterialParameters.ScreenPosition, SvPosition, Shadow, DynamicShadowFactors, NoL, MobileLightAccumulator);
// Skylight
bool bApplySkyLighting = !(MATERIAL_TWOSIDED && LQ_TEXTURE_LIGHTMAP) || NoL == 0;
AccumulateSkyLighting(GBuffer, ShadingModelContext, ResolvedView.SkyLightColor.rgb, bApplySkyLighting, IndirectIrradiance, MobileLightAccumulator);
float2 LocalPosition = SvPosition.xy - ResolvedView.ViewRectMin.xy;
uint GridIndex = ComputeLightGridCellIndex(uint2(LocalPosition.x, LocalPosition.y), SvPosition.w);
// Reflection IBL
#if !(MATERIAL_SINGLE_SHADINGMODEL && MATERIAL_SHADINGMODEL_HAIR)
AccumulateReflection(GBuffer
, ShadingModelContext
, MaterialParameters.WorldPosition_CamRelative
, MaterialParameters.ReflectionVector
, IndirectIrradiance
, GridIndex
, MobileLightAccumulator);
#endif
// Local lights
#if !MATERIAL_SHADINGMODEL_SINGLELAYERWATER && ENABLE_CLUSTERED_LIGHTS
{
const uint EyeIndex = 0;
const FCulledLightsGridData CulledLightGridData = GetCulledLightsGrid(GridIndex, EyeIndex);
half4 LocalLightDynamicShadowFactors = 1.0f;
#if USE_SHADOWMASKTEXTURE
LocalLightDynamicShadowFactors = DynamicShadowFactors;
#endif
uint LightingChannelMask = GetPrimitive_LightingChannelMask(MaterialParameters.PrimitiveId);
AccumulateLightGridLocalLighting(CulledLightGridData, ShadingModelContext, GBuffer, MaterialParameters.WorldPosition_CamRelative, MaterialParameters.CameraVector, EyeIndex, 0, LocalLightDynamicShadowFactors, LightingChannelMask, MobileLightAccumulator);
}
#endif
#if MATERIAL_SHADINGMODEL_SINGLELAYERWATER
{
const bool bSeparateMainDirLightLuminance = false;
float3 SeparatedWaterMainDirLightLuminance = float3(0, 0, 0);
const bool CameraIsUnderWater = false; // Fade out the material contribution over to water contribution according to material opacity.
const float3 SunIlluminance = ResolvedView.DirectionalLightColor.rgb * PI; // times PI because it is divided by PI on CPU (=luminance) and we want illuminance here.
const float3 WaterDiffuseIndirectIlluminance = ShadingModelContext.WaterDiffuseIndirectLuminance * PI; // DiffuseIndirectLighting is luminance. So we need to multiply by PI to get illuminance.
const float3 EnvBrdf = ShadingModelContext.EnvBrdf;
const uint EyeIndex = 0;
const float4 NullDistortionParams = 1.0f;
WaterVolumeLightingOutput WaterLighting = EvaluateWaterVolumeLighting(
MaterialParameters, PixelMaterialInputs, ResolvedView,
Shadow, GBuffer.Specular, NullDistortionParams,
SunIlluminance, WaterDiffuseIndirectIlluminance, EnvBrdf,
CameraIsUnderWater, ShadingModelContext.WaterVisibility, EyeIndex,
bSeparateMainDirLightLuminance, SeparatedWaterMainDirLightLuminance);
// Accumulate luminance and occlude the background according to transmittance to view and mean transmittance to lights.
MobileLightAccumulator_Add(MobileLightAccumulator, WaterLighting.Luminance, 0.0f, 1.0f);
ShadingModelContext.Opacity = 1.0 - ((1.0 - ShadingModelContext.Opacity) * dot(WaterLighting.WaterToSceneToLightTransmittance, float3(1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0)));
}
#endif // MATERIAL_SHADINGMODEL_SINGLELAYERWATER
#endif// DEFERRED_SHADING_PATH
#if !MATERIAL_SHADINGMODEL_UNLIT
half3 Color = MobileLightAccumulator_GetResult(MobileLightAccumulator);
#else
half3 Color = 0.0f;
#endif
half4 VertexFog = half4(0, 0, 0, 1);
#if USE_VERTEX_FOG
#if PACK_INTERPOLANTS
VertexFog = PackedInterpolants[0];
#else
VertexFog = BasePassInterpolants.VertexFog;
#endif
#endif
// NEEDS_BASEPASS_PIXEL_FOGGING is not allowed on mobile for the sake of performance.
half3 Emissive = GetMaterialEmissive(PixelMaterialInputs);
#if MATERIAL_SHADINGMODEL_THIN_TRANSLUCENT
Emissive *= TopMaterialCoverage;
#endif
Color += Emissive;
#if !MATERIAL_SHADINGMODEL_UNLIT && MOBILE_EMULATION
Color = lerp(Color, ShadingModelContext.DiffuseColor, ResolvedView.UnlitViewmodeMask);
#endif
// On mobile, water (an opaque material) is rendered as trnaslucent with forced premultiplied alpha blending (see MobileBasePass::SetTranslucentRenderState)
#if MATERIALBLENDING_ALPHACOMPOSITE || MATERIAL_SHADINGMODEL_SINGLELAYERWATER
OutColor = half4(Color * VertexFog.a + VertexFog.rgb * ShadingModelContext.Opacity, ShadingModelContext.Opacity);
#elif MATERIALBLENDING_ALPHAHOLDOUT
// not implemented for holdout
OutColor = half4(Color * VertexFog.a + VertexFog.rgb * ShadingModelContext.Opacity, ShadingModelContext.Opacity);
#elif MATERIALBLENDING_TRANSLUCENT
OutColor = half4(Color * VertexFog.a + VertexFog.rgb, ShadingModelContext.Opacity);
#elif MATERIALBLENDING_ADDITIVE
OutColor = half4(Color * (VertexFog.a * ShadingModelContext.Opacity.x), 0.0f);
#elif MATERIALBLENDING_MODULATE
half3 FoggedColor = lerp(half3(1, 1, 1), Color, VertexFog.aaa * VertexFog.aaa);
OutColor = half4(FoggedColor, ShadingModelContext.Opacity);
#else
OutColor.rgb = Color * VertexFog.a + VertexFog.rgb;
#if !MATERIAL_USE_ALPHA_TO_COVERAGE
// Planar reflections and scene captures use scene color alpha to keep track of where content has been rendered, for compositing into a different scene later
OutColor.a = 0.0;
#else
half MaterialOpacityClip = GetMaterialOpacityMaskClipValue();
float Mask = GetMaterialMask(PixelMaterialInputs) / (1.0 - MaterialOpacityClip);
OutColor.a = uint((Mask + 0.25f) * 4.0f) / 4.0f;
#endif
#endif
#if USE_SCENE_DEPTH_AUX
OutSceneDepthAux = SvPosition.z;
#endif
#if !MATERIALBLENDING_MODULATE
OutColor.rgb *= ResolvedView.PreExposure;
#endif
#if MATERIAL_IS_SKY
// Sky materials can result in high luminance values, e.g. the sun disk.
// This is so we make sure to at least stay within the boundaries of fp10 and not cause NaN on some platforms.
// We also half that range to also make sure we have room for other additive elements such as bloom, clouds or particle visual effects.
OutColor.rgb = min(OutColor.rgb, Max10BitsFloat.xxx * 0.5f);
#endif
#if USE_EDITOR_COMPOSITING && (MOBILE_EMULATION)
// Editor primitive depth testing
OutColor.a = 1.0;
#if MATERIALBLENDING_MASKED
// some material might have an opacity value
OutColor.a = GetMaterialMaskInputRaw(PixelMaterialInputs);
#endif
clip(OutColor.a - GetMaterialOpacityMaskClipValue());
#else
#if OUTPUT_GAMMA_SPACE
OutColor.rgb = sqrt(OutColor.rgb);
#endif
#endif
#if NUM_VIRTUALTEXTURE_SAMPLES || LIGHTMAP_VT_ENABLED
FinalizeVirtualTextureFeedback(
MaterialParameters.VirtualTextureFeedback,
MaterialParameters.SvPosition,
ShadingModelContext.Opacity,
View.FrameNumber,
View.VTFeedbackBuffer
);
#endif
#if DEFERRED_SHADING_PATH && USE_GLES_FBF_DEFERRED
OutProxy.rgb = OutColor.rgb;
#endif
}