From 12d5d5f1762a0c00405950b6ff5e564880f0ff36 Mon Sep 17 00:00:00 2001 From: skal Date: Sun, 22 Mar 2026 23:51:40 +0100 Subject: refactor(cnn_v3): simplify sphere SDF in shadow pass, remove per-frame alloc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gbuf_shadow.wgsl — dfWithID(): - Sphere: replace inv_model local-space transform with direct world-space formula (length(p - center) - radius). Exact, no matrix multiply, no floating-point error from matrix inversion that can corrupt soft-shadow penumbra over 64 march steps. - lp/scale now computed only inside the cases that need them (box/torus/plane) instead of eagerly for every object. gbuffer_effect.cc — upload_scene_data(): - Replace per-frame std::vector heap allocation with a file-static staging buffer s_obj_staging[256]: zero alloc per frame. handoff(Gemini): sphere SDF now exact; shadow march should be cleaner. --- cnn_v3/src/gbuffer_effect.cc | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'cnn_v3/src/gbuffer_effect.cc') diff --git a/cnn_v3/src/gbuffer_effect.cc b/cnn_v3/src/gbuffer_effect.cc index b059915..829c199 100644 --- a/cnn_v3/src/gbuffer_effect.cc +++ b/cnn_v3/src/gbuffer_effect.cc @@ -30,6 +30,9 @@ struct GBufObjectData { static_assert(sizeof(GBufObjectData) == sizeof(float) * 40, "GBufObjectData must be 160 bytes"); +// Reusable CPU staging buffer (single-threaded demo — no concurrency needed). +static GBufObjectData s_obj_staging[kGBufMaxObjects]; + // GlobalUniforms struct mirroring renderer.h struct GBufGlobalUniforms { mat4 view_proj; @@ -446,23 +449,19 @@ void GBufferEffect::upload_scene_data(const Scene& scene, wgpuQueueWriteBuffer(ctx_.queue, global_uniforms_buf_.buffer, 0, &gu, sizeof(GBufGlobalUniforms)); - // Upload object data. + // Upload object data (no per-frame heap alloc — reuse s_obj_staging). if (num_objects > 0) { ensure_objects_buffer(num_objects); - std::vector obj_data; - obj_data.reserve((size_t)num_objects); for (int i = 0; i < num_objects; ++i) { const Object3D& obj = scene.objects[(size_t)i]; const mat4 m = obj.get_model_matrix(); - GBufObjectData d; - d.model = m; - d.inv_model = m.inverse(); - d.color = obj.color; - d.params = vec4((float)(int)obj.type, 0.0f, 0.0f, 0.0f); - obj_data.push_back(d); + s_obj_staging[i].model = m; + s_obj_staging[i].inv_model = m.inverse(); + s_obj_staging[i].color = obj.color; + s_obj_staging[i].params = vec4((float)(int)obj.type, 0.0f, 0.0f, 0.0f); } wgpuQueueWriteBuffer(ctx_.queue, objects_buf_.buffer, 0, - obj_data.data(), + s_obj_staging, (size_t)num_objects * sizeof(GBufObjectData)); } } -- cgit v1.2.3