442 lines
		
	
	
	
		
			17 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			442 lines
		
	
	
	
		
			17 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| // NOTE: Shader automatically converted from Godot Engine 4.3.stable's ParticleProcessMaterial.
 | |
| 
 | |
| shader_type particles;
 | |
| render_mode disable_velocity;
 | |
| 
 | |
| uniform vec3 direction;
 | |
| uniform float spread;
 | |
| uniform float flatness;
 | |
| uniform float inherit_emitter_velocity_ratio = 0.0;
 | |
| uniform float initial_linear_velocity_min;
 | |
| uniform float initial_linear_velocity_max;
 | |
| uniform float directional_velocity_min;
 | |
| uniform float directional_velocity_max;
 | |
| uniform float angular_velocity_min;
 | |
| uniform float angular_velocity_max;
 | |
| uniform float orbit_velocity_min;
 | |
| uniform float orbit_velocity_max;
 | |
| uniform float radial_velocity_min;
 | |
| uniform float radial_velocity_max;
 | |
| uniform float linear_accel_min;
 | |
| uniform float linear_accel_max;
 | |
| uniform float radial_accel_min;
 | |
| uniform float radial_accel_max;
 | |
| uniform float tangent_accel_min;
 | |
| uniform float tangent_accel_max;
 | |
| uniform float damping_min;
 | |
| uniform float damping_max;
 | |
| uniform float initial_angle_min;
 | |
| uniform float initial_angle_max;
 | |
| uniform float scale_min;
 | |
| uniform float scale_max;
 | |
| uniform float hue_variation_min;
 | |
| uniform float hue_variation_max;
 | |
| uniform float anim_speed_min;
 | |
| uniform float anim_speed_max;
 | |
| uniform float anim_offset_min;
 | |
| uniform float anim_offset_max;
 | |
| uniform float lifetime_randomness;
 | |
| uniform vec3 emission_shape_offset = vec3(0.0);
 | |
| uniform vec3 emission_shape_scale = vec3(1.0);
 | |
| uniform vec3 velocity_pivot = vec3(0.0);
 | |
| uniform vec4 color_value : source_color;
 | |
| uniform vec3 gravity;
 | |
| uniform sampler2D color_ramp : repeat_disable;
 | |
| uniform float turbulence_noise_strength;
 | |
| uniform float turbulence_noise_scale;
 | |
| uniform float turbulence_influence_min;
 | |
| uniform float turbulence_influence_max;
 | |
| uniform float turbulence_initial_displacement_min;
 | |
| uniform float turbulence_initial_displacement_max;
 | |
| uniform float turbulence_noise_speed_random;
 | |
| uniform vec3 turbulence_noise_speed = vec3(1.0, 1.0, 1.0);
 | |
| 
 | |
| // Functions for 3D noise / turbulence.
 | |
| vec4 grad(vec4 p) {
 | |
| 	p = fract(vec4(
 | |
| 			dot(p, vec4(0.143081, 0.001724, 0.280166, 0.262771)),
 | |
| 			dot(p, vec4(0.645401, -0.047791, -0.146698, 0.595016)),
 | |
| 			dot(p, vec4(-0.499665, -0.095734, 0.425674, -0.207367)),
 | |
| 			dot(p, vec4(-0.013596, -0.848588, 0.423736, 0.17044))));
 | |
| 	return fract((p.xyzw * p.yzwx) * 2365.952041) * 2.0 - 1.0;
 | |
| }
 | |
| 
 | |
