168 lines
3.0 KiB
GLSL
168 lines
3.0 KiB
GLSL
[vertex]
|
|
|
|
|
|
|
|
layout(location=0) in highp vec4 color;
|
|
layout(location=1) in highp vec4 velocity_active;
|
|
layout(location=2) in highp vec4 custom;
|
|
layout(location=3) in highp vec4 xform_1;
|
|
layout(location=4) in highp vec4 xform_2;
|
|
layout(location=5) in highp vec4 xform_3;
|
|
|
|
|
|
struct Attractor {
|
|
|
|
vec3 pos;
|
|
vec3 dir;
|
|
float radius;
|
|
float eat_radius;
|
|
float strength;
|
|
float attenuation;
|
|
};
|
|
|
|
#define MAX_ATTRACTORS 64
|
|
|
|
uniform mat4 origin;
|
|
uniform float system_phase;
|
|
uniform float prev_system_phase;
|
|
uniform float total_particles;
|
|
uniform float explosiveness;
|
|
uniform vec4 time;
|
|
uniform float delta;
|
|
uniform vec3 gravity;
|
|
uniform int attractor_count;
|
|
uniform Attractor attractors[MAX_ATTRACTORS];
|
|
|
|
|
|
out highp vec4 out_color; //tfb:
|
|
out highp vec4 out_velocity_active; //tfb:
|
|
out highp vec4 out_custom; //tfb:
|
|
out highp vec4 out_xform_1; //tfb:
|
|
out highp vec4 out_xform_2; //tfb:
|
|
out highp vec4 out_xform_3; //tfb:
|
|
|
|
VERTEX_SHADER_GLOBALS
|
|
|
|
#if defined(USE_MATERIAL)
|
|
|
|
layout(std140) uniform UniformData { //ubo:0
|
|
|
|
MATERIAL_UNIFORMS
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
void main() {
|
|
|
|
bool apply_forces=true;
|
|
bool apply_velocity=true;
|
|
|
|
float mass = 1.0;
|
|
|
|
float restart_phase = float(gl_InstanceID)/total_particles;
|
|
restart_phase*= explosiveness;
|
|
bool restart=false;
|
|
bool active = out_velocity_active.a > 0.5;
|
|
|
|
if (system_phase > prev_system_phase) {
|
|
restart = prev_system_phase < restart_phase && system_phase >= restart_phase;
|
|
} else {
|
|
restart = prev_system_phase < restart_phase || system_phase >= restart_phase;
|
|
}
|
|
|
|
if (restart) {
|
|
active=true;
|
|
}
|
|
|
|
out_color=color;
|
|
out_velocity_active=velocity_active;
|
|
out_custom=custom;
|
|
|
|
mat4 xform = transpose(mat4(xform_1,xform_2,xform_3,vec4(vec3(0.0),1.0)));
|
|
|
|
|
|
out_rot_active=rot_active;
|
|
|
|
if (active) {
|
|
//execute shader
|
|
|
|
{
|
|
VERTEX_SHADER_CODE
|
|
}
|
|
|
|
#if !defined(DISABLE_FORCE)
|
|
|
|
{
|
|
|
|
vec3 force = gravity;
|
|
for(int i=0;i<attractor_count;i++) {
|
|
|
|
vec3 rel_vec = out_pos_lifetime.xyz - attractors[i].pos;
|
|
float dist = rel_vec.length();
|
|
if (attractors[i].radius < dist)
|
|
continue;
|
|
if (attractors[i].eat_radius>0 && attractors[i].eat_radius > dist) {
|
|
out_velocity_active.a=0.0;
|
|
}
|
|
|
|
rel_vec = normalize(rel_vec);
|
|
|
|
float attenuation = pow(dist / attractors[i].radius,attractors[i].attenuation);
|
|
|
|
if (attractors[i].dir==vec3(0.0)) {
|
|
//towards center
|
|
force+=attractors[i].strength * rel_vec * attenuation * mass;
|
|
} else {
|
|
force+=attractors[i].strength * attractors[i].dir * attenuation *mass;
|
|
|
|
}
|
|
}
|
|
|
|
out_velocity_seed.xyz += force * delta;
|
|
}
|
|
#endif
|
|
|
|
#if !defined(DISABLE_VELOCITY)
|
|
|
|
{
|
|
|
|
out_pos_lifetime.xyz += out_velocity_seed.xyz * delta;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
xform = transpose(xform);
|
|
|
|
out_velocity_active.a = mix(0.0,1.0,active);
|
|
|
|
out_xform_1 = xform[0];
|
|
out_xform_2 = xform[1];
|
|
out_xform_3 = xform[2];
|
|
|
|
|
|
}
|
|
|
|
[fragment]
|
|
|
|
//any code here is never executed, stuff is filled just so it works
|
|
|
|
FRAGMENT_SHADER_GLOBALS
|
|
|
|
#if defined(USE_MATERIAL)
|
|
|
|
layout(std140) uniform UniformData {
|
|
|
|
MATERIAL_UNIFORMS
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
void main() {
|
|
|
|
{
|
|
FRAGMENT_SHADER_CODE
|
|
}
|
|
}
|