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

Started by
8 comments, last by LHLaurini 8 years, 3 months ago
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?
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.

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?

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

SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.

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.

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'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)

I would try with natural cubic splines.

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.

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

[attachment=30288:new_curve.png]

Thank you.

This topic is closed to new replies.

Advertisement