| float noise(vec4 coord) {
 | |
| 	// Domain rotation to improve the look of XYZ slices + animation patterns.
 | |
| 	coord = vec4(
 | |
| 			coord.xyz + dot(coord, vec4(vec3(-0.1666667), -0.5)),
 | |
| 			dot(coord, vec4(0.5)));
 | |
| 
 | |
| 	vec4 base = floor(coord), delta = coord - base;
 | |
| 
 | |
| 	vec4 grad_0000 = grad(base + vec4(0.0, 0.0, 0.0, 0.0)), grad_1000 = grad(base + vec4(1.0, 0.0, 0.0, 0.0));
 | |
| 	vec4 grad_0100 = grad(base + vec4(0.0, 1.0, 0.0, 0.0)), grad_1100 = grad(base + vec4(1.0, 1.0, 0.0, 0.0));
 | |
| 	vec4 grad_0010 = grad(base + vec4(0.0, 0.0, 1.0, 0.0)), grad_1010 = grad(base + vec4(1.0, 0.0, 1.0, 0.0));
 | |
| 	vec4 grad_0110 = grad(base + vec4(0.0, 1.0, 1.0, 0.0)), grad_1110 = grad(base + vec4(1.0, 1.0, 1.0, 0.0));
 | |
| 	vec4 grad_0001 = grad(base + vec4(0.0, 0.0, 0.0, 1.0)), grad_1001 = grad(base + vec4(1.0, 0.0, 0.0, 1.0));
 | |
| 	vec4 grad_0101 = grad(base + vec4(0.0, 1.0, 0.0, 1.0)), grad_1101 = grad(base + vec4(1.0, 1.0, 0.0, 1.0));
 | |
| 	vec4 grad_0011 = grad(base + vec4(0.0, 0.0, 1.0, 1.0)), grad_1011 = grad(base + vec4(1.0, 0.0, 1.0, 1.0));
 | |
| 	vec4 grad_0111 = grad(base + vec4(0.0, 1.0, 1.0, 1.0)), grad_1111 = grad(base + vec4(1.0, 1.0, 1.0, 1.0));
 | |
| 
 | |
| 	vec4 result_0123 = vec4(
 | |
| 			dot(delta - vec4(0.0, 0.0, 0.0, 0.0), grad_0000), dot(delta - vec4(1.0, 0.0, 0.0, 0.0), grad_1000),
 | |
| 			dot(delta - vec4(0.0, 1.0, 0.0, 0.0), grad_0100), dot(delta - vec4(1.0, 1.0, 0.0, 0.0), grad_1100));
 | |
| 	vec4 result_4567 = vec4(
 | |
| 			dot(delta - vec4(0.0, 0.0, 1.0, 0.0), grad_0010), dot(delta - vec4(1.0, 0.0, 1.0, 0.0), grad_1010),
 | |
| 			dot(delta - vec4(0.0, 1.0, 1.0, 0.0), grad_0110), dot(delta - vec4(1.0, 1.0, 1.0, 0.0), grad_1110));
 | |
| 	vec4 result_89AB = vec4(
 | |
| 			dot(delta - vec4(0.0, 0.0, 0.0, 1.0), grad_0001), dot(delta - vec4(1.0, 0.0, 0.0, 1.0), grad_1001),
 | |
| 			dot(delta - vec4(0.0, 1.0, 0.0, 1.0), grad_0101), dot(delta - vec4(1.0, 1.0, 0.0, 1.0), grad_1101));
 | |
| 	vec4 result_CDEF = vec4(
 | |
| 			dot(delta - vec4(0.0, 0.0, 1.0, 1.0), grad_0011), dot(delta - vec4(1.0, 0.0, 1.0, 1.0), grad_1011),
 | |
| 			dot(delta - vec4(0.0, 1.0, 1.0, 1.0), grad_0111), dot(delta - vec4(1.0, 1.0, 1.0, 1.0), grad_1111));
 | |
| 
 | |
| 	vec4 fade = delta * delta * delta * (10.0 + delta * (-15.0 + delta * 6.0));
 | |
| 	vec4 result_W0 = mix(result_0123, result_89AB, fade.w), result_W1 = mix(result_4567, result_CDEF, fade.w);
 | |
| 	vec4 result_WZ = mix(result_W0, result_W1, fade.z);
 | |
| 	vec2 result_WZY = mix(result_WZ.xy, result_WZ.zw, fade.y);
 | |
| 	return mix(result_WZY.x, result_WZY.y, fade.x);
 | |
| }
 | |
| 
 | |
| // Curl 3D and three-noise function with friendly permission by Isaac Cohen.
 | |
| // Modified to accept 4D noise.
 | |
| vec3 noise_3x(vec4 p) {
 | |
| 	float s = noise(p);
 | |
| 	float s1 = noise(p + vec4(vec3(0.0), 1.7320508 * 2048.333333));
 | |
| 	float s2 = noise(p - vec4(vec3(0.0), 1.7320508 * 2048.333333));
 | |
| 	vec3 c = vec3(s, s1, s2);
 | |
| 	return c;
 | |
| }
 | |
