128 lines
2.6 KiB
HLSL
128 lines
2.6 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
// These follow the corresponding C++ functions in PCGHelpers.
|
|
uint ComputeSeed(uint A, uint B)
|
|
{
|
|
return ((A * 196314165U) + 907633515U) ^ ((B * 73148459U) + 453816763U);
|
|
}
|
|
|
|
uint ComputeSeed(uint A, uint B, uint C)
|
|
{
|
|
return ((A * 196314165U) + 907633515U) ^ ((B * 73148459U) + 453816763U) ^ ((C * 34731343U) + 453816743U);
|
|
}
|
|
|
|
uint ComputeSeedFromPosition(float3 InPosition)
|
|
{
|
|
const int3 PosInt = (int3)InPosition;
|
|
const int Seed = ((PosInt.x * 196314165U) + 907633515U) ^ ((PosInt.y * 73148459U) + 453816763U) ^ ((PosInt.z * 34731343U) + 453816743U);
|
|
return (uint)Seed;
|
|
}
|
|
|
|
// This follows the implementation in FRandomStream.
|
|
float FRand(inout uint InOutSeed)
|
|
{
|
|
InOutSeed = (InOutSeed * 196314165U) + 907633515U;
|
|
|
|
const float Result = asfloat(0x3F800000U | (InOutSeed >> 9));
|
|
|
|
return Result - 1.0f;
|
|
}
|
|
|
|
float3 CreateGrid2D(uint ElementIndex, uint NumPoints, uint NumRows, float3 Min, float3 Max)
|
|
{
|
|
if (NumRows == 0)
|
|
{
|
|
return Min;
|
|
}
|
|
|
|
const uint NumCols = ceil((0.f + NumPoints) / NumRows);
|
|
|
|
if (NumCols == 0)
|
|
{
|
|
return Min;
|
|
}
|
|
|
|
const uint IndexX = ElementIndex / NumRows;
|
|
const uint IndexY = ElementIndex - NumRows * IndexX;
|
|
|
|
float3 Spacing = (Max - Min);
|
|
|
|
if (NumCols > 1)
|
|
{
|
|
Spacing.x /= (NumCols - 1);
|
|
}
|
|
|
|
if (NumRows > 1)
|
|
{
|
|
Spacing.y /= (NumRows - 1);
|
|
}
|
|
|
|
float3 Position = Min;
|
|
Position.x += IndexX * Spacing.x;
|
|
Position.y += IndexY * Spacing.y;
|
|
|
|
return Position;
|
|
}
|
|
|
|
float3 CreateGrid2D(uint ElementIndex, uint NumPoints, float3 Min, float3 Max)
|
|
{
|
|
if (NumPoints == 0)
|
|
{
|
|
return Min;
|
|
}
|
|
|
|
const uint NumRows = ceil(sqrt(NumPoints));
|
|
return CreateGrid2D(ElementIndex, NumPoints, NumRows, Min, Max);
|
|
}
|
|
|
|
float3 CreateGrid3D(uint ElementIndex, uint NumPoints, uint NumRows, uint NumCols, float3 Min, float3 Max)
|
|
{
|
|
if (NumRows == 0 || NumCols == 0)
|
|
{
|
|
return Min;
|
|
}
|
|
|
|
const uint NumLayers = ceil((0.f + NumPoints) / (NumRows * NumCols));
|
|
|
|
if (NumLayers == 0)
|
|
{
|
|
return Min;
|
|
}
|
|
|
|
uint3 Index;
|
|
Index.x = ElementIndex % NumCols;
|
|
Index.y = (ElementIndex / NumCols) % NumRows;
|
|
Index.z = ElementIndex / (NumRows * NumCols);
|
|
|
|
float3 Spacing = Max - Min;
|
|
if (NumCols > 1)
|
|
{
|
|
Spacing.x /= (NumCols - 1);
|
|
}
|
|
if (NumRows > 1)
|
|
{
|
|
Spacing.y /= (NumRows - 1);
|
|
}
|
|
if (NumLayers > 1)
|
|
{
|
|
Spacing.z /= (NumLayers - 1);
|
|
}
|
|
|
|
return Min + Index * Spacing;
|
|
}
|
|
|
|
float3 CreateGrid3D(uint ElementIndex, uint NumPoints, float3 Min, float3 Max)
|
|
{
|
|
if (NumPoints == 0)
|
|
{
|
|
return Min;
|
|
}
|
|
|
|
const uint NumRows = round(pow(NumPoints, 1.f / 3.f));
|
|
const uint NumCols = NumRows;
|
|
|
|
return CreateGrid3D(ElementIndex, NumPoints, NumRows, NumCols, Min, Max);
|
|
}
|