fn stepSequence(x: f32, steps: f32, smoothing: f32, minValue: f32, maxValue: f32) -> vec2<f32> {
// Ensure at least 1 step and positive smoothing
let numSteps = max(1.0, floor(steps));
let smoothFactor = max(0.0, smoothing);
// Normalize x to 0-1 range
let normalizedX = fract(x);
// Calculate the size of each step
let stepSize = 1.0 / numSteps;
// Calculate the current step (0 to numSteps-1)
let currentStep = floor(normalizedX * numSteps);
let nextStep = fract(currentStep + 1.0);
// Calculate progress within the current step
let stepProgress = fract(normalizedX * numSteps);
// Calculate the progress values for current and next steps
let currentStepValue = currentStep / (numSteps - 1.0);
// Prepare next step value, handle the last step case
var nextStepValue: f32 = 0.0;
if (currentStep >= numSteps - 1.0) {
nextStepValue = 1.0;
} else {
nextStepValue = nextStep / (numSteps - 1.0);
}
// Apply smoothing between steps if needed
var result: f32 = 0.0;
if (smoothFactor > 0.0 && stepProgress > (1.0 - smoothFactor) && numSteps > 1.0) {
// Calculate smoothing factor
let t = (stepProgress - (1.0 - smoothFactor)) / smoothFactor;
// Smoothstep for better transition
let smoothT = t * t * (3.0 - 2.0 * t);
// Interpolate between current and next step
result = mix(currentStepValue, nextStepValue, smoothT);
} else {
result = currentStepValue;
}
// Scale to min-max range
let range = maxValue - minValue;
let finalResult = minValue + result * range;
return vec2<f32>(finalResult, currentStep);
}