Jump to content
  • Advertisement
Sign in to follow this  
LHLaurini

[Solved] What's the best type of curve for this case?

This topic is 982 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to make a curve editor in my game engine so I can have a better control over tone mapping, contrast and brightness. I was thinking about bézier, but I'm not a fan of dealing with all those tangent control points (also béziers can loop, which is not a good thing). Then I chose cardinal splines because they are relatively easy to implement.

[attachment=30244:curves.png]
Text is in Potuguese, but the words are almost the same. In case of doubt, just ask me.

As you can see, the curve is pretty decent until the 4th point ruins everything. If I try to adjust tension, then the other ones get bent. So, as you can see, cardinal splines are easy to use, but hard to control. Yes, I could make the curve a little different, but that's not the point. Yes, I can edit tangents for each point, but first I want to know if there isn't any better alternative. I like Gimp's curve editor, because you just give the points and it deals with everything else pretty well.

[attachment=30245:gimp-curve.png]

What type of curve could be the best for this case? Also, do someone know what type of curve Gimp uses?

Share this post


Link to post
Share on other sites
Advertisement

Béziers can loop, but you can prevent looping in the editor by clamping the control points to the left and the right of the anchor they belong to. That's what we do in any case and it works great.

Share this post


Link to post
Share on other sites

A Spline shouldn't look like this (At least if you are using to describe a function (not a 2D curve)).

Could you paste your formulas?

Share this post


Link to post
Share on other sites

Béziers can loop, but you can prevent looping in the editor by clamping the control points to the left and the right of the anchor they belong to. That's what we do in any case and it works great.

Okay, I can try that.
 
 

A Spline shouldn't look like this (At least if you are using to describe a function (not a 2D curve)).

Could you paste your formulas?

It isn't a 2D curve, it's a representation of a function. X is input and Y is output. These are the C++ functions (sorry for messy code):
 
inline float h1(float t) { return 2.0f * pow(t, 3.0f) - 3.0f * pow(t, 2.0f) + 1.0f; };
inline float h2(float t) { return -2.0f*pow(t, 3.0f) + 3.0f*pow(t, 2.0f); };
inline float h3(float t) { return pow(t, 3.0f) - 2.0f * pow(t, 2.0f) + t; };
inline float h4(float t) { return pow(t, 3.0f) - pow(t, 2.0f); };
inline float m(float k, const vector<Gdiplus::PointF>& p, float a) { return a * (p[k + 1].Y - p[k - 1].Y); };

inline float spline_start(float x, int i, const vector<Gdiplus::PointF>& p, float a, float q)
{
	float t = (x - p[i].X) / (p[i + 1].X - p[i].X);
	float affine = p[i + 1].X - p[i].X;
	return h1(t) * p[i].Y + h2(t) * p[i + 1].Y + h3(t) * q * affine + h4(t) * m(i + 1, p, a) * affine;
};

inline float spline(float x, int i, const vector<Gdiplus::PointF>& p, float a)
{
	float t = (x - p[i].X) / (p[i + 1].X - p[i].X);
	float affine = p[i + 1].X - p[i].X;
	return h1(t) * p[i].Y + h2(t) * p[i + 1].Y + h3(t) * m(i, p, a) * affine + h4(t) * m(i + 1, p, a) * affine;
};

inline float spline_end(float x, int i, const vector<Gdiplus::PointF>& p, float a, float q)
{
	float t = (x - p[i].X) / (p[i + 1].X - p[i].X);
	float affine = p[i + 1].X - p[i].X;
	return h1(t) * p[i].Y + h2(t) * p[i + 1].Y + h3(t) * m(i, p, a) * affine + h4(t) * q * affine;
};

inline float spline_unique(float x, int i, const vector<Gdiplus::PointF>& p, float a, float q1, float q2)
{
	float t = (x - p[i].X) / (p[i + 1].X - p[i].X);
	return h1(t) * p[i].Y + h2(t) * p[i + 1].Y + h3(t) * q1 + h4(t) * q2;
};

Have you tried a simple cubic spline? https://en.wikipedia.org/wiki/Spline_interpolation

Not yet. I may try that.


This is what I made before the C++ code, in Desmos: https://www.desmos.com/calculator/bojlsvd4qs. Edited by LHLaurini

Share this post


Link to post
Share on other sites

I've used Catmull-Rom before and liked the results, but I haven't tried all that many splines, so I can't compare between them.

 

I like Catmull-Rom because it's fairly straightforward and goes through all it's control points.  If you need it to match a specific curve, you just add more control points.  (it's not perfect, but it's usually my goto spline of choice)

Share this post


Link to post
Share on other sites

Bezier curves were designed to be natural for non-mathematics types to use them. They can loop, but as stated before, but that behavior can be controlled. I would try it out and see.

Share this post


Link to post
Share on other sites

Catmull-Rom worked very well and I could get rid of those sliders. New curve:

[attachment=30288:new_curve.png]

 

Thank you.

Edited by LHLaurini

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!