| 
 | |
| vec3 curl_3d(vec4 p, float c) {
 | |
| 	float epsilon = 0.001 + c;
 | |
| 	vec4 dx = vec4(epsilon, 0.0, 0.0, 0.0);
 | |
| 	vec4 dy = vec4(0.0, epsilon, 0.0, 0.0);
 | |
| 	vec4 dz = vec4(0.0, 0.0, epsilon, 0.0);
 | |
| 	vec3 x0 = noise_3x(p - dx).xyz;
 | |
| 	vec3 x1 = noise_3x(p + dx).xyz;
 | |
| 	vec3 y0 = noise_3x(p - dy).xyz;
 | |
| 	vec3 y1 = noise_3x(p + dy).xyz;
 | |
| 	vec3 z0 = noise_3x(p - dz).xyz;
 | |
| 	vec3 z1 = noise_3x(p + dz).xyz;
 | |
| 	float x = (y1.z - y0.z) - (z1.y - z0.y);
 | |
| 	float y = (z1.x - z0.x) - (x1.z - x0.z);
 | |
| 	float z = (x1.y - x0.y) - (y1.x - y0.x);
 | |
| 	return normalize(vec3(x, y, z));
 | |
| }
 | |
| 
 | |
| vec3 get_noise_direction(vec3 pos) {
 | |
| 	float adj_contrast = max((turbulence_noise_strength - 1.0), 0.0) * 70.0;
 | |
| 	vec4 noise_time = TIME * vec4(turbulence_noise_speed, turbulence_noise_speed_random);
 | |
| 	vec4 noise_pos = vec4(pos * turbulence_noise_scale, 0.0);
 | |
| 	vec3 noise_direction = curl_3d(noise_pos + noise_time, adj_contrast);
 | |
| 	noise_direction = mix(0.9 * noise_direction, noise_direction, turbulence_noise_strength - 9.0);
 | |
| 	return noise_direction;
 | |
| }
 | |
| 
 | |
| vec4 rotate_hue(vec4 current_color, float hue_rot_angle) {
 | |
| 	float hue_rot_c = cos(hue_rot_angle);
 | |
| 	float hue_rot_s = sin(hue_rot_angle);
 | |
| 	mat4 hue_rot_mat =
 | |
| 			mat4(vec4(0.299, 0.587, 0.114, 0.0),
 | |
| 					vec4(0.299, 0.587, 0.114, 0.0),
 | |
| 					vec4(0.299, 0.587, 0.114, 0.0),
 | |
| 					vec4(0.000, 0.000, 0.000, 1.0)) +
 | |
| 			mat4(vec4(0.701, -0.587, -0.114, 0.0),
 | |
| 					vec4(-0.299, 0.413, -0.114, 0.0),
 | |
| 					vec4(-0.300, -0.588, 0.886, 0.0),
 | |
| 					vec4(0.000, 0.000, 0.000, 0.0)) *
 | |
| 					hue_rot_c +
 | |
| 			mat4(vec4(0.168, 0.330, -0.497, 0.0),
 | |
| 					vec4(-0.328, 0.035, 0.292, 0.0),
 | |
| 					vec4(1.250, -1.050, -0.203, 0.0),
 | |
| 					vec4(0.000, 0.000, 0.000, 0.0)) *
 | |
| 					hue_rot_s;
 | |
| 	return hue_rot_mat * current_color;
 | |
| }
 | |
| 
 | |
| float rand_from_seed(inout uint seed) {
 | |
| 	int k;
 | |
| 	int s = int(seed);
 | |
| 	if (s == 0) {
 | |
| 		s = 305420679;
 | |
| 	}
 | |
| 	k = s / 127773;
 | |
| 	s = 16807 * (s - k * 127773) - 2836 * k;
 | |
| 	if (s < 0) {
 | |
| 		s += 2147483647;
 | |
| 	}
 | |
| 	seed = uint(s);
 | |
| 	return float(seed % uint(65536)) / 65535.0;
 | |
| }
 | |
| 
 | |
