Commit 3caaefe8 authored by Florian Oetke's avatar Florian Oetke
Browse files

working spawn direction

parent 7b80919d
{
"emitters": [{
"spawn": [
{"particles_per_second": 2000, "stddev":0, "time": 1},
{"particles_per_second": 20000, "stddev":0, "time": 1},
{"particles_per_second": 0, "stddev":0, "time": 4}
],
"spawn_loop": true,
"size": {"x":0, "y":0},
"direction": {"mean":{"elevation":0.85, "azimuth":-0.25}, "stddev":{"elevation":0.1, "azimuth":0.1}},
"ttl": {"mean": 4, "stddev": 0.5},
"velocity": {"mean": 1, "stddev": 0.0},
"velocity": {"mean": 3, "stddev": 0.6},
"emit_script_id": "comp_shader:particle_spawn_sphere",
......
......@@ -3,7 +3,7 @@
{
"time": 0,
"color": {"mean":{"hue":0}, "stddev":{"hue":0.5}},
"size": {"mean": {"x": 0.04, "y":0.15, "z":0.04}, "stddev":{"x": 0.02, "y":0.02, "z":0.02}},
"size": {"mean": {"x": 0.05, "y":0.15, "z":0.04}, "stddev":{"x": 0.04, "y":0.02, "z":0.02}},
"rotation": {"mean":{"angle":0}, "stddev":{"elevation":1, "azimuth":1, "angle": 1}},
"drag": 0.1
},
......@@ -16,7 +16,7 @@
}
],
"symmetric_scaling": false,
"symmetric_scaling": true,
"rotate_with_velocity": false,
"blend": "solid",
/*
......
......@@ -51,15 +51,23 @@ namespace mirrage::renderer {
sf2_structDef(Particle_color, hue, saturation, value, alpha);
/// angle + axis rotation with the axis expressed in spherical coordinates
/// elevation=0 and azimuth=0 is (0,0,1)
/// elevation=1 and azimuth=0 is (0,0,1) and the base-plane is XZ
struct Particle_rotation {
float elevation = 0.f; //< 0=0°, 1= 90°
float elevation = 1.f; //< 0=0°, 1= 90°
float azimuth = 0.f; //< 0=0°, 1=360°
float angle = 0.f; //< 0=0°, 1=360°
float padding;
};
sf2_structDef(Particle_rotation, elevation, azimuth, angle);
struct Particle_direction {
float elevation = 1.f;
float azimuth = 0.f;
float velocity_elevation = 1.f;
float velocity_azimuth = 0.f;
};
sf2_structDef(Particle_direction, elevation, azimuth, velocity_elevation, velocity_azimuth);
template <typename T>
struct Random_value {
T mean{};
......@@ -69,6 +77,7 @@ namespace mirrage::renderer {
sf2_structDef(Random_value<glm::vec4>, mean, stddev);
sf2_structDef(Random_value<Particle_rotation>, mean, stddev);
sf2_structDef(Random_value<Particle_color>, mean, stddev);
sf2_structDef(Random_value<Particle_direction>, mean, stddev);
/// modify velocities of living particles
......@@ -185,10 +194,9 @@ namespace mirrage::renderer {
glm::vec4 size = {0.f, 1.f, 0.f, 0.f}; // min_radius, max_radius, <ignored>, <ignored>
bool independent_direction = false; // initial velocity direction is independent of spawn position
Random_value<glm::vec4> direction = {
glm::vec4{0},
glm::vec4(glm::pi<float>())}; // elevation, azimuth, velocity-elevation, velocity-azimuth
bool direction_normal_distribution = false;
Random_value<Particle_direction> direction = {Particle_direction{},
Particle_direction{1.f, 0.5f, 1.f, 0.5f}};
bool direction_normal_distribution = false;
float parent_velocity = 0.f;
......
#include "../random.glsl"
vec3 quaternion_rotate(vec3 v, vec4 q) {
return v + 2.0 * cross(cross(v, q.xyz ) + q.w*v, q.xyz);
}
struct Random_vec4 {
vec4 mean;
vec4 stddev;
......@@ -35,23 +39,43 @@ vec4 rand_vec4(Random_vec4 range, vec4 rand) {
vec3 rand_xyz(Random_vec4 range, vec3 rand) {
return range.mean.xyz + range.stddev.xyz*rand;
}
vec3 rand_dir(vec2 mean_angles, vec2 stddev_angles, vec2 rand) {
vec2 angles = mean_angles + stddev_angles * rand;
return vec3(sin(angles.x)*cos(angles.y),
sin(angles.x)*sin(angles.y),
cos(angles.x));
}
vec4 rand_quat(Random_vec4 range, vec3 rand) {
range.mean *= vec4(0.5, 1, 1, 1) * 3.14159265359;
range.stddev *= vec4(0.5, 1, 1, 1) * 3.14159265359;
vec3 axis = rand_dir(range.mean.xy, range.stddev.xy, rand.xy);
vec2 angles = range.mean.xy + range.stddev.xy * rand.xy;
vec3 axis = vec3(cos(angles.x)*cos(angles.y),
cos(angles.x)*sin(angles.y),
sin(angles.x)).xzy;
float angle = range.mean.z + range.stddev.z * rand.z;
float half_angle = angle/2.0;
float sha = sin(half_angle);
return vec4(axis * sha, cos(half_angle));
}
vec3 rand_dir(vec2 mean_angles, vec2 stddev_angles, vec2 rand) {
vec2 rot = stddev_angles * rand*3.14159265359;
vec3 rand_dir = vec3(cos(rot.x)*cos(rot.y),
cos(rot.x)*sin(rot.y),
sin(rot.x)).xzy;
vec3 base_dir = vec3(cos(mean_angles.x)*cos(mean_angles.y),
cos(mean_angles.x)*sin(mean_angles.y),
sin(mean_angles.x)).xzy;
if(base_dir.x <= -1.0) {
rand_dir = vec3(-1, -1, 1) * rand_dir;
} else if(base_dir.x < 1.0) {
vec3 mx = normalize(base_dir);
vec3 my = normalize(cross(mx, vec3(1,0,0)));
vec3 mz = normalize(cross(mx, my));
rand_dir = mat3(mx,my,mz) * rand_dir;
}
return rand_dir;
}
struct Effector {
......@@ -110,6 +134,4 @@ struct Particle_keyframe {
uint keyframe_count; \
Particle_keyframe[] keyframes;
vec3 quaternion_rotate(vec3 v, vec4 q) {
return v + 2.0 * cross(cross(v, q.xyz ) + q.w*v, q.xyz);
}
......@@ -35,15 +35,17 @@ void main() {
vec2 r01 = normal_rand(seed, 0, 1);
float rand_ttl = rand_float(emitter_cfg.ttl, r01[0]);
float rand_vel = rand_float(emitter_cfg.velocity, r01[1]);
float rand_vel = rand_float(emitter_cfg.velocity, r01[1])*0.5 + 0.5;
pout.particles[index].position.w = rand_ttl;
pout.particles[index].velocity.w = rand_ttl;
pout.particles[index].data = uvec4(emitter_cfg.feedback_buffer_id, seed, 0, floatBitsToUint(0));
vec2 dir_mean_factor = vec2(0.5*3.14159265359, 2.0*3.14159265359);
bool dir_normal_distr = (emitter_cfg.direction_flags & 2) != 0;
vec2 r23 = dir_normal_distr ? normal_rand(seed, 2, 3) : uniform_rand(seed, 2,3)*2-1;
vec3 dir = quaternion_rotate(rand_dir(emitter_cfg.direction.mean.xy,
vec3 dir = quaternion_rotate(rand_dir(emitter_cfg.direction.mean.xy*dir_mean_factor,
emitter_cfg.direction.stddev.xy,
r23),
emitter_cfg.rotation_quat);
......@@ -51,14 +53,14 @@ void main() {
vec3 vel_dir = dir;
if((emitter_cfg.direction_flags & 1) != 0) {
vec2 r45 = dir_normal_distr ? normal_rand(seed, 4, 5) : uniform_rand(seed, 4, 5)*2-1;
vel_dir = quaternion_rotate(rand_dir(emitter_cfg.direction.mean.zw,
vel_dir = quaternion_rotate(rand_dir(emitter_cfg.direction.mean.zw*dir_mean_factor,
emitter_cfg.direction.stddev.zw,
r45),
emitter_cfg.rotation_quat);
}
float r = mix(emitter_cfg.size[0], emitter_cfg.size[1], uniform_rand(seed, 6));
vec3 pos = emitter_cfg.position.xyz + dir;
vec3 pos = emitter_cfg.position.xyz + dir*r;
vec3 velocity = vel_dir*rand_vel + emitter_cfg.parent_velocity.xyz;
// single euler step to distribute particles more evenly with bigger delta-times
......
......@@ -563,7 +563,7 @@ namespace mirrage::renderer {
glm::vec4 position;
glm::quat rotation_quat;
Random_value<glm::vec4> direction;
Random_value<Particle_direction> direction;
glm::vec2 size;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment