gamnit :: ParticleProgram :: defaultinit
# Particle drawing program using `gl_POINTS`
#
# This program should be subclassed to create custom particle effects.
# Either `vertex_shader_source` and `vertex_shader_core` can be refined.
class ParticleProgram
super GamnitProgramFromSource
redef var vertex_shader_source = """
// Coordinates of particle effects
attribute vec4 center;
// Particles color tint
attribute vec4 color;
varying vec4 v_color;
// Per particle scaling
attribute float scale;
// Model view projection matrix
uniform mat4 mvp;
// Time-to-live of each particle
attribute float ttl;
// Creation time of each particle
attribute float ot;
// Current time
uniform float t;
void main()
{
// Pass varyings to the fragment shader
v_color = color;
float dt = t - ot;
float pt = dt/ttl;
// Discard expired or not yet created particles
if (dt > ttl || dt < 0.0) {
gl_PointSize = 0.0;
return;
}
{{{vertex_shader_core}}}
}
"""
# Core GLSL code for `vertex_shader_source`
#
# Refine this function to easily tweak the position, size and color of particles.
#
# Reminder: Each execution of the vertex shader applies to a single particle.
#
# ## Input variables:
# * `center`: reference coordinates of the particle effect.
# This if often the center of the particle itself,
# but it can also be reference coordinates for a moving particle.
# * `mvp`: model-view-projection matrix.
# * `color`: color tint of the particle.
#
# * `t`: global seconds counter since the creation of this particle emitter.
# * `ot`: creation time of the particle, in seconds, in reference to `t`.
# * `dt`: seconds since creation of the particle.
# * `ttl`: time-to-live of the particle, in seconds.
# * `pt`: advancement of this particle in its lifetime, in `[0.0 .. 1.0]`.
#
# ## Output variables:
# * `gl_Position`: position of the particle in camera coordinates.
# * `gl_PointSize`: size of the particle in camera coordinates.
# Set to `0.0` to discard the particle.
# * `v_color`: tint applied to the particle.
# Assigned by default to the value of `color`.
#
# ## Reference implementation
#
# The default implementation apply the model-view-projection matrix on the position
# and scales according to the distance from the camera.
# Most particle effects should apply the same base logic as the default implementation.
# Here it is for reference:
#
# ~~~glsl
# gl_Position = center * mvp;
# gl_PointSize = scale / gl_Position.z;
# ~~~
fun vertex_shader_core: String do return """
gl_Position = center * mvp;
gl_PointSize = scale / gl_Position.z;
"""
redef var fragment_shader_source = """
precision mediump float;
// Input from the vertex shader
varying vec4 v_color;
// Does this particle use a texture?
uniform bool use_texture;
// Texture to apply on this particle
uniform sampler2D texture0;
void main()
{
if (use_texture) {
gl_FragColor = texture2D(texture0, gl_PointCoord) * v_color;
} else {
gl_FragColor = v_color;
}
}
""" @ glsl_fragment_shader
# Coordinates of particle effects
var center = attributes["center"].as(AttributeVec4) is lazy
# Should this program use the texture `texture`?
var use_texture = uniforms["use_texture"].as(UniformBool) is lazy
# Visible texture unit
var texture = uniforms["texture0"].as(UniformSampler2D) is lazy
# Color tint per vertex
var color = attributes["color"].as(AttributeVec4) is lazy
# Scaling per vertex
var scale = attributes["scale"].as(AttributeFloat) is lazy
# Model view projection matrix
var mvp = uniforms["mvp"].as(UniformMat4) is lazy
# Creation time of each particle
var ot = attributes["ot"].as(AttributeFloat) is lazy
# Current time
var t = uniforms["t"].as(UniformFloat) is lazy
# Time-to-live of each particle
var ttl = attributes["ttl"].as(AttributeFloat) is lazy
end
lib/gamnit/depth/particles.nit:165,1--303,3