| float rand_from_seed_m1_p1(inout uint seed) {
 | |
| 	return rand_from_seed(seed) * 2.0 - 1.0;
 | |
| }
 | |
| 
 | |
| uint hash(uint x) {
 | |
| 	x = ((x >> uint(16)) ^ x) * uint(73244475);
 | |
| 	x = ((x >> uint(16)) ^ x) * uint(73244475);
 | |
| 	x = (x >> uint(16)) ^ x;
 | |
| 	return x;
 | |
| }
 | |
| 
 | |
| struct DisplayParameters {
 | |
| 	vec3 scale;
 | |
| 	float hue_rotation;
 | |
| 	float animation_speed;
 | |
| 	float animation_offset;
 | |
| 	float lifetime;
 | |
| 	vec4 color;
 | |
| };
 | |
| 
 | |
| struct DynamicsParameters {
 | |
| 	float angle;
 | |
| 	float angular_velocity;
 | |
| 	float initial_velocity_multiplier;
 | |
| 	float directional_velocity;
 | |
| 	float radial_velocity;
 | |
| 	float orbit_velocity;
 | |
| 	float turb_influence;
 | |
| };
 | |
| 
 | |
| struct PhysicalParameters {
 | |
| 	float linear_accel;
 | |
| 	float radial_accel;
 | |
| 	float tangent_accel;
 | |
| 	float damping;
 | |
| };
 | |
| 
 | |
| void calculate_initial_physical_params(inout PhysicalParameters params, inout uint alt_seed) {
 | |
| 	params.linear_accel = mix(linear_accel_min, linear_accel_max, rand_from_seed(alt_seed));
 | |
| 	params.radial_accel = mix(radial_accel_min, radial_accel_max, rand_from_seed(alt_seed));
 | |
| 	params.tangent_accel = mix(tangent_accel_min, tangent_accel_max, rand_from_seed(alt_seed));
 | |
| 	params.damping = mix(damping_min, damping_max, rand_from_seed(alt_seed));
 | |
| }
 | |
| 
 | |
| void calculate_initial_dynamics_params(inout DynamicsParameters params, inout uint alt_seed) {
 | |
| 	// -------------------- DO NOT REORDER OPERATIONS, IT BREAKS VISUAL COMPATIBILITY
 | |
| 	// -------------------- ADD NEW OPERATIONS AT THE BOTTOM
 | |
| 	params.angle = mix(initial_angle_min, initial_angle_max, rand_from_seed(alt_seed));
 | |
| 	params.angular_velocity = mix(angular_velocity_min, angular_velocity_max, rand_from_seed(alt_seed));
 | |
| 	params.initial_velocity_multiplier = mix(initial_linear_velocity_min, initial_linear_velocity_max, rand_from_seed(alt_seed));
 | |
| 	params.directional_velocity = mix(directional_velocity_min, directional_velocity_max, rand_from_seed(alt_seed));
 | |
| 	params.radial_velocity = mix(radial_velocity_min, radial_velocity_max, rand_from_seed(alt_seed));
 | |
| 	params.orbit_velocity = mix(orbit_velocity_min, orbit_velocity_max, rand_from_seed(alt_seed));
 | |
| 	params.turb_influence = mix(turbulence_influence_min, turbulence_influence_max, rand_from_seed(alt_seed));
 | |
| }
 | |
| 
 | |
| void calculate_initial_display_params(inout DisplayParameters params, inout uint alt_seed) {
 | |
| 	// -------------------- DO NOT REORDER OPERATIONS, IT BREAKS VISUAL COMPATIBILITY
 | |
| 	// -------------------- ADD NEW OPERATIONS AT THE BOTTOM
 | |
| 	float pi = 3.14159;
 | |
| 	params.scale = vec3(mix(scale_min, scale_max, rand_from_seed(alt_seed)));
 | |
| 	params.scale = sign(params.scale) * max(abs(params.scale), 0.001);
 | |
| 	params.hue_rotation = pi * 2.0 * mix(hue_variation_min, hue_variation_max, rand_from_seed(alt_seed));
 | |
| 	params.animation_speed = mix(anim_speed_min, anim_speed_max, rand_from_seed(alt_seed));
 | |
| 	params.animation_offset = mix(anim_offset_min, anim_offset_max, rand_from_seed(alt_seed));
 | |
| 	params.lifetime = (1.0 - lifetime_randomness * rand_from_seed(alt_seed));
 | |
| 	params.color = color_value;
 | |
| }
 | |
