• Godot Help
  • Synchronizing time between shaders and _process() for animation in 4.0

I'm using 4.0 and trying to animate a HeightMap3d collision shape to match a mesh I'm animating through a shader. I am using the same equation for both, but I'm getting inconsistent results. Sometimes my collision shape is perfectly in sync with my mesh, sometimes very out of sync. I have been unable to discern a pattern here, so I'm thinking it has to do with the difference between the shader's TIME, and the GDscript Time.get_unix_time_from_system().
See screenshots of good and bad cases. I took the first screenshot, reloaded the game, then the second. I reloaded again and it was off, like the second case again.

See my code below:

extends CollisionShape3D

var heightmap
var heightmap_array
var accumulator = 0.0
var wave_direction = Vector2(1.0, 4.0)
var wave_time: float

const SIZE = 30
const H_RESOLUTION = 4

# Called when the node enters the scene tree for the first time.
func _ready():
	heightmap = HeightMapShape3D.new()
	heightmap.set_map_depth(SIZE * H_RESOLUTION)
	heightmap.set_map_width(SIZE * H_RESOLUTION)
	heightmap_array = PackedFloat32Array()
	heightmap_array.resize(SIZE * SIZE * H_RESOLUTION * H_RESOLUTION)
	heightmap_array.fill(0.0)
	heightmap.set_map_data(heightmap_array)
	set_shape(heightmap)
	

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	accumulator += delta
	if(accumulator > 0.2):
		#heightmap_array = my_wave(Time.get_unix_time_from_system(), heightmap_array)
		#heightmap.set_map_data(heightmap_array)
		heightmap.set_map_data(my_wave(Time.get_unix_time_from_system(), heightmap_array))
		set_shape(heightmap)
		accumulator = 0.0
	
func my_wave(time, data):
	for i in data.size():
		var offset = 0
		# goes goes by row of x, -x to +x
		# bottom left, then up, then right
		var x_int: int = i % (H_RESOLUTION * SIZE) # within row
		var z_int: int = floor(i / (H_RESOLUTION * SIZE)) # which row?
		var x_pos: float = x_int / (H_RESOLUTION) - (SIZE / 2.0)
		var z_pos: float = z_int / (H_RESOLUTION) - (SIZE / 2.0)
		var wave_pos: float = (wave_direction.x * x_pos) + (wave_direction.y * z_pos) 
		# we have to account for how the height map is scaled down
		data[i] =  0.5 * H_RESOLUTION * cos( ((2.0 * time) + wave_pos + offset) / (2 * PI) )
	return data
shader_type spatial;

uniform vec3 colors[2];
uniform vec2 wave_direction;
uniform vec3 points[30];

varying float func_val;

void vertex() {
	vec3 world_pos = MODEL_MATRIX[3].xyz;
	float wave_pos = (wave_direction.x * VERTEX.x) + (wave_direction.y * VERTEX.z);
	func_val = 0.5 * cos( ((2.0 * TIME) + wave_pos) / (2.0 * PI));
	VERTEX.y = func_val;
	//  :)
	float f_x = -0.5 * wave_direction.x * sin( (2.0 * TIME + wave_pos) / (2.0 * PI));
	float f_z = -0.5 * wave_direction.y * sin( (2.0 * TIME + wave_pos) / (2.0 * PI));
	float mag = sqrt(1.0 + f_x * f_x + f_z * f_z);
	NORMAL = vec3(f_x/mag, 1.0/mag, f_z);
}

Note that both the shader and the collision shape are passed wave_direction by a parent script when in-game conditions are met. My functions seem to work correctly, just my waves are often out of sync. Is there a fix for this so it works dependably?

Any thoughts or tips welcome. Thanks!