Use uniform rendering code for particle rendering
1. Remove pow in shader and do srgb conversion in code 2. Fix setGreen and setBlue order 3. Multiply particle color first like vertex color in the other shaders 4. Fix incorrect smoothstep
This commit is contained in:
parent
155b73d452
commit
dcad21b830
@ -6,10 +6,10 @@ out vec4 FragColor;
|
|||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
vec4 color = texture(tex, tc);
|
vec4 color = texture(tex, tc) * pc;
|
||||||
if (color.a < 0.5)
|
if (color.a < 0.5)
|
||||||
{
|
{
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
FragColor = color * pc;
|
FragColor = color;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
uniform int flips;
|
uniform int flips;
|
||||||
|
uniform float billboard;
|
||||||
|
|
||||||
#ifdef Explicit_Attrib_Location_Usable
|
#ifdef Explicit_Attrib_Location_Usable
|
||||||
|
|
||||||
@ -35,14 +36,10 @@ void main(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float lifetime = color_lifetime.w;
|
float lifetime = size.y;
|
||||||
vec4 particle_color = vec4(color_lifetime.zyx, 1.0);
|
vec2 particle_size = mix(size.xx, size, billboard);
|
||||||
tc = Texcoord;
|
tc = Texcoord;
|
||||||
|
pc = color_lifetime.zyxw;
|
||||||
#if !defined(Advanced_Lighting_Enabled)
|
|
||||||
particle_color.rgb = pow(particle_color.rgb, vec3(1.0 / 2.2));
|
|
||||||
#endif
|
|
||||||
pc = particle_color;
|
|
||||||
|
|
||||||
vec4 viewpos = vec4(0.);
|
vec4 viewpos = vec4(0.);
|
||||||
if (flips == 1)
|
if (flips == 1)
|
||||||
@ -51,7 +48,7 @@ void main(void)
|
|||||||
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 = vec3(size * quadcorner, 0.0);
|
vec3 newquadcorner = vec3(particle_size * quadcorner, 0.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 = u_view_matrix * vec4(Position + newquadcorner, 1.0);
|
viewpos = u_view_matrix * vec4(Position + newquadcorner, 1.0);
|
||||||
@ -59,7 +56,7 @@ void main(void)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
viewpos = u_view_matrix * vec4(Position, 1.0);
|
viewpos = u_view_matrix * vec4(Position, 1.0);
|
||||||
viewpos += vec4(size * quadcorner, 0.0, 0.0);
|
viewpos += vec4(particle_size * quadcorner, 0.0, 0.0);
|
||||||
}
|
}
|
||||||
gl_Position = u_projection_matrix * viewpos;
|
gl_Position = u_projection_matrix * viewpos;
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,7 @@ out vec4 FragColor;
|
|||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
float billboard_alpha = mix(1.0, texture(tex, tc).a, billboard);
|
vec4 color = texture(tex, tc) * pc;
|
||||||
vec4 color = texture(tex, tc);
|
|
||||||
#if defined(Advanced_Lighting_Enabled)
|
#if defined(Advanced_Lighting_Enabled)
|
||||||
vec2 xy = gl_FragCoord.xy / u_screen;
|
vec2 xy = gl_FragCoord.xy / u_screen;
|
||||||
float FragZ = gl_FragCoord.z;
|
float FragZ = gl_FragCoord.z;
|
||||||
@ -19,9 +18,11 @@ void main(void)
|
|||||||
float EnvZ = texture(dtex, xy).x;
|
float EnvZ = texture(dtex, xy).x;
|
||||||
vec4 EnvPos = getPosFromUVDepth(vec3(xy, EnvZ), u_inverse_projection_matrix);
|
vec4 EnvPos = getPosFromUVDepth(vec3(xy, EnvZ), u_inverse_projection_matrix);
|
||||||
float alpha = clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.);
|
float alpha = clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.);
|
||||||
|
// TODO remove this later if possible when implementing GE
|
||||||
|
alpha = mix(alpha, texture(tex, tc).a, billboard);
|
||||||
#else
|
#else
|
||||||
float alpha = 1.0;
|
float alpha = 1.0;
|
||||||
#endif
|
#endif
|
||||||
color = vec4(color.rgb * color.a, color.a);
|
color = vec4(color.rgb * color.a * alpha, color.a * alpha);
|
||||||
FragColor = color * billboard_alpha * pc * alpha;
|
FragColor = color;
|
||||||
}
|
}
|
||||||
|
@ -36,15 +36,10 @@ void main(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float lifetime = color_lifetime.w;
|
float lifetime = size.y;
|
||||||
float alpha = mix(smoothstep(1.0, 0.8, lifetime), lifetime, billboard);
|
vec2 particle_size = mix(size.xx, size, billboard);
|
||||||
vec4 particle_color = vec4(color_lifetime.zyx, 1.0) * alpha;
|
|
||||||
tc = Texcoord;
|
tc = Texcoord;
|
||||||
|
pc = color_lifetime.zyxw;
|
||||||
#if !defined(Advanced_Lighting_Enabled)
|
|
||||||
particle_color.rgb = pow(particle_color.rgb, vec3(1.0 / 2.2));
|
|
||||||
#endif
|
|
||||||
pc = particle_color;
|
|
||||||
|
|
||||||
vec4 viewpos = vec4(0.);
|
vec4 viewpos = vec4(0.);
|
||||||
if (flips == 1)
|
if (flips == 1)
|
||||||
@ -53,7 +48,7 @@ void main(void)
|
|||||||
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 = vec3(size * quadcorner, 0.0);
|
vec3 newquadcorner = vec3(particle_size * quadcorner, 0.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 = u_view_matrix * vec4(Position + newquadcorner, 1.0);
|
viewpos = u_view_matrix * vec4(Position + newquadcorner, 1.0);
|
||||||
@ -61,7 +56,7 @@ void main(void)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
viewpos = u_view_matrix * vec4(Position, 1.0);
|
viewpos = u_view_matrix * vec4(Position, 1.0);
|
||||||
viewpos += vec4(size * quadcorner, 0.0, 0.0);
|
viewpos += vec4(particle_size * quadcorner, 0.0, 0.0);
|
||||||
}
|
}
|
||||||
gl_Position = u_projection_matrix * viewpos;
|
gl_Position = u_projection_matrix * viewpos;
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "graphics/cpu_particle_manager.hpp"
|
#include "graphics/cpu_particle_manager.hpp"
|
||||||
|
#include "graphics/sp/sp_base.hpp"
|
||||||
#include "graphics/stk_particle.hpp"
|
#include "graphics/stk_particle.hpp"
|
||||||
#include "graphics/irr_driver.hpp"
|
#include "graphics/irr_driver.hpp"
|
||||||
#include "graphics/material.hpp"
|
#include "graphics/material.hpp"
|
||||||
@ -49,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, int>
|
<AlphaTestParticleRenderer, 1, int, float>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AlphaTestParticleRenderer()
|
AlphaTestParticleRenderer()
|
||||||
@ -57,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("flips");
|
assignUniforms("flips", "billboard");
|
||||||
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
||||||
} // AlphaTestParticleRenderer
|
} // AlphaTestParticleRenderer
|
||||||
}; // AlphaTestParticleRenderer
|
}; // AlphaTestParticleRenderer
|
||||||
@ -95,6 +96,56 @@ void CPUParticleManager::addParticleNode(STKParticle* node)
|
|||||||
m_particles_queue[tex_name].push_back(node);
|
m_particles_queue[tex_name].push_back(node);
|
||||||
} // addParticleNode
|
} // addParticleNode
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
CPUParticle::CPUParticle(const core::vector3df& position,
|
||||||
|
const core::vector3df& color_from,
|
||||||
|
const core::vector3df& color_to, float lf_time,
|
||||||
|
float size)
|
||||||
|
: m_position(position)
|
||||||
|
{
|
||||||
|
core::vector3df ret = color_from + (color_to - color_from) * lf_time;
|
||||||
|
float alpha = 1.0f - lf_time;
|
||||||
|
alpha = glslSmoothstep(0.0f, 0.35f, alpha);
|
||||||
|
int r = core::clamp((int)(ret.X * 255.0f), 0, 255);
|
||||||
|
int g = core::clamp((int)(ret.Y * 255.0f), 0, 255);
|
||||||
|
int b = core::clamp((int)(ret.Z * 255.0f), 0, 255);
|
||||||
|
if (CVS->isDeferredEnabled() && CVS->isGLSL())
|
||||||
|
{
|
||||||
|
using namespace SP;
|
||||||
|
r = srgb255ToLinear(r);
|
||||||
|
g = srgb255ToLinear(g);
|
||||||
|
b = srgb255ToLinear(b);
|
||||||
|
}
|
||||||
|
m_color_lifetime.setRed(r);
|
||||||
|
m_color_lifetime.setGreen(g);
|
||||||
|
m_color_lifetime.setBlue(b);
|
||||||
|
m_color_lifetime.setAlpha(core::clamp((int)(alpha * 255.0f), 0, 255));
|
||||||
|
if (size != 0.0f)
|
||||||
|
{
|
||||||
|
m_size[0] = MiniGLM::toFloat16(size);
|
||||||
|
m_size[1] = MiniGLM::toFloat16(lf_time);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
memset(m_size, 0, sizeof(m_size));
|
||||||
|
} // CPUParticle
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
CPUParticle::CPUParticle(scene::IBillboardSceneNode* node)
|
||||||
|
{
|
||||||
|
m_position = node->getAbsolutePosition();
|
||||||
|
video::SColor unused_bottom;
|
||||||
|
node->getColor(m_color_lifetime, unused_bottom);
|
||||||
|
if (CVS->isDeferredEnabled() && CVS->isGLSL())
|
||||||
|
{
|
||||||
|
using namespace SP;
|
||||||
|
m_color_lifetime.setRed(srgb255ToLinear(m_color_lifetime.getRed()));
|
||||||
|
m_color_lifetime.setGreen(srgb255ToLinear(m_color_lifetime.getGreen()));
|
||||||
|
m_color_lifetime.setBlue(srgb255ToLinear(m_color_lifetime.getBlue()));
|
||||||
|
}
|
||||||
|
m_size[0] = MiniGLM::toFloat16(node->getSize().Width);
|
||||||
|
m_size[1] = MiniGLM::toFloat16(node->getSize().Height);
|
||||||
|
} // CPUParticle
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
GLuint CPUParticleManager::m_particle_quad = 0;
|
GLuint CPUParticleManager::m_particle_quad = 0;
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -327,7 +378,8 @@ void CPUParticleManager::drawAll()
|
|||||||
{
|
{
|
||||||
AlphaTestParticleRenderer::getInstance()->setTextureUnits
|
AlphaTestParticleRenderer::getInstance()->setTextureUnits
|
||||||
(cur_mat->getTexture()->getTextureHandler());
|
(cur_mat->getTexture()->getTextureHandler());
|
||||||
AlphaTestParticleRenderer::getInstance()->setUniforms(flips);
|
AlphaTestParticleRenderer::getInstance()->setUniforms(flips,
|
||||||
|
billboard);
|
||||||
}
|
}
|
||||||
glBindVertexArray(m_gl_particles.at(p.second)->m_vao);
|
glBindVertexArray(m_gl_particles.at(p.second)->m_vao);
|
||||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4,
|
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4,
|
||||||
|
@ -48,26 +48,9 @@ struct CPUParticle
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
CPUParticle(const core::vector3df& position,
|
CPUParticle(const core::vector3df& position,
|
||||||
const core::vector3df& color_from,
|
const core::vector3df& color_from,
|
||||||
const core::vector3df& color_to, float lf_time, float size)
|
const core::vector3df& color_to, float lf_time, float size);
|
||||||
: m_position(position)
|
|
||||||
{
|
|
||||||
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];
|
|
||||||
}
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
CPUParticle(scene::IBillboardSceneNode* node)
|
CPUParticle(scene::IBillboardSceneNode* node);
|
||||||
{
|
|
||||||
m_position = node->getAbsolutePosition();
|
|
||||||
video::SColor unused_bottom;
|
|
||||||
node->getColor(m_color_lifetime, unused_bottom);
|
|
||||||
m_size[0] = MiniGLM::toFloat16(node->getSize().Width);
|
|
||||||
m_size[1] = MiniGLM::toFloat16(node->getSize().Height);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -523,10 +523,12 @@ void STKParticle::OnRegisterSceneNode()
|
|||||||
m_particles_generating[i].m_size);
|
m_particles_generating[i].m_size);
|
||||||
core::vector3df ret = m_color_from + (m_color_to - m_color_from) *
|
core::vector3df ret = m_color_from + (m_color_to - m_color_from) *
|
||||||
m_particles_generating[i].m_lifetime;
|
m_particles_generating[i].m_lifetime;
|
||||||
|
float alpha = 1.0f - m_particles_generating[i].m_lifetime;
|
||||||
|
alpha = glslSmoothstep(0.0f, 0.35f, alpha);
|
||||||
p.color.setRed(core::clamp((int)(ret.X * 255.0f), 0, 255));
|
p.color.setRed(core::clamp((int)(ret.X * 255.0f), 0, 255));
|
||||||
p.color.setBlue(core::clamp((int)(ret.Y * 255.0f), 0, 255));
|
p.color.setGreen(core::clamp((int)(ret.Y * 255.0f), 0, 255));
|
||||||
p.color.setGreen(core::clamp((int)(ret.Z * 255.0f), 0, 255));
|
p.color.setBlue(core::clamp((int)(ret.Z * 255.0f), 0, 255));
|
||||||
p.color.setAlpha(255);
|
p.color.setAlpha(core::clamp((int)(alpha * 255.0f), 0, 255));
|
||||||
Particles.push_back(p);
|
Particles.push_back(p);
|
||||||
}
|
}
|
||||||
core::matrix4 inv(AbsoluteTransformation, core::matrix4::EM4CONST_INVERSE);
|
core::matrix4 inv(AbsoluteTransformation, core::matrix4::EM4CONST_INVERSE);
|
||||||
|
@ -29,6 +29,12 @@ using namespace irr;
|
|||||||
|
|
||||||
struct CPUParticle;
|
struct CPUParticle;
|
||||||
|
|
||||||
|
inline float glslSmoothstep(float edge0, float edge1, float x)
|
||||||
|
{
|
||||||
|
float t = core::clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f);
|
||||||
|
return t * t * (3.0f - 2.0f * t);
|
||||||
|
}
|
||||||
|
|
||||||
class STKParticle : public scene::CParticleSystemSceneNode
|
class STKParticle : public scene::CParticleSystemSceneNode
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user