#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 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; }