Files
2026-07-13 13:13:17 +08:00

123 lines
3.4 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 Params : register(b0)
{
float4x4 TransformVolume;
float3 Translate; // 16
float ScatterTranslate;
float3 Scale; // 20
float ScaleMagnitude;
float3 RotateAxis; // 24
float FallOff;
float2 GainAndBias;
float Phase;
float Threshold;
float ScaleFx1;
float OffsetFx1;
float Strength;
}
cbuffer Params : register(b1)
{
// float UseWAsWeight;
int VolumeShape; // 28
int StrengthFactor;
}
StructuredBuffer<Point> SourcePoints : t0;
RWStructuredBuffer<Point> ResultPoints : u0;
float sdEllipsoid(float3 p, float3 r)
{
float k0 = length(p / r);
float k1 = length(p / (r * r));
return k0 * (k0 - 1.0) / k1;
}
// 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));
// }
static const float VolumeSphere = 0.5;
static const float VolumeBox = 1.5;
static const float VolumePlane = 2.5;
static const float VolumeZebra = 3.5;
// static const float VolumeNoise = 4.5;
[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];
float3 posInObject = p.Position;
float3 posInVolume = mul(float4(posInObject, 1), TransformVolume).xyz;
float s = 1;
if (VolumeShape < VolumeSphere)
{
float distance = length(posInVolume);
s = smoothstep(1 + FallOff, 1, distance);
// s = distance;
}
else if (VolumeShape < VolumeBox)
{
float3 t = abs(posInVolume);
float distance = max(max(t.x, t.y), t.z) + Phase;
s = smoothstep(1 + FallOff, 1, distance);
}
else if (VolumeShape < VolumePlane)
{
float distance = posInVolume.y;
s = smoothstep(FallOff, 0, distance);
}
else if (VolumeShape < VolumeZebra)
{
float distance = 1 - abs(mod(posInVolume.y * 1 + Phase, 2) - 1);
s = smoothstep(Threshold + 0.5 + FallOff, Threshold + 0.5, distance);
}
s = ApplyGainAndBias(s, GainAndBias);
float strength = s * Strength * (StrengthFactor == 0 ? 1 : (StrengthFactor == 1) ? p.FX1
: p.FX2);
float3 volumeCenter = TransformVolume._m30_m31_m32_m03.xyz;
float3 posInVolume2 = posInObject + volumeCenter.xyz;
float3 rot = RotateAxis * PI / 180 * strength;
float4 rotationX = qFromAngleAxis(rot.x, float3(1, 0, 0));
float4 rotationY = qFromAngleAxis(rot.y, float3(0, 1, 0));
float4 rotationZ = qFromAngleAxis(rot.z, float3(0, 0, 1));
posInVolume2 = qRotateVec3(posInVolume2, rotationX);
posInVolume2 = qRotateVec3(posInVolume2, rotationY);
posInVolume2 = qRotateVec3(posInVolume2, rotationZ);
p.Position = lerp(p.Position, -volumeCenter.xyz + posInVolume2 * Scale * ScaleMagnitude, strength) + strength * Translate;
p.Rotation = qMul(p.Rotation, rotationX);
float fx1 = SourcePoints[i.x].FX1;
p.FX1 = lerp(fx1, fx1 * ScaleFx1 + OffsetFx1, strength);
p.Position.y += Translate.y * strength;
ResultPoints[i.x] = p;
}