| 
 | |
| void process_display_param(inout DisplayParameters parameters, float lifetime) {
 | |
| 	// Compile-time add textures.
 | |
| 	parameters.color *= texture(color_ramp, vec2(lifetime));
 | |
| 	parameters.color = rotate_hue(parameters.color, parameters.hue_rotation);
 | |
| }
 | |
| 
 | |
| vec3 calculate_initial_position(inout uint alt_seed) {
 | |
| 	float pi = 3.14159;
 | |
| 	vec3 pos = vec3(0.0);
 | |
| 	{ // Emission shape.
 | |
| 	 	pos = vec3(0.0);
 | |
| 	}
 | |
| 	return pos * emission_shape_scale + emission_shape_offset;
 | |
| }
 | |
| 
 | |
| vec3 get_random_direction_from_spread(inout uint alt_seed, float spread_angle) {
 | |
| 	float pi = 3.14159;
 | |
| 	float degree_to_rad = pi / 180.0;
 | |
| 	float spread_rad = spread_angle * degree_to_rad;
 | |
| 	float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;
 | |
| 	float angle2_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);
 | |
| 	vec3 direction_xz = vec3(sin(angle1_rad), 0.0, cos(angle1_rad));
 | |
| 	vec3 direction_yz = vec3(0.0, sin(angle2_rad), cos(angle2_rad));
 | |
| 	direction_yz.z = direction_yz.z / max(0.0001, sqrt(abs(direction_yz.z))); // Better uniform distribution.
 | |
| 	vec3 spread_direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);
 | |
| 	vec3 direction_nrm = length(direction) > 0.0 ? normalize(direction) : vec3(0.0, 0.0, 1.0);
 | |
| 	// Rotate spread to direction.
 | |
| 	vec3 binormal = cross(vec3(0.0, 1.0, 0.0), direction_nrm);
 | |
| 	if (length(binormal) < 0.0001) {
 | |
| 		// Direction is parallel to Y. Choose Z as the binormal.
 | |
| 		binormal = vec3(0.0, 0.0, 1.0);
 | |
| 	}
 | |
| 	binormal = normalize(binormal);
 | |
| 	vec3 normal = cross(binormal, direction_nrm);
 | |
| 	spread_direction = binormal * spread_direction.x + normal * spread_direction.y + direction_nrm * spread_direction.z;
 | |
| 	return normalize(spread_direction);
 | |
| }
 | |
| 
 | |
| vec3 process_radial_displacement(DynamicsParameters param, float lifetime, inout uint alt_seed, mat4 transform, mat4 emission_transform, float delta) {
 | |
| 	vec3 radial_displacement = vec3(0.0);
 | |
| 	if (delta < 0.001) {
 | |
| 		return radial_displacement;
 | |
| 	}
 | |
| 	float radial_displacement_multiplier = 1.0;
 | |
| 	vec3 global_pivot = (emission_transform * vec4(velocity_pivot, 1.0)).xyz;
 | |
| 	if (length(transform[3].xyz - global_pivot) > 0.01) {
 | |
| 		radial_displacement = normalize(transform[3].xyz - global_pivot) * radial_displacement_multiplier * param.radial_velocity;
 | |
| 	} else {
 | |
| 		radial_displacement = get_random_direction_from_spread(alt_seed, 360.0) * param.radial_velocity;
 | |
| 	}
 | |
| 	if (radial_displacement_multiplier * param.radial_velocity < 0.0) {
 | |
| 		// Prevent inwards velocity to flicker once the point is reached.
 | |
| 		radial_displacement = normalize(radial_displacement) * min(abs(radial_displacement_multiplier * param.radial_velocity), length(transform[3].xyz - global_pivot) / delta);
 | |
| 	}
 | |
| 	return radial_displacement;
 | |
| }
 | |
| 
 | |
| void process_physical_parameters(inout PhysicalParameters params, float lifetime_percent) {
 | |
| }
 | |
| 
 | |
