Merge branch 'Elderme-Fix_particles'
This commit is contained in:
commit
ce17da98bf
@ -1,4 +1,5 @@
|
||||
uniform int dt;
|
||||
uniform mat4 previous_frame_sourcematrix;
|
||||
uniform mat4 sourcematrix;
|
||||
uniform int level;
|
||||
uniform float size_increase_factor;
|
||||
@ -32,31 +33,48 @@ out float new_size;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
float updated_lifetime = lifetime + (float(dt)/lifetime_initial);
|
||||
if (updated_lifetime > 1.)
|
||||
{
|
||||
if (gl_VertexID < level)
|
||||
float updated_lifetime = lifetime + (float(dt)/lifetime_initial);
|
||||
if (updated_lifetime > 1.)
|
||||
{
|
||||
float dt_from_last_frame = fract(updated_lifetime) * lifetime_initial;
|
||||
vec4 updated_initialposition = sourcematrix * vec4(particle_position_initial, 1.0);
|
||||
vec4 updated_initial_velocity = sourcematrix * vec4(particle_position_initial + particle_velocity_initial, 1.0) - updated_initialposition;
|
||||
new_particle_position = updated_initialposition.xyz + updated_initial_velocity.xyz * float(dt_from_last_frame);
|
||||
new_particle_velocity = updated_initial_velocity.xyz;
|
||||
new_lifetime = fract(updated_lifetime);
|
||||
new_size = mix(size_initial, size_initial * size_increase_factor, fract(updated_lifetime));
|
||||
if (gl_VertexID < level)
|
||||
{
|
||||
float dt_from_last_frame = fract(updated_lifetime) * lifetime_initial;
|
||||
float coeff = dt_from_last_frame / dt;
|
||||
|
||||
vec4 previous_frame_position = previous_frame_sourcematrix * vec4(particle_position_initial, 1.0);
|
||||
vec4 current_frame_position = sourcematrix * vec4(particle_position_initial, 1.0);
|
||||
|
||||
vec4 updated_initialposition = mix(current_frame_position,
|
||||
previous_frame_position,
|
||||
coeff);
|
||||
|
||||
vec4 updated_initial_velocity = mix(sourcematrix * vec4(particle_velocity_initial, 0.0),
|
||||
previous_frame_sourcematrix * vec4(particle_velocity_initial, 0.0),
|
||||
coeff);
|
||||
//+ (current_frame_position - previous_frame_position) / dt;
|
||||
//To be accurate, emitter speed should be added.
|
||||
//But the simple formula ( (current_frame_position - previous_frame_position) / dt ) with a constant speed
|
||||
//between 2 frames creates visual artifacts when the framerate is low, and a more accurate formula would need
|
||||
//more complex computations.
|
||||
|
||||
new_particle_position = updated_initialposition.xyz + dt_from_last_frame * updated_initial_velocity.xyz;
|
||||
new_particle_velocity = updated_initial_velocity.xyz;
|
||||
|
||||
new_lifetime = fract(updated_lifetime);
|
||||
new_size = mix(size_initial, size_initial * size_increase_factor, fract(updated_lifetime));
|
||||
}
|
||||
else
|
||||
{
|
||||
new_lifetime = fract(updated_lifetime);
|
||||
new_size = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
new_lifetime = fract(updated_lifetime);
|
||||
new_size = 0;
|
||||
new_particle_position = particle_position + particle_velocity.xyz * float(dt);
|
||||
new_particle_velocity = particle_velocity;
|
||||
new_lifetime = updated_lifetime;
|
||||
new_size = (size == 0) ? 0. : mix(size_initial, size_initial * size_increase_factor, updated_lifetime);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
new_particle_position = particle_position + particle_velocity.xyz * float(dt);
|
||||
new_particle_velocity = particle_velocity;
|
||||
new_lifetime = updated_lifetime;
|
||||
new_size = (size == 0) ? 0. : mix(size_initial, size_initial * size_increase_factor, updated_lifetime);
|
||||
}
|
||||
gl_Position = vec4(0.);
|
||||
gl_Position = vec4(0.);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@
|
||||
/** Transform feedback shader that simulates the particles on GPU.
|
||||
*/
|
||||
class PointEmitterShader : public Shader
|
||||
< PointEmitterShader, core::matrix4, int, int, float >
|
||||
< PointEmitterShader, core::matrix4, core::matrix4, int, int, float >
|
||||
{
|
||||
public:
|
||||
PointEmitterShader()
|
||||
@ -45,7 +45,8 @@ public:
|
||||
const char *varyings[] = { "new_particle_position", "new_lifetime",
|
||||
"new_particle_velocity", "new_size" };
|
||||
loadTFBProgram("pointemitter.vert", varyings, 4);
|
||||
assignUniforms("sourcematrix", "dt", "level", "size_increase_factor");
|
||||
assignUniforms("previous_frame_sourcematrix", "sourcematrix",
|
||||
"dt", "level", "size_increase_factor");
|
||||
} // PointEmitterShader
|
||||
|
||||
}; // PointEmitterShader
|
||||
@ -262,7 +263,7 @@ void ParticleSystemProxy::generateParticlesFromPointEmitter(scene::IParticlePoin
|
||||
ParticleParams[i].PositionZ = 0;
|
||||
// Initial lifetime is >1
|
||||
InitialValues[i].Lifetime = 2.;
|
||||
|
||||
|
||||
memcpy(&(InitialValues[i].PositionX), &(ParticleParams[i].PositionX), 3 * sizeof(float));
|
||||
|
||||
generateLifetimeSizeDirection(emitter, ParticleParams[i].Lifetime, ParticleParams[i].Size,
|
||||
@ -466,11 +467,11 @@ void ParticleSystemProxy::CommonSimulationVAO(GLuint position_vbo, GLuint initia
|
||||
}
|
||||
|
||||
void ParticleSystemProxy::simulate()
|
||||
{
|
||||
{
|
||||
int timediff = int(GUIEngine::getLatestDt() * 1000.f);
|
||||
int active_count = getEmitter()->getMaxLifeTime() * getEmitter()->getMaxParticlesPerSecond() / 1000;
|
||||
core::matrix4 matrix = getAbsoluteTransformation();
|
||||
|
||||
|
||||
glEnable(GL_RASTERIZER_DISCARD);
|
||||
if (has_height_map)
|
||||
{
|
||||
@ -482,9 +483,10 @@ void ParticleSystemProxy::simulate()
|
||||
else
|
||||
{
|
||||
PointEmitterShader::getInstance()->use();
|
||||
PointEmitterShader::getInstance()->setUniforms(matrix, timediff, active_count, size_increase_factor);
|
||||
PointEmitterShader::getInstance()->setUniforms(m_previous_frame_matrix, matrix, timediff, active_count, size_increase_factor);
|
||||
}
|
||||
|
||||
m_previous_frame_matrix = matrix;
|
||||
|
||||
glBindVertexArray(current_simulation_vao);
|
||||
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_buffers[1]);
|
||||
|
||||
@ -617,8 +619,14 @@ void ParticleSystemProxy::render() {
|
||||
return;
|
||||
}
|
||||
if (m_first_execution)
|
||||
{
|
||||
generateVAOs();
|
||||
m_first_execution = false;
|
||||
simulate();
|
||||
draw();
|
||||
m_previous_frame_matrix = getAbsoluteTransformation();
|
||||
m_first_execution = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
simulate();
|
||||
draw();
|
||||
}
|
||||
}
|
||||
|
@ -40,9 +40,12 @@ protected:
|
||||
float m_color_to[3];
|
||||
bool m_first_execution;
|
||||
bool m_randomize_initial_y;
|
||||
|
||||
|
||||
GLuint texture;
|
||||
|
||||
|
||||
/** Previous frame particles emitter source matrix */
|
||||
core::matrix4 m_previous_frame_matrix;
|
||||
|
||||
/** Current count of particles. */
|
||||
unsigned m_count;
|
||||
/** Previous count - for error handling only. */
|
||||
|
@ -2582,9 +2582,8 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
|
||||
// the normal maximum speed of the kart.
|
||||
if(nitro_frac>1.0f) nitro_frac = 1.0f;
|
||||
}
|
||||
// speed * dt is the new size of the box in which particles start
|
||||
m_kart_gfx->updateNitroGraphics(nitro_frac, getSpeed()*dt);
|
||||
|
||||
m_kart_gfx->updateNitroGraphics(nitro_frac);
|
||||
|
||||
// Handle leaning of karts
|
||||
// -----------------------
|
||||
// Note that we compare with maximum speed of the kart, not
|
||||
|
@ -350,11 +350,10 @@ void KartGFX::update(float dt)
|
||||
} // update
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Updates nitro dependent particle effects (and box sizes).
|
||||
/** Updates nitro dependent particle effects.
|
||||
* \param nitro_frac Nitro fraction/
|
||||
* \param new_size New size of the box in which new particles are emitted.
|
||||
*/
|
||||
void KartGFX::updateNitroGraphics(float nitro_frac, float new_size)
|
||||
void KartGFX::updateNitroGraphics(float nitro_frac)
|
||||
{
|
||||
// Upate particle effects (creation rate, and emitter size
|
||||
// depending on speed)
|
||||
@ -375,11 +374,6 @@ void KartGFX::updateNitroGraphics(float nitro_frac, float new_size)
|
||||
setCreationRateAbsolute(KartGFX::KGFX_NITROSMOKE2, 0);
|
||||
m_nitro_light->setVisible(false);
|
||||
}
|
||||
resizeBox(KartGFX::KGFX_NITRO1, new_size);
|
||||
resizeBox(KartGFX::KGFX_NITRO2, new_size);
|
||||
resizeBox(KartGFX::KGFX_NITROSMOKE1, new_size);
|
||||
resizeBox(KartGFX::KGFX_NITROSMOKE2, new_size);
|
||||
resizeBox(KartGFX::KGFX_ZIPPER, new_size);
|
||||
|
||||
} // updateGraphics
|
||||
|
||||
|
@ -99,7 +99,7 @@ public:
|
||||
void setCreationRateRelative(const KartGFXType type, float f);
|
||||
void updateTerrain(const ParticleKind *pk);
|
||||
void update(float dt);
|
||||
void updateNitroGraphics(float f, float new_size);
|
||||
void updateNitroGraphics(float f);
|
||||
void updateSkidLight(unsigned int level);
|
||||
|
||||
}; // KartWGFX
|
||||
|
Loading…
Reference in New Issue
Block a user