Pack mixed color into instanced array

With half-floats for lifetime and size for same stride
This commit is contained in:
Benau 2017-10-14 12:33:08 +08:00
parent e49a7139d7
commit a0c9ba2b8c
7 changed files with 61 additions and 61 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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,

View File

@ -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;

View File

@ -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");

View File

@ -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);
}
}
}

View File

@ -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() {}