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