| void start() {
 | |
| 	uint base_number = NUMBER;
 | |
| 	uint alt_seed = hash(base_number + uint(1) + RANDOM_SEED);
 | |
| 	DisplayParameters params;
 | |
| 	calculate_initial_display_params(params, alt_seed);
 | |
| 	// Reset alt seed?
 | |
| 	//alt_seed = hash(base_number + uint(1) + RANDOM_SEED);
 | |
| 	DynamicsParameters dynamic_params;
 | |
| 	calculate_initial_dynamics_params(dynamic_params, alt_seed);
 | |
| 	PhysicalParameters physics_params;
 | |
| 	calculate_initial_physical_params(physics_params, alt_seed);
 | |
| 	process_display_param(params, 0.0);
 | |
| 	if (rand_from_seed(alt_seed) > AMOUNT_RATIO) {
 | |
| 		ACTIVE = false;
 | |
| 	}
 | |
| 
 | |
| 	if (RESTART_CUSTOM) {
 | |
| 		CUSTOM = vec4(0.0);
 | |
| 		CUSTOM.w = params.lifetime;
 | |
| 		CUSTOM.x = dynamic_params.angle;
 | |
| 	}
 | |
| 	if (RESTART_COLOR) {
 | |
| 		COLOR = params.color;
 | |
| 	}
 | |
| 	if (RESTART_ROT_SCALE) {
 | |
| 		TRANSFORM[0].xyz = vec3(1.0, 0.0, 0.0);
 | |
| 		TRANSFORM[1].xyz = vec3(0.0, 1.0, 0.0);
 | |
| 		TRANSFORM[2].xyz = vec3(0.0, 0.0, 1.0);
 | |
| 	}
 | |
| 	if (RESTART_POSITION) {
 | |
| 		TRANSFORM[3].xyz = calculate_initial_position(alt_seed);
 | |
| 		float initial_turbulence_displacement = mix(turbulence_initial_displacement_min, turbulence_initial_displacement_max, rand_from_seed(alt_seed));
 | |
| 		vec3 noise_direction = get_noise_direction(TRANSFORM[3].xyz);
 | |
| 		TRANSFORM[3].xyz += noise_direction * initial_turbulence_displacement;
 | |
| 		TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;
 | |
| 	}
 | |
| 	if (RESTART_VELOCITY) {
 | |
| 		VELOCITY = get_random_direction_from_spread(alt_seed, spread) * dynamic_params.initial_velocity_multiplier;
 | |
| 	}
 | |
| 
 | |
| 	process_display_param(params, 0.0);
 | |
| 
 | |
| 	VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;
 | |
| 	VELOCITY += EMITTER_VELOCITY * inherit_emitter_velocity_ratio;
 | |
| }
 | |
| 
 | |
