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

133 lines
3.8 KiB
HLSL

#include "shared/hash-functions.hlsl"
#include "shared/point.hlsl"
#include "shared/quat-functions.hlsl"
#include "shared/bias-functions.hlsl"
cbuffer Params : register(b0)
{
float Radius;
float RadiusOffset;
float StartAngle;
float Cycles;
float CloseCircle;
float3 Center;
float3 CenterOffset;
float __padding1;
float3 Axis;
float1 OrientationAngle;
float3 OrientationAxis;
float __padding2;
float2 GainAndBias;
float2 PointScaleRange;
float2 FX1;
float2 FX2;
float4 Color;
float OrientationMode;
}
RWStructuredBuffer<Point> ResultPoints : u0; // output
float3 RotatePointAroundAxis(float3 In, float3 Axis, float Rotation)
{
float s = sin(Rotation);
float c = cos(Rotation);
float one_minus_c = 1.0 - c;
Axis = normalize(Axis);
float3x3 rot_mat =
{one_minus_c * Axis.x * Axis.x + c, one_minus_c * Axis.x * Axis.y - Axis.z * s, one_minus_c * Axis.z * Axis.x + Axis.y * s,
one_minus_c * Axis.x * Axis.y + Axis.z * s, one_minus_c * Axis.y * Axis.y + c, one_minus_c * Axis.y * Axis.z - Axis.x * s,
one_minus_c * Axis.z * Axis.x - Axis.y * s, one_minus_c * Axis.y * Axis.z + Axis.x * s, one_minus_c * Axis.z * Axis.z + c};
return mul(rot_mat, In);
}
float3 GetPosForF(float f, float3 up)
{
float angle = (StartAngle * PI / 180 + Cycles * 2 * PI * f);
float l = Radius + RadiusOffset * f;
float3 direction = normalize(cross(Axis, up));
float3 v2 = RotatePointAroundAxis(direction * l, Axis, angle);
float3 c = Center + CenterOffset * f;
float3 v = v2 + c;
return v;
}
[numthreads(256, 4, 1)] void main(uint3 i : SV_DispatchThreadID)
{
uint pointCount, stride;
ResultPoints.GetDimensions(pointCount, stride);
if (i.x >= pointCount)
return;
Point p;
uint index = i.x;
bool closeCircle = CloseCircle > 0.5;
float angleStepCount = closeCircle ? (pointCount - 2) : pointCount;
float ff = (float)(index) / angleStepCount;
float f = ApplyGainAndBias(ff, GainAndBias);
float angle = (StartAngle * PI / 180 + Cycles * 2 * PI * f);
float3 up = Axis.y > 0.7 ? float3(0, 0, 1) : float3(0, 1, 0);
float l = Radius + RadiusOffset * f;
float3 direction = normalize(cross(Axis, up));
float3 v2 = RotatePointAroundAxis(direction * l, Axis, angle);
float3 c = Center + CenterOffset * f;
float3 v = v2 + c;
p.Position = v;
p.Scale = ((closeCircle && index == pointCount - 1)
? NAN
: PointScaleRange.x + PointScaleRange.y * f);
if(OrientationMode < 0.5)
{
float4 orientation = qFromAngleAxis(PI / 2 * 1, normalize(OrientationAxis));
orientation = qMul(orientation, qFromAngleAxis((OrientationAngle) / 180 * PI, float3(1, 0, 0)));
float4 lookat = qLookAt(Axis, up);
float4 quat = qMul(orientation, qFromAngleAxis(angle, normalize(Axis)));
float4 spin = qFromAngleAxis((OrientationAngle) / 180 * PI, normalize(OrientationAxis));
float4 spin2 = qFromAngleAxis(angle, float3(Axis));
p.Rotation = qMul(normalize(qMul(spin2, lookat)), spin);
}
else {
float3 pos2 = GetPosForF(f+0.0001, up );
float3 vy = normalize( pos2 -v);
float3 vx = normalize( v - c);
float3 vz= normalize(cross(vx, vy));
vx = cross(vy, vz);
float3x3 meshRotMatrix = float3x3(vx, vy, vz);
float4 rot = qFromMatrix3Precise(transpose(meshRotMatrix));
float4 spin = normalize(qFromAngleAxis(OrientationAngle / 180 * PI, normalize(OrientationAxis)));
//float4 spin2 = qFromAngleAxis(angle, float3(Axis));
p.Rotation = qMul( rot,spin);
}
p.Color = Color;
p.FX1 = FX1.x + FX1.y * f;
p.FX2 = FX2.x + FX2.y * f;
ResultPoints[index] = p;
}