You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
reviewedby michael.trepka, rolando.caloca, lee.clark [CL 2670859 by Mark Satterthwaite in Main branch]
228 lines
10 KiB
Plaintext
228 lines
10 KiB
Plaintext
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
GlobalDistanceFieldShared.usf
|
|
=============================================================================*/
|
|
|
|
#if FEATURE_LEVEL >= FEATURE_LEVEL_SM5
|
|
|
|
float MaxGlobalDistance;
|
|
|
|
//@todo - get the clipmap branches to compile under gl
|
|
#if SM5_PROFILE || PS4_PROFILE
|
|
|
|
// Must match C++
|
|
#define MAX_GLOBAL_DF_CLIPMAPS 4
|
|
|
|
Texture3D GlobalDistanceFieldTexture0;
|
|
Texture3D GlobalDistanceFieldTexture1;
|
|
Texture3D GlobalDistanceFieldTexture2;
|
|
Texture3D GlobalDistanceFieldTexture3;
|
|
SamplerState GlobalDistanceFieldSampler0;
|
|
SamplerState GlobalDistanceFieldSampler1;
|
|
SamplerState GlobalDistanceFieldSampler2;
|
|
SamplerState GlobalDistanceFieldSampler3;
|
|
float4 GlobalVolumeCenterAndExtent[MAX_GLOBAL_DF_CLIPMAPS];
|
|
float4 GlobalVolumeWorldToUVAddAndMul[MAX_GLOBAL_DF_CLIPMAPS];
|
|
float GlobalVolumeDimension;
|
|
float GlobalVolumeTexelSize;
|
|
|
|
float4 SampleGlobalDistanceField(int ClipmapIndex, float3 UV)
|
|
{
|
|
if (ClipmapIndex == 0)
|
|
{
|
|
return Texture3DSampleLevel(GlobalDistanceFieldTexture0, GlobalDistanceFieldSampler0, UV, 0);
|
|
}
|
|
else if (ClipmapIndex == 1)
|
|
{
|
|
return Texture3DSampleLevel(GlobalDistanceFieldTexture1, GlobalDistanceFieldSampler1, UV, 0);
|
|
}
|
|
else if (ClipmapIndex == 2)
|
|
{
|
|
return Texture3DSampleLevel(GlobalDistanceFieldTexture2, GlobalDistanceFieldSampler2, UV, 0);
|
|
}
|
|
else
|
|
{
|
|
return Texture3DSampleLevel(GlobalDistanceFieldTexture3, GlobalDistanceFieldSampler3, UV, 0);
|
|
}
|
|
}
|
|
|
|
float3 ComputeGlobalUV(float3 WorldPosition, uint ClipmapIndex)
|
|
{
|
|
//return ((WorldPosition - GlobalVolumeCenterAndExtent[ClipmapIndex].xyz + GlobalVolumeScollOffset[ClipmapIndex].xyz) / (GlobalVolumeCenterAndExtent[ClipmapIndex].w * 2) + .5f);
|
|
float4 WorldToUVAddAndMul = GlobalVolumeWorldToUVAddAndMul[ClipmapIndex];
|
|
return WorldPosition * WorldToUVAddAndMul.www + WorldToUVAddAndMul.xyz;
|
|
}
|
|
|
|
float GetDistanceToNearestSurfaceGlobalClipmap(float3 WorldPosition, uint ClipmapIndex)
|
|
{
|
|
float3 GlobalUV = ComputeGlobalUV(WorldPosition, ClipmapIndex);
|
|
float DistanceToSurface = 0;
|
|
if (ClipmapIndex == 0)
|
|
{
|
|
DistanceToSurface = Texture3DSampleLevel(GlobalDistanceFieldTexture0, GlobalDistanceFieldSampler0, GlobalUV, 0).x;
|
|
}
|
|
else if (ClipmapIndex == 1)
|
|
{
|
|
DistanceToSurface = Texture3DSampleLevel(GlobalDistanceFieldTexture1, GlobalDistanceFieldSampler1, GlobalUV, 0).x;
|
|
}
|
|
else if (ClipmapIndex == 2)
|
|
{
|
|
DistanceToSurface = Texture3DSampleLevel(GlobalDistanceFieldTexture2, GlobalDistanceFieldSampler2, GlobalUV, 0).x;
|
|
}
|
|
else if (ClipmapIndex == 3)
|
|
{
|
|
DistanceToSurface = Texture3DSampleLevel(GlobalDistanceFieldTexture3, GlobalDistanceFieldSampler3, GlobalUV, 0).x;
|
|
}
|
|
return DistanceToSurface;
|
|
}
|
|
|
|
float GetDistanceToNearestSurfaceGlobal(float3 WorldPosition)
|
|
{
|
|
float DistanceToSurface = MaxGlobalDistance;
|
|
float DistanceFromClipmap = ComputeDistanceFromBoxToPointInside(GlobalVolumeCenterAndExtent[0].xyz, GlobalVolumeCenterAndExtent[0].www, WorldPosition);
|
|
|
|
//@todo - would be nice to atlas to get rid of branches and multiple samplers but the partial update scrolling relies on wrap addressing
|
|
BRANCH
|
|
if (DistanceFromClipmap > GlobalVolumeCenterAndExtent[0].w * GlobalVolumeTexelSize)
|
|
{
|
|
DistanceToSurface = GetDistanceToNearestSurfaceGlobalClipmap(WorldPosition, 0);
|
|
}
|
|
else
|
|
{
|
|
DistanceFromClipmap = ComputeDistanceFromBoxToPointInside(GlobalVolumeCenterAndExtent[1].xyz, GlobalVolumeCenterAndExtent[1].www, WorldPosition);
|
|
|
|
BRANCH
|
|
if (DistanceFromClipmap > GlobalVolumeCenterAndExtent[1].w * GlobalVolumeTexelSize)
|
|
{
|
|
DistanceToSurface = GetDistanceToNearestSurfaceGlobalClipmap(WorldPosition, 1);
|
|
}
|
|
else
|
|
{
|
|
DistanceFromClipmap = ComputeDistanceFromBoxToPointInside(GlobalVolumeCenterAndExtent[2].xyz, GlobalVolumeCenterAndExtent[2].www, WorldPosition);
|
|
float DistanceFromLastClipmap = ComputeDistanceFromBoxToPointInside(GlobalVolumeCenterAndExtent[3].xyz, GlobalVolumeCenterAndExtent[3].www, WorldPosition);
|
|
|
|
BRANCH
|
|
if (DistanceFromClipmap > GlobalVolumeCenterAndExtent[2].w * GlobalVolumeTexelSize)
|
|
{
|
|
DistanceToSurface = GetDistanceToNearestSurfaceGlobalClipmap(WorldPosition, 2);
|
|
}
|
|
else if (DistanceFromLastClipmap > GlobalVolumeCenterAndExtent[3].w * GlobalVolumeTexelSize)
|
|
{
|
|
DistanceToSurface = GetDistanceToNearestSurfaceGlobalClipmap(WorldPosition, 3);
|
|
}
|
|
}
|
|
}
|
|
|
|
return DistanceToSurface;
|
|
}
|
|
|
|
float3 GetDistanceFieldGradientGlobalClipmap(float3 WorldPosition, uint ClipmapIndex)
|
|
{
|
|
float3 GlobalUV = ComputeGlobalUV(WorldPosition, ClipmapIndex);
|
|
|
|
float R = 0;
|
|
float L = 0;
|
|
float F = 0;
|
|
float B = 0;
|
|
float U = 0;
|
|
float D = 0;
|
|
|
|
if (ClipmapIndex == 0)
|
|
{
|
|
R = Texture3DSampleLevel(GlobalDistanceFieldTexture0, GlobalDistanceFieldSampler0, float3(GlobalUV.x + GlobalVolumeTexelSize, GlobalUV.y, GlobalUV.z), 0).x;
|
|
L = Texture3DSampleLevel(GlobalDistanceFieldTexture0, GlobalDistanceFieldSampler0, float3(GlobalUV.x - GlobalVolumeTexelSize, GlobalUV.y, GlobalUV.z), 0).x;
|
|
F = Texture3DSampleLevel(GlobalDistanceFieldTexture0, GlobalDistanceFieldSampler0, float3(GlobalUV.x, GlobalUV.y + GlobalVolumeTexelSize, GlobalUV.z), 0).x;
|
|
B = Texture3DSampleLevel(GlobalDistanceFieldTexture0, GlobalDistanceFieldSampler0, float3(GlobalUV.x, GlobalUV.y - GlobalVolumeTexelSize, GlobalUV.z), 0).x;
|
|
U = Texture3DSampleLevel(GlobalDistanceFieldTexture0, GlobalDistanceFieldSampler0, float3(GlobalUV.x, GlobalUV.y, GlobalUV.z + GlobalVolumeTexelSize), 0).x;
|
|
D = Texture3DSampleLevel(GlobalDistanceFieldTexture0, GlobalDistanceFieldSampler0, float3(GlobalUV.x, GlobalUV.y, GlobalUV.z - GlobalVolumeTexelSize), 0).x;
|
|
}
|
|
else if (ClipmapIndex == 1)
|
|
{
|
|
R = Texture3DSampleLevel(GlobalDistanceFieldTexture1, GlobalDistanceFieldSampler1, float3(GlobalUV.x + GlobalVolumeTexelSize, GlobalUV.y, GlobalUV.z), 0).x;
|
|
L = Texture3DSampleLevel(GlobalDistanceFieldTexture1, GlobalDistanceFieldSampler1, float3(GlobalUV.x - GlobalVolumeTexelSize, GlobalUV.y, GlobalUV.z), 0).x;
|
|
F = Texture3DSampleLevel(GlobalDistanceFieldTexture1, GlobalDistanceFieldSampler1, float3(GlobalUV.x, GlobalUV.y + GlobalVolumeTexelSize, GlobalUV.z), 0).x;
|
|
B = Texture3DSampleLevel(GlobalDistanceFieldTexture1, GlobalDistanceFieldSampler1, float3(GlobalUV.x, GlobalUV.y - GlobalVolumeTexelSize, GlobalUV.z), 0).x;
|
|
U = Texture3DSampleLevel(GlobalDistanceFieldTexture1, GlobalDistanceFieldSampler1, float3(GlobalUV.x, GlobalUV.y, GlobalUV.z + GlobalVolumeTexelSize), 0).x;
|
|
D = Texture3DSampleLevel(GlobalDistanceFieldTexture1, GlobalDistanceFieldSampler1, float3(GlobalUV.x, GlobalUV.y, GlobalUV.z - GlobalVolumeTexelSize), 0).x;
|
|
}
|
|
else if (ClipmapIndex == 2)
|
|
{
|
|
R = Texture3DSampleLevel(GlobalDistanceFieldTexture2, GlobalDistanceFieldSampler2, float3(GlobalUV.x + GlobalVolumeTexelSize, GlobalUV.y, GlobalUV.z), 0).x;
|
|
L = Texture3DSampleLevel(GlobalDistanceFieldTexture2, GlobalDistanceFieldSampler2, float3(GlobalUV.x - GlobalVolumeTexelSize, GlobalUV.y, GlobalUV.z), 0).x;
|
|
F = Texture3DSampleLevel(GlobalDistanceFieldTexture2, GlobalDistanceFieldSampler2, float3(GlobalUV.x, GlobalUV.y + GlobalVolumeTexelSize, GlobalUV.z), 0).x;
|
|
B = Texture3DSampleLevel(GlobalDistanceFieldTexture2, GlobalDistanceFieldSampler2, float3(GlobalUV.x, GlobalUV.y - GlobalVolumeTexelSize, GlobalUV.z), 0).x;
|
|
U = Texture3DSampleLevel(GlobalDistanceFieldTexture2, GlobalDistanceFieldSampler2, float3(GlobalUV.x, GlobalUV.y, GlobalUV.z + GlobalVolumeTexelSize), 0).x;
|
|
D = Texture3DSampleLevel(GlobalDistanceFieldTexture2, GlobalDistanceFieldSampler2, float3(GlobalUV.x, GlobalUV.y, GlobalUV.z - GlobalVolumeTexelSize), 0).x;
|
|
}
|
|
else if (ClipmapIndex == 3)
|
|
{
|
|
R = Texture3DSampleLevel(GlobalDistanceFieldTexture3, GlobalDistanceFieldSampler3, float3(GlobalUV.x + GlobalVolumeTexelSize, GlobalUV.y, GlobalUV.z), 0).x;
|
|
L = Texture3DSampleLevel(GlobalDistanceFieldTexture3, GlobalDistanceFieldSampler3, float3(GlobalUV.x - GlobalVolumeTexelSize, GlobalUV.y, GlobalUV.z), 0).x;
|
|
F = Texture3DSampleLevel(GlobalDistanceFieldTexture3, GlobalDistanceFieldSampler3, float3(GlobalUV.x, GlobalUV.y + GlobalVolumeTexelSize, GlobalUV.z), 0).x;
|
|
B = Texture3DSampleLevel(GlobalDistanceFieldTexture3, GlobalDistanceFieldSampler3, float3(GlobalUV.x, GlobalUV.y - GlobalVolumeTexelSize, GlobalUV.z), 0).x;
|
|
U = Texture3DSampleLevel(GlobalDistanceFieldTexture3, GlobalDistanceFieldSampler3, float3(GlobalUV.x, GlobalUV.y, GlobalUV.z + GlobalVolumeTexelSize), 0).x;
|
|
D = Texture3DSampleLevel(GlobalDistanceFieldTexture3, GlobalDistanceFieldSampler3, float3(GlobalUV.x, GlobalUV.y, GlobalUV.z - GlobalVolumeTexelSize), 0).x;
|
|
}
|
|
|
|
float Extent = GlobalVolumeCenterAndExtent[ClipmapIndex].w;
|
|
float3 Gradient = .5f * float3(R - L, F - B, U - D) / Extent;
|
|
return Gradient;
|
|
}
|
|
|
|
float3 GetDistanceFieldGradientGlobal(float3 WorldPosition)
|
|
{
|
|
float3 Gradient = float3(0, 0, .001f);
|
|
float DistanceFromClipmap = ComputeDistanceFromBoxToPointInside(GlobalVolumeCenterAndExtent[0].xyz, GlobalVolumeCenterAndExtent[0].www, WorldPosition);
|
|
// Don't sample near the border to avoid sampling out of bounds during partial differencing
|
|
float BorderTexels = GlobalVolumeTexelSize * 4;
|
|
|
|
BRANCH
|
|
if (DistanceFromClipmap > GlobalVolumeCenterAndExtent[0].w * BorderTexels)
|
|
{
|
|
Gradient = GetDistanceFieldGradientGlobalClipmap(WorldPosition, 0);
|
|
}
|
|
else
|
|
{
|
|
DistanceFromClipmap = ComputeDistanceFromBoxToPointInside(GlobalVolumeCenterAndExtent[1].xyz, GlobalVolumeCenterAndExtent[1].www, WorldPosition);
|
|
|
|
BRANCH
|
|
if (DistanceFromClipmap > GlobalVolumeCenterAndExtent[1].w * BorderTexels)
|
|
{
|
|
Gradient = GetDistanceFieldGradientGlobalClipmap(WorldPosition, 1);
|
|
}
|
|
else
|
|
{
|
|
DistanceFromClipmap = ComputeDistanceFromBoxToPointInside(GlobalVolumeCenterAndExtent[2].xyz, GlobalVolumeCenterAndExtent[2].www, WorldPosition);
|
|
float DistanceFromLastClipmap = ComputeDistanceFromBoxToPointInside(GlobalVolumeCenterAndExtent[3].xyz, GlobalVolumeCenterAndExtent[3].www, WorldPosition);
|
|
|
|
BRANCH
|
|
if (DistanceFromClipmap > GlobalVolumeCenterAndExtent[2].w * BorderTexels)
|
|
{
|
|
Gradient = GetDistanceFieldGradientGlobalClipmap(WorldPosition, 2);
|
|
}
|
|
else if (DistanceFromLastClipmap > GlobalVolumeCenterAndExtent[3].w * BorderTexels)
|
|
{
|
|
Gradient = GetDistanceFieldGradientGlobalClipmap(WorldPosition, 3);
|
|
}
|
|
}
|
|
}
|
|
|
|
return Gradient;
|
|
}
|
|
|
|
#else
|
|
|
|
float GetDistanceToNearestSurfaceGlobal(float3 WorldPosition)
|
|
{
|
|
return MaxGlobalDistance;
|
|
}
|
|
|
|
float3 GetDistanceFieldGradientGlobal(float3 WorldPosition)
|
|
{
|
|
return float3(0, 0, .001f);
|
|
}
|
|
|
|
#endif
|
|
#endif // FEATURE_LEVEL >= FEATURE_LEVEL_SM5
|