Skip to content
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

Merged
merged 1 commit into from
May 31, 2024

Conversation

Flynsarmy
Copy link
Contributor

When converting a ParticleProcessMaterial to a ShaderMaterial 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.
image

There was also one indentation too many on part of the turbulence code so I fixed that while I was in there.

@akien-mga
Copy link
Member

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 .glsl file and formatted with clang-format.

// 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";
Copy link
Member

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 floats properly use x.0 format, not x or x. or .0.

Comment on lines +389 to +392
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";
Copy link
Member

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

Comment on lines +437 to +438
code += "}\n\n";

Copy link
Member

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.

Comment on lines +491 to +493
code += " if (s == 0) {\n";
code += " s = 305420679;\n";
code += " }\n";
Copy link
Member

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";
Copy link
Member

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.

Comment on lines +830 to +831
code += " // Reset alt seed?\n";
code += " //alt_seed = hash(base_number + uint(1) + RANDOM_SEED);\n";
Copy link
Member

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";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead code removed.

Comment on lines +899 to +901
code += " //if (repeatable) {\n";
code += " // base_number = INDEX;\n";
code += " //}\n";
Copy link
Member

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?

Comment on lines -922 to -923
code += " // will use this later to calculate final displacement and orient the particle.\n";
code += " vec3 starting_position = TRANSFORM[3].xyz;\n";
Copy link
Member

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 :)

Comment on lines 926 to 927
code += "// VELOCITY += process_physics_parameters(dynamic_params, lifetime_percent, alt_seed, TRANSFORM, EMISSION_TRANSFORM, DELTA);\n";
code += "\n";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead code.

@akien-mga akien-mga changed the title Keep shader code indent type consistent Fix code style for generated shader code from ParticleProcessMaterial May 14, 2024
@Flynsarmy Flynsarmy requested review from a team as code owners May 17, 2024 12:00
@akien-mga
Copy link
Member

Fixed, with merge conflicts resolved.

@dalexeev dalexeev removed request for a team May 17, 2024 12:12
@akien-mga
Copy link
Member

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 <rverschelde@gmail.com>
@akien-mga akien-mga merged commit 2e51be3 into godotengine:master May 31, 2024
15 checks passed
@akien-mga
Copy link
Member

Thanks!

@Flynsarmy Flynsarmy deleted the tabby_tab_tabs branch May 31, 2024 12:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants