Fix sky particles rendering in modern gl3 too, see #2779

This commit is contained in:
Benau 2022-10-17 09:33:51 +08:00
parent 5ecdc11ffd
commit 1b604666c3
4 changed files with 65 additions and 18 deletions

View File

@ -1,4 +1,6 @@
uniform int flips;
uniform int sky;
uniform vec3 view_position;
uniform float billboard;
#ifdef Explicit_Attrib_Location_Usable
@ -26,6 +28,11 @@ in float anglespeed;
out vec2 tc;
out vec4 pc;
vec4 getQuat(float half_sin, float half_cos)
{
return normalize(vec4(vec3(0.0, 1.0, 0.0) * half_sin, half_cos));
}
void main(void)
{
if (size.x == 0.0 && size.y == 0.0)
@ -42,12 +49,22 @@ void main(void)
pc = color_lifetime.zyxw;
vec4 viewpos = vec4(0.);
if (flips == 1)
if (flips == 1 || sky == 1)
{
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));
vec4 quat = vec4(0.0);
if (flips == 1)
{
float angle = lifetime * anglespeed;
float sin_a = sin(mod(angle / 2.0, 6.283185307179586));
float cos_a = cos(mod(angle / 2.0, 6.283185307179586));
quat = getQuat(sin_a, cos_a);
}
else
{
vec3 diff = Position - view_position;
float angle = atan(diff.x, diff.z);
quat = getQuat(sin(angle / -2.0), cos(angle / -2.0));
}
vec3 newquadcorner = vec3(particle_size * quadcorner, 0.0);
newquadcorner = newquadcorner + 2.0 * cross(cross(newquadcorner,
quat.xyz) + quat.w * newquadcorner, quat.xyz);

View File

@ -1,4 +1,6 @@
uniform int flips;
uniform int sky;
uniform vec3 view_position;
uniform float billboard;
#ifdef Explicit_Attrib_Location_Usable
@ -26,6 +28,11 @@ in float anglespeed;
out vec2 tc;
out vec4 pc;
vec4 getQuat(float half_sin, float half_cos)
{
return normalize(vec4(vec3(0.0, 1.0, 0.0) * half_sin, half_cos));
}
void main(void)
{
if (size.x == 0.0 && size.y == 0.0)
@ -42,12 +49,22 @@ void main(void)
pc = color_lifetime.zyxw;
vec4 viewpos = vec4(0.);
if (flips == 1)
if (flips == 1 || sky == 1)
{
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));
vec4 quat = vec4(0.0);
if (flips == 1)
{
float angle = lifetime * anglespeed;
float sin_a = sin(mod(angle / 2.0, 6.283185307179586));
float cos_a = cos(mod(angle / 2.0, 6.283185307179586));
quat = getQuat(sin_a, cos_a);
}
else
{
vec3 diff = Position - view_position;
float angle = atan(diff.x, diff.z);
quat = getQuat(sin(angle / -2.0), cos(angle / -2.0));
}
vec3 newquadcorner = vec3(particle_size * quadcorner, 0.0);
newquadcorner = newquadcorner + 2.0 * cross(cross(newquadcorner,
quat.xyz) + quat.w * newquadcorner, quat.xyz);

View File

@ -32,7 +32,8 @@
// ============================================================================
/** A Shader to render particles.
*/
class ParticleRenderer : public TextureShader<ParticleRenderer, 2, int, float>
class ParticleRenderer : public TextureShader
<ParticleRenderer, 2, int, int, core::vector3df, float>
{
public:
ParticleRenderer()
@ -40,7 +41,7 @@ public:
loadProgram(PARTICLES_RENDERING,
GL_VERTEX_SHADER, "simple_particle.vert",
GL_FRAGMENT_SHADER, "simple_particle.frag");
assignUniforms("flips", "billboard");
assignUniforms("flips", "sky", "view_position", "billboard");
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED,
1, "dtex", ST_NEAREST_FILTERED);
} // ParticleRenderer
@ -50,7 +51,7 @@ public:
/** A Shader to render alpha-test particles.
*/
class AlphaTestParticleRenderer : public TextureShader
<AlphaTestParticleRenderer, 1, int, float>
<AlphaTestParticleRenderer, 1, int, int, core::vector3df, float>
{
public:
AlphaTestParticleRenderer()
@ -58,7 +59,7 @@ public:
loadProgram(PARTICLES_RENDERING,
GL_VERTEX_SHADER, "alphatest_particle.vert",
GL_FRAGMENT_SHADER, "alphatest_particle.frag");
assignUniforms("flips", "billboard");
assignUniforms("flips", "sky", "view_position", "billboard");
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED);
} // AlphaTestParticleRenderer
}; // AlphaTestParticleRenderer
@ -93,6 +94,10 @@ void CPUParticleManager::addParticleNode(STKParticle* node)
{
m_flips_material.insert(tex_name);
}
else if (node->isSkyParticle())
{
m_sky_material.insert(tex_name);
}
m_particles_queue[tex_name].push_back(node);
} // addParticleNode
@ -324,9 +329,15 @@ void CPUParticleManager::drawAll()
});
std::string shader_name;
core::vector3df view_position;
scene::ICameraSceneNode* cam = irr_driver->getSceneManager()
->getActiveCamera();
if (cam)
view_position = cam->getPosition();
for (auto& p : particle_drawn)
{
const bool flips = isFlipsMaterial(p.second);
const bool sky = m_sky_material.find(p.second) != m_sky_material.end();
const float billboard = p.second.substr(0, 4) == "_bb_" ? 1.0f : 0.0f;
Material* cur_mat = p.first;
if (cur_mat->getShaderName() != shader_name)
@ -372,14 +383,15 @@ void CPUParticleManager::drawAll()
(cur_mat->getTexture()->getTextureHandler(),
CVS->isDeferredEnabled() ?
irr_driver->getDepthStencilTexture() : 0);
ParticleRenderer::getInstance()->setUniforms(flips, billboard);
ParticleRenderer::getInstance()->setUniforms(flips, sky,
view_position, billboard);
}
else
{
AlphaTestParticleRenderer::getInstance()->setTextureUnits
(cur_mat->getTexture()->getTextureHandler());
AlphaTestParticleRenderer::getInstance()->setUniforms(flips,
billboard);
AlphaTestParticleRenderer::getInstance()->setUniforms(flips, sky,
view_position, billboard);
}
glBindVertexArray(m_gl_particles.at(p.second)->m_vao);
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4,

View File

@ -89,7 +89,7 @@ private:
std::unordered_map<std::string, Material*> m_material_map;
std::unordered_set<std::string> m_flips_material;
std::unordered_set<std::string> m_flips_material, m_sky_material;
static GLuint m_particle_quad;
@ -137,6 +137,7 @@ public:
{
m_material_map.clear();
m_flips_material.clear();
m_sky_material.clear();
}
};