Pack mixed color into instanced array
With half-floats for lifetime and size for same stride
This commit is contained in:
parent
e49a7139d7
commit
a0c9ba2b8c
@ -1,12 +1,10 @@
|
|||||||
uniform vec3 color_from;
|
|
||||||
uniform vec3 color_to;
|
|
||||||
uniform int flips;
|
uniform int flips;
|
||||||
|
|
||||||
#ifdef Explicit_Attrib_Location_Usable
|
#ifdef Explicit_Attrib_Location_Usable
|
||||||
|
|
||||||
layout(location = 0) in vec3 Position;
|
layout(location = 0) in vec3 Position;
|
||||||
layout(location = 1) in float lifetime;
|
layout(location = 1) in vec4 mixed_color;
|
||||||
layout(location = 2) in float size;
|
layout(location = 2) in vec2 lifetime_and_size;
|
||||||
|
|
||||||
layout(location = 3) in vec2 Texcoord;
|
layout(location = 3) in vec2 Texcoord;
|
||||||
layout(location = 4) in vec2 quadcorner;
|
layout(location = 4) in vec2 quadcorner;
|
||||||
@ -15,8 +13,8 @@ layout(location = 6) in float anglespeed;
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
in vec3 Position;
|
in vec3 Position;
|
||||||
in float lifetime;
|
in vec4 mixed_color;
|
||||||
in float size;
|
in vec2 lifetime_and_size;
|
||||||
|
|
||||||
in vec2 Texcoord;
|
in vec2 Texcoord;
|
||||||
in vec2 quadcorner;
|
in vec2 quadcorner;
|
||||||
@ -29,24 +27,24 @@ out vec4 pc;
|
|||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
if (size == 0.0)
|
if (lifetime_and_size.y == 0.0)
|
||||||
{
|
{
|
||||||
gl_Position = vec4(0.);
|
gl_Position = vec4(0.);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tc = Texcoord;
|
tc = Texcoord;
|
||||||
pc = vec4(vec3(color_from + (color_to - color_from) * lifetime), 1.0);
|
pc = mixed_color.zyxw;
|
||||||
#if !defined(sRGB_Framebuffer_Usable) && !defined(Advanced_Lighting_Enabled)
|
#if !defined(sRGB_Framebuffer_Usable) && !defined(Advanced_Lighting_Enabled)
|
||||||
pc.rgb = pow(pc.rgb, vec3(1. / 2.2));
|
pc.rgb = pow(pc.rgb, vec3(1.0 / 2.2));
|
||||||
#endif
|
#endif
|
||||||
vec4 viewpos = vec4(0.);
|
vec4 viewpos = vec4(0.);
|
||||||
if (flips == 1)
|
if (flips == 1)
|
||||||
{
|
{
|
||||||
float angle = lifetime * anglespeed;
|
float angle = lifetime_and_size.x * anglespeed;
|
||||||
float sin_a = sin(mod(angle / 2.0, 6.283185307179586));
|
float sin_a = sin(mod(angle / 2.0, 6.283185307179586));
|
||||||
float cos_a = cos(mod(angle / 2.0, 6.283185307179586));
|
float cos_a = cos(mod(angle / 2.0, 6.283185307179586));
|
||||||
vec4 quat = normalize(vec4(vec3(0.0, 1.0, 0.0) * sin_a, cos_a));
|
vec4 quat = normalize(vec4(vec3(0.0, 1.0, 0.0) * sin_a, cos_a));
|
||||||
vec3 newquadcorner = size * vec3(quadcorner, 0.);
|
vec3 newquadcorner = lifetime_and_size.y * vec3(quadcorner, 0.);
|
||||||
newquadcorner = newquadcorner + 2.0 * cross(cross(newquadcorner,
|
newquadcorner = newquadcorner + 2.0 * cross(cross(newquadcorner,
|
||||||
quat.xyz) + quat.w * newquadcorner, quat.xyz);
|
quat.xyz) + quat.w * newquadcorner, quat.xyz);
|
||||||
viewpos = ViewMatrix * vec4(Position + newquadcorner, 1.0);
|
viewpos = ViewMatrix * vec4(Position + newquadcorner, 1.0);
|
||||||
@ -54,7 +52,7 @@ void main(void)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
viewpos = ViewMatrix * vec4(Position, 1.0);
|
viewpos = ViewMatrix * vec4(Position, 1.0);
|
||||||
viewpos += size * vec4(quadcorner, 0., 0.);
|
viewpos += lifetime_and_size.y * vec4(quadcorner, 0., 0.);
|
||||||
}
|
}
|
||||||
gl_Position = ProjectionMatrix * viewpos;
|
gl_Position = ProjectionMatrix * viewpos;
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
uniform vec3 color_from;
|
|
||||||
uniform vec3 color_to;
|
|
||||||
uniform int flips;
|
uniform int flips;
|
||||||
|
|
||||||
#ifdef Explicit_Attrib_Location_Usable
|
#ifdef Explicit_Attrib_Location_Usable
|
||||||
|
|
||||||
layout(location = 0) in vec3 Position;
|
layout(location = 0) in vec3 Position;
|
||||||
layout(location = 1) in float lifetime;
|
layout(location = 1) in vec4 mixed_color;
|
||||||
layout(location = 2) in float size;
|
layout(location = 2) in vec2 lifetime_and_size;
|
||||||
|
|
||||||
layout(location = 3) in vec2 Texcoord;
|
layout(location = 3) in vec2 Texcoord;
|
||||||
layout(location = 4) in vec2 quadcorner;
|
layout(location = 4) in vec2 quadcorner;
|
||||||
@ -15,8 +13,8 @@ layout(location = 6) in float anglespeed;
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
in vec3 Position;
|
in vec3 Position;
|
||||||
in float lifetime;
|
in vec4 mixed_color;
|
||||||
in float size;
|
in vec2 lifetime_and_size;
|
||||||
|
|
||||||
in vec2 Texcoord;
|
in vec2 Texcoord;
|
||||||
in vec2 quadcorner;
|
in vec2 quadcorner;
|
||||||
@ -29,25 +27,24 @@ out vec4 pc;
|
|||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
if (size == 0.0)
|
if (lifetime_and_size.y == 0.0)
|
||||||
{
|
{
|
||||||
gl_Position = vec4(0.);
|
gl_Position = vec4(0.);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tc = Texcoord;
|
tc = Texcoord;
|
||||||
pc = vec4(vec3(color_from + (color_to - color_from) * lifetime), 1.0) *
|
pc = mixed_color.zyxw * smoothstep(1.0, 0.8, lifetime_and_size.x);
|
||||||
smoothstep(1., 0.8, lifetime);
|
|
||||||
#if !defined(sRGB_Framebuffer_Usable) && !defined(Advanced_Lighting_Enabled)
|
#if !defined(sRGB_Framebuffer_Usable) && !defined(Advanced_Lighting_Enabled)
|
||||||
pc.rgb = pow(pc.rgb, vec3(1. / 2.2));
|
pc.rgb = pow(pc.rgb, vec3(1.0 / 2.2));
|
||||||
#endif
|
#endif
|
||||||
vec4 viewpos = vec4(0.);
|
vec4 viewpos = vec4(0.);
|
||||||
if (flips == 1)
|
if (flips == 1)
|
||||||
{
|
{
|
||||||
float angle = lifetime * anglespeed;
|
float angle = lifetime_and_size.x * anglespeed;
|
||||||
float sin_a = sin(mod(angle / 2.0, 6.283185307179586));
|
float sin_a = sin(mod(angle / 2.0, 6.283185307179586));
|
||||||
float cos_a = cos(mod(angle / 2.0, 6.283185307179586));
|
float cos_a = cos(mod(angle / 2.0, 6.283185307179586));
|
||||||
vec4 quat = normalize(vec4(vec3(0.0, 1.0, 0.0) * sin_a, cos_a));
|
vec4 quat = normalize(vec4(vec3(0.0, 1.0, 0.0) * sin_a, cos_a));
|
||||||
vec3 newquadcorner = size * vec3(quadcorner, 0.);
|
vec3 newquadcorner = lifetime_and_size.y * vec3(quadcorner, 0.);
|
||||||
newquadcorner = newquadcorner + 2.0 * cross(cross(newquadcorner,
|
newquadcorner = newquadcorner + 2.0 * cross(cross(newquadcorner,
|
||||||
quat.xyz) + quat.w * newquadcorner, quat.xyz);
|
quat.xyz) + quat.w * newquadcorner, quat.xyz);
|
||||||
viewpos = ViewMatrix * vec4(Position + newquadcorner, 1.0);
|
viewpos = ViewMatrix * vec4(Position + newquadcorner, 1.0);
|
||||||
@ -55,7 +52,7 @@ void main(void)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
viewpos = ViewMatrix * vec4(Position, 1.0);
|
viewpos = ViewMatrix * vec4(Position, 1.0);
|
||||||
viewpos += size * vec4(quadcorner, 0., 0.);
|
viewpos += lifetime_and_size.y * vec4(quadcorner, 0., 0.);
|
||||||
}
|
}
|
||||||
gl_Position = ProjectionMatrix * viewpos;
|
gl_Position = ProjectionMatrix * viewpos;
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,7 @@
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
/** A Shader to render particles.
|
/** A Shader to render particles.
|
||||||
*/
|
*/
|
||||||
class ParticleRenderer : public TextureShader
|
class ParticleRenderer : public TextureShader<ParticleRenderer, 2, int>
|
||||||
<ParticleRenderer, 2, video::SColorf, video::SColorf, int>
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ParticleRenderer()
|
ParticleRenderer()
|
||||||
@ -41,7 +40,7 @@ public:
|
|||||||
loadProgram(PARTICLES_RENDERING,
|
loadProgram(PARTICLES_RENDERING,
|
||||||
GL_VERTEX_SHADER, "simple_particle.vert",
|
GL_VERTEX_SHADER, "simple_particle.vert",
|
||||||
GL_FRAGMENT_SHADER, "simple_particle.frag");
|
GL_FRAGMENT_SHADER, "simple_particle.frag");
|
||||||
assignUniforms("color_from", "color_to", "flips");
|
assignUniforms("flips");
|
||||||
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED,
|
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED,
|
||||||
1, "dtex", ST_NEAREST_FILTERED);
|
1, "dtex", ST_NEAREST_FILTERED);
|
||||||
} // ParticleRenderer
|
} // ParticleRenderer
|
||||||
@ -51,7 +50,7 @@ public:
|
|||||||
/** A Shader to render alpha-test particles.
|
/** A Shader to render alpha-test particles.
|
||||||
*/
|
*/
|
||||||
class AlphaTestParticleRenderer : public TextureShader
|
class AlphaTestParticleRenderer : public TextureShader
|
||||||
<AlphaTestParticleRenderer, 1, video::SColorf, video::SColorf, int>
|
<AlphaTestParticleRenderer, 1, int>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AlphaTestParticleRenderer()
|
AlphaTestParticleRenderer()
|
||||||
@ -59,7 +58,7 @@ public:
|
|||||||
loadProgram(PARTICLES_RENDERING,
|
loadProgram(PARTICLES_RENDERING,
|
||||||
GL_VERTEX_SHADER, "alphatest_particle.vert",
|
GL_VERTEX_SHADER, "alphatest_particle.vert",
|
||||||
GL_FRAGMENT_SHADER, "alphatest_particle.frag");
|
GL_FRAGMENT_SHADER, "alphatest_particle.frag");
|
||||||
assignUniforms("color_from", "color_to", "flips");
|
assignUniforms("flips");
|
||||||
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
||||||
} // AlphaTestParticleRenderer
|
} // AlphaTestParticleRenderer
|
||||||
}; // AlphaTestParticleRenderer
|
}; // AlphaTestParticleRenderer
|
||||||
@ -164,10 +163,12 @@ void CPUParticleManager::uploadAll()
|
|||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 20, 0);
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 20, 0);
|
||||||
glVertexAttribDivisorARB(0, 1);
|
glVertexAttribDivisorARB(0, 1);
|
||||||
glEnableVertexAttribArray(1);
|
glEnableVertexAttribArray(1);
|
||||||
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 20, (void*)12);
|
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, 20,
|
||||||
|
(void*)12);
|
||||||
glVertexAttribDivisorARB(1, 1);
|
glVertexAttribDivisorARB(1, 1);
|
||||||
glEnableVertexAttribArray(2);
|
glEnableVertexAttribArray(2);
|
||||||
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 20, (void*)16);
|
glVertexAttribPointer(2, 2, GL_HALF_FLOAT, GL_FALSE, 20,
|
||||||
|
(void*)16);
|
||||||
glVertexAttribDivisorARB(2, 1);
|
glVertexAttribDivisorARB(2, 1);
|
||||||
bool flips = false;
|
bool flips = false;
|
||||||
for (unsigned i = 0; i < m_particles_queue[p.first].size(); i++)
|
for (unsigned i = 0; i < m_particles_queue[p.first].size(); i++)
|
||||||
@ -282,17 +283,13 @@ void CPUParticleManager::drawAll()
|
|||||||
ParticleRenderer::getInstance()->setTextureUnits
|
ParticleRenderer::getInstance()->setTextureUnits
|
||||||
(cur_mat->getTexture()->getOpenGLTextureName(),
|
(cur_mat->getTexture()->getOpenGLTextureName(),
|
||||||
irr_driver->getDepthStencilTexture());
|
irr_driver->getDepthStencilTexture());
|
||||||
ParticleRenderer::getInstance()->setUniforms(
|
ParticleRenderer::getInstance()->setUniforms(flips);
|
||||||
m_particles_queue.at(p.second)[0]->getColorFrom(),
|
|
||||||
m_particles_queue.at(p.second)[0]->getColorTo(), flips);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AlphaTestParticleRenderer::getInstance()->setTextureUnits
|
AlphaTestParticleRenderer::getInstance()->setTextureUnits
|
||||||
(cur_mat->getTexture()->getOpenGLTextureName());
|
(cur_mat->getTexture()->getOpenGLTextureName());
|
||||||
AlphaTestParticleRenderer::getInstance()->setUniforms(
|
AlphaTestParticleRenderer::getInstance()->setUniforms(flips);
|
||||||
m_particles_queue.at(p.second)[0]->getColorFrom(),
|
|
||||||
m_particles_queue.at(p.second)[0]->getColorTo(), flips);
|
|
||||||
}
|
}
|
||||||
glBindVertexArray(std::get<0>(m_gl_particles[p.second]));
|
glBindVertexArray(std::get<0>(m_gl_particles[p.second]));
|
||||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4,
|
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4,
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#ifndef SERVER_ONLY
|
#ifndef SERVER_ONLY
|
||||||
|
|
||||||
#include "graphics/gl_headers.hpp"
|
#include "graphics/gl_headers.hpp"
|
||||||
|
#include "utils/mini_glm.hpp"
|
||||||
#include "utils/no_copy.hpp"
|
#include "utils/no_copy.hpp"
|
||||||
#include "utils/singleton.hpp"
|
#include "utils/singleton.hpp"
|
||||||
|
|
||||||
@ -39,11 +40,21 @@ using namespace irr;
|
|||||||
struct CPUParticle
|
struct CPUParticle
|
||||||
{
|
{
|
||||||
core::vector3df m_position;
|
core::vector3df m_position;
|
||||||
float m_lifetime;
|
video::SColor m_mixed_color;
|
||||||
float m_size;
|
short m_lifetime_and_size[2];
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
CPUParticle(const core::vector3df& position, float lifetime, float size)
|
CPUParticle(const core::vector3df& position,
|
||||||
: m_position(position), m_lifetime(lifetime), m_size(size) {}
|
const core::vector3df& color_from,
|
||||||
|
const core::vector3df& color_to, float lifetime, float size)
|
||||||
|
: m_position(position), m_mixed_color(-1)
|
||||||
|
{
|
||||||
|
core::vector3df ret = color_from + (color_to - color_from) * lifetime;
|
||||||
|
m_mixed_color.setRed(core::clamp((int)(ret.X * 255.0f), 0, 255));
|
||||||
|
m_mixed_color.setBlue(core::clamp((int)(ret.Y * 255.0f), 0, 255));
|
||||||
|
m_mixed_color.setGreen(core::clamp((int)(ret.Z * 255.0f), 0, 255));
|
||||||
|
m_lifetime_and_size[0] = MiniGLM::toFloat16(lifetime);
|
||||||
|
m_lifetime_and_size[1] = MiniGLM::toFloat16(size);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class STKParticle;
|
class STKParticle;
|
||||||
|
@ -156,15 +156,16 @@ void ShaderBase::setAttribute(AttributeType type)
|
|||||||
glBindAttribLocation(m_program, 5, "lifetime_initial");
|
glBindAttribLocation(m_program, 5, "lifetime_initial");
|
||||||
glBindAttribLocation(m_program, 6, "particle_velocity_initial");
|
glBindAttribLocation(m_program, 6, "particle_velocity_initial");
|
||||||
glBindAttribLocation(m_program, 7, "size_initial");
|
glBindAttribLocation(m_program, 7, "size_initial");
|
||||||
|
|
||||||
if (CVS->needsVertexIdWorkaround())
|
if (CVS->needsVertexIdWorkaround())
|
||||||
{
|
{
|
||||||
glBindAttribLocation(m_program, 8, "vertex_id");
|
glBindAttribLocation(m_program, 8, "vertex_id");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PARTICLES_RENDERING:
|
case PARTICLES_RENDERING:
|
||||||
glBindAttribLocation(m_program, 1, "lifetime");
|
glBindAttribLocation(m_program, 0, "Position");
|
||||||
glBindAttribLocation(m_program, 2, "size");
|
glBindAttribLocation(m_program, 1, "mixed_color");
|
||||||
|
glBindAttribLocation(m_program, 2, "lifetime_and_size");
|
||||||
|
glBindAttribLocation(m_program, 3, "Texcoord");
|
||||||
glBindAttribLocation(m_program, 4, "quadcorner");
|
glBindAttribLocation(m_program, 4, "quadcorner");
|
||||||
glBindAttribLocation(m_program, 5, "rotationvec");
|
glBindAttribLocation(m_program, 5, "rotationvec");
|
||||||
glBindAttribLocation(m_program, 6, "anglespeed");
|
glBindAttribLocation(m_program, 6, "anglespeed");
|
||||||
|
@ -57,7 +57,7 @@ STKParticle::STKParticle(bool createDefaultEmitter,
|
|||||||
position, rotation, scale)
|
position, rotation, scale)
|
||||||
{
|
{
|
||||||
m_hm = NULL;
|
m_hm = NULL;
|
||||||
m_color_to = video::SColorf(video::SColor(-1));
|
m_color_to = core::vector3df(1.0f);
|
||||||
m_color_from = m_color_to;
|
m_color_from = m_color_to;
|
||||||
m_size_increase_factor = 0.0f;
|
m_size_increase_factor = 0.0f;
|
||||||
m_first_execution = true;
|
m_first_execution = true;
|
||||||
@ -358,8 +358,8 @@ void STKParticle::stimulateHeightMap(float dt, unsigned int active_count,
|
|||||||
}
|
}
|
||||||
if (out != NULL)
|
if (out != NULL)
|
||||||
{
|
{
|
||||||
out->emplace_back(new_particle_position, new_lifetime,
|
out->emplace_back(new_particle_position, m_color_from,
|
||||||
new_size);
|
m_color_to, new_lifetime, new_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -463,8 +463,8 @@ void STKParticle::stimulateNormal(float dt, unsigned int active_count,
|
|||||||
}
|
}
|
||||||
if (out != NULL)
|
if (out != NULL)
|
||||||
{
|
{
|
||||||
out->emplace_back(new_particle_position, new_lifetime,
|
out->emplace_back(new_particle_position, m_color_from,
|
||||||
new_size);
|
m_color_to, new_lifetime, new_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ private:
|
|||||||
|
|
||||||
std::vector<ParticleData> m_particles_generating, m_initial_particles;
|
std::vector<ParticleData> m_particles_generating, m_initial_particles;
|
||||||
|
|
||||||
video::SColorf m_color_from, m_color_to;
|
core::vector3df m_color_from, m_color_to;
|
||||||
|
|
||||||
float m_size_increase_factor;
|
float m_size_increase_factor;
|
||||||
|
|
||||||
@ -109,22 +109,18 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void setColorFrom(float r, float g, float b)
|
void setColorFrom(float r, float g, float b)
|
||||||
{
|
{
|
||||||
m_color_from.r = r;
|
m_color_from.X = r;
|
||||||
m_color_from.g = g;
|
m_color_from.Y = g;
|
||||||
m_color_from.b = b;
|
m_color_from.Z = b;
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void setColorTo(float r, float g, float b)
|
void setColorTo(float r, float g, float b)
|
||||||
{
|
{
|
||||||
m_color_to.r = r;
|
m_color_to.X = r;
|
||||||
m_color_to.g = g;
|
m_color_to.Y = g;
|
||||||
m_color_to.b = b;
|
m_color_to.Z = b;
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
const video::SColorf getColorFrom() const { return m_color_from; }
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
const video::SColorf getColorTo() const { return m_color_to; }
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
virtual void setEmitter(scene::IParticleEmitter* emitter);
|
virtual void setEmitter(scene::IParticleEmitter* emitter);
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
virtual void render() {}
|
virtual void render() {}
|
||||||
|
Loading…
Reference in New Issue
Block a user