Files
UnrealEngineUWP/Engine/Shaders/LightmapCommon.usf
Ben Marsh 149375b14b Update copyright notices to 2015.
[CL 2379638 by Ben Marsh in Main branch]
2014-12-07 19:09:38 -05:00

168 lines
5.4 KiB
Plaintext

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
#if HQ_TEXTURE_LIGHTMAP || LQ_TEXTURE_LIGHTMAP
#ifndef MATERIAL_USE_LM_DIRECTIONALITY
#define MATERIAL_USE_LM_DIRECTIONALITY 1
#endif
Texture2D LightMapTexture;
SamplerState LightMapSampler;
Texture2D SkyOcclusionTexture;
SamplerState SkyOcclusionSampler;
half4 LightMapScale[NUM_LIGHTMAP_COEFFICIENTS];
half4 LightMapAdd[NUM_LIGHTMAP_COEFFICIENTS];
half4 GetLightMapColorLQ( float2 LightmapUV0, float2 LightmapUV1, half3 WorldNormal )
{
half4 Lightmap0 = Texture2DSample( LightMapTexture, LightMapSampler, LightmapUV0 );
half4 Lightmap1 = Texture2DSample( LightMapTexture, LightMapSampler, LightmapUV1 );
// Range scale
half3 LogRGB = Lightmap0.rgb * LightMapScale[0].xyz + LightMapAdd[0].xyz; // 1 vmad
half LogL = Luminance( LogRGB ); // 1 dot
// LogL -> L
const half LogBlackPoint = 0.00390625; // exp2(-8);
half L = exp2( LogL * 16 - 8 ) - LogBlackPoint; // 1 exp2, 1 smad, 1 ssub
#if MATERIAL_USE_LM_DIRECTIONALITY
// Alpha doesn't matter, will scaled by zero
half4 SH = Lightmap1 * LightMapScale[1] + LightMapAdd[1]; // 1 vmad
// Sample SH with normal
half Directionality = max( 0.0, dot( SH, half4(WorldNormal.yzx, 1) ) ); // 1 dot, 1 smax
#else
half Directionality = 0.6;
#endif
half Luma = L * Directionality;
half3 Color = LogRGB * (Luma / LogL); // 1 rcp, 1 smul, 1 vmul
return half4( Color, Luma );
}
void GetLightMapColorHQ( float2 LightmapUV0, float2 LightmapUV1, half3 WorldNormal, out half3 OutDiffuseLighting, out half3 OutSubsurfaceLighting )
{
OutSubsurfaceLighting = 0;
half4 Lightmap0 = Texture2DSample( LightMapTexture, LightMapSampler, LightmapUV0 );
half4 Lightmap1 = Texture2DSample( LightMapTexture, LightMapSampler, LightmapUV1 );
half LogL = Lightmap0.w;
// Add residual
LogL += Lightmap1.w * (1.0 / 255) - (0.5 / 255);
// Range scale LogL
LogL = LogL * LightMapScale[0].w + LightMapAdd[0].w;
// Range scale UVW
half3 UVW = Lightmap0.rgb * Lightmap0.rgb * LightMapScale[0].rgb + LightMapAdd[0].rgb;
// LogL -> L
const half LogBlackPoint = 0.01858136;
half L = exp2( LogL ) - LogBlackPoint;
#if MATERIAL_USE_LM_DIRECTIONALITY
// Range scale SH. Alpha doesn't matter, will scale with zero
half4 SH = Lightmap1 * LightMapScale[1] + LightMapAdd[1];
// Sample SH with normal
half Directionality = max( 0.0, dot( SH, half4(WorldNormal.yzx, 1) ) );
#if MATERIAL_SHADINGMODEL_TWOSIDED_FOLIAGE
half SubsurfaceDirectionality = max( 0.0, dot( SH, half4(-WorldNormal.yzx, 1) ) );
OutSubsurfaceLighting = L * SubsurfaceDirectionality * UVW;
#endif
#else
half Directionality = 0.6;
#endif
half Luma = L * Directionality;
half3 Color = Luma * UVW;
OutDiffuseLighting = Color;
}
float4 GetSkyBentNormalAndOcclusion(float2 LightmapUV)
{
#if SUPPORTS_INDEPENDENT_SAMPLERS
// Share sampler with lightmaps to give artists more available
float4 TextureValue = Texture2DSample(SkyOcclusionTexture, LightMapSampler, LightmapUV.xy);
#else
float4 TextureValue = Texture2DSample(SkyOcclusionTexture, SkyOcclusionSampler, LightmapUV.xy);
#endif
// Unpack vector
TextureValue.rgb = TextureValue.rgb * 2 - 1;
// Undo sqrt which allocated more precision toward 0
TextureValue.a = TextureValue.a * TextureValue.a;
return TextureValue;
}
#endif
#if STATICLIGHTING_TEXTUREMASK && STATICLIGHTING_SIGNEDDISTANCEFIELD
float4 StaticShadowMapMasks;
float4 DistanceFieldParameters;
Texture2D StaticShadowTexture;
SamplerState StaticShadowTextureSampler;
#endif
half4 GetPrecomputedShadowMasks(FVertexFactoryInterpolantsVSToPS Interpolants)
{
#if STATICLIGHTING_TEXTUREMASK && STATICLIGHTING_SIGNEDDISTANCEFIELD
// Fetch the 4 channels of distance field data
half4 DistanceField = Texture2DSample(StaticShadowTexture, StaticShadowTextureSampler, GetShadowMapCoordinate(Interpolants));
// Compute shadow factors by scaling and biasing the distance
half4 ShadowFactors = saturate( DistanceField * DistanceFieldParameters.x + DistanceFieldParameters.y );
return StaticShadowMapMasks * ShadowFactors * ShadowFactors;
#elif HQ_TEXTURE_LIGHTMAP || LQ_TEXTURE_LIGHTMAP
// Mark as shadowed for lightmapped objects with no shadowmap
// This is necessary because objects inside a light's influence that were determined to be completely shadowed won't be rendered with STATICLIGHTING_TEXTUREMASK==1
return 0;
#else
// Mark as unshadowed by default
return 1;
#endif
}
half GetPrimaryPrecomputedShadowMask(FVertexFactoryInterpolantsVSToPS Interpolants)
{
#if STATICLIGHTING_TEXTUREMASK && STATICLIGHTING_SIGNEDDISTANCEFIELD
// Fetch the distance field data
half DistanceField = Texture2DSample(StaticShadowTexture, StaticShadowTextureSampler, GetShadowMapCoordinate(Interpolants)).r;
// Compute shadow factors by scaling and biasing the distance
half ShadowFactor = saturate( DistanceField * DistanceFieldParameters.x + DistanceFieldParameters.y );
return ShadowFactor * ShadowFactor;
#elif MOVABLE_DIRECTIONAL_LIGHT
// Do this before checking for lightmaps as we might have a lightmap + directional light
//@mw todo
// TODO: Filter shadowmap
return 1;
#elif HQ_TEXTURE_LIGHTMAP || LQ_TEXTURE_LIGHTMAP
// Mark as shadowed for lightmapped objects with no shadowmap
// This is necessary because objects inside a light's influence that were determined to be completely shadowed won't be rendered with STATICLIGHTING_TEXTUREMASK==1
return 0;
#else
// Mark as unshadowed by default
return 1;
#endif
}