Prechádzať zdrojové kódy

Merge pull request #14330 from matrem/particles_spread

Spread should be in degree (see documentation, and flag_disable_z case)
Rémi Verschelde 7 rokov pred
rodič
commit
1c18943e97
1 zmenil súbory, kde vykonal 23 pridanie a 11 odobranie
  1. 23 11
      scene/3d/particles.cpp

+ 23 - 11
scene/3d/particles.cpp

@@ -598,6 +598,11 @@ void ParticlesMaterial::_update_shader() {
 	code += "}\n";
 	code += "\n";
 
+	code += "float rand_from_seed_m1_p1(inout uint seed) {\n";
+	code += "	return rand_from_seed(seed)*2.0-1.0;\n";
+	code += "}\n";
+	code += "\n";
+
 	//improve seed quality
 	code += "uint hash(uint x) {\n";
 	code += "	x = ((x >> uint(16)) ^ x) * uint(73244475);\n";
@@ -614,6 +619,8 @@ void ParticlesMaterial::_update_shader() {
 	code += "	float scale_rand = rand_from_seed(alt_seed);\n";
 	code += "	float hue_rot_rand = rand_from_seed(alt_seed);\n";
 	code += "	float anim_offset_rand = rand_from_seed(alt_seed);\n";
+	code += "	float pi = 3.14159;\n";
+	code += "	float degree_to_rad = pi / 180.0;\n";
 	code += "\n";
 
 	if (emission_shape >= EMISSION_SHAPE_POINTS) {
@@ -638,23 +645,28 @@ void ParticlesMaterial::_update_shader() {
 	else
 		code += "		float tex_anim_offset = 0.0;\n";
 
+	code += "		float spread_rad = spread*degree_to_rad;\n";
+
 	if (flags[FLAG_DISABLE_Z]) {
 
-		code += "		float angle1 = (rand_from_seed(alt_seed)*2.0-1.0)*spread/180.0*3.1416;\n";
-		code += "		vec3 rot = vec3( cos(angle1), sin(angle1),0.0 );\n";
+		code += "		float angle1_rad = rand_from_seed_m1_p1(alt_seed)*spread_rad;\n";
+		code += "		vec3 rot = vec3( cos(angle1_rad), sin(angle1_rad),0.0 );\n";
 		code += "		VELOCITY = rot*initial_linear_velocity*mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n";
 
 	} else {
 		//initiate velocity spread in 3D
-		code += "		float angle1 = rand_from_seed(alt_seed)*spread*3.1416;\n";
-		code += "		float angle2 = rand_from_seed(alt_seed)*20.0*3.1416; // make it more random like\n";
-		code += "		vec3 rot_xz = vec3( sin(angle1), 0.0, cos(angle1) );\n";
-		code += "		vec3 rot = vec3( cos(angle2)*rot_xz.x,sin(angle2)*rot_xz.x, rot_xz.z);\n";
-		code += "		VELOCITY = rot*initial_linear_velocity*mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n";
+		code += "		float angle1_rad = rand_from_seed_m1_p1(alt_seed)*spread_rad;\n";
+		code += "		float angle2_rad = rand_from_seed_m1_p1(alt_seed)*spread_rad*(1.0-flatness);\n";
+		code += "		vec3 direction_xz = vec3( sin(angle1_rad), 0, cos(angle1_rad));\n";
+		code += "		vec3 direction_yz = vec3( 0, sin(angle2_rad), cos(angle2_rad));\n";
+		code += "		direction_yz.z = direction_yz.z / sqrt(direction_yz.z); //better uniform distribution\n";
+		code += "		vec3 direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);\n";
+		code += "		direction = normalize(direction);\n";
+		code += "		VELOCITY = direction*initial_linear_velocity*mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n";
 	}
 
 	code += "		float base_angle = (initial_angle+tex_angle)*mix(1.0,angle_rand,initial_angle_random);\n";
-	code += "		CUSTOM.x = base_angle*3.1416/180.0;\n"; //angle
+	code += "		CUSTOM.x = base_angle*degree_to_rad;\n"; //angle
 	code += "		CUSTOM.y = 0.0;\n"; //phase
 	code += "		CUSTOM.z = (anim_offset+tex_anim_offset)*mix(1.0,anim_offset_rand,anim_offset_random);\n"; //animation offset (0-1)
 	switch (emission_shape) {
@@ -777,7 +789,7 @@ void ParticlesMaterial::_update_shader() {
 
 		code += "		float orbit_amount = (orbit_velocity+tex_orbit_velocity)*mix(1.0,rand_from_seed(alt_seed),orbit_velocity_random);\n";
 		code += "		if (orbit_amount!=0.0) {\n";
-		code += "		     float ang = orbit_amount * DELTA * 3.1416 * 2.0;\n";
+		code += "		     float ang = orbit_amount * DELTA * pi * 2.0;\n";
 		code += "		     mat2 rot = mat2(vec2(cos(ang),-sin(ang)),vec2(sin(ang),cos(ang)));\n";
 		code += "		     TRANSFORM[3].xy-=diff.xy;\n";
 		code += "		     TRANSFORM[3].xy+=rot * diff.xy;\n";
@@ -800,7 +812,7 @@ void ParticlesMaterial::_update_shader() {
 	code += "		}\n";
 	code += "		float base_angle = (initial_angle+tex_angle)*mix(1.0,angle_rand,initial_angle_random);\n";
 	code += "		base_angle += CUSTOM.y*LIFETIME*(angular_velocity+tex_angular_velocity)*mix(1.0,rand_from_seed(alt_seed)*2.0-1.0,angular_velocity_random);\n";
-	code += "		CUSTOM.x = base_angle*3.1416/180.0;\n"; //angle
+	code += "		CUSTOM.x = base_angle*degree_to_rad;\n"; //angle
 	code += "		CUSTOM.z = (anim_offset+tex_anim_offset)*mix(1.0,anim_offset_rand,anim_offset_random)+CUSTOM.y*(anim_speed+tex_anim_speed)*mix(1.0,rand_from_seed(alt_seed),anim_speed_random);\n"; //angle
 	if (flags[FLAG_ANIM_LOOP]) {
 		code += "		CUSTOM.z = mod(CUSTOM.z,1.0);\n"; //loop
@@ -821,7 +833,7 @@ void ParticlesMaterial::_update_shader() {
 	else
 		code += "	float tex_hue_variation = 0.0;\n";
 
-	code += "	float hue_rot_angle = (hue_variation+tex_hue_variation)*3.1416*2.0*mix(1.0,hue_rot_rand*2.0-1.0,hue_variation_random);\n";
+	code += "	float hue_rot_angle = (hue_variation+tex_hue_variation)*pi*2.0*mix(1.0,hue_rot_rand*2.0-1.0,hue_variation_random);\n";
 	code += "	float hue_rot_c = cos(hue_rot_angle);\n";
 	code += "	float hue_rot_s = sin(hue_rot_angle);\n";
 	code += "	mat4 hue_rot_mat = mat4( vec4(0.299,  0.587,  0.114, 0.0),\n";