133 lines
3.5 KiB
HLSL
133 lines
3.5 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#ifndef USE_RAY_TRACING_DECAL_GRID
|
|
#define USE_RAY_TRACING_DECAL_GRID 0
|
|
#endif
|
|
|
|
#include "../Common.ush"
|
|
#include "../Visualization.ush"
|
|
#include "/Engine/Shared/RayTracingDefinitions.h"
|
|
|
|
struct FDecalLoopCount {
|
|
uint NumDecals;
|
|
#if USE_RAY_TRACING_DECAL_GRID
|
|
uint DecalGridOffset;
|
|
#endif
|
|
};
|
|
|
|
#if USE_RAY_TRACING_DECAL_GRID
|
|
|
|
FDecalLoopCount DecalGridLookup(float3 TranslatedWorldPos)
|
|
{
|
|
FDecalLoopCount Result;
|
|
Result.NumDecals = 0;
|
|
Result.DecalGridOffset = ~0u;
|
|
|
|
if (all(RayTracingDecals.TranslatedBoundMin <= TranslatedWorldPos) && all(TranslatedWorldPos <= RayTracingDecals.TranslatedBoundMax))
|
|
{
|
|
float3 P = TranslatedWorldPos - RayTracingDecals.TranslatedBoundMin;
|
|
float3 D = RayTracingDecals.TranslatedBoundMax - RayTracingDecals.TranslatedBoundMin;
|
|
|
|
int2 UVx = int2(floor(RayTracingDecals.GridResolution * P.yz / D.yz));
|
|
int2 UVy = int2(floor(RayTracingDecals.GridResolution * P.xz / D.xz));
|
|
int2 UVz = int2(floor(RayTracingDecals.GridResolution * P.xy / D.xy));
|
|
|
|
uint DecalNx = RayTracingDecals.Grid.Load(int4(UVx, 0, 0));
|
|
uint DecalNy = RayTracingDecals.Grid.Load(int4(UVy, 1, 0));
|
|
uint DecalNz = RayTracingDecals.Grid.Load(int4(UVz, 2, 0));
|
|
uint DecalN = DecalNx;
|
|
uint DecalOffset = RayTracingDecals.GridMaxCount * (0 + 3 * (UVx.x + UVx.y * RayTracingDecals.GridResolution));
|
|
if ((RayTracingDecals.GridAxis > 2 && DecalNy < DecalN) || RayTracingDecals.GridAxis == 1)
|
|
{
|
|
DecalN = DecalNy;
|
|
DecalOffset = RayTracingDecals.GridMaxCount * (1 + 3 * (UVy.x + UVy.y * RayTracingDecals.GridResolution));
|
|
}
|
|
if ((RayTracingDecals.GridAxis > 2 && DecalNz < DecalN) || RayTracingDecals.GridAxis == 2)
|
|
{
|
|
DecalN = DecalNz;
|
|
DecalOffset = RayTracingDecals.GridMaxCount * (2 + 3 * (UVz.x + UVz.y * RayTracingDecals.GridResolution));
|
|
}
|
|
|
|
Result.DecalGridOffset = DecalOffset;
|
|
Result.NumDecals += DecalN;
|
|
}
|
|
return Result;
|
|
}
|
|
|
|
float3 DecalGridVisualize(FDecalLoopCount LoopCount, int VisualizeMode)
|
|
{
|
|
const float3 OutsideColor = 0.18;
|
|
const float3 EmptyColor = 0.36;
|
|
|
|
if (LoopCount.DecalGridOffset != ~0u)
|
|
{
|
|
switch (VisualizeMode)
|
|
{
|
|
case 2:
|
|
{
|
|
// color by unique decal list
|
|
uint H = 0;
|
|
for (int Index = 0, Num = LoopCount.NumDecals; Index < Num; Index++)
|
|
{
|
|
H = MurmurMix(H + RayTracingDecals.GridData[LoopCount.DecalGridOffset + Index]);
|
|
}
|
|
return IntToColor(H);
|
|
}
|
|
case 3:
|
|
{
|
|
// color by chosen axis
|
|
int Axis = (LoopCount.DecalGridOffset / RayTracingDecals.GridMaxCount) % 3;
|
|
if (Axis == 0) return float3(0.9, 0.2, 0.2);
|
|
if (Axis == 1) return float3(0.2, 0.9, 0.2);
|
|
if (Axis == 2) return float3(0.2, 0.2, 0.9);
|
|
return float3(0.8, 0.2, 0.8); // error
|
|
}
|
|
default:
|
|
{
|
|
// default mode - color by decal count
|
|
uint N = LoopCount.NumDecals;
|
|
if (N < 1)
|
|
{
|
|
return EmptyColor;
|
|
}
|
|
float Max = RayTracingDecals.GridMaxCount;
|
|
float t = saturate(float(N) / Max);
|
|
return BlueGreenRedColorMap(t);
|
|
}
|
|
}
|
|
}
|
|
// outside decal grid bounds
|
|
return OutsideColor;
|
|
}
|
|
|
|
uint GetDecalId(uint Index, FDecalLoopCount LoopCount)
|
|
{
|
|
if (Index >= 0)
|
|
{
|
|
return RayTracingDecals.GridData[LoopCount.DecalGridOffset + Index];
|
|
}
|
|
return Index;
|
|
}
|
|
|
|
#else
|
|
|
|
FDecalLoopCount DecalGridLookup(float3 TranslatedWorldPos)
|
|
{
|
|
uint NumDecals = min(RayTracingDecals.Count, RAY_TRACING_DECAL_COUNT_MAXIMUM);
|
|
FDecalLoopCount Result;
|
|
Result.NumDecals = NumDecals;
|
|
return Result;
|
|
}
|
|
|
|
float3 DecalGridVisualize(FDecalLoopCount LoopCount, int VisualizeMode)
|
|
{
|
|
return 0.5;
|
|
}
|
|
|
|
uint GetDecalId(uint Index, FDecalLoopCount LoopCount)
|
|
{
|
|
return Index;
|
|
}
|
|
|
|
#endif
|