200x perf improvement on world rendering task creation

This commit is contained in:
Tuomas Katajisto 2026-05-03 00:35:31 +03:00
parent d00885a73b
commit c27fa53236
3 changed files with 88 additions and 34 deletions

View File

@ -143,9 +143,9 @@ backend_add_trile_positions :: (positions : []Trile_Instance, chunk: Chunk_Key)
array_reset_keeping_memory(*trile_position_staging); array_reset_keeping_memory(*trile_position_staging);
for position : positions { for position : positions {
array_add(*trile_position_staging, Vector4.{ array_add(*trile_position_staging, Vector4.{
cast(float)(position.x + chunk.x), cast(float)(position.x + chunk.x * 32.0),
cast(float)(position.y + chunk.y), cast(float)(position.y + chunk.y * 32.0),
cast(float)(position.z + chunk.z), cast(float)(position.z + chunk.z * 32.0),
cast(float)(position.orientation) cast(float)(position.orientation)
}); });
} }
@ -178,7 +178,11 @@ backend_draw_trile_positions_gbuffer :: (trile : string, amount : s32, worldConf
offset := trile_offsets[offset_index]; offset := trile_offsets[offset_index];
trilegfx := get_trile_gfx(trile); trilegfx, success := get_trile_gfx(trile);
if !success {
log_warn("Failed to get trile: %\n", trile);
return;
}
vbuf, nbuf, cbuf : sg_buffer; vbuf, nbuf, cbuf : sg_buffer;
vcount : s64; vcount : s64;
@ -217,7 +221,12 @@ backend_draw_trile_positions_main :: (trile : string, amount : s32, worldConf: *
return; return;
} }
trilegfx := get_trile_gfx(trile); trilegfx, success := get_trile_gfx(trile);
if !success {
log_warn("Failed to get trile: %\n", trile);
return;
}
offset := trile_offsets[offset_index]; offset := trile_offsets[offset_index];
// Pick mesh source based on LOD level. For shadow + gbuffer we keep the original pipeline // Pick mesh source based on LOD level. For shadow + gbuffer we keep the original pipeline
@ -363,7 +372,11 @@ backend_add_trile_rdm_position :: (position: Vector4) {
backend_draw_trile_rdm :: (trile: string, worldConf: *World_Config, atlas_rect: Vector4, offset_index: s32) { backend_draw_trile_rdm :: (trile: string, worldConf: *World_Config, atlas_rect: Vector4, offset_index: s32) {
if offset_index >= trile_rdm_offsets.count then return; if offset_index >= trile_rdm_offsets.count then return;
trilegfx := get_trile_gfx(trile); trilegfx, success := get_trile_gfx(trile);
if !success {
log_warn("Failed to get trile: %\n", trile);
return;
}
offset := trile_rdm_offsets[offset_index]; offset := trile_rdm_offsets[offset_index];
mvp := create_viewproj(*camera); mvp := create_viewproj(*camera);

View File

@ -83,34 +83,49 @@ create_world_rendering_tasks :: (world: *World, camera: Camera, plane_height: fl
reflect_planes := extract_frustum_planes(reflect_mvp); reflect_planes := extract_frustum_planes(reflect_mvp);
for chunk: world.chunks { for chunk: world.chunks {
chunk_quadrant_vis : [8]bool; // Skip chunks that are completely out of view.
any_vis : bool;
for i: 0..1 {
for j: 0..1 {
for k: 0..1 {
bmin := Vector3.{ bmin := Vector3.{
chunk.coord.x * 32.0 + i * 16.0, chunk.coord.x * 32.0,
chunk.coord.y * 32.0 + j * 16.0, chunk.coord.y * 32.0,
chunk.coord.z * 32.0 + k * 16.0 chunk.coord.z * 32.0
}; };
bmax := bmin + .{16, 16, 16}; bmax := bmin + .{32, 32, 32};
in_cam := aabb_in_frustum(cam_planes, bmin, bmax); in_cam := aabb_in_frustum(cam_planes, bmin, bmax);
in_reflect := aabb_in_frustum(reflect_planes, bmin, bmax); in_reflect := aabb_in_frustum(reflect_planes, bmin, bmax);
in_shad := aabb_in_frustum(shadow_planes, bmin, bmax); in_shad := aabb_in_frustum(shadow_planes, bmin, bmax);
vis := in_cam || in_reflect || in_shad; vis := in_cam || in_reflect || in_shad;
chunk_quadrant_vis[i+j*2+k*2*2] = vis; if !vis then continue;
if !any_vis then any_vis = vis;
}
}
}
for group : chunk.groups { for group : chunk.groups {
if group.instances.count < 1 then continue;
gmin := group.bounding_min;
gmax := group.bounding_max;
gmin += Vector3.{cast(float)chunk.coord.x * 32, cast(float)chunk.coord.y * 32, cast(float)chunk.coord.z * 32};
gmax += Vector3.{cast(float)chunk.coord.x * 32, cast(float)chunk.coord.y * 32, cast(float)chunk.coord.z * 32};
in_cam := aabb_in_frustum(cam_planes, gmin, gmax);
in_reflect := aabb_in_frustum(reflect_planes, gmin, gmax);
in_shad := aabb_in_frustum(shadow_planes, gmin, gmax);
vis := in_cam || in_reflect || in_shad;
if !vis then continue;
diff := group.average_pos - camera.position;
dist := length(diff);
lod_index : s32 = 0;
for lod_dist : LOD_DISTANCES {
if dist < lod_dist then break;
lod_index += 1;
}
task := Rendering_Task_Trile.{ task := Rendering_Task_Trile.{
trile = group.trile_name, trile = group.trile_name,
chunk_key = chunk.coord, chunk_key = chunk.coord,
positions = group.instances, positions = group.instances,
worldConf = *world.conf worldConf = *world.conf,
lod_index = lod_index
}; };
add_rendering_task(task); add_rendering_task(task);
} }

View File

@ -45,6 +45,12 @@ Trile_Instance :: struct {
Chunk_Trile_Group :: struct { Chunk_Trile_Group :: struct {
trile_name : string; trile_name : string;
// Precalculated to save time when we are creating render tasks.
bounding_min : Vector3;
bounding_max : Vector3;
average_pos : Vector3;
instances : [..]Trile_Instance; instances : [..]Trile_Instance;
is_buried : [..]bool; // Runtime-only, parallel to instances. Not serialized. is_buried : [..]bool; // Runtime-only, parallel to instances. Not serialized.
} }
@ -676,6 +682,25 @@ load_world_from_json :: (json_str: string, chunk_bin: []u8) -> (World, bool) {
inst := read_value(chunk_data, *chunk_cursor, Trile_Instance); inst := read_value(chunk_data, *chunk_cursor, Trile_Instance);
array_add(*group.instances, inst); array_add(*group.instances, inst);
} }
gmin := Vector3.{31,31,31};
gmax := Vector3.{0,0,0};
gavg := Vector3.{0,0,0};
for i : group.instances {
gmin.x = min(gmin.x, xx i.x);
gmin.y = min(gmin.y, xx i.y);
gmin.z = min(gmin.z, xx i.z);
gmax.x = max(gmax.x, xx i.x);
gmax.y = max(gmax.y, xx i.y);
gmax.z = max(gmax.z, xx i.z);
gavg += Vector3.{xx i.x, xx i.y, xx i.z};
}
gavg /= cast(float) group.instances.count;
group.bounding_min = gmin;
group.bounding_max = gmax;
group.average_pos = gavg;
array_add(*chunk.groups, group); array_add(*chunk.groups, group);
} }
table_set(*world.chunks, chunk.coord, chunk); table_set(*world.chunks, chunk.coord, chunk);
@ -771,6 +796,7 @@ load_world_from_data :: (data: []u8) -> (World, bool) {
inst := read_value(data, *chunk_cursor, Trile_Instance); inst := read_value(data, *chunk_cursor, Trile_Instance);
array_add(*group.instances, inst); array_add(*group.instances, inst);
} }
array_add(*chunk.groups, group); array_add(*chunk.groups, group);
} }
table_set(*world.chunks, chunk.coord, chunk); table_set(*world.chunks, chunk.coord, chunk);