You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
130 lines
5.9 KiB
Plaintext
130 lines
5.9 KiB
Plaintext
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
GlobalDistanceFieldShared.usf
|
|
=============================================================================*/
|
|
|
|
#if FEATURE_LEVEL >= FEATURE_LEVEL_SM5
|
|
|
|
// Must match C++
|
|
#define MAX_GLOBAL_DF_CLIPMAPS 4
|
|
|
|
Texture3D GlobalDistanceFieldTexture[MAX_GLOBAL_DF_CLIPMAPS];
|
|
SamplerState GlobalDistanceFieldSampler[MAX_GLOBAL_DF_CLIPMAPS];
|
|
float4 GlobalVolumeCenterAndExtent[MAX_GLOBAL_DF_CLIPMAPS];
|
|
float4 GlobalVolumeWorldToUVAddAndMul[MAX_GLOBAL_DF_CLIPMAPS];
|
|
float GlobalVolumeDimension;
|
|
float GlobalVolumeTexelSize;
|
|
float MaxGlobalDistance;
|
|
|
|
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 = Texture3DSampleLevel(GlobalDistanceFieldTexture[ClipmapIndex], GlobalDistanceFieldSampler[ClipmapIndex], 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 = Texture3DSampleLevel(GlobalDistanceFieldTexture[ClipmapIndex], GlobalDistanceFieldSampler[ClipmapIndex], float3(GlobalUV.x + GlobalVolumeTexelSize, GlobalUV.y, GlobalUV.z), 0).x;
|
|
float L = Texture3DSampleLevel(GlobalDistanceFieldTexture[ClipmapIndex], GlobalDistanceFieldSampler[ClipmapIndex], float3(GlobalUV.x - GlobalVolumeTexelSize, GlobalUV.y, GlobalUV.z), 0).x;
|
|
float F = Texture3DSampleLevel(GlobalDistanceFieldTexture[ClipmapIndex], GlobalDistanceFieldSampler[ClipmapIndex], float3(GlobalUV.x, GlobalUV.y + GlobalVolumeTexelSize, GlobalUV.z), 0).x;
|
|
float B = Texture3DSampleLevel(GlobalDistanceFieldTexture[ClipmapIndex], GlobalDistanceFieldSampler[ClipmapIndex], float3(GlobalUV.x, GlobalUV.y - GlobalVolumeTexelSize, GlobalUV.z), 0).x;
|
|
float U = Texture3DSampleLevel(GlobalDistanceFieldTexture[ClipmapIndex], GlobalDistanceFieldSampler[ClipmapIndex], float3(GlobalUV.x, GlobalUV.y, GlobalUV.z + GlobalVolumeTexelSize), 0).x;
|
|
float D = Texture3DSampleLevel(GlobalDistanceFieldTexture[ClipmapIndex], GlobalDistanceFieldSampler[ClipmapIndex], 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 = 0;
|
|
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;
|
|
}
|
|
|
|
#endif |