mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-17 10:41:42 +02:00
Merge pull request #6720 from ctrlaltdavid/20760
Fix particle radius and rgba start, middle, finish interpolation
This commit is contained in:
commit
a2135dfdd2
2 changed files with 47 additions and 10 deletions
|
@ -71,7 +71,7 @@
|
|||
Entities.editEntity(particles, {
|
||||
radiusSpread: 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
|
||||
});
|
||||
break;
|
||||
|
|
|
@ -56,13 +56,50 @@ 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;
|
||||
}
|
||||
|
||||
vec4 interpolate3Vec4(vec4 y1, vec4 y2, vec4 y3, float u) {
|
||||
return vec4(bezierInterpolate(y1.x, y2.x, y3.x, u),
|
||||
bezierInterpolate(y1.y, y2.y, y3.y, u),
|
||||
bezierInterpolate(y1.z, y2.z, y3.z, u),
|
||||
bezierInterpolate(y1.w, y2.w, y3.w, u));
|
||||
float interpolate3Points(float y1, float y2, float y3, float u) {
|
||||
// Makes the interpolated values intersect the middle value.
|
||||
|
||||
if ((u <= 0.5f && y1 == y2) || (u >= 0.5f && y2 == y3)) {
|
||||
// Flat line.
|
||||
return y2;
|
||||
}
|
||||
|
||||
float halfSlope;
|
||||
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.
|
||||
halfSlope = 0.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.
|
||||
halfSlope = (y3 - y1) / 2.0f;
|
||||
float slope12 = y2 - y1;
|
||||
float slope23 = y3 - y2;
|
||||
if (abs(halfSlope) > abs(slope12)) {
|
||||
halfSlope = slope12;
|
||||
} else if (abs(halfSlope) > abs(slope23)) {
|
||||
halfSlope = slope23;
|
||||
}
|
||||
}
|
||||
|
||||
float stepU = step(0.5f, u); // 0.0 if u < 0.5, 1.0 otherwise.
|
||||
float slopeSign = 2.0f * stepU - 1.0f; // -1.0 if u < 0.5, 1.0 otherwise
|
||||
float start = (1.0f - stepU) * y1 + stepU * y2; // y1 if u < 0.5, y2 otherwise
|
||||
float middle = y2 + slopeSign * halfSlope;
|
||||
float finish = (1.0f - stepU) * y2 + stepU * y3; // y2 if u < 0.5, y3 otherwise
|
||||
float v = 2.0f * u - step(0.5f, u); // 0.0-0.5 -> 0.0-1.0 and 0.5-1.0 -> 0.0-1.0
|
||||
return bezierInterpolate(start, middle, finish, v);
|
||||
}
|
||||
|
||||
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) {
|
||||
TransformCamera cam = getTransformCamera();
|
||||
|
@ -73,21 +110,21 @@ void main(void) {
|
|||
// Which quad vertex pos?
|
||||
int twoTriID = gl_VertexID - particleID * NUM_VERTICES_PER_PARTICLE;
|
||||
|
||||
// Particle properties
|
||||
// Particle properties
|
||||
float age = inColor.x / particle.lifespan;
|
||||
float seed = inColor.y;
|
||||
|
||||
// Pass the texcoord and the z texcoord is representing the texture icon
|
||||
varTexcoord = vec2((UNIT_QUAD[twoTriID].xy + 1.0) * 0.5);
|
||||
varColor = interpolate3Vec4(particle.color.start, particle.color.middle, particle.color.finish, age);
|
||||
|
||||
|
||||
// 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 anchorPoint;
|
||||
<$transformModelToEyePos(cam, obj, inPosition, anchorPoint)$>
|
||||
|
||||
|
||||
vec4 eyePos = anchorPoint + quadPos;
|
||||
<$transformEyeToClipPos(cam, eyePos, gl_Position)$>
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue