You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
* Decreased Global Distance Field border from full voxel to half voxel and decreased page size from 16 to 8. This removes ~30% of pages, saving memory and improving update speed * Half texel border requires to compute gradients using 8 page table fetches, but it didn�t influence Lumen tracing performance on console * Smaller pages put some pressure on culling and other passes. Culling grid was switch from per page to per 4x4x4 pages. Overall full GDF update speed in FortGPUTestBed decreased from 5.89ms to 4.57ms * Switched page table format to UInt32 in order to support larger Global Distance Field resolutions * Moved all GlobalDistanceField shaders into /DistanceField/* folder, in future we should move other distance field shaders there * Moved GlobalDistanceField page stats from r.Lumen.Visualize.Stats in Lumen code to r.GlobalDistanceField.Debug in GlobalDistanceField code * Fixed Lumen normal visualization when only Global Distance Field tracing is enabled #preflight 62630427006fa20b683b405a [FYI] Tiago.Costa, Daniel.Wright #ROBOMERGE-AUTHOR: krzysztof.narkowicz #ROBOMERGE-SOURCE: CL 19873116 via CL 19873429 via CL 19874251 #ROBOMERGE-BOT: UE5 (Release-Engine-Staging -> Main) (v940-19807014) [CL 19878047 by krzysztof narkowicz in ue5-main branch]
328 lines
14 KiB
Plaintext
328 lines
14 KiB
Plaintext
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#if FEATURE_LEVEL >= FEATURE_LEVEL_SM5
|
|
|
|
#if IS_MATERIAL_SHADER
|
|
#define DISTANCE_FIELD_IN_VIEW_UB 1
|
|
#endif
|
|
|
|
#if DISTANCE_FIELD_IN_VIEW_UB
|
|
#define MaxGlobalDFAOConeDistance View.MaxGlobalDFAOConeDistance
|
|
#else
|
|
float MaxGlobalDFAOConeDistance;
|
|
#endif
|
|
|
|
#if PLATFORM_SUPPORTS_DISTANCE_FIELDS
|
|
|
|
// Must match C++
|
|
// Most functions in this file still using 4 to match legacy
|
|
#define MAX_GLOBAL_DF_CLIPMAPS 6
|
|
|
|
#if DISTANCE_FIELD_IN_VIEW_UB
|
|
// for materials, these are in the view UB
|
|
#define GlobalDistanceFieldPageAtlasTexture View.GlobalDistanceFieldPageAtlasTexture
|
|
#define GlobalDistanceFieldCoverageAtlasTexture View.GlobalDistanceFieldCoverageAtlasTexture
|
|
#define GlobalDistanceFieldPageTableTexture View.GlobalDistanceFieldPageTableTexture
|
|
#define GlobalDistanceFieldMipTexture View.GlobalDistanceFieldMipTexture
|
|
#define GlobalVolumeCenterAndExtent View.GlobalVolumeCenterAndExtent
|
|
#define GlobalVolumeWorldToUVAddAndMul View.GlobalVolumeWorldToUVAddAndMul
|
|
#define GlobalDistanceFieldMipWorldToUVScale View.GlobalDistanceFieldMipWorldToUVScale
|
|
#define GlobalDistanceFieldMipWorldToUVBias View.GlobalDistanceFieldMipWorldToUVBias
|
|
#define GlobalDistanceFieldMipUVMinZ View.GlobalDistanceFieldMipUVMinZ
|
|
#define GlobalDistanceFieldMipUVMaxZ View.GlobalDistanceFieldMipUVMaxZ
|
|
#define GlobalDistanceFieldMipFactor View.GlobalDistanceFieldMipFactor
|
|
#define GlobalDistanceFieldMipTransition View.GlobalDistanceFieldMipTransition
|
|
#define GlobalDistanceFieldInvPageAtlasSize View.GlobalDistanceFieldInvPageAtlasSize
|
|
#define GlobalDistanceFieldInvCoverageAtlasSize View.GlobalDistanceFieldInvCoverageAtlasSize
|
|
#define GlobalDistanceFieldClipmapSizeInPages View.GlobalDistanceFieldClipmapSizeInPages
|
|
#define GlobalVolumeDimension View.GlobalVolumeDimension
|
|
#define GlobalVolumeTexelSize View.GlobalVolumeTexelSize
|
|
#define NumGlobalSDFClipmaps View.NumGlobalSDFClipmaps
|
|
#define FullyCoveredExpandSurfaceScale View.FullyCoveredExpandSurfaceScale
|
|
#define UncoveredExpandSurfaceScale View.UncoveredExpandSurfaceScale
|
|
#define UncoveredMinStepScale View.UncoveredMinStepScale
|
|
#else
|
|
// these are only used for the precomputation shaders; which don't have a view UB
|
|
Texture3D GlobalDistanceFieldPageAtlasTexture;
|
|
Texture3D GlobalDistanceFieldCoverageAtlasTexture;
|
|
Texture3D<uint> GlobalDistanceFieldPageTableTexture;
|
|
Texture3D GlobalDistanceFieldMipTexture;
|
|
float4 GlobalVolumeCenterAndExtent[MAX_GLOBAL_DF_CLIPMAPS];
|
|
float4 GlobalVolumeWorldToUVAddAndMul[MAX_GLOBAL_DF_CLIPMAPS];
|
|
float4 GlobalDistanceFieldMipWorldToUVScale[MAX_GLOBAL_DF_CLIPMAPS];
|
|
float4 GlobalDistanceFieldMipWorldToUVBias[MAX_GLOBAL_DF_CLIPMAPS];
|
|
float GlobalDistanceFieldMipFactor;
|
|
float GlobalDistanceFieldMipTransition;
|
|
float3 GlobalDistanceFieldInvPageAtlasSize;
|
|
float3 GlobalDistanceFieldInvCoverageAtlasSize;
|
|
uint GlobalDistanceFieldClipmapSizeInPages;
|
|
float GlobalVolumeDimension;
|
|
float GlobalVolumeTexelSize;
|
|
uint NumGlobalSDFClipmaps;
|
|
float FullyCoveredExpandSurfaceScale;
|
|
float UncoveredExpandSurfaceScale;
|
|
float UncoveredMinStepScale;
|
|
#endif
|
|
|
|
// Must match GlobalDistanceField.cpp
|
|
#define GLOBAL_DISTANCE_FIELD_PAGE_BORDER 0.5f
|
|
#define GLOBAL_DISTANCE_FIELD_PAGE_RESOLUTION_IN_ATLAS 8 // Includes 0.5 texel trilinear filter margin
|
|
#define GLOBAL_DISTANCE_FIELD_PAGE_RESOLUTION (GLOBAL_DISTANCE_FIELD_PAGE_RESOLUTION_IN_ATLAS - 1)
|
|
#define GLOBAL_DISTANCE_FIELD_PAGE_ATLAS_SIZE_IN_PAGES_X 128
|
|
#define GLOBAL_DISTANCE_FIELD_PAGE_ATLAS_SIZE_IN_PAGES_Y 128
|
|
#define GLOBAL_DISTANCE_FIELD_INFLUENCE_RANGE_IN_VOXELS 4
|
|
#define GLOBAL_DISTANCE_FIELD_INVALID_PAGE_ID 0xFFFFFFFF
|
|
|
|
// Coverage is a payload layer alongside the SDF
|
|
#define GLOBAL_DISTANCE_FIELD_COVERAGE_PAGE_RESOLUTION_IN_ATLAS 4 // Includes 0.5 texel trilinear filter margin
|
|
#define GLOBAL_DISTANCE_FIELD_COVERAGE_PAGE_RESOLUTION (GLOBAL_DISTANCE_FIELD_COVERAGE_PAGE_RESOLUTION_IN_ATLAS - 1)
|
|
#define GLOBAL_DISTANCE_FIELD_COVERAGE_DOWNSAMPLE_FACTOR (GLOBAL_DISTANCE_FIELD_PAGE_RESOLUTION_IN_ATLAS / GLOBAL_DISTANCE_FIELD_COVERAGE_PAGE_RESOLUTION_IN_ATLAS)
|
|
|
|
uint3 GlobalDistanceFieldPageLinearIndexToPageAtlasOffset(uint PageLinearIndex)
|
|
{
|
|
uint3 PageAtlasOffset;
|
|
//PageAtlasOffset.x = (PageLinearIndex % GLOBAL_DISTANCE_FIELD_PAGE_ATLAS_SIZE_IN_PAGES_X);
|
|
//PageAtlasOffset.y = ((PageLinearIndex / GLOBAL_DISTANCE_FIELD_PAGE_ATLAS_SIZE_IN_PAGES_X) % GLOBAL_DISTANCE_FIELD_PAGE_ATLAS_SIZE_IN_PAGES_Y);
|
|
//PageAtlasOffset.z = ((PageLinearIndex / GLOBAL_DISTANCE_FIELD_PAGE_ATLAS_SIZE_IN_PAGES_X) / GLOBAL_DISTANCE_FIELD_PAGE_ATLAS_SIZE_IN_PAGES_Y);
|
|
|
|
// Same as above, but with bit operations
|
|
PageAtlasOffset.x = PageLinearIndex & 0x7F;
|
|
PageAtlasOffset.y = (PageLinearIndex >> 7) & 0x7F;
|
|
PageAtlasOffset.z = PageLinearIndex >> 14;
|
|
|
|
return PageAtlasOffset;
|
|
}
|
|
|
|
uint GetGlobalDistanceFieldPage(float3 VolumeUV, uint ClipmapIndex)
|
|
{
|
|
int4 PageTableCoord = int4(saturate(VolumeUV) * GlobalDistanceFieldClipmapSizeInPages + int3(0, 0, ClipmapIndex * GlobalDistanceFieldClipmapSizeInPages), 0);
|
|
|
|
uint PageIndex = GlobalDistanceFieldPageTableTexture.Load(PageTableCoord);
|
|
return PageIndex;
|
|
}
|
|
|
|
void ComputeGlobalDistanceFieldPageUV(float3 VolumeUV, uint PageIndex, out float3 OutPageUV, out float3 OutCoveragePageUV)
|
|
{
|
|
uint3 PageAtlasOffset = GlobalDistanceFieldPageLinearIndexToPageAtlasOffset(PageIndex);
|
|
float3 VolumePageUV = frac(VolumeUV * GlobalDistanceFieldClipmapSizeInPages);
|
|
|
|
float3 PageAtlasCoord = PageAtlasOffset * GLOBAL_DISTANCE_FIELD_PAGE_RESOLUTION_IN_ATLAS + VolumePageUV * GLOBAL_DISTANCE_FIELD_PAGE_RESOLUTION + 0.5f;
|
|
OutPageUV = PageAtlasCoord * GlobalDistanceFieldInvPageAtlasSize;
|
|
|
|
float3 CoveragePageAtlasCoord = PageAtlasOffset * GLOBAL_DISTANCE_FIELD_COVERAGE_PAGE_RESOLUTION_IN_ATLAS + VolumePageUV * GLOBAL_DISTANCE_FIELD_COVERAGE_PAGE_RESOLUTION + 0.5f;
|
|
OutCoveragePageUV = CoveragePageAtlasCoord * GlobalDistanceFieldInvCoverageAtlasSize;
|
|
}
|
|
|
|
float3 ComputeGlobalDistanceFieldPageUV(float3 VolumeUV, uint PageIndex)
|
|
{
|
|
uint3 PageAtlasOffset = GlobalDistanceFieldPageLinearIndexToPageAtlasOffset(PageIndex);
|
|
float3 VolumePageUV = frac(VolumeUV * GlobalDistanceFieldClipmapSizeInPages);
|
|
float3 PageAtlasCoord = PageAtlasOffset * GLOBAL_DISTANCE_FIELD_PAGE_RESOLUTION_IN_ATLAS + VolumePageUV * GLOBAL_DISTANCE_FIELD_PAGE_RESOLUTION + 0.5f;
|
|
float3 PageUV = PageAtlasCoord * GlobalDistanceFieldInvPageAtlasSize;
|
|
return PageUV;
|
|
}
|
|
|
|
float3 ComputeGlobalDistanceFieldCoveragePageUV(float3 VolumeUV, uint PageIndex)
|
|
{
|
|
uint3 PageAtlasOffset = GlobalDistanceFieldPageLinearIndexToPageAtlasOffset(PageIndex);
|
|
float3 VolumePageUV = frac(VolumeUV * GlobalDistanceFieldClipmapSizeInPages);
|
|
float3 CoveragePageAtlasCoord = PageAtlasOffset * GLOBAL_DISTANCE_FIELD_COVERAGE_PAGE_RESOLUTION_IN_ATLAS + VolumePageUV * GLOBAL_DISTANCE_FIELD_COVERAGE_PAGE_RESOLUTION + 0.5f;
|
|
float3 CoveragePageUV = CoveragePageAtlasCoord * GlobalDistanceFieldInvCoverageAtlasSize;
|
|
return CoveragePageUV;
|
|
}
|
|
|
|
float EncodeGlobalDistanceFieldPageDistance(float Distance, float ClipmapInfluenceRange)
|
|
{
|
|
return saturate(Distance / (2.0f * ClipmapInfluenceRange) + 0.5f);
|
|
}
|
|
|
|
float DecodeGlobalDistanceFieldPageDistance(float EncodedDistance, float ClipmapInfluenceRange)
|
|
{
|
|
return (EncodedDistance * 2.0f - 1.0f) * ClipmapInfluenceRange;
|
|
}
|
|
|
|
float3 ComputeGlobalUV(float3 WorldPosition, uint ClipmapIndex)
|
|
{
|
|
//return ((WorldPosition - GlobalVolumeCenterAndExtent[ClipmapIndex].xyz + GlobalVolumeScollOffset[ClipmapIndex].xyz) / (GlobalVolumeCenterAndExtent[ClipmapIndex].w * 2) + .5f);
|
|
float4 WorldToUVAddAndMul = GlobalVolumeWorldToUVAddAndMul[ClipmapIndex];
|
|
float3 UV = frac(WorldPosition * WorldToUVAddAndMul.www + WorldToUVAddAndMul.xyz); // wraparound addressing
|
|
UV = frac(UV); // apply frac twice to prevent UV == 1.0f because frac(-0.00...001f) = 1.0f
|
|
return UV;
|
|
}
|
|
|
|
float3 ComputeGlobalMipUV(float3 WorldPosition, uint ClipmapIndex)
|
|
{
|
|
float3 MipUV = saturate(WorldPosition * GlobalDistanceFieldMipWorldToUVScale[ClipmapIndex].xyz + GlobalDistanceFieldMipWorldToUVBias[ClipmapIndex].xyz);
|
|
|
|
// Clamp MipUV.z to a valid bilinear region to prevent filtering across clipmaps
|
|
float MipUVMinZ = GlobalDistanceFieldMipWorldToUVScale[ClipmapIndex].w;
|
|
float MipUVMaxZ = GlobalDistanceFieldMipWorldToUVBias[ClipmapIndex].w;
|
|
MipUV.z = clamp(MipUV.z, MipUVMinZ, MipUVMaxZ);
|
|
|
|
return MipUV;
|
|
}
|
|
|
|
float GetDistanceToNearestSurfaceGlobal(float3 WorldPosition)
|
|
{
|
|
float Distance = 0.0f;
|
|
|
|
for (uint ClipmapIndex = 0; ClipmapIndex < NumGlobalSDFClipmaps; ClipmapIndex++)
|
|
{
|
|
float DistanceFromClipmap = ComputeDistanceFromBoxToPointInside(GlobalVolumeCenterAndExtent[ClipmapIndex].xyz, GlobalVolumeCenterAndExtent[ClipmapIndex].www, WorldPosition);
|
|
const float ClipmapVoxelExtent = GlobalVolumeCenterAndExtent[ClipmapIndex].w * GlobalVolumeTexelSize;
|
|
const float ClipmapInfluenceRange = 2.0f * GLOBAL_DISTANCE_FIELD_INFLUENCE_RANGE_IN_VOXELS * ClipmapVoxelExtent;
|
|
|
|
Distance = ClipmapInfluenceRange;
|
|
|
|
if (DistanceFromClipmap > ClipmapVoxelExtent)
|
|
{
|
|
float3 ClipmapVolumeUV = ComputeGlobalUV(WorldPosition, ClipmapIndex);
|
|
|
|
uint PageIndex = GetGlobalDistanceFieldPage(ClipmapVolumeUV, ClipmapIndex);
|
|
|
|
if (PageIndex < GLOBAL_DISTANCE_FIELD_INVALID_PAGE_ID)
|
|
{
|
|
float3 PageUV = ComputeGlobalDistanceFieldPageUV(ClipmapVolumeUV, PageIndex);
|
|
|
|
float DistanceFieldValue = Texture3DSampleLevel(GlobalDistanceFieldPageAtlasTexture, GlobalTrilinearWrappedSampler, PageUV, 0).x;
|
|
|
|
if (DistanceFieldValue < 1.0f)
|
|
{
|
|
Distance = DecodeGlobalDistanceFieldPageDistance(DistanceFieldValue, ClipmapInfluenceRange);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return Distance;
|
|
}
|
|
|
|
float SampleGlobalDistanceField(float3 WorldPosition, float MaxDistance, int MinClipmapIndex)
|
|
{
|
|
float Distance = MaxDistance;
|
|
|
|
for (uint ClipmapIndex = MinClipmapIndex; Distance <= MaxDistance && ClipmapIndex < NumGlobalSDFClipmaps; ++ClipmapIndex)
|
|
{
|
|
const float ClipmapInfluenceRange = GLOBAL_DISTANCE_FIELD_INFLUENCE_RANGE_IN_VOXELS * 2.0f * GlobalVolumeCenterAndExtent[ClipmapIndex].w * GlobalVolumeTexelSize;
|
|
|
|
float3 ClipmapVolumeUV = ComputeGlobalUV(WorldPosition, ClipmapIndex);
|
|
uint PageIndex = GetGlobalDistanceFieldPage(ClipmapVolumeUV, ClipmapIndex);
|
|
|
|
if (PageIndex < GLOBAL_DISTANCE_FIELD_INVALID_PAGE_ID)
|
|
{
|
|
float3 PageUV = ComputeGlobalDistanceFieldPageUV(ClipmapVolumeUV, PageIndex);
|
|
|
|
float DistanceFieldValue = Texture3DSampleLevel(GlobalDistanceFieldPageAtlasTexture, GlobalTrilinearWrappedSampler, PageUV, 0).x;
|
|
|
|
if (DistanceFieldValue < 1.0f)
|
|
{
|
|
Distance = DecodeGlobalDistanceFieldPageDistance(DistanceFieldValue, ClipmapInfluenceRange);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return Distance;
|
|
}
|
|
|
|
float GlobalDistanceFieldSampleClipmap(float3 ClipmapVolumeUV, uint ClipmapIndex)
|
|
{
|
|
float DistanceFieldValue = 1.0f;
|
|
|
|
// Wrap UV sampling
|
|
ClipmapVolumeUV = frac(ClipmapVolumeUV);
|
|
|
|
uint PageIndex = GetGlobalDistanceFieldPage(ClipmapVolumeUV, ClipmapIndex);
|
|
if (PageIndex < GLOBAL_DISTANCE_FIELD_INVALID_PAGE_ID)
|
|
{
|
|
float3 PageUV = ComputeGlobalDistanceFieldPageUV(ClipmapVolumeUV, PageIndex);
|
|
DistanceFieldValue = Texture3DSampleLevel(GlobalDistanceFieldPageAtlasTexture, GlobalTrilinearWrappedSampler, PageUV, 0).x;
|
|
}
|
|
|
|
return DistanceFieldValue;
|
|
}
|
|
|
|
float3 GlobalDistanceFieldPageCentralDiff(float3 ClipmapVolumeUV, uint ClipmapIndex)
|
|
{
|
|
float3 TexelOffset = 0.5f * GlobalVolumeTexelSize;
|
|
|
|
float R = GlobalDistanceFieldSampleClipmap(ClipmapVolumeUV + float3(+TexelOffset.x, 0, 0), ClipmapIndex);
|
|
float L = GlobalDistanceFieldSampleClipmap(ClipmapVolumeUV + float3(-TexelOffset.x, 0, 0), ClipmapIndex);
|
|
float F = GlobalDistanceFieldSampleClipmap(ClipmapVolumeUV + float3(0, +TexelOffset.y, 0), ClipmapIndex);
|
|
float B = GlobalDistanceFieldSampleClipmap(ClipmapVolumeUV + float3(0, -TexelOffset.y, 0), ClipmapIndex);
|
|
float U = GlobalDistanceFieldSampleClipmap(ClipmapVolumeUV + float3(0, 0, +TexelOffset.z), ClipmapIndex);
|
|
float D = GlobalDistanceFieldSampleClipmap(ClipmapVolumeUV + float3(0, 0, -TexelOffset.z), ClipmapIndex);
|
|
|
|
return float3(R - L, F - B, U - D);
|
|
}
|
|
|
|
float3 ComputeGlobalDistanceFieldNormal(float3 SampleWorldPosition, uint ClipmapIndex, float3 FallbackNormal)
|
|
{
|
|
float3 ClipmapVolumeUV = ComputeGlobalUV(SampleWorldPosition, ClipmapIndex);
|
|
float3 DistanceFieldGradient = GlobalDistanceFieldPageCentralDiff(ClipmapVolumeUV, ClipmapIndex);
|
|
float DistanceFieldGradientLength = length(DistanceFieldGradient);
|
|
float3 DistanceFieldNormal = DistanceFieldGradientLength > 0.001f ? DistanceFieldGradient / DistanceFieldGradientLength : FallbackNormal;
|
|
return DistanceFieldNormal;
|
|
}
|
|
|
|
// Returns vector (unnormalized) to the nearest surface point.
|
|
// This vector is rescaled by 128 * GlobalVolumeTexelSize for backwards compatiblity.
|
|
float3 GetDistanceFieldGradientGlobal(float3 WorldPosition)
|
|
{
|
|
float3 Gradient = float3(0, 0, 0.001f);
|
|
|
|
for (uint ClipmapIndex = 0; ClipmapIndex < NumGlobalSDFClipmaps; ClipmapIndex++)
|
|
{
|
|
const float ClipmapVoxelExtent = GlobalVolumeCenterAndExtent[ClipmapIndex].w * GlobalVolumeTexelSize;
|
|
const float DistanceFromClipmap = ComputeDistanceFromBoxToPointInside(GlobalVolumeCenterAndExtent[ClipmapIndex].xyz, GlobalVolumeCenterAndExtent[ClipmapIndex].www, WorldPosition);
|
|
|
|
if (DistanceFromClipmap >= ClipmapVoxelExtent)
|
|
{
|
|
const float3 ClipmapVolumeUV = ComputeGlobalUV(WorldPosition, ClipmapIndex);
|
|
|
|
uint PageIndex = GetGlobalDistanceFieldPage(ClipmapVolumeUV, ClipmapIndex);
|
|
|
|
if (PageIndex < GLOBAL_DISTANCE_FIELD_INVALID_PAGE_ID)
|
|
{
|
|
float3 PageUV = ComputeGlobalDistanceFieldPageUV(ClipmapVolumeUV, PageIndex);
|
|
|
|
float DistanceFieldValue = Texture3DSampleLevel(GlobalDistanceFieldPageAtlasTexture, GlobalTrilinearWrappedSampler, PageUV, 0).x;
|
|
|
|
// Find a page which where narrow band isn't clipped
|
|
if (DistanceFieldValue < 0.9f)
|
|
{
|
|
float3 PageCentralDiff = GlobalDistanceFieldPageCentralDiff(ClipmapVolumeUV, ClipmapIndex);
|
|
|
|
const float ClipmapInfluenceRange = GLOBAL_DISTANCE_FIELD_INFLUENCE_RANGE_IN_VOXELS * 2.0f * ClipmapVoxelExtent;
|
|
const float PageDistanceDecodeFactor = 2.0f * ClipmapInfluenceRange;
|
|
float ClipmapExtent = GlobalVolumeCenterAndExtent[ClipmapIndex].w;
|
|
|
|
// Rescale to keep backwards compatability
|
|
const float BackwardsCompatibilityFactor = 128.0f * GlobalVolumeTexelSize;
|
|
Gradient = PageDistanceDecodeFactor * PageCentralDiff / (ClipmapExtent * BackwardsCompatibilityFactor);
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return Gradient;
|
|
}
|
|
|
|
#else
|
|
|
|
float GetDistanceToNearestSurfaceGlobal(float3 WorldPosition)
|
|
{
|
|
return MaxGlobalDFAOConeDistance;
|
|
}
|
|
|
|
float3 GetDistanceFieldGradientGlobal(float3 WorldPosition)
|
|
{
|
|
return float3(0, 0, .001f);
|
|
}
|
|
|
|
#endif
|
|
#endif // FEATURE_LEVEL >= FEATURE_LEVEL_SM5
|