107 lines
2.8 KiB
HLSL
107 lines
2.8 KiB
HLSL
#include "shared/hash-functions.hlsl"
|
|
#include "shared/point.hlsl"
|
|
#include "shared/quat-functions.hlsl"
|
|
|
|
cbuffer Params : register(b0)
|
|
{
|
|
float BlendFactor;
|
|
float BlendMode;
|
|
float PairingMode;
|
|
float Width;
|
|
float Scatter;
|
|
}
|
|
|
|
StructuredBuffer<Point> PointsA : t0; // input
|
|
StructuredBuffer<Point> PointsB : t1; // input
|
|
RWStructuredBuffer<Point> ResultPoints : u0; // output
|
|
|
|
float SmootherStep(float x)
|
|
{
|
|
x = saturate(x);
|
|
return x * x * x * (x * (x * 6.0 - 15.0) + 10.0);
|
|
}
|
|
|
|
[numthreads(64, 1, 1)] void main(uint3 i : SV_DispatchThreadID)
|
|
{
|
|
uint resultCount, countA, countB, stride;
|
|
ResultPoints.GetDimensions(resultCount, stride);
|
|
PointsA.GetDimensions(countA, stride);
|
|
PointsB.GetDimensions(countB, stride);
|
|
|
|
if (i.x > resultCount)
|
|
return;
|
|
|
|
uint aIndex = i.x;
|
|
uint bIndex = i.x;
|
|
|
|
float t = i.x / ((float)resultCount-1);
|
|
|
|
if (PairingMode > 0.5 && countA != countB)
|
|
{
|
|
uint maxCount = max(countA, countB);
|
|
|
|
// This calculates the first index i.x that would map to the current pair.
|
|
// It's essentially the inverse of (count * i.x) / resultCount
|
|
uint firstIxA = (uint)((aIndex * (float)resultCount) / countA);
|
|
uint firstIxB = (uint)((bIndex * (float)resultCount) / countB);
|
|
|
|
uint firstIx = max(firstIxA, firstIxB);
|
|
|
|
if (i.x > firstIx)
|
|
return;
|
|
}
|
|
|
|
Point A = PointsA[aIndex];
|
|
Point B = PointsB[bIndex];
|
|
|
|
float f = 0;
|
|
|
|
if (BlendMode < 0.5)
|
|
{
|
|
f = BlendFactor;
|
|
}
|
|
else if (BlendMode < 1.5)
|
|
{
|
|
f = A.FX1;
|
|
}
|
|
else if (BlendMode < 2.5)
|
|
{
|
|
f = (1 - B.FX1);
|
|
}
|
|
|
|
// Ranged
|
|
// see https://www.desmos.com/calculator/zxs1fy06uh
|
|
else if (BlendMode < 3.5)
|
|
{
|
|
f = 1 - saturate((t - BlendFactor) / Width - BlendFactor + 1);
|
|
}
|
|
else
|
|
{
|
|
float b = BlendFactor % 2;
|
|
if (b > 1)
|
|
{
|
|
b = 2 - b;
|
|
t = 1 - t;
|
|
}
|
|
//f = 1 - smoothstep(0, 1, saturate((t - b) / Width - b + 1));
|
|
f = 1 - SmootherStep(saturate((t - b) / Width - b + 1));
|
|
}
|
|
|
|
float fallOffFromCenter = smoothstep(0, 1, 1 - abs(f - 0.5) * 2);
|
|
//float fallOffFromCenter = SmootherStep(1 - abs(f - 0.5) * 2);
|
|
f += (hash11(t) - 0.5) * Scatter * fallOffFromCenter;
|
|
|
|
bool noBlend = isnan(A.Scale.x * B.Scale.x);
|
|
|
|
|
|
f = noBlend ? (f< 0.5 ? 0 : 1) : f;
|
|
|
|
ResultPoints[i.x].Scale = noBlend ? (f<0.1 ? A.Scale: B.Scale) : (lerp(A.Scale, B.Scale, f));
|
|
ResultPoints[i.x].Rotation = qSlerp(A.Rotation, B.Rotation, f);
|
|
ResultPoints[i.x].FX1 = lerp(A.FX1, B.FX1, f);
|
|
ResultPoints[i.x].FX2 = lerp(A.FX2, B.FX2, f);
|
|
ResultPoints[i.x].Color = lerp(A.Color, B.Color, f);
|
|
ResultPoints[i.x].Position = lerp(A.Position, B.Position, f);
|
|
// ResultPoints[i.x].FX1 = f; why this overwriting ?
|
|
}
|