Some work to make particle shader able to render billboard

The lifetime in height map stimulation will always now < 1.0f
This commit is contained in:
Benau 2017-10-15 13:57:01 +08:00
parent f646a26fbe
commit 058f9163db
5 changed files with 45 additions and 32 deletions

View File

@ -3,8 +3,8 @@ uniform int flips;
#ifdef Explicit_Attrib_Location_Usable
layout(location = 0) in vec3 Position;
layout(location = 1) in vec4 mixed_color;
layout(location = 2) in vec2 lifetime_and_size;
layout(location = 1) in vec4 color_lifetime;
layout(location = 2) in vec2 size;
layout(location = 3) in vec2 Texcoord;
layout(location = 4) in vec2 quadcorner;
@ -13,8 +13,8 @@ layout(location = 6) in float anglespeed;
#else
in vec3 Position;
in vec4 mixed_color;
in vec2 lifetime_and_size;
in vec4 color_lifetime;
in vec2 size;
in vec2 Texcoord;
in vec2 quadcorner;
@ -27,24 +27,30 @@ out vec4 pc;
void main(void)
{
if (lifetime_and_size.y == 0.0)
if (size.x == 0.0 && size.y == 0.0)
{
gl_Position = vec4(0.);
pc = vec4(0.0);
tc = vec2(0.0);
return;
}
float lifetime = color_lifetime.w;
pc = vec4(color_lifetime.zyx, 1.0);
tc = Texcoord;
pc = mixed_color.zyxw;
#if !defined(sRGB_Framebuffer_Usable) && !defined(Advanced_Lighting_Enabled)
pc.rgb = pow(pc.rgb, vec3(1.0 / 2.2));
#endif
vec4 viewpos = vec4(0.);
if (flips == 1)
{
float angle = lifetime_and_size.x * anglespeed;
float angle = lifetime * 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 = lifetime_and_size.y * vec3(quadcorner, 0.);
vec3 newquadcorner = vec3(size * quadcorner, 0.0);
newquadcorner = newquadcorner + 2.0 * cross(cross(newquadcorner,
quat.xyz) + quat.w * newquadcorner, quat.xyz);
viewpos = ViewMatrix * vec4(Position + newquadcorner, 1.0);
@ -52,7 +58,7 @@ void main(void)
else
{
viewpos = ViewMatrix * vec4(Position, 1.0);
viewpos += lifetime_and_size.y * vec4(quadcorner, 0., 0.);
viewpos += vec4(size * quadcorner, 0.0, 0.0);
}
gl_Position = ProjectionMatrix * viewpos;
}

View File

@ -3,8 +3,8 @@ uniform int flips;
#ifdef Explicit_Attrib_Location_Usable
layout(location = 0) in vec3 Position;
layout(location = 1) in vec4 mixed_color;
layout(location = 2) in vec2 lifetime_and_size;
layout(location = 1) in vec4 color_lifetime;
layout(location = 2) in vec2 size;
layout(location = 3) in vec2 Texcoord;
layout(location = 4) in vec2 quadcorner;
@ -13,8 +13,8 @@ layout(location = 6) in float anglespeed;
#else
in vec3 Position;
in vec4 mixed_color;
in vec2 lifetime_and_size;
in vec4 color_lifetime;
in vec2 size;
in vec2 Texcoord;
in vec2 quadcorner;
@ -27,24 +27,30 @@ out vec4 pc;
void main(void)
{
if (lifetime_and_size.y == 0.0)
if (size.x == 0.0 && size.y == 0.0)
{
gl_Position = vec4(0.);
pc = vec4(0.0);
tc = vec2(0.0);
return;
}
float lifetime = color_lifetime.w;
pc = vec4(color_lifetime.zyx, 1.0) * smoothstep(1.0, 0.8, lifetime);
tc = Texcoord;
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.0 / 2.2));
#endif
vec4 viewpos = vec4(0.);
if (flips == 1)
{
float angle = lifetime_and_size.x * anglespeed;
float angle = lifetime * 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 = lifetime_and_size.y * vec3(quadcorner, 0.);
vec3 newquadcorner = vec3(size * quadcorner, 0.0);
newquadcorner = newquadcorner + 2.0 * cross(cross(newquadcorner,
quat.xyz) + quat.w * newquadcorner, quat.xyz);
viewpos = ViewMatrix * vec4(Position + newquadcorner, 1.0);
@ -52,7 +58,7 @@ void main(void)
else
{
viewpos = ViewMatrix * vec4(Position, 1.0);
viewpos += lifetime_and_size.y * vec4(quadcorner, 0., 0.);
viewpos += vec4(size * quadcorner, 0.0, 0.0);
}
gl_Position = ProjectionMatrix * viewpos;
}

View File

@ -40,20 +40,21 @@ using namespace irr;
struct CPUParticle
{
core::vector3df m_position;
video::SColor m_mixed_color;
short m_lifetime_and_size[2];
video::SColor m_color_lifetime;
short m_size[2];
// ------------------------------------------------------------------------
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)
const core::vector3df& color_to, float lf_time, float size)
: m_position(position)
{
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);
core::vector3df ret = color_from + (color_to - color_from) * lf_time;
m_color_lifetime.setRed(core::clamp((int)(ret.X * 255.0f), 0, 255));
m_color_lifetime.setBlue(core::clamp((int)(ret.Y * 255.0f), 0, 255));
m_color_lifetime.setGreen(core::clamp((int)(ret.Z * 255.0f), 0, 255));
m_color_lifetime.setAlpha(core::clamp((int)(lf_time * 255.0f), 0, 255));
m_size[0] = MiniGLM::toFloat16(size);
m_size[1] = m_size[0];
}
};

View File

@ -163,8 +163,8 @@ void ShaderBase::setAttribute(AttributeType type)
break;
case PARTICLES_RENDERING:
glBindAttribLocation(m_program, 0, "Position");
glBindAttribLocation(m_program, 1, "mixed_color");
glBindAttribLocation(m_program, 2, "lifetime_and_size");
glBindAttribLocation(m_program, 1, "color_lifetime");
glBindAttribLocation(m_program, 2, "size");
glBindAttribLocation(m_program, 3, "Texcoord");
glBindAttribLocation(m_program, 4, "quadcorner");
glBindAttribLocation(m_program, 5, "rotationvec");

View File

@ -333,8 +333,8 @@ void STKParticle::stimulateHeightMap(float dt, unsigned int active_count,
core::vector3df adjusted_initial_direction =
initial_new_position - initial_position;
float adjusted_lifetime = lifetime + (dt / lifetime_initial);
reset = reset || ((adjusted_lifetime > 1.0f) && (i <= active_count));
reset = reset || (lifetime < 0.0f);
reset = reset || adjusted_lifetime > 1.0f;
reset = reset || lifetime < 0.0f;
new_particle_position = !reset ?
(particle_position + particle_direction * dt) : initial_position;