-
-
Notifications
You must be signed in to change notification settings - Fork 21.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix code style for generated shader code from ParticleProcessMaterial #91946
Conversation
So I was nerd sniped by this PR, and did a deep dive on this file to fix all the many remaining style issues with the generated code. I added my changes as a separate commit for review, to be squashed once approved. I'll point out some logic changes that may result from the cleanup. Here's the output of this PR on a 2D ParticlesProcessMaterial converted to a ShaderMaterial after assigning an empty Curve to most optional curve fields, to try to get as much coverage for the conditionals as possible (still doesn't include all potential code, so some issues may remain here and there). This code passes our style checks if pasted in a // NOTE: Shader automatically converted from Godot Engine 4.3.beta'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 float scale_over_velocity_min = 0.0;
uniform float scale_over_velocity_max = 5.0;
uniform sampler2D emission_texture_normal : hint_default_black;
uniform sampler2D emission_texture_points : hint_default_black;
uniform int emission_texture_point_count;
uniform sampler2D emission_texture_color : hint_default_white;
uniform float sub_emitter_frequency;
uniform bool sub_emitter_keep_velocity;
uniform vec4 color_value : source_color;
uniform vec3 gravity;
uniform sampler2D color_ramp : repeat_disable;
uniform sampler2D color_initial_ramp : repeat_disable;
uniform sampler2D alpha_curve : repeat_disable;
uniform sampler2D emission_curve : repeat_disable;
uniform sampler2D orbit_velocity_curve : repeat_disable;
uniform sampler2D angular_velocity_texture : repeat_disable;
uniform sampler2D linear_accel_texture : repeat_disable;
uniform sampler2D radial_accel_texture : repeat_disable;
uniform sampler2D tangent_accel_texture : repeat_disable;
uniform sampler2D damping_texture : repeat_disable;
uniform sampler2D angle_texture : repeat_disable;
uniform sampler2D scale_curve : repeat_disable;
uniform sampler2D hue_rot_curve : repeat_disable;
uniform sampler2D animation_speed_curve : repeat_disable;
uniform sampler2D animation_offset_curve : repeat_disable;
uniform sampler2D radial_velocity_curve : repeat_disable;
uniform sampler2D scale_over_velocity_curve : repeat_disable;
uniform sampler2D directional_velocity_curve : repeat_disable;
uniform sampler2D velocity_limit_curve : repeat_disable;
uniform float collision_friction;
uniform float collision_bounce;
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);
uniform sampler2D turbulence_influence_over_life;
// 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;
params.color *= texture(color_initial_ramp, vec2(rand_from_seed(alt_seed)));
int point = min(emission_texture_point_count - 1, int(rand_from_seed(alt_seed) * float(emission_texture_point_count)));
ivec2 emission_tex_size = textureSize(emission_texture_points, 0);
ivec2 emission_tex_ofs = ivec2(point % emission_tex_size.x, point / emission_tex_size.x);
params.color *= texelFetch(emission_texture_color, emission_tex_ofs, 0);
}
void process_display_param(inout DisplayParameters parameters, float lifetime) {
// Compile-time add textures.
parameters.scale *= texture(scale_curve, vec2(lifetime)).rgb;
parameters.hue_rotation *= texture(hue_rot_curve, vec2(lifetime)).r;
parameters.animation_offset += texture(animation_offset_curve, vec2(lifetime)).r;
parameters.animation_speed *= texture(animation_speed_curve, vec2(lifetime)).r;
parameters.color *= texture(color_ramp, vec2(lifetime));
parameters.color.a *= texture(alpha_curve, vec2(lifetime)).r;
parameters.color = rotate_hue(parameters.color, parameters.hue_rotation);
parameters.color.rgb *= 1.0 + texture(emission_curve, vec2(lifetime)).r;
}
vec3 calculate_initial_position(inout uint alt_seed) {
float pi = 3.14159;
vec3 pos = vec3(0.0);
{ // Emission shape.
int point = min(emission_texture_point_count - 1, int(rand_from_seed(alt_seed) * float(emission_texture_point_count)));
ivec2 emission_tex_size = textureSize(emission_texture_points, 0);
ivec2 emission_tex_ofs = ivec2(point % emission_tex_size.x, point / emission_tex_size.x);
pos = texelFetch(emission_texture_points, emission_tex_ofs, 0).xyz;
}
return pos * emission_shape_scale + emission_shape_offset;
}
vec3 process_orbit_displacement(DynamicsParameters param, float lifetime, inout uint alt_seed, mat4 transform, mat4 emission_transform, float delta, float total_lifetime) {
if (abs(param.orbit_velocity) < 0.01 || delta < 0.001) {
return vec3(0.0);
}
vec3 displacement = vec3(0.0);
float pi = 3.14159;
float orbit_amount = param.orbit_velocity;
orbit_amount *= texture(orbit_velocity_curve, vec2(lifetime)).r;
if (orbit_amount != 0.0) {
vec3 pos = transform[3].xyz;
vec3 org = emission_transform[3].xyz;
vec3 diff = pos - org;
float ang = orbit_amount * pi * 2.0 * delta;
mat2 rot = mat2(vec2(cos(ang), -sin(ang)), vec2(sin(ang), cos(ang)));
displacement.xy -= diff.xy;
displacement.xy += rot * diff.xy;
}
return (emission_transform * vec4(displacement / delta, 0.0)).xyz;
}
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;
angle1_rad += direction.x != 0.0 ? atan(direction.y, direction.x) : sign(direction.y) * (pi / 2.0);
vec3 spread_direction = vec3(cos(angle1_rad), sin(angle1_rad), 0.0);
return 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;
radial_displacement_multiplier = texture(radial_velocity_curve, vec2(lifetime)).r;
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;
}
vec3 process_directional_displacement(DynamicsParameters param, float lifetime_percent, mat4 transform, mat4 emission_transform) {
vec3 displacement = texture(directional_velocity_curve, vec2(lifetime_percent)).xyz * param.directional_velocity;
return displacement;
}
void process_physical_parameters(inout PhysicalParameters params, float lifetime_percent) {
params.linear_accel *= texture(linear_accel_texture, vec2(lifetime_percent)).r;
params.radial_accel *= texture(radial_accel_texture, vec2(lifetime_percent)).r;
params.tangent_accel *= texture(tangent_accel_texture, vec2(lifetime_percent)).r;
params.damping *= texture(damping_texture, vec2(lifetime_percent)).r;
}
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;
int point = min(emission_texture_point_count - 1, int(rand_from_seed(alt_seed) * float(emission_texture_point_count)));
ivec2 emission_tex_size = textureSize(emission_texture_points, 0);
ivec2 emission_tex_ofs = ivec2(point % emission_tex_size.x, point / emission_tex_size.x);
{
mat2 rotm;
rotm[0] = texelFetch(emission_texture_normal, emission_tex_ofs, 0).xy;
rotm[1] = rotm[0].yx * vec2(1.0, -1.0);
VELOCITY.xy = rotm * VELOCITY.xy;
}
}
process_display_param(params, 0.0);
VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;
VELOCITY += EMITTER_VELOCITY * inherit_emitter_velocity_ratio;
VELOCITY.z = 0.0;
TRANSFORM[3].z = 0.0;
}
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_orbit_displacement(dynamic_params, lifetime_percent, alt_seed, TRANSFORM, EMISSION_TRANSFORM, DELTA, params.lifetime * LIFETIME);
controlled_displacement += process_radial_displacement(dynamic_params, lifetime_percent, alt_seed, TRANSFORM, EMISSION_TRANSFORM, DELTA);
controlled_displacement += process_directional_displacement(dynamic_params, lifetime_percent, TRANSFORM, EMISSION_TRANSFORM);
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;
force += length(diff.yx) > 0.0 ? vec3(normalize(diff.yx * vec2(-1.0, 1.0)), 0.0) * tangent_accel_val : vec3(0.0);
force += ATTRACTOR_FORCE;
force.z = 0.0;
// 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;
}
}
}
if (COLLIDED) {
if (length(VELOCITY) > 3.0) {
TRANSFORM[3].xyz += COLLISION_NORMAL * COLLISION_DEPTH;
VELOCITY -= COLLISION_NORMAL * dot(COLLISION_NORMAL, VELOCITY) * (1.0 + collision_bounce);
VELOCITY = mix(VELOCITY, vec3(0.0), clamp(collision_friction, 0.0, 1.0));
} else {
VELOCITY = vec3(0.0);
}
}
// Turbulence before limiting.
float turbulence_influence = textureLod(turbulence_influence_over_life, vec2(lifetime_percent, 0.0), 0.0).r;
vec3 noise_direction = get_noise_direction(TRANSFORM[3].xyz);
if (!COLLIDED) {
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;
// Limit velocity.
if (length(final_velocity) > 0.001) {
final_velocity = normalize(final_velocity) * min(abs(length(final_velocity)), abs(texture(velocity_limit_curve, vec2(lifetime_percent)).r));
}
final_velocity.z = 0.0;
TRANSFORM[3].xyz += final_velocity * DELTA;
process_display_param(params, lifetime_percent);
float base_angle = dynamic_params.angle;
base_angle *= texture(angle_texture, vec2(lifetime_percent)).r;
base_angle += CUSTOM.y * LIFETIME * dynamic_params.angular_velocity * texture(angular_velocity_texture, vec2(lifetime_percent)).r;
CUSTOM.x = base_angle * degree_to_rad;
COLOR = params.color;
TRANSFORM[0] = vec4(cos(CUSTOM.x), -sin(CUSTOM.x), 0.0, 0.0);
TRANSFORM[1] = vec4(sin(CUSTOM.x), cos(CUSTOM.x), 0.0, 0.0);
TRANSFORM[2] = vec4(0.0, 0.0, 1.0, 0.0);
TRANSFORM[3].z = 0.0;
if (length(final_velocity) > 0.001) {
params.scale *= texture(scale_over_velocity_curve, vec2(clamp(length(final_velocity) / (scale_over_velocity_max - scale_over_velocity_min), 0.0, 1.0), 0.0)).rgb;
} else {
params.scale *= texture(scale_over_velocity_curve, vec2(0.0)).rgb;
}
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;
int emit_count = 0;
float interval_from = CUSTOM.y * LIFETIME - DELTA;
float interval_rem = sub_emitter_frequency - mod(interval_from, sub_emitter_frequency);
if (DELTA >= interval_rem) {
emit_count = 1;
}
for (int i = 0; i < emit_count; i++) {
uint flags = FLAG_EMIT_POSITION | FLAG_EMIT_ROT_SCALE;
if (sub_emitter_keep_velocity) {
flags |= FLAG_EMIT_VELOCITY;
}
emit_subparticle(TRANSFORM, VELOCITY, vec4(0.0), vec4(0.0), flags);
}
if (CUSTOM.y > CUSTOM.w) {
ACTIVE = false;
}
} |
|
||
code += "uniform vec3 direction;\n"; | ||
code += "uniform float spread;\n"; | ||
code += "uniform float flatness;\n"; | ||
|
||
code += "uniform float inherit_emitter_velocity_ratio = 0;\n"; | ||
code += "uniform float inherit_emitter_velocity_ratio = 0.0;\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to make sure float
s properly use x.0
format, not x
or x.
or .0
.
code += " dot(p, vec4(0.143081, 0.001724, 0.280166, 0.262771)),\n"; | ||
code += " dot(p, vec4(0.645401, -0.047791, -0.146698, 0.595016)),\n"; | ||
code += " dot(p, vec4(-0.499665, -0.095734, 0.425674, -0.207367)),\n"; | ||
code += " dot(p, vec4(-0.013596, -0.848588, 0.423736, 0.17044))));\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to match our clang-format
ContinuationIndentWidth: 8
code += "}\n\n"; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I aimed to standardize vertical spacing like we do in engine code, with an empty line between each function definition, or between separate logic blocks.
In the codegen, whenever we have a \n\n
, it should be followed by an actual empty line to help make this obvious.
code += " if (s == 0) {\n"; | ||
code += " s = 305420679;\n"; | ||
code += " }\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure use of brackets.
|
||
code += "vec3 calculate_initial_position(inout uint alt_seed) {\n"; | ||
code += " float pi = 3.14159;\n"; | ||
code += " float degree_to_rad = pi / 180.0;\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed degree_to_rad
in some functions where it's not used.
I suppose the idea here was to always make it available in case new code would need it. Happy to bring it back if that's the case.
code += " // Reset alt seed?\n"; | ||
code += " //alt_seed = hash(base_number + uint(1) + RANDOM_SEED);\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I remove this dead code?
@@ -882,73 +883,63 @@ void ParticleProcessMaterial::_update_shader() { | |||
code += " }\n"; | |||
} | |||
} | |||
code += " }\n"; | |||
code += " process_display_param(params, 0.);\n"; | |||
code += "// process_dynamic_parameters(dynamic_params, 0., alt_seed, TRANSFORM, EMISSION_TRANSFORM, DELTA);\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dead code removed.
code += " //if (repeatable) {\n"; | ||
code += " // base_number = INDEX;\n"; | ||
code += " //}\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we remove the dead code and only keep the TODO in cpp? Or even remove the TODO?
code += " // will use this later to calculate final displacement and orient the particle.\n"; | ||
code += " vec3 starting_position = TRANSFORM[3].xyz;\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment was a lie :)
code += "// VELOCITY += process_physics_parameters(dynamic_params, lifetime_percent, alt_seed, TRANSFORM, EMISSION_TRANSFORM, DELTA);\n"; | ||
code += "\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dead code.
Fixed, with merge conflicts resolved. |
I'm scheduling to merge this after 4.3-beta1, for beta2. Just in case this would introduce regressions due to the highly manual process used to improve the code style. |
The results now match what our clang-format config would do. Co-authored-by: Rémi Verschelde <[email protected]>
Thanks! |
When converting a
ParticleProcessMaterial
to aShaderMaterial
I noticed a few places where the indentation of the resulting GLSL was incorrect. The source uses almost entirely tabs but in a few places it uses spaces. This PR converts all spaces to tabs to keep things consistent.There was also one indentation too many on part of the turbulence code so I fixed that while I was in there.