I’m twisting a mesh and want to smooth the transition between the twisted and untwisted region. So I turned to smooth step. For the life of me I couldn’t figure out how to get it to work!
lerp() worked fine before and I wasn’t sure why smoothstep() would require different inputs. Eventually I decided to try Mathf.SmoothStep() to see if the problem was on my end. Bam. Mathf.SmoothStep worked like a charm. Is the implementation in the new mathematics library different or is it just broken?
Here’s the code, if you need context.
[BurstCompile (CompileSynchronously = COMPILE_SYNCHRONOUSLY)]
private struct LimitedTwistDeformJob : IJobParallelFor
{
public float angle;
public float top;
public float bottom;
public float4x4 axisSpace;
public float4x4 inverseAxisSpace;
public NativeMeshData data;
public void Execute (int index)
{
var range = abs (top - bottom);
if (range < MIN_RANGE)
top += MIN_RANGE;
var positionOnAxis = mul (axisSpace, float4 (data.vertices[index], 1f));
// this is the relevant line
var rotationAngle = Mathf.SmoothStep (0f, angle, (clamp (positionOnAxis.z, bottom, top) - bottom) / range);
positionOnAxis.xy = rotate (positionOnAxis.xy, radians (rotationAngle) + (float)PI);
data.vertices[index] = mul (inverseAxisSpace, positionOnAxis).xyz;
}
}
[edit 1] and yes, I can just call “smoothstep” because I have using static Unity.Mathematics.math; at the top of the file.
[edit 2] ok so I got tired of waiting and recreated the smoothstep effect in the new mathematics library. it behaves exactly the same as Mathf.SmoothStep.
[MethodImpl (MethodImplOptions.AggressiveInlining)]
public static float smoothstep (float a, float b, float t)
{
t = saturate (t);
t = -2f * t * t * t + 3f * t * t;
return b * t + a * (1f - t);
}
How am I supposed to use the shader version of smoothstep? Is it not supposed to be treated like lerp, because that’s how I’m using it but it doesn’t work.
Mathf : It is clamped first, the t value is expected to be between 0~1 then maps smoothly with from~to
Unity.Mathematics : It is interpolated first before the clamp, the x value is expected to be between edge values a~b and not 0~1.
Shader language’s smoothstep works like the Unity.Mathematics version.
Thanks for the answer. I got it working now. I just need to multiply the 0~1 value that I was using for the lerp by the max value which is ‘angle’ in this instance. Then multiply the result by angle.
I think it helps if you don’t think smoothstep as lerp but instead a smooth version of the regular step function. It returns 0 or 1 depending if the given value bigger than the limit. smoothstep does the same thing but has smooth transition from 0 to 1.