157 lines
3.7 KiB
HLSL
157 lines
3.7 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "../../Common.ush"
|
|
#include "Voxel.ush"
|
|
|
|
#define VOXEL_NUM_LEVELS 2
|
|
#define VOXEL_SCATTER 0
|
|
|
|
static const float VoxelSize = 0.125; // World space size of smallest voxel
|
|
static const float BrickSize = VOXEL_NUM_LEVELS == 2 ? 16 : 4; // Num voxels wide
|
|
static const float BrickSizeLog2 = log2( BrickSize );
|
|
|
|
struct FBrick
|
|
{
|
|
uint3 Key;
|
|
uint BlockOffset;
|
|
};
|
|
|
|
StructuredBuffer< FBrick > BrickBuffer;
|
|
RWStructuredBuffer< FBrick > RWBrickBuffer;
|
|
|
|
#if 0
|
|
uint EncodeBrickKey( float3 BrickPos, float Level )
|
|
{
|
|
BrickPos += 256;
|
|
|
|
uint3 Brick = uint3( BrickPos ) & 511;
|
|
uint uLevel = uint( Level ) & 31;
|
|
|
|
uint Key;
|
|
Key = Brick.x << 0;
|
|
Key |= Brick.y << 9;
|
|
Key |= Brick.z << 18;
|
|
Key |= uLevel << 27;
|
|
return Key;
|
|
}
|
|
|
|
void DecodeBrickKey( uint BrickKey, out float3 BrickPos, out float CubeSize )
|
|
{
|
|
float Level;
|
|
BrickPos.x = float( ( BrickKey >> 0 ) & 0x1ff );
|
|
BrickPos.y = float( ( BrickKey >> 9 ) & 0x1ff );
|
|
BrickPos.z = float( ( BrickKey >> 18 ) & 0x1ff );
|
|
Level = float( ( BrickKey >> 27 ) & 0x1f );
|
|
|
|
BrickPos -= 256;
|
|
|
|
CubeSize = (VoxelSize * BrickSize) * exp2( Level );
|
|
}
|
|
#else
|
|
uint3 EncodeBrickKey( float3 BrickPos, float Level )
|
|
{
|
|
int3 Signed = int3( BrickPos ) + 0x1000000;
|
|
uint3 Brick = uint3( Signed ) & 0xfffffff;
|
|
uint uLevel = uint( Level ) & 15;
|
|
|
|
uint3 Key;
|
|
Key.x = Brick.x;
|
|
Key.y = Brick.y;
|
|
Key.z = Brick.z;
|
|
Key.z |= uLevel << 28;
|
|
return Key;
|
|
}
|
|
|
|
void DecodeBrickKey( uint3 BrickKey, out float3 BrickPos, out float CubeSize )
|
|
{
|
|
int3 Signed;
|
|
Signed.x = BrickKey.x;
|
|
Signed.y = BrickKey.y;
|
|
Signed.z = BrickKey.z & 0xfffffff;
|
|
Signed -= 0x1000000;
|
|
BrickPos = float3( Signed );
|
|
|
|
float Level = float( ( BrickKey.z >> 28 ) & 0xf );
|
|
|
|
CubeSize = (VoxelSize * BrickSize) * exp2( Level );
|
|
}
|
|
#endif
|
|
|
|
FRay GetViewRay( float2 SvPosition )
|
|
{
|
|
FRay Ray;
|
|
Ray.Origin = View.TranslatedWorldCameraOrigin;
|
|
Ray.Time[0] = 0;
|
|
Ray.Time[1] = 1e24;
|
|
|
|
Ray.Direction = mul( float4( SvPosition, 0, 1 ), View.SVPositionToTranslatedWorld ).xyz;
|
|
//Ray.Direction = normalize( Ray.Direction );
|
|
|
|
const float Epsilon = 1e-4;
|
|
float3 Replacement = select( Ray.Direction > 0, Epsilon, -Epsilon );
|
|
Ray.Direction = select( abs( Ray.Direction ) < Epsilon, Replacement, Ray.Direction );
|
|
|
|
return Ray;
|
|
}
|
|
|
|
float3 VisualizeCount( uint Count )
|
|
{
|
|
switch( Count )
|
|
{
|
|
case 0: return float3(0.1, 0.1, 0.1);
|
|
case 1: return float3(1, 0, 0);
|
|
case 2: return float3(0, 1, 0);
|
|
case 3: return float3(0, 0, 1);
|
|
case 4: return float3(1, 1, 0);
|
|
case 5: return float3(0, 1, 1);
|
|
case 6: return float3(1, 0, 1);
|
|
default: return float3(1, 1, 1);
|
|
}
|
|
}
|
|
|
|
|
|
#define DRAW_RECTS 1
|
|
|
|
#if PLATFORM_SUPPORTS_RECT_LIST
|
|
static const uint VertsPerBrick = 3;
|
|
static const uint IndexesPerBrick = 3;
|
|
static const uint BricksPerInstance = 21;
|
|
#elif DRAW_RECTS
|
|
static const uint VertsPerBrick = 4;
|
|
static const uint IndexesPerBrick = 6;
|
|
static const uint BricksPerInstance = 16;
|
|
#else
|
|
static const uint VertsPerBrick = 8;
|
|
static const uint IndexesPerBrick = 36;
|
|
static const uint BricksPerInstance = 8;
|
|
#endif
|
|
|
|
Buffer< uint > DrawIndirectArgs;
|
|
RWBuffer< uint > RWDrawIndirectArgs;
|
|
|
|
Buffer< uint > DispatchIndirectArgs;
|
|
RWBuffer< uint > RWDispatchIndirectArgs;
|
|
|
|
uint GetNumBricks()
|
|
{
|
|
return DispatchIndirectArgs[3];
|
|
}
|
|
|
|
uint GetNumBlocks()
|
|
{
|
|
return DrawIndirectArgs[5];
|
|
}
|
|
|
|
void SetDrawIndirectArgs( uint NumBricks )
|
|
{
|
|
#if VOXEL_SCATTER // Scatter
|
|
RWDrawIndirectArgs[0] = 3 * 64; // NumIndexes
|
|
RWDrawIndirectArgs[1] = NumBricks; // NumInstances
|
|
#else
|
|
RWDrawIndirectArgs[0] = IndexesPerBrick * BricksPerInstance; // NumIndexes
|
|
RWDrawIndirectArgs[1] = ( NumBricks + BricksPerInstance - 1 ) / BricksPerInstance; // NumInstances
|
|
RWDrawIndirectArgs[2] = 0; // IndexOffset
|
|
RWDrawIndirectArgs[3] = 0; // VertexOffset
|
|
RWDrawIndirectArgs[4] = 0; // InstanceOffset
|
|
#endif
|
|
} |