mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 04:37:48 +02:00
Fix particle radius and rgba start, middle, finish interpolation
Bezier interpolation of 3 points doesn't intersect the middle value. Instead, use separate Bezier interpolations for start-middle and middle- finish, so that the interpolated values intersect the middle value as a user would expect.
This commit is contained in:
parent
fc4ece5671
commit
58f1371eba
2 changed files with 45 additions and 7 deletions
|
@ -71,7 +71,7 @@
|
||||||
Entities.editEntity(particles, {
|
Entities.editEntity(particles, {
|
||||||
radiusSpread: 0.0,
|
radiusSpread: 0.0,
|
||||||
radiusStart: 0.0,
|
radiusStart: 0.0,
|
||||||
particleRadius: 2 * PARTICLE_RADIUS, // Bezier interpolation used means that middle value isn't intersected
|
particleRadius: PARTICLE_RADIUS,
|
||||||
radiusFinish: 0.0
|
radiusFinish: 0.0
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -56,13 +56,51 @@ float bezierInterpolate(float y1, float y2, float y3, float u) {
|
||||||
return (1.0 - u) * (1.0 - u) * y1 + 2.0 * (1.0 - u) * u * y2 + u * u * y3;
|
return (1.0 - u) * (1.0 - u) * y1 + 2.0 * (1.0 - u) * u * y2 + u * u * y3;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 interpolate3Vec4(vec4 y1, vec4 y2, vec4 y3, float u) {
|
float interpolate3Points(float y1, float y2, float y3, float u) {
|
||||||
return vec4(bezierInterpolate(y1.x, y2.x, y3.x, u),
|
// Makes the interpolated values intersect the middle value.
|
||||||
bezierInterpolate(y1.y, y2.y, y3.y, u),
|
|
||||||
bezierInterpolate(y1.z, y2.z, y3.z, u),
|
if ((u <= 0.5f && y1 == y2) || (u >= 0.5f && y2 == y3)) {
|
||||||
bezierInterpolate(y1.w, y2.w, y3.w, u));
|
// Flat line.
|
||||||
|
return y2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((y2 >= y1 && y2 >= y3) || (y2 <= y1 && y2 <= y3)) {
|
||||||
|
// U or inverted-U shape.
|
||||||
|
// Make the slope at y2 = 0, which means that the control points half way between the value points have the value y2.
|
||||||
|
if (u <= 0.5f) {
|
||||||
|
return bezierInterpolate(y1, y2, y2, 2.0f * u);
|
||||||
|
} else {
|
||||||
|
return bezierInterpolate(y2, y2, y3, 2.0f * u - 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// L or inverted and/or mirrored L shape.
|
||||||
|
// Make the slope at y2 be the slope between y1 and y3, up to a maximum of double the minimum of the slopes between y1
|
||||||
|
// and y2, and y2 and y3. Use this slope to calculate the control points half way between the value points.
|
||||||
|
// Note: The maximum ensures that the control points and therefore the interpolated values stay between y1 and y3.
|
||||||
|
float slope = y3 - y1;
|
||||||
|
float slope12 = y2 - y1;
|
||||||
|
float slope23 = y3 - y2;
|
||||||
|
if (abs(slope) > abs(2.0f * slope12)) {
|
||||||
|
slope = 2.0f * slope12;
|
||||||
|
} else if (abs(slope) > abs(2.0f * slope23)) {
|
||||||
|
slope = 2.0f * slope23;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u <= 0.5f) {
|
||||||
|
return bezierInterpolate(y1, y2 - slope / 2.0f, y2, 2.0f * u);
|
||||||
|
} else {
|
||||||
|
return bezierInterpolate(y2, y2 + slope / 2.0f, y3, 2.0f * u - 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec4 interpolate3Vec4(vec4 y1, vec4 y2, vec4 y3, float u) {
|
||||||
|
return vec4(interpolate3Points(y1.x, y2.x, y3.x, u),
|
||||||
|
interpolate3Points(y1.y, y2.y, y3.y, u),
|
||||||
|
interpolate3Points(y1.z, y2.z, y3.z, u),
|
||||||
|
interpolate3Points(y1.w, y2.w, y3.w, u));
|
||||||
|
}
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
TransformCamera cam = getTransformCamera();
|
TransformCamera cam = getTransformCamera();
|
||||||
|
@ -82,7 +120,7 @@ void main(void) {
|
||||||
varColor = interpolate3Vec4(particle.color.start, particle.color.middle, particle.color.finish, age);
|
varColor = interpolate3Vec4(particle.color.start, particle.color.middle, particle.color.finish, age);
|
||||||
|
|
||||||
// anchor point in eye space
|
// anchor point in eye space
|
||||||
float radius = bezierInterpolate(particle.radius.start, particle.radius.middle, particle.radius.finish, age);
|
float radius = interpolate3Points(particle.radius.start, particle.radius.middle, particle.radius.finish, age);
|
||||||
vec4 quadPos = radius * UNIT_QUAD[twoTriID];
|
vec4 quadPos = radius * UNIT_QUAD[twoTriID];
|
||||||
|
|
||||||
vec4 anchorPoint;
|
vec4 anchorPoint;
|
||||||
|
|
Loading…
Reference in a new issue