diff options
Diffstat (limited to 'scene')
-rw-r--r-- | scene/3d/particles.cpp | 336 | ||||
-rw-r--r-- | scene/3d/particles.h | 2 |
2 files changed, 171 insertions, 167 deletions
diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp index 80c706898d..869138e6d8 100644 --- a/scene/3d/particles.cpp +++ b/scene/3d/particles.cpp @@ -587,298 +587,294 @@ void ParticlesMaterial::_update_shader() { //need a random function code += "\n\n"; code += "float rand_from_seed(inout uint seed) {\n"; - code += " int k;\n"; - code += " int s = int(seed);\n"; - code += " if (s == 0)\n"; + code += " int k;\n"; + code += " int s = int(seed);\n"; + code += " if (s == 0)\n"; code += " s = 305420679;\n"; - code += " k = s / 127773;\n"; - code += " s = 16807 * (s - k * 127773) - 2836 * k;\n"; - code += " if (s < 0)\n"; - code += " s += 2147483647;\n"; - code += " seed = uint(s);\n"; - code += " return float(seed % uint(65536))/65535.0;\n"; + code += " k = s / 127773;\n"; + code += " s = 16807 * (s - k * 127773) - 2836 * k;\n"; + code += " if (s < 0)\n"; + code += " s += 2147483647;\n"; + code += " seed = uint(s);\n"; + code += " return float(seed % uint(65536))/65535.0;\n"; code += "}\n"; + code += "\n"; + //improve seed quality code += "uint hash(uint x) {\n"; - code += " x = ((x >> uint(16)) ^ x) * uint(73244475);\n"; - code += " x = ((x >> uint(16)) ^ x) * uint(73244475);\n"; - code += " x = (x >> uint(16)) ^ x;\n"; - code += " return x;\n"; + code += " x = ((x >> uint(16)) ^ x) * uint(73244475);\n"; + code += " x = ((x >> uint(16)) ^ x) * uint(73244475);\n"; + code += " x = (x >> uint(16)) ^ x;\n"; + code += " return x;\n"; code += "}\n"; - code += "void vertex() {\n\n"; code += "\n"; - code += " uint base_number=NUMBER/uint(trail_divisor);\n"; - code += " uint alt_seed=hash(base_number+uint(1)+RANDOM_SEED);\n"; - code += " float angle_rand=rand_from_seed(alt_seed);\n"; - 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 += "\n"; - code += "\n"; - code += "\n"; + code += "void vertex() {\n"; + code += " uint base_number = NUMBER/uint(trail_divisor);\n"; + code += " uint alt_seed = hash(base_number+uint(1)+RANDOM_SEED);\n"; + code += " float angle_rand = rand_from_seed(alt_seed);\n"; + 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 += "\n"; + if (emission_shape >= EMISSION_SHAPE_POINTS) { - code += " int point = min(emission_texture_point_count-1,int(rand_from_seed(alt_seed) * float(emission_texture_point_count)));\n"; - code += " ivec2 emission_tex_size = textureSize( emission_texture_points, 0 );\n"; - code += " ivec2 emission_tex_ofs = ivec2( point % emission_tex_size.x, point / emission_tex_size.x );\n"; + code += " int point = min(emission_texture_point_count-1,int(rand_from_seed(alt_seed) * float(emission_texture_point_count)));\n"; + code += " ivec2 emission_tex_size = textureSize( emission_texture_points, 0 );\n"; + code += " ivec2 emission_tex_ofs = ivec2( point % emission_tex_size.x, point / emission_tex_size.x );\n"; } - code += " if (RESTART) {\n"; + code += " if (RESTART) {\n"; if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) - code += " float tex_linear_velocity = textureLod(linear_velocity_texture,vec2(0.0,0.0),0.0).r;\n"; + code += " float tex_linear_velocity = textureLod(linear_velocity_texture,vec2(0.0,0.0),0.0).r;\n"; else - code += " float tex_linear_velocity = 0.0;\n"; + code += " float tex_linear_velocity = 0.0;\n"; if (tex_parameters[PARAM_ANGLE].is_valid()) - code += " float tex_angle = textureLod(angle_texture,vec2(0.0,0.0),0.0).r;\n"; + code += " float tex_angle = textureLod(angle_texture,vec2(0.0,0.0),0.0).r;\n"; else - code += " float tex_angle = 0.0;\n"; + code += " float tex_angle = 0.0;\n"; if (tex_parameters[PARAM_ANIM_OFFSET].is_valid()) - code += " float tex_anim_offset = textureLod(anim_offset_texture,vec2(0.0,0.0),0.0).r;\n"; + code += " float tex_anim_offset = textureLod(anim_offset_texture,vec2(0.0,0.0),0.0).r;\n"; else - code += " float tex_anim_offset = 0.0;\n"; + code += " float tex_anim_offset = 0.0;\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 += " VELOCITY=(rot*initial_linear_velocity+rot*initial_linear_velocity_random*rand_from_seed(alt_seed));\n"; + 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 += " VELOCITY = (rot*initial_linear_velocity+rot*initial_linear_velocity_random*rand_from_seed(alt_seed));\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+rot*initial_linear_velocity_random*rand_from_seed(alt_seed));\n"; + 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+rot*initial_linear_velocity_random*rand_from_seed(alt_seed));\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.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) + 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.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) { case EMISSION_SHAPE_POINT: { //do none } break; case EMISSION_SHAPE_SPHERE: { - code += " TRANSFORM[3].xyz = normalize(vec3(rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0-1.0, rand_from_seed(alt_seed) * 2.0-1.0 ))*emission_sphere_radius;\n"; + code += " TRANSFORM[3].xyz = normalize(vec3(rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0-1.0, rand_from_seed(alt_seed) * 2.0-1.0 ))*emission_sphere_radius;\n"; } break; case EMISSION_SHAPE_BOX: { - code += " TRANSFORM[3].xyz = vec3(rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0-1.0, rand_from_seed(alt_seed) * 2.0-1.0)*emission_box_extents;\n"; + code += " TRANSFORM[3].xyz = vec3(rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0-1.0, rand_from_seed(alt_seed) * 2.0-1.0)*emission_box_extents;\n"; } break; case EMISSION_SHAPE_POINTS: case EMISSION_SHAPE_DIRECTED_POINTS: { - code += " TRANSFORM[3].xyz = texelFetch(emission_texture_points, emission_tex_ofs,0).xyz;\n"; + code += " TRANSFORM[3].xyz = texelFetch(emission_texture_points, emission_tex_ofs,0).xyz;\n"; if (emission_shape == EMISSION_SHAPE_DIRECTED_POINTS) { if (flags[FLAG_DISABLE_Z]) { - code += " mat2 rotm;"; - code += " rotm[0]=texelFetch(emission_texture_normal, emission_tex_ofs,0).xy;\n"; - code += " rotm[1]=rotm[0].yx * vec2(1.0,-1.0);\n"; - code += " VELOCITY.xy = rotm * VELOCITY.xy;\n"; + code += " mat2 rotm;"; + code += " rotm[0] = texelFetch(emission_texture_normal, emission_tex_ofs,0).xy;\n"; + code += " rotm[1] = rotm[0].yx * vec2(1.0,-1.0);\n"; + code += " VELOCITY.xy = rotm * VELOCITY.xy;\n"; } else { - code += " vec3 normal = texelFetch(emission_texture_normal, emission_tex_ofs,0).xyz;\n"; - code += " vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0, 1.0, 0.0);\n"; - code += " vec3 tangent = normalize(cross(v0, normal));\n"; - code += " vec3 bitangent = normalize(cross(tangent, normal));\n"; - code += " VELOCITY = mat3(tangent,bitangent,normal) * VELOCITY;\n"; + code += " vec3 normal = texelFetch(emission_texture_normal, emission_tex_ofs,0).xyz;\n"; + code += " vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0, 1.0, 0.0);\n"; + code += " vec3 tangent = normalize(cross(v0, normal));\n"; + code += " vec3 bitangent = normalize(cross(tangent, normal));\n"; + code += " VELOCITY = mat3(tangent,bitangent,normal) * VELOCITY;\n"; } } } break; } - code += " VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY,0.0)).xyz;\n"; - code += " TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n"; + code += " VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY,0.0)).xyz;\n"; + code += " TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n"; if (flags[FLAG_DISABLE_Z]) { - code += " VELOCITY.z=0.0;\n"; - code += " TRANSFORM[3].z=0.0;\n"; + code += " VELOCITY.z = 0.0;\n"; + code += " TRANSFORM[3].z = 0.0;\n"; } - code += " } else {\n"; + code += " } else {\n"; - code += " CUSTOM.y+=DELTA/LIFETIME;\n"; + code += " CUSTOM.y += DELTA/LIFETIME;\n"; if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) - code += " float tex_linear_velocity = textureLod(linear_velocity_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; + code += " float tex_linear_velocity = textureLod(linear_velocity_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; else - code += " float tex_linear_velocity = 0.0;\n"; + code += " float tex_linear_velocity = 0.0;\n"; if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid()) - code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; + code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; else - code += " float tex_orbit_velocity = 0.0;\n"; + code += " float tex_orbit_velocity = 0.0;\n"; if (tex_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) - code += " float tex_angular_velocity = textureLod(angular_velocity_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; + code += " float tex_angular_velocity = textureLod(angular_velocity_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; else - code += " float tex_angular_velocity = 0.0;\n"; + code += " float tex_angular_velocity = 0.0;\n"; if (tex_parameters[PARAM_LINEAR_ACCEL].is_valid()) - code += " float tex_linear_accel = textureLod(linear_accel_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; + code += " float tex_linear_accel = textureLod(linear_accel_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; else - code += " float tex_linear_accel = 0.0;\n"; + code += " float tex_linear_accel = 0.0;\n"; if (tex_parameters[PARAM_RADIAL_ACCEL].is_valid()) - code += " float tex_radial_accel = textureLod(radial_accel_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; + code += " float tex_radial_accel = textureLod(radial_accel_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; else - code += " float tex_radial_accel = 0.0;\n"; + code += " float tex_radial_accel = 0.0;\n"; if (tex_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) - code += " float tex_tangent_accel = textureLod(tangent_accel_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; + code += " float tex_tangent_accel = textureLod(tangent_accel_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; else - code += " float tex_tangent_accel = 0.0;\n"; + code += " float tex_tangent_accel = 0.0;\n"; if (tex_parameters[PARAM_DAMPING].is_valid()) - code += " float tex_damping = textureLod(damping_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; + code += " float tex_damping = textureLod(damping_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; else - code += " float tex_damping = 0.0;\n"; + code += " float tex_damping = 0.0;\n"; if (tex_parameters[PARAM_ANGLE].is_valid()) - code += " float tex_angle = textureLod(angle_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; + code += " float tex_angle = textureLod(angle_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; else - code += " float tex_angle = 0.0;\n"; + code += " float tex_angle = 0.0;\n"; if (tex_parameters[PARAM_ANIM_SPEED].is_valid()) - code += " float tex_anim_speed = textureLod(anim_speed_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; + code += " float tex_anim_speed = textureLod(anim_speed_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; else - code += " float tex_anim_speed = 0.0;\n"; + code += " float tex_anim_speed = 0.0;\n"; if (tex_parameters[PARAM_ANIM_OFFSET].is_valid()) - code += " float tex_anim_offset = textureLod(anim_offset_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; + code += " float tex_anim_offset = textureLod(anim_offset_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; else - code += " float tex_anim_offset = 0.0;\n"; + code += " float tex_anim_offset = 0.0;\n"; - code += " vec3 force = gravity; \n"; - code += " vec3 pos = TRANSFORM[3].xyz; \n"; + code += " vec3 force = gravity; \n"; + code += " vec3 pos = TRANSFORM[3].xyz; \n"; if (flags[FLAG_DISABLE_Z]) { - code += " pos.z=0.0; \n"; + code += " pos.z = 0.0; \n"; } - code += " //apply linear acceleration\n"; - code += " force+= length(VELOCITY) > 0.0 ? normalize(VELOCITY) * (linear_accel+tex_linear_accel)*mix(1.0,rand_from_seed(alt_seed),linear_accel_random) : vec3(0.0);\n"; - code += " //apply radial acceleration\n"; - code += " vec3 org = vec3(0.0);\n"; - code += " // if (!p_system->local_coordinates)\n"; - code += " //org=p_transform.origin;\n"; - code += " vec3 diff = pos-org;\n"; - code += " force+=length(diff) > 0.0 ? normalize(diff) * (radial_accel+tex_radial_accel)*mix(1.0,rand_from_seed(alt_seed),radial_accel_random) : vec3(0.0);\n"; - code += " //apply tangential acceleration;\n"; + code += " //apply linear acceleration\n"; + code += " force += length(VELOCITY) > 0.0 ? normalize(VELOCITY) * (linear_accel+tex_linear_accel)*mix(1.0,rand_from_seed(alt_seed),linear_accel_random) : vec3(0.0);\n"; + code += " //apply radial acceleration\n"; + code += " vec3 org = vec3(0.0);\n"; + code += " vec3 diff = pos-org;\n"; + code += " force += length(diff) > 0.0 ? normalize(diff) * (radial_accel+tex_radial_accel)*mix(1.0,rand_from_seed(alt_seed),radial_accel_random) : vec3(0.0);\n"; + code += " //apply tangential acceleration;\n"; if (flags[FLAG_DISABLE_Z]) { - code += " force+=length(diff.yx) > 0.0 ? vec3(normalize(diff.yx * vec2(-1.0,1.0)),0.0) * ((tangent_accel+tex_tangent_accel)*mix(1.0,rand_from_seed(alt_seed),radial_accel_random)) : vec3(0.0);\n"; + code += " force += length(diff.yx) > 0.0 ? vec3(normalize(diff.yx * vec2(-1.0,1.0)),0.0) * ((tangent_accel+tex_tangent_accel)*mix(1.0,rand_from_seed(alt_seed),radial_accel_random)) : vec3(0.0);\n"; } else { - code += " vec3 crossDiff = cross(normalize(diff),normalize(gravity));\n"; - code += " force+=length(crossDiff) > 0.0 ? normalize(crossDiff) * ((tangent_accel+tex_tangent_accel)*mix(1.0,rand_from_seed(alt_seed),radial_accel_random)) : vec3(0.0);\n"; + code += " vec3 crossDiff = cross(normalize(diff),normalize(gravity));\n"; + code += " force += length(crossDiff) > 0.0 ? normalize(crossDiff) * ((tangent_accel+tex_tangent_accel)*mix(1.0,rand_from_seed(alt_seed),radial_accel_random)) : vec3(0.0);\n"; } - code += " //apply attractor forces\n"; - code += " VELOCITY+=force * DELTA;\n"; + code += " //apply attractor forces\n"; + code += " VELOCITY += force * DELTA;\n"; if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) { - code += " VELOCITY=normalize(VELOCITY)*tex_linear_velocity;\n"; + code += " VELOCITY = normalize(VELOCITY)*tex_linear_velocity;\n"; } - code += " if (damping+tex_damping>0.0) {\n"; - code += " \n"; - code += " float v = length(VELOCITY);\n"; - code += " float damp = (damping+tex_damping)*mix(1.0,rand_from_seed(alt_seed),damping_random);\n"; - code += " v -= damp * DELTA;\n"; - code += " if (v<0.0) {\n"; - code += " VELOCITY=vec3(0.0);\n"; - code += " } else {\n"; - code += " VELOCITY=normalize(VELOCITY) * v;\n"; - code += " }\n"; - 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.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 + code += " if (damping + tex_damping > 0.0) {\n"; + code += " \n"; + code += " float v = length(VELOCITY);\n"; + code += " float damp = (damping+tex_damping)*mix(1.0,rand_from_seed(alt_seed),damping_random);\n"; + code += " v -= damp * DELTA;\n"; + code += " if (v < 0.0) {\n"; + code += " VELOCITY = vec3(0.0);\n"; + code += " } else {\n"; + code += " VELOCITY = normalize(VELOCITY) * v;\n"; + code += " }\n"; + 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.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 + code += " CUSTOM.z = mod(CUSTOM.z,1.0);\n"; //loop } else { - code += " CUSTOM.z=clamp(CUSTOM.z,0.0,1.0);\n"; //0 to 1 only + code += " CUSTOM.z = clamp(CUSTOM.z,0.0,1.0);\n"; //0 to 1 only } - code += " }\n"; + code += " }\n"; //apply color //apply hue rotation if (tex_parameters[PARAM_SCALE].is_valid()) - code += " float tex_scale = textureLod(scale_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; + code += " float tex_scale = textureLod(scale_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; else - code += " float tex_scale = 1.0;\n"; + code += " float tex_scale = 1.0;\n"; if (tex_parameters[PARAM_HUE_VARIATION].is_valid()) - code += " float tex_hue_variation = textureLod(hue_variation_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; + code += " float tex_hue_variation = textureLod(hue_variation_texture,vec2(CUSTOM.y,0.0),0.0).r;\n"; 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_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"; - code += " vec4(0.299, 0.587, 0.114, 0.0),\n"; - code += " vec4(0.299, 0.587, 0.114, 0.0),\n"; - code += " vec4(0.000, 0.000, 0.000, 1.0)) +\n"; - code += " \n"; - code += " mat4( vec4(0.701, -0.587, -0.114, 0.0),\n"; - code += " vec4(-0.299, 0.413, -0.114, 0.0),\n"; - code += " vec4(-0.300, -0.588, 0.886, 0.0),\n"; - code += " vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_c +\n"; - code += "\n"; - code += " mat4( vec4(0.168, 0.330, -0.497, 0.0),\n"; - code += " vec4(-0.328, 0.035, 0.292, 0.0),\n"; - code += " vec4(1.250, -1.050, -0.203, 0.0),\n"; - code += " vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_s;\n"; + 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_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"; + code += " vec4(0.299, 0.587, 0.114, 0.0),\n"; + code += " vec4(0.299, 0.587, 0.114, 0.0),\n"; + code += " vec4(0.000, 0.000, 0.000, 1.0)) +\n"; + code += " mat4( vec4(0.701, -0.587, -0.114, 0.0),\n"; + code += " vec4(-0.299, 0.413, -0.114, 0.0),\n"; + code += " vec4(-0.300, -0.588, 0.886, 0.0),\n"; + code += " vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_c +\n"; + code += " mat4( vec4(0.168, 0.330, -0.497, 0.0),\n"; + code += " vec4(-0.328, 0.035, 0.292, 0.0),\n"; + code += " vec4(1.250, -1.050, -0.203, 0.0),\n"; + code += " vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_s;\n"; if (color_ramp.is_valid()) { - code += " COLOR = textureLod(color_ramp,vec2(CUSTOM.y,0.0),0.0) * hue_rot_mat;\n"; + code += " COLOR = textureLod(color_ramp,vec2(CUSTOM.y,0.0),0.0) * hue_rot_mat;\n"; } else { - code += " COLOR = color_value * hue_rot_mat;\n"; + code += " COLOR = color_value * hue_rot_mat;\n"; } if (emission_color_texture.is_valid() && emission_shape >= EMISSION_SHAPE_POINTS) { - code += " COLOR*= texelFetch(emission_texture_color,emission_tex_ofs,0);\n"; + code += " COLOR*= texelFetch(emission_texture_color,emission_tex_ofs,0);\n"; } if (trail_color_modifier.is_valid()) { - code += "if (trail_divisor>1) { COLOR*=textureLod(trail_color_modifier,vec2(float(int(NUMBER)%trail_divisor)/float(trail_divisor-1),0.0),0.0); }\n"; + code += " if (trail_divisor > 1) { COLOR *= textureLod(trail_color_modifier,vec2(float(int(NUMBER)%trail_divisor)/float(trail_divisor-1),0.0),0.0); }\n"; } code += "\n"; if (flags[FLAG_DISABLE_Z]) { - code += " TRANSFORM[0]=vec4(cos(CUSTOM.x),-sin(CUSTOM.x),0.0,0.0);\n"; - code += " TRANSFORM[1]=vec4(sin(CUSTOM.x),cos(CUSTOM.x),0.0,0.0);\n"; - code += " TRANSFORM[2]=vec4(0.0,0.0,1.0,0.0);\n"; + code += " TRANSFORM[0] = vec4(cos(CUSTOM.x),-sin(CUSTOM.x),0.0,0.0);\n"; + code += " TRANSFORM[1] = vec4(sin(CUSTOM.x),cos(CUSTOM.x),0.0,0.0);\n"; + code += " TRANSFORM[2] = vec4(0.0,0.0,1.0,0.0);\n"; } else { //orient particle Y towards velocity if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) { - code += " if (length(VELOCITY)>0.0) {TRANSFORM[1].xyz=normalize(VELOCITY);} else {TRANSFORM[1].xyz=normalize(TRANSFORM[1].xyz);}\n"; - code += " if (TRANSFORM[1].xyz==normalize(TRANSFORM[0].xyz)) {\n"; - code += "\tTRANSFORM[0].xyz=normalize(cross(normalize(TRANSFORM[1].xyz),normalize(TRANSFORM[2].xyz)));\n"; - code += "\tTRANSFORM[2].xyz=normalize(cross(normalize(TRANSFORM[0].xyz),normalize(TRANSFORM[1].xyz)));\n"; - code += " } else {\n"; - code += "\tTRANSFORM[2].xyz=normalize(cross(normalize(TRANSFORM[0].xyz),normalize(TRANSFORM[1].xyz)));\n"; - code += "\tTRANSFORM[0].xyz=normalize(cross(normalize(TRANSFORM[1].xyz),normalize(TRANSFORM[2].xyz)));\n"; - code += " }\n"; + code += " if (length(VELOCITY) > 0.0) { TRANSFORM[1].xyz = normalize(VELOCITY); } else { TRANSFORM[1].xyz = normalize(TRANSFORM[1].xyz); }\n"; + code += " if (TRANSFORM[1].xyz == normalize(TRANSFORM[0].xyz)) {\n"; + code += " TRANSFORM[0].xyz = normalize(cross(normalize(TRANSFORM[1].xyz),normalize(TRANSFORM[2].xyz)));\n"; + code += " TRANSFORM[2].xyz = normalize(cross(normalize(TRANSFORM[0].xyz),normalize(TRANSFORM[1].xyz)));\n"; + code += " } else {\n"; + code += " TRANSFORM[2].xyz = normalize(cross(normalize(TRANSFORM[0].xyz),normalize(TRANSFORM[1].xyz)));\n"; + code += " TRANSFORM[0].xyz = normalize(cross(normalize(TRANSFORM[1].xyz),normalize(TRANSFORM[2].xyz)));\n"; + code += " }\n"; } else { - code += "\tTRANSFORM[0].xyz=normalize(TRANSFORM[0].xyz);\n"; - code += "\tTRANSFORM[1].xyz=normalize(TRANSFORM[1].xyz);\n"; - code += "\tTRANSFORM[2].xyz=normalize(TRANSFORM[2].xyz);\n"; + code += " TRANSFORM[0].xyz = normalize(TRANSFORM[0].xyz);\n"; + code += " TRANSFORM[1].xyz = normalize(TRANSFORM[1].xyz);\n"; + code += " TRANSFORM[2].xyz = normalize(TRANSFORM[2].xyz);\n"; } //turn particle by rotation in Y if (flags[FLAG_ROTATE_Y]) { - code += "\tTRANSFORM = TRANSFORM * mat4( vec4(cos(CUSTOM.x),0.0,-sin(CUSTOM.x),0.0), vec4(0.0,1.0,0.0,0.0),vec4(sin(CUSTOM.x),0.0,cos(CUSTOM.x),0.0),vec4(0.0,0.0,0.0,1.0));\n"; + code += " TRANSFORM = TRANSFORM * mat4( vec4(cos(CUSTOM.x),0.0,-sin(CUSTOM.x),0.0), vec4(0.0,1.0,0.0,0.0),vec4(sin(CUSTOM.x),0.0,cos(CUSTOM.x),0.0),vec4(0.0,0.0,0.0,1.0));\n"; } } //scale by scale - code += " float base_scale=mix(scale*tex_scale,1.0,scale_random*scale_rand);\n"; + code += " float base_scale = mix(scale*tex_scale,1.0,scale_random*scale_rand);\n"; if (trail_size_modifier.is_valid()) { - code += "if (trail_divisor>1) { base_scale*=textureLod(trail_size_modifier,vec2(float(int(NUMBER)%trail_divisor)/float(trail_divisor-1),0.0),0.0).r; } \n"; + code += " if (trail_divisor > 1) { base_scale *= textureLod(trail_size_modifier,vec2(float(int(NUMBER)%trail_divisor)/float(trail_divisor-1),0.0),0.0).r; } \n"; } - code += " TRANSFORM[0].xyz*=base_scale;\n"; - code += " TRANSFORM[1].xyz*=base_scale;\n"; - code += " TRANSFORM[2].xyz*=base_scale;\n"; + code += " TRANSFORM[0].xyz *= base_scale;\n"; + code += " TRANSFORM[1].xyz *= base_scale;\n"; + code += " TRANSFORM[2].xyz *= base_scale;\n"; if (flags[FLAG_DISABLE_Z]) { - code += " VELOCITY.z=0.0;\n"; - code += " TRANSFORM[3].z=0.0;\n"; + code += " VELOCITY.z = 0.0;\n"; + code += " TRANSFORM[3].z = 0.0;\n"; } code += "}\n"; code += "\n"; @@ -1329,6 +1325,12 @@ Vector3 ParticlesMaterial::get_gravity() const { return gravity; } +RID ParticlesMaterial::get_shader_rid() const { + + ERR_FAIL_COND_V(!shader_map.has(current_key), RID()); + return shader_map[current_key].shader; +} + void ParticlesMaterial::_validate_property(PropertyInfo &property) const { if (property.name == "color" && color_ramp.is_valid()) { diff --git a/scene/3d/particles.h b/scene/3d/particles.h index 2c109d6ec8..e3109f470f 100644 --- a/scene/3d/particles.h +++ b/scene/3d/particles.h @@ -388,6 +388,8 @@ public: static void finish_shaders(); static void flush_changes(); + RID get_shader_rid() const; + ParticlesMaterial(); ~ParticlesMaterial(); }; |