I am stuck on this https://docs.godotengine.org Godot Tutorial for animating fish. I have finished the initial part where we created the fish and got the swim movement done. I am now trying to implement the GPUParticles3D
to make them move across the screen.
My issue is I cannot figure out how these particles are supposed to be combined with the MultiMeshInstance3D
created in the first part of the tutorial (or is it not supposed to be). Is this particles portion supposed to not utilize the multimesh created in the first part? If not then how do I combine the first Spatial
shader we created with the Particle
shader created in the second part? I can't seem to figure out how to add two shaders to the particle system. I also tried taking the code from the Spatial
shader and putting it in the _process
function of the Particle
shader but that didn't work.
Here is what I currently have
The green fish are a multimesh controlled by the Spatial
shader and the orange fish are the particle system. How do I make this all-in-one like the end gif of the tutuorial?
shader_type spatial;
uniform float time_scale = 0.5;
uniform float side_to_side = 0.5;
uniform float pivot = 3;
uniform float wave = 1.2;
uniform float twist = 2;
uniform float mask_black = 0;
uniform float mask_white = 1;
const vec3 pos = vec3(1.0, 0.0, 1.0);
varying vec3 col;
void vertex() {
float time = (TIME * (0.5 + INSTANCE_CUSTOM.y) * time_scale) + (TAU * INSTANCE_CUSTOM.x);
VERTEX.x += cos(time) * side_to_side;
float pivot_angle = cos(time) * 0.1 * pivot;
mat2 rotation_matrix = mat2(vec2(cos(pivot_angle), -sin(pivot_angle)), vec2(sin(pivot_angle), cos(pivot_angle)));
VERTEX.xz *= rotation_matrix;
float body = (VERTEX.z + 1.0) / 2.0;
float mask = smoothstep(mask_black, mask_white, 1.0 - body);
VERTEX.x += cos(time + body) * wave * mask;
float twist_angle = cos(time) * 0.3 * twist;
mat2 rotation_y = mat2(vec2(cos(twist_angle), -sin(twist_angle)), vec2(sin(twist_angle), cos(twist_angle)));
VERTEX.xy = mix(VERTEX.xy, rotation_y * VERTEX.xy, mask);
col = vec3(0.0, 1.0, 0.0);
}
void fragment() {
if (VERTEX.y > -10.0) {
ALBEDO = col;
}
}
shader_type particles;
float rand_from_seed(in 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;
}
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;
}
void start() {
uint alt_seed1 = hash(NUMBER + uint(1) + RANDOM_SEED);
uint alt_seed2 = hash(NUMBER + uint(27) + RANDOM_SEED);
uint alt_seed3 = hash(NUMBER + uint(43) + RANDOM_SEED);
uint alt_seed4 = hash(NUMBER + uint(111) + RANDOM_SEED);
CUSTOM.x = rand_from_seed(alt_seed1);
vec3 position = vec3(rand_from_seed(alt_seed2) * 2.0 - 1.0,
rand_from_seed(alt_seed3) * 2.0 - 1.0,
rand_from_seed(alt_seed4) * 2.0 - 1.0);
TRANSFORM[3].xyz = position * 20.0;
VELOCITY.z = cos(TIME + CUSTOM.x * TAU) * 4.0 + 6.0;
}
void process() {
}