"Nice" tweakable S-function

Started by
10 comments, last by Dirk Gregorius 5 years, 6 months ago

Hi, I am looking for a tweakable function, which I believe somebody already calculated - it has shape of an S-function/logistic function, but with a few additional properties.
Basically I want a tweakable interpolation function - that for tweakable constant s=0 or 1(doesn't matter) goes from linear interpolation and converges to a "set" interpolation as 's' goes to infinity and having some smooth interpolation between, see the picture:

image.png.f4430ceef9709f63df037556ac72abfc.png

Input are real numbers from 0.0 to 1.0
f(0.0) = 0.0
f(0.5) = 0.5
f(1.0) = 1.0

Not sure if it's possible and still keeps the nice shape, but Ideally the first derivation should be:
f '(0) = 0
f '(1) = 0

Since it's meant for games, I am ok if we neglect the derivation condition as long as the formula is simple and curve is "nice".

Advertisement

Although I'm not positive, it looks like the function in the accepted answer here:

https://math.stackexchange.com/questions/121720/ease-in-out-function/121755

Might have the properties you're looking for.

Try this:


1/(1+exp(-s*(-log(1/x-1))))

s=1 is the identity. As s grows, the function converges to the step function, as you wanted. Values of s between 0 and 1 are also possible, and behave reasonably.

 

EDIT: Oh, I think my function is actually the same as x^s/(x^s+(1-x)^s), which is what Zakwayda pointed to:

http://www.wolframalpha.com/input/?i=simplify+1%2F(1%2Bexp(s*ln(1%2Fx-1)))-x^s%2F(x^s%2B(1-x)^s),+assuming+s>1+and+0<x<1

Works perfectly! Thank you!

This might be overkill for your needs, but if you want to also be able to tweak when you switch from accelerating to decelerating I put this together a while back:

https://www.desmos.com/calculator/3zhzwbfrxd

I was looking for some functions like this recently as well. I found these functions very useful:

https://en.wikipedia.org/wiki/Smoothstep

https://blog.demofox.org/2012/09/24/bias-and-gain-are-your-friend/

http://demofox.org/biasgain.html

 

 

You could also check out the generalized logistic function.

This thread is a great resource! :D

At one point in time, I wanted a tweakable S-curve that could have a linear section in the middle and ended up with this mess:


float SCurve( float x, float white = 10, float shoulder = 3, float slope = 1.5; )
{
	float invWhite = 1/((slope/shoulder)*(white-shoulder*2));
	float one_on_shoulder = 1/shoulder;
	float slope_on_shoulder = slope/shoulder;
	float white_minus_two_shoulder = white-shoulder*2;
	float white_minus_shoulder = white-shoulder;
	x = min(x,white);
	float a = pow( abs(x*one_on_shoulder), slope );
	float b = slope_on_shoulder*(x-shoulder)+1;
	float c = slope_on_shoulder*white_minus_two_shoulder + 2 - pow(abs((white-x)*one_on_shoulder), slope);
	return x < shoulder ? a : (x > white_minus_shoulder ? c : b);
}

The maximum x value is called "white" because I was using it for tonemapping HDR images :) 
http://www.wolframalpha.com/input/?i=plot+piecewise[{+{abs(x%2F3)^1.5,+x+<+3},+{(1.5%2F3)*(10-2*3)+%2B+2+-+abs((10-x)%2F3)^1.5,+x+>+10-3},+{(1.5%2F3)*(x-3)%2B1,+3<%3Dx<%3D10-3}+}],+x+%3D+0+to+10
http://www.wolframalpha.com/input/?i=plot+piecewise[{+{abs(x%2F5)^4,+x+<+5},+{(4%2F5)*(10-2*5)+%2B+2+-+abs((10-x)%2F5)^4,+x+>+10-5}+}],+x+%3D+0+to+10
Left: white = 10, slope = 1.5, shoulder = 3 (x<3 is the bottom shoulder, 3<x<7 is linear, 7<x is the top shoulder)
Right: white = 10, slope = 4, shoulder = 5 (x<5 is the bottom shoulder, 5<x is the top shoulder)
MSP1064018i84agg75857a2900002b6d5c147ac9ac03.gif.074ec53df116b9b4ece5db5368d892ae.gifMSP30501f7c67g37262557000003967622hfhgddbc9.gif.aeb5fb1812626e81bc47736a58a7ff02.gif

[edit]

https://www.desmos.com/calculator/p7emj3bmmq

18 hours ago, Hodgman said:

This thread is a great resource! :D

Then you will appreciate this one as well. Accidentally stumbled over it yesterday:

https://www.youtube.com/watch?reload=9&v=mr5xkf6zSzk

This topic is closed to new replies.

Advertisement