Files
UnrealEngineUWP/Engine/Shaders/GlobalDistanceFieldShared.usf
Daniel Wright 5eeb053e18 Removed 'uniform' keywords for gl
[CL 2556331 by Daniel Wright in Main branch]
2015-05-18 22:28:55 -04:00

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