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!