#include "shared/hash-functions.hlsl" #include "shared/point.hlsl" #include "shared/quat-functions.hlsl" #include "shared/bias-functions.hlsl" #include "shared/color-functions.hlsl" cbuffer Params : register(b0) { float Strength; float3 RandomizePosition; float3 RandomizeRotation; float RandomizeF1; float4 RandomizeColor; float3 Stretch; float RandomSeed; float2 GainAndBias; float Scale; float RandomizeF2; } cbuffer IntParams : register(b1) { uint OffsetMode; uint UsePointSpace; uint Interpolation; int ClampColorsEtc; int Repeat; int StrengthFactor; } StructuredBuffer SourcePoints : t0; RWStructuredBuffer ResultPoints : u0; [numthreads(64, 1, 1)] void main(uint3 i : SV_DispatchThreadID) { uint pointCount, stride; SourcePoints.GetDimensions(pointCount, stride); Point p = SourcePoints[i.x]; uint pointId = i.x; uint pointU = pointId * _PRIME0 % (Repeat == 0 ? 999999999 : Repeat); float particlePhaseOffset = hash11u(pointU); float phase = abs(particlePhaseOffset + RandomSeed); int phaseIndex = (uint)phase + pointU; float t = fmod(phase, 1); t = Interpolation == 0 ? 0 : (Interpolation == 1 ? t : smoothstep(0, 1, t)); float4 biasedA = ApplyGainAndBias(lerp(hash41u(phaseIndex), hash41u(phaseIndex + 1), t), GainAndBias); float4 biasedB = ApplyGainAndBias(lerp(hash41u(phaseIndex + _PRIME0), hash41u(phaseIndex + _PRIME0 + 1), t), GainAndBias); float strength = Strength * (StrengthFactor == 0 ? 1 : (StrengthFactor == 1) ? p.FX1 : p.FX2); float4 rot = p.Rotation; if (OffsetMode == 1) { biasedA = (biasedA * 2) - 1; biasedB = (biasedB * 2) - 1; // biasedB -= OffsetMode * 0.5; } p.Position += strength * (UsePointSpace == 0 ? qRotateVec3(biasedA.xyz * RandomizePosition, p.Rotation) : biasedA.xyz * RandomizePosition); float4 rgba = p.Color; if (length(RandomizeColor) > 0.001) { float4 HSBa = float4(rgb2hsb(p.Color.rgb), p.Color.a); HSBa += biasedB * RandomizeColor * strength; HSBa.x = fmod(HSBa.x, 1); rgba = float4(hsb2rgb(HSBa.xyz), HSBa.a); } p.Color = ClampColorsEtc ? clamp(rgba, 0, float4(1000, 1000, 1000, 1)) : rgba; p.FX1 += biasedA.w * RandomizeF1 * strength; p.FX2 += biasedA.r * RandomizeF2 * strength; if (ClampColorsEtc && !isnan(p.Scale.x)) { p.FX1 = max(0, p.FX1); p.FX2 = max(0, p.FX2); } p.Scale += ((float3(biasedB.w, biasedA.w, biasedA.z) * Stretch) + biasedA.r * Scale) * strength; // Not ideal... distribution overlap // Rotation float3 randomRotate = (RandomizeRotation / 180 * PI) * strength * biasedA.xyz; rot = normalize(qMul(rot, qFromAngleAxis(randomRotate.x, float3(1, 0, 0)))); rot = normalize(qMul(rot, qFromAngleAxis(randomRotate.y, float3(0, 1, 0)))); rot = normalize(qMul(rot, qFromAngleAxis(randomRotate.z, float3(0, 0, 1)))); p.Rotation = rot; ResultPoints[i.x] = p; }