178 lines
4.1 KiB
HLSL
178 lines
4.1 KiB
HLSL
#include "shared/hash-functions.hlsl"
|
|
#include "shared/noise-functions.hlsl"
|
|
#include "shared/point.hlsl"
|
|
#include "shared/quat-functions.hlsl"
|
|
#include "shared/bias-functions.hlsl"
|
|
|
|
cbuffer Transforms : register(b0)
|
|
{
|
|
float4x4 CameraToClipSpace;
|
|
float4x4 ClipSpaceToCamera;
|
|
float4x4 WorldToCamera;
|
|
float4x4 CameraToWorld;
|
|
float4x4 WorldToClipSpace;
|
|
float4x4 ClipSpaceToWorld;
|
|
float4x4 ObjectToWorld;
|
|
float4x4 WorldToObject;
|
|
float4x4 ObjectToCamera;
|
|
float4x4 ObjectToClipSpace;
|
|
}
|
|
|
|
cbuffer Params : register(b1)
|
|
{
|
|
float4x4 TransformVolume;
|
|
float FallOff;
|
|
float Strength;
|
|
float2 GainAndBias;
|
|
float Phase;
|
|
float Threshold;
|
|
float Scatter;
|
|
}
|
|
|
|
cbuffer Params : register(b2)
|
|
{
|
|
int VolumeShape;
|
|
int SelectMode;
|
|
int ClampResult;
|
|
int DiscardNonSelected;
|
|
|
|
int StrengthFactor;
|
|
int WriteTo;
|
|
}
|
|
|
|
StructuredBuffer<Point> SourcePoints : t0;
|
|
RWStructuredBuffer<Point> ResultPoints : u0;
|
|
|
|
static const float NoisePhase = 0;
|
|
|
|
#define VolumeSphere 0
|
|
#define VolumeBox 1
|
|
#define VolumePlane 2
|
|
#define VolumeZebra 3
|
|
#define VolumeNoise 4
|
|
|
|
#define ModeOverride 0
|
|
#define ModeAdd 1
|
|
#define ModeSub 2
|
|
#define ModeMultiply 3
|
|
#define ModeInvert 4
|
|
|
|
float Bias2(float x, float bias)
|
|
{
|
|
return bias < 0
|
|
? pow(x, clamp(bias + 1, 0.005, 1))
|
|
: 1 - pow(1 - x, clamp(1 - bias, 0.005, 1));
|
|
}
|
|
|
|
inline float LinearStep(float min, float max, float t)
|
|
{
|
|
return saturate((t - min) / (max - min));
|
|
}
|
|
|
|
[numthreads(64, 1, 1)] void main(uint3 i
|
|
: SV_DispatchThreadID)
|
|
{
|
|
uint numStructs, stride;
|
|
SourcePoints.GetDimensions(numStructs, stride);
|
|
if (i.x >= numStructs)
|
|
return;
|
|
|
|
Point p = SourcePoints[i.x];
|
|
|
|
if (isnan(p.Scale.x))
|
|
{
|
|
ResultPoints[i.x] = p;
|
|
return;
|
|
}
|
|
|
|
float3 posInObject = p.Position;
|
|
float3 posInVolume = mul(float4(posInObject, 1), TransformVolume).xyz;
|
|
|
|
float s = 1;
|
|
float scatter = Scatter * (hash11u(i.x) - 0.5);
|
|
|
|
if (VolumeShape == VolumeSphere)
|
|
{
|
|
float distance = length(posInVolume) + scatter;
|
|
s = LinearStep(1 + FallOff, 1, distance);
|
|
}
|
|
else if (VolumeShape == VolumeBox)
|
|
{
|
|
float3 t = abs(posInVolume);
|
|
float distance = max(max(t.x, t.y), t.z) + Phase + scatter;
|
|
s = LinearStep(1 + FallOff, 1, distance);
|
|
}
|
|
else if (VolumeShape == VolumePlane)
|
|
{
|
|
float distance = posInVolume.y + scatter;
|
|
s = LinearStep(FallOff, 0, distance);
|
|
}
|
|
else if (VolumeShape == VolumeZebra)
|
|
{
|
|
float distance = 1 - abs(mod(posInVolume.y * 1 + Phase, 2) - 1) + scatter;
|
|
s = LinearStep(Threshold + 0.5 + FallOff, Threshold + 0.5, distance);
|
|
}
|
|
else if (VolumeShape == VolumeNoise)
|
|
{
|
|
float3 noiseLookup = (posInVolume * 0.91 + Phase);
|
|
float noise = snoise(noiseLookup);
|
|
s = LinearStep(Threshold + FallOff, Threshold, noise + scatter);
|
|
}
|
|
|
|
s = ApplyGainAndBias(s, GainAndBias);
|
|
|
|
float w = WriteTo == 0
|
|
? 1
|
|
: (WriteTo == 1) ? p.FX1
|
|
: p.FX2;
|
|
|
|
float strength = Strength * (StrengthFactor == 0
|
|
? 1
|
|
: (StrengthFactor == 1) ? p.FX1
|
|
: p.FX2);
|
|
|
|
if (SelectMode == ModeOverride)
|
|
{
|
|
s *= strength;
|
|
}
|
|
else if (SelectMode == ModeAdd)
|
|
{
|
|
s += w * strength;
|
|
}
|
|
else if (SelectMode == ModeSub)
|
|
{
|
|
s = w - s * strength;
|
|
}
|
|
else if (SelectMode == ModeMultiply)
|
|
{
|
|
s = lerp(w, w * s, strength);
|
|
}
|
|
else if (SelectMode == ModeInvert)
|
|
{
|
|
s = s * (1 - w);
|
|
}
|
|
|
|
float result = (DiscardNonSelected && s <= 0)
|
|
? NAN
|
|
: (ClampResult)
|
|
? saturate(s)
|
|
: s;
|
|
|
|
switch (WriteTo)
|
|
{
|
|
case 1:
|
|
p.FX1 = result;
|
|
break;
|
|
case 2:
|
|
p.FX2 = result;
|
|
break;
|
|
}
|
|
// p.Selected = result;
|
|
// if (SetW)
|
|
// {
|
|
// p.W = result;
|
|
// }
|
|
|
|
ResultPoints[i.x] = p;
|
|
}
|