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)
|
||||
{
|
||||
vec4 color = texture(tex, tc);
|
||||
vec4 color = texture(tex, tc) * pc;
|
||||
if (color.a < 0.5)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
FragColor = color * pc;
|
||||
FragColor = color;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
uniform int flips;
|
||||
uniform float billboard;
|
||||
|
||||
#ifdef Explicit_Attrib_Location_Usable
|
||||
|
||||
@ -35,14 +36,10 @@ void main(void)
|
||||
return;
|
||||
}
|
||||
|
||||
float lifetime = color_lifetime.w;
|
||||
vec4 particle_color = vec4(color_lifetime.zyx, 1.0);
|
||||
float lifetime = size.y;
|
||||
vec2 particle_size = mix(size.xx, size, billboard);
|
||||
tc = Texcoord;
|
||||
|
||||
#if !defined(Advanced_Lighting_Enabled)
|
||||
particle_color.rgb = pow(particle_color.rgb, vec3(1.0 / 2.2));
|
||||
#endif
|
||||
pc = particle_color;
|
||||
pc = color_lifetime.zyxw;
|
||||
|
||||
vec4 viewpos = vec4(0.);
|
||||
if (flips == 1)
|
||||
@ -51,7 +48,7 @@ void main(void)
|
||||
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 = vec3(size * quadcorner, 0.0);
|
||||
vec3 newquadcorner = vec3(particle_size * quadcorner, 0.0);
|
||||
newquadcorner = newquadcorner + 2.0 * cross(cross(newquadcorner,
|
||||
quat.xyz) + quat.w * newquadcorner, quat.xyz);
|
||||
viewpos = u_view_matrix * vec4(Position + newquadcorner, 1.0);
|
||||
@ -59,7 +56,7 @@ void main(void)
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -10,8 +10,7 @@ out vec4 FragColor;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
float billboard_alpha = mix(1.0, texture(tex, tc).a, billboard);
|
||||
vec4 color = texture(tex, tc);
|
||||
vec4 color = texture(tex, tc) * pc;
|
||||
#if defined(Advanced_Lighting_Enabled)
|
||||
vec2 xy = gl_FragCoord.xy / u_screen;
|
||||
float FragZ = gl_FragCoord.z;
|
||||
@ -19,9 +18,11 @@ void main(void)
|
||||
float EnvZ = texture(dtex, xy).x;
|
||||
vec4 EnvPos = getPosFromUVDepth(vec3(xy, EnvZ), u_inverse_projection_matrix);
|
||||
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
|
||||
float alpha = 1.0;
|
||||
#endif
|
||||
color = vec4(color.rgb * color.a, color.a);
|
||||
FragColor = color * billboard_alpha * pc * alpha;
|
||||
color = vec4(color.rgb * color.a * alpha, color.a * alpha);
|
||||
FragColor = color;
|
||||
}
|
||||
|
@ -36,15 +36,10 @@ void main(void)
|
||||
return;
|
||||
}
|
||||
|
||||
float lifetime = color_lifetime.w;
|
||||
float alpha = mix(smoothstep(1.0, 0.8, lifetime), lifetime, billboard);
|
||||
vec4 particle_color = vec4(color_lifetime.zyx, 1.0) * alpha;
|
||||
float lifetime = size.y;
|
||||
vec2 particle_size = mix(size.xx, size, billboard);
|
||||
tc = Texcoord;
|
||||
|
||||
#if !defined(Advanced_Lighting_Enabled)
|
||||
particle_color.rgb = pow(particle_color.rgb, vec3(1.0 / 2.2));
|
||||
#endif
|
||||
pc = particle_color;
|
||||
pc = color_lifetime.zyxw;
|
||||
|
||||
vec4 viewpos = vec4(0.);
|
||||
if (flips == 1)
|
||||
@ -53,7 +48,7 @@ void main(void)
|
||||
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 = vec3(size * quadcorner, 0.0);
|
||||
vec3 newquadcorner = vec3(particle_size * quadcorner, 0.0);
|
||||
newquadcorner = newquadcorner + 2.0 * cross(cross(newquadcorner,
|
||||
quat.xyz) + quat.w * newquadcorner, quat.xyz);
|
||||
viewpos = u_view_matrix * vec4(Position + newquadcorner, 1.0);
|
||||
@ -61,7 +56,7 @@ void main(void)
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
|
||||
#include "graphics/cpu_particle_manager.hpp"
|
||||
#include "graphics/sp/sp_base.hpp"
|
||||
#include "graphics/stk_particle.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
@ -49,7 +50,7 @@ public:
|
||||
/** A Shader to render alpha-test particles.
|
||||
*/
|
||||
class AlphaTestParticleRenderer : public TextureShader
|
||||
<AlphaTestParticleRenderer, 1, int>
|
||||
<AlphaTestParticleRenderer, 1, int, float>
|
||||
{
|
||||
public:
|
||||
AlphaTestParticleRenderer()
|
||||
@ -57,7 +58,7 @@ public:
|
||||
loadProgram(PARTICLES_RENDERING,
|
||||
GL_VERTEX_SHADER, "alphatest_particle.vert",
|
||||
GL_FRAGMENT_SHADER, "alphatest_particle.frag");
|
||||
assignUniforms("flips");
|
||||
assignUniforms("flips", "billboard");
|
||||
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
||||
} // AlphaTestParticleRenderer
|
||||
}; // AlphaTestParticleRenderer
|
||||
@ -95,6 +96,56 @@ void CPUParticleManager::addParticleNode(STKParticle* node)
|
||||
m_particles_queue[tex_name].push_back(node);
|
||||
} // 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;
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -327,7 +378,8 @@ void CPUParticleManager::drawAll()
|
||||
{
|
||||
AlphaTestParticleRenderer::getInstance()->setTextureUnits
|
||||
(cur_mat->getTexture()->getTextureHandler());
|
||||
AlphaTestParticleRenderer::getInstance()->setUniforms(flips);
|
||||
AlphaTestParticleRenderer::getInstance()->setUniforms(flips,
|
||||
billboard);
|
||||
}
|
||||
glBindVertexArray(m_gl_particles.at(p.second)->m_vao);
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4,
|
||||
|
@ -48,26 +48,9 @@ struct 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;
|
||||
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];
|
||||
}
|
||||
const core::vector3df& color_to, float lf_time, float size);
|
||||
// ------------------------------------------------------------------------
|
||||
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);
|
||||
}
|
||||
CPUParticle(scene::IBillboardSceneNode* node);
|
||||
};
|
||||
|
||||
|
||||
|
@ -523,10 +523,12 @@ void STKParticle::OnRegisterSceneNode()
|
||||
m_particles_generating[i].m_size);
|
||||
core::vector3df ret = m_color_from + (m_color_to - m_color_from) *
|
||||
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.setBlue(core::clamp((int)(ret.Y * 255.0f), 0, 255));
|
||||
p.color.setGreen(core::clamp((int)(ret.Z * 255.0f), 0, 255));
|
||||
p.color.setAlpha(255);
|
||||
p.color.setGreen(core::clamp((int)(ret.Y * 255.0f), 0, 255));
|
||||
p.color.setBlue(core::clamp((int)(ret.Z * 255.0f), 0, 255));
|
||||
p.color.setAlpha(core::clamp((int)(alpha * 255.0f), 0, 255));
|
||||
Particles.push_back(p);
|
||||
}
|
||||
core::matrix4 inv(AbsoluteTransformation, core::matrix4::EM4CONST_INVERSE);
|
||||
|
@ -29,6 +29,12 @@ using namespace irr;
|
||||
|
||||
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
|
||||
{
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user