| void process() {
 | |
| 	uint base_number = NUMBER;
 | |
| 	//if (repeatable) {
 | |
| 	//	base_number = INDEX;
 | |
| 	//}
 | |
| 	uint alt_seed = hash(base_number + uint(1) + RANDOM_SEED);
 | |
| 	DisplayParameters params;
 | |
| 	calculate_initial_display_params(params, alt_seed);
 | |
| 	DynamicsParameters dynamic_params;
 | |
| 	calculate_initial_dynamics_params(dynamic_params, alt_seed);
 | |
| 	PhysicalParameters physics_params;
 | |
| 	calculate_initial_physical_params(physics_params, alt_seed);
 | |
| 
 | |
| 	float pi = 3.14159;
 | |
| 	float degree_to_rad = pi / 180.0;
 | |
| 
 | |
| 	CUSTOM.y += DELTA / LIFETIME;
 | |
| 	CUSTOM.y = mix(CUSTOM.y, 1.0, INTERPOLATE_TO_END);
 | |
| 	float lifetime_percent = CUSTOM.y / params.lifetime;
 | |
| 	if (CUSTOM.y > CUSTOM.w) {
 | |
| 		ACTIVE = false;
 | |
| 	}
 | |
| 
 | |
| 	// Calculate all velocity.
 | |
| 	vec3 controlled_displacement = vec3(0.0);
 | |
| 	controlled_displacement += process_radial_displacement(dynamic_params, lifetime_percent, alt_seed, TRANSFORM, EMISSION_TRANSFORM, DELTA);
 | |
| 
 | |
| 	process_physical_parameters(physics_params, lifetime_percent);
 | |
| 	vec3 force;
 | |
| 	{
 | |
| 		// Copied from previous version.
 | |
| 		vec3 pos = TRANSFORM[3].xyz;
 | |
| 		force = gravity;
 | |
| 		// Apply linear acceleration.
 | |
| 		force += length(VELOCITY) > 0.0 ? normalize(VELOCITY) * physics_params.linear_accel : vec3(0.0);
 | |
| 		// Apply radial acceleration.
 | |
| 		vec3 org = EMISSION_TRANSFORM[3].xyz;
 | |
| 		vec3 diff = pos - org;
 | |
| 		force += length(diff) > 0.0 ? normalize(diff) * physics_params.radial_accel : vec3(0.0);
 | |
| 		// Apply tangential acceleration.
 | |
| 		float tangent_accel_val = physics_params.tangent_accel;
 | |
| 		vec3 crossDiff = cross(normalize(diff), normalize(gravity));
 | |
| 		force += length(crossDiff) > 0.0 ? normalize(crossDiff) * tangent_accel_val : vec3(0.0);
 | |
| 		force += ATTRACTOR_FORCE;
 | |
| 		// Apply attractor forces.
 | |
| 		VELOCITY += force * DELTA;
 | |
| 	}
 | |
| 	{
 | |
| 		// Copied from previous version.
 | |
| 		if (physics_params.damping > 0.0) {
 | |
| 			float v = length(VELOCITY);
 | |
| 			v -= physics_params.damping * DELTA;
 | |
| 			if (v < 0.0) {
 | |
| 				VELOCITY = vec3(0.0);
 | |
| 			} else {
 | |
| 				VELOCITY = normalize(VELOCITY) * v;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// Turbulence before limiting.
 | |
| 	float turbulence_influence = 1.0;
 | |
| 
 | |
| 	vec3 noise_direction = get_noise_direction(TRANSFORM[3].xyz);
 | |
| 	{
 | |
| 		float vel_mag = length(VELOCITY);
 | |
| 		float vel_infl = clamp(dynamic_params.turb_influence * turbulence_influence, 0.0, 1.0);
 | |
| 		VELOCITY = mix(VELOCITY, normalize(noise_direction) * vel_mag * (1.0 + (1.0 - vel_infl) * 0.2), vel_infl);
 | |
| 		vel_mag = length(controlled_displacement);
 | |
| 		controlled_displacement = mix(controlled_displacement, normalize(noise_direction) * vel_mag * (1.0 + (1.0 - vel_infl) * 0.2), vel_infl);
 | |
| 	}
 | |
| 	vec3 final_velocity = controlled_displacement + VELOCITY;
 | |
| 
 | |
| 	TRANSFORM[3].xyz += final_velocity * DELTA;
 | |
| 
 | |
| 	process_display_param(params, lifetime_percent);
 | |
| 
 | |
| 	float base_angle = dynamic_params.angle;
 | |
| 	base_angle += CUSTOM.y * LIFETIME * dynamic_params.angular_velocity;
 | |
| 	CUSTOM.x = base_angle * degree_to_rad;
 | |
| 	COLOR = params.color;
 | |
| 
 | |
| 	TRANSFORM[0].xyz = normalize(TRANSFORM[0].xyz);
 | |
| 	TRANSFORM[1].xyz = normalize(TRANSFORM[1].xyz);
 | |
| 	TRANSFORM[2].xyz = normalize(TRANSFORM[2].xyz);
 | |
| 	TRANSFORM[0].xyz *= sign(params.scale.x) * max(abs(params.scale.x), 0.001);
 | |
| 	TRANSFORM[1].xyz *= sign(params.scale.y) * max(abs(params.scale.y), 0.001);
 | |
| 	TRANSFORM[2].xyz *= sign(params.scale.z) * max(abs(params.scale.z), 0.001);
 | |
| 
 | |
| 	CUSTOM.z = params.animation_offset + lifetime_percent * params.animation_speed;
 | |
| 
 | |
| 	if (CUSTOM.y > CUSTOM.w) {
 | |
| 		ACTIVE = false;
 | |
| 	}
 | |
| }
 |