You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
[FYI] Chris.Bunner, Krzysztof.Narkowicz, Marcus.Wassmer, Yuriy.Odonnell, Matt.Kuhlenschmidt #rb Krzysztof.Narkowicz #ROBOMERGE-OWNER: ryan.vance #ROBOMERGE-AUTHOR: kevin.ortegren #ROBOMERGE-SOURCE: CL 6308573 via CL 6309266 via CL 6315508 #ROBOMERGE-BOT: DEVVR (Main -> Dev-VR) [CL 6348696 by joe conley in Dev-VR branch]
275 lines
11 KiB
Plaintext
275 lines
11 KiB
Plaintext
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "ShadingCommon.ush"
|
|
#include "/Engine/Generated/UniformBuffers/PrecomputedLightingBuffer.ush"
|
|
#include "VolumetricLightmapShared.ush"
|
|
#include "VirtualTextureCommon.ush"
|
|
#include "LightmapData.ush"
|
|
|
|
#if HQ_TEXTURE_LIGHTMAP || LQ_TEXTURE_LIGHTMAP
|
|
|
|
#ifndef MATERIAL_USE_LM_DIRECTIONALITY
|
|
#define MATERIAL_USE_LM_DIRECTIONALITY 1
|
|
#endif
|
|
|
|
// Material quality overrides
|
|
#ifndef QL_FORCEDISABLE_LM_DIRECTIONALITY
|
|
#define QL_FORCEDISABLE_LM_DIRECTIONALITY 0
|
|
#endif
|
|
|
|
#define USE_LM_DIRECTIONALITY (MATERIAL_USE_LM_DIRECTIONALITY && !QL_FORCEDISABLE_LM_DIRECTIONALITY)
|
|
|
|
half4 SampleLightmapVT(float2 UV, Texture2D CacheTexture, SamplerState CacheSampler, float2 SvPositionXY, out uint Request)
|
|
{
|
|
#if LIGHTMAP_VT_ENABLED
|
|
VTSampleInfo VTInfo = GetVTSampleInfo(PrecomputedLightingBuffer.LightmapVirtualTextureUniformData, UV, LIGHTMAP_VT_16BIT, SvPositionXY);
|
|
|
|
uint2 pPage;
|
|
uint vPagesWideInLevel;
|
|
|
|
#if LIGHTMAP_VT_16BIT
|
|
PageTable2DTranslation16( PrecomputedLightingBuffer.LightmapVirtualTexturePageTable, GetVirtualTexturePageTableSize(PrecomputedLightingBuffer.LightmapVirtualTextureUniformData), VTInfo.vPage, VTInfo.Level, pPage, vPagesWideInLevel );
|
|
#else
|
|
PageTable2DTranslation32( PrecomputedLightingBuffer.LightmapVirtualTexturePageTable, PrecomputedLightingBuffer.LightmapVirtualTexturePageTableSampler, UV, VTInfo.Level, pPage, vPagesWideInLevel );
|
|
#endif
|
|
|
|
const float vPageSize = GetVirtualTexturePageSize(PrecomputedLightingBuffer.LightmapVirtualTextureUniformData);
|
|
const float pPageBorder = GetVirtualTexturePageBorder(PrecomputedLightingBuffer.LightmapVirtualTextureUniformData);
|
|
const float pPageSize = vPageSize + 2 * pPageBorder;
|
|
const float2 pTextureSize = GetVirtualTextureCacheSize(PrecomputedLightingBuffer.LightmapVirtualTextureUniformData);
|
|
|
|
const float2 pUV = VirtualToPhysical2D( pTextureSize, vPageSize, pPageSize, pPage, vPagesWideInLevel, UV, VTInfo.dUVdx, VTInfo.dUVdy );
|
|
|
|
Request = VTInfo.Request;
|
|
|
|
return CacheTexture.SampleGrad( CacheSampler, pUV, VTInfo.dUVdx, VTInfo.dUVdy );
|
|
|
|
#else
|
|
Request = 0xffffffff;
|
|
return Texture2DSample( CacheTexture, CacheSampler, UV );
|
|
#endif
|
|
}
|
|
|
|
half4 GetLightMapColorLQ( float2 LightmapUV0, float2 LightmapUV1, uint LightmapDataIndex, half3 WorldNormal )
|
|
{
|
|
half4 Lightmap0 = Texture2DSample( LightmapResourceCluster.LightMapTexture, LightmapResourceCluster.LightMapSampler, LightmapUV0 );
|
|
half4 Lightmap1 = Texture2DSample( LightmapResourceCluster.LightMapTexture, LightmapResourceCluster.LightMapSampler, LightmapUV1 );
|
|
|
|
// Range scale
|
|
half3 LogRGB = Lightmap0.rgb * GetLightmapData(LightmapDataIndex).LightMapScale[0].xyz + GetLightmapData(LightmapDataIndex).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 USE_LM_DIRECTIONALITY
|
|
// Alpha doesn't matter, will scaled by zero
|
|
float4 SH = Lightmap1 * GetLightmapData(LightmapDataIndex).LightMapScale[1] + GetLightmapData(LightmapDataIndex).LightMapAdd[1]; // 1 vmad
|
|
|
|
// Sample SH with normal
|
|
half Directionality = max( 0.0, dot( SH, float4(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, uint LightmapDataIndex, half3 WorldNormal, float2 SvPositionXY, uint ShadingModel, out half3 OutDiffuseLighting, out half3 OutSubsurfaceLighting, out uint VTRequest )
|
|
{
|
|
OutSubsurfaceLighting = 0;
|
|
|
|
#if LIGHTMAP_VT_ENABLED
|
|
LightmapUV0 *= float2(1, 2);
|
|
#endif
|
|
|
|
half4 Lightmap0 = SampleLightmapVT( LightmapUV0 , LightmapResourceCluster.LightMapTexture, LightmapResourceCluster.LightMapSampler, SvPositionXY, VTRequest);
|
|
|
|
uint VTRequest_notused = 0;
|
|
half4 Lightmap1 = SampleLightmapVT(
|
|
#if LIGHTMAP_VT_ENABLED
|
|
LightmapUV0, LightmapResourceCluster.LightMapTexture_1,
|
|
#else
|
|
LightmapUV1, LightmapResourceCluster.LightMapTexture,
|
|
#endif
|
|
LightmapResourceCluster.LightMapSampler, SvPositionXY, VTRequest_notused);
|
|
|
|
|
|
|
|
half LogL = Lightmap0.w;
|
|
|
|
// Add residual
|
|
LogL += Lightmap1.w * (1.0 / 255) - (0.5 / 255);
|
|
|
|
// Range scale LogL
|
|
LogL = LogL * GetLightmapData(LightmapDataIndex).LightMapScale[0].w + GetLightmapData(LightmapDataIndex).LightMapAdd[0].w;
|
|
|
|
// Range scale UVW
|
|
half3 UVW = Lightmap0.rgb * Lightmap0.rgb * GetLightmapData(LightmapDataIndex).LightMapScale[0].rgb + GetLightmapData(LightmapDataIndex).LightMapAdd[0].rgb;
|
|
|
|
// LogL -> L
|
|
const half LogBlackPoint = 0.01858136;
|
|
half L = exp2( LogL ) - LogBlackPoint;
|
|
|
|
#if USE_LM_DIRECTIONALITY
|
|
// Range scale SH. Alpha doesn't matter, will scale with zero
|
|
float4 SH = Lightmap1 * GetLightmapData(LightmapDataIndex).LightMapScale[1] + GetLightmapData(LightmapDataIndex).LightMapAdd[1];
|
|
|
|
// Sample SH with normal
|
|
half Directionality = max( 0.0, dot( SH, float4(WorldNormal.yzx, 1) ) );
|
|
|
|
#if MATERIAL_SHADINGMODEL_TWOSIDED_FOLIAGE
|
|
if (ShadingModel == SHADINGMODELID_TWOSIDED_FOLIAGE)
|
|
{
|
|
half SubsurfaceDirectionality = max(0.0, dot(SH, float4(-WorldNormal.yzx, 1)));
|
|
OutSubsurfaceLighting = L * SubsurfaceDirectionality * UVW;
|
|
}
|
|
#endif
|
|
#else
|
|
half Directionality = 0.6;
|
|
|
|
#if MATERIAL_SHADINGMODEL_TWOSIDED_FOLIAGE
|
|
if (ShadingModel == SHADINGMODELID_TWOSIDED_FOLIAGE)
|
|
{
|
|
OutSubsurfaceLighting = L * Directionality * UVW;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
half Luma = L * Directionality;
|
|
half3 Color = Luma * UVW;
|
|
|
|
OutDiffuseLighting = Color;
|
|
}
|
|
|
|
float4 GetSkyBentNormalAndOcclusion(float2 LightmapUV, float2 SvPositionXY)
|
|
{
|
|
uint VTRequest_notused;
|
|
#if SUPPORTS_INDEPENDENT_SAMPLERS
|
|
// Share sampler with lightmaps to give artists more available
|
|
float4 TextureValue = SampleLightmapVT( LightmapUV.xy , LightmapResourceCluster.SkyOcclusionTexture, LightmapResourceCluster.LightMapSampler, SvPositionXY, VTRequest_notused);
|
|
#else
|
|
float4 TextureValue = SampleLightmapVT( LightmapUV.xy , LightmapResourceCluster.SkyOcclusionTexture, LightmapResourceCluster.SkyOcclusionSampler, SvPositionXY, VTRequest_notused);
|
|
#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;
|
|
}
|
|
|
|
float GetAOMaterialMask(float2 LightmapUV, float2 SvPositionXY)
|
|
{
|
|
uint VTRequest_notused;
|
|
#if SUPPORTS_INDEPENDENT_SAMPLERS
|
|
// Share sampler with lightmaps to give artists more available
|
|
float TextureValue = SampleLightmapVT( LightmapUV.xy , LightmapResourceCluster.AOMaterialMaskTexture, LightmapResourceCluster.LightMapSampler, SvPositionXY, VTRequest_notused).x;
|
|
#else
|
|
float TextureValue = SampleLightmapVT( LightmapUV.xy , LightmapResourceCluster.AOMaterialMaskTexture, LightmapResourceCluster.AOMaterialMaskSampler, SvPositionXY, VTRequest_notused).x;
|
|
#endif
|
|
// Undo sqrt which allocated more precision toward 0
|
|
return TextureValue * TextureValue;
|
|
}
|
|
|
|
#endif
|
|
|
|
// Used by deferred renderer only
|
|
half4 GetPrecomputedShadowMasks(FVertexFactoryInterpolantsVSToPS Interpolants, uint PrimitiveId, float3 WorldPosition, float3 VolumetricLightmapBrickTextureUVs)
|
|
{
|
|
// Note: WRITES_PRECSHADOWFACTOR_ZERO have to match the logic here
|
|
#if STATICLIGHTING_TEXTUREMASK && STATICLIGHTING_SIGNEDDISTANCEFIELD
|
|
|
|
float2 ShadowMapCoordinate;
|
|
uint LightmapDataIndex;
|
|
GetShadowMapCoordinate(Interpolants, ShadowMapCoordinate, LightmapDataIndex);
|
|
|
|
// Fetch the 4 channels of distance field data
|
|
half4 DistanceField = Texture2DSample(LightmapResourceCluster.StaticShadowTexture, LightmapResourceCluster.StaticShadowTextureSampler, ShadowMapCoordinate);
|
|
float4 InvUniformPenumbraSizes = GetLightmapData(LightmapDataIndex).InvUniformPenumbraSizes;
|
|
float4 DistanceFieldBias = -.5f * InvUniformPenumbraSizes + .5f;
|
|
|
|
// Compute shadow factors by scaling and biasing the distance
|
|
half4 ShadowFactors = saturate(DistanceField * InvUniformPenumbraSizes + DistanceFieldBias);
|
|
return GetLightmapData(LightmapDataIndex).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
|
|
|
|
float DirectionalLightShadowing = 1.0f;
|
|
|
|
#if CACHED_POINT_INDIRECT_LIGHTING || CACHED_VOLUME_INDIRECT_LIGHTING
|
|
if (GetPrimitiveData(PrimitiveId).UseSingleSampleShadowFromStationaryLights > 0 && View.IndirectLightingCacheShowFlag > 0.0f)
|
|
{
|
|
DirectionalLightShadowing = IndirectLightingCache.DirectionalLightShadowing;
|
|
}
|
|
#endif
|
|
|
|
BRANCH
|
|
if (GetPrimitiveData(PrimitiveId).UseVolumetricLightmapShadowFromStationaryLights > 0)
|
|
{
|
|
#if !PRECOMPUTED_IRRADIANCE_VOLUME_LIGHTING
|
|
// Compute brick UVs if we haven't already
|
|
VolumetricLightmapBrickTextureUVs = ComputeVolumetricLightmapBrickTextureUVs(WorldPosition);
|
|
#endif
|
|
|
|
DirectionalLightShadowing = GetVolumetricLightmapDirectionalLightShadowing(VolumetricLightmapBrickTextureUVs);
|
|
}
|
|
|
|
// Directional light is always packed into the first static shadowmap channel, so output the per-primitive directional light shadowing there if requested
|
|
return half4(DirectionalLightShadowing, 1, 1, 1);
|
|
|
|
#endif
|
|
}
|
|
|
|
// Used by mobile renderer only
|
|
half GetPrimaryPrecomputedShadowMask(FVertexFactoryInterpolantsVSToPS Interpolants)
|
|
{
|
|
#if STATICLIGHTING_TEXTUREMASK && STATICLIGHTING_SIGNEDDISTANCEFIELD
|
|
|
|
float2 ShadowMapCoordinate;
|
|
uint LightmapDataIndex;
|
|
GetShadowMapCoordinate(Interpolants, ShadowMapCoordinate, LightmapDataIndex);
|
|
|
|
// Fetch the distance field data
|
|
half DistanceField = Texture2DSample(LightmapResourceCluster.StaticShadowTexture, LightmapResourceCluster.StaticShadowTextureSampler, ShadowMapCoordinate).r;
|
|
float4 InvUniformPenumbraSizes = GetLightmapData(LightmapDataIndex).InvUniformPenumbraSizes;
|
|
float DistanceFieldBias = -.5f * InvUniformPenumbraSizes.x + .5f;
|
|
// Compute shadow factors by scaling and biasing the distance
|
|
half ShadowFactor = saturate( DistanceField * InvUniformPenumbraSizes.x + DistanceFieldBias );
|
|
return GetLightmapData(LightmapDataIndex).StaticShadowMapMasks.r * 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
|
|
#if CACHED_POINT_INDIRECT_LIGHTING || CACHED_VOLUME_INDIRECT_LIGHTING
|
|
// output per-primitive directional light shadowing if requested
|
|
if (GetPrimitiveData(Interpolants.PrimitiveId).UseSingleSampleShadowFromStationaryLights > 0 && ResolvedView.IndirectLightingCacheShowFlag > 0.0f)
|
|
{
|
|
return IndirectLightingCache.DirectionalLightShadowing;
|
|
}
|
|
#endif
|
|
|
|
return 1;
|
|
#endif
|
|
}
|