// GBufferEffect: Multi-pass G-buffer rendering for CNN v3 input // Outputs: gbuf_feat0, gbuf_feat1 (packed rgba32uint feature textures, 32 bytes/pixel) #pragma once #include "3d/camera.h" #include "3d/scene.h" #include "gpu/effect.h" #include "gpu/sequence.h" #include "gpu/uniform_helper.h" #include "gpu/wgpu_resource.h" #include "util/mini_math.h" // Uniform for the pack compute shader struct GBufResUniforms { vec2 resolution; float _pad0; float _pad1; }; static_assert(sizeof(GBufResUniforms) == 16, "GBufResUniforms must be 16 bytes"); class GBufferEffect : public Effect { public: GBufferEffect(const GpuContext& ctx, const std::vector& inputs, const std::vector& outputs, float start_time, float end_time); void declare_nodes(NodeRegistry& registry) override; void render(WGPUCommandEncoder encoder, const UniformsSequenceParams& params, NodeRegistry& nodes) override; void set_scene(const Scene* scene, const Camera* camera); private: // Internal G-buffer node names std::string node_albedo_; std::string node_normal_mat_; std::string node_depth_; std::string node_shadow_; std::string node_transp_; std::string node_feat0_; std::string node_feat1_; const Scene* scene_ = nullptr; const Camera* camera_ = nullptr; // Pass 1: MRT rasterization pipeline RenderPipeline raster_pipeline_; BindGroup raster_bind_group_; // Pass 4: Pack compute pipeline ComputePipeline pack_pipeline_; BindGroup pack_bind_group_; UniformBuffer pack_res_uniform_; // Placeholder textures for shadow/transp (white/black cleared once) Texture shadow_placeholder_tex_; TextureView shadow_placeholder_view_; Texture transp_placeholder_tex_; TextureView transp_placeholder_view_; // GPU-side object data buffers (global uniforms + objects storage) // These mirror the layout expected by gbuf_raster.wgsl GpuBuffer global_uniforms_buf_; GpuBuffer objects_buf_; int objects_buf_capacity_ = 0; // number of ObjectData slots allocated void create_raster_pipeline(); void create_pack_pipeline(); void update_raster_bind_group(NodeRegistry& nodes); void update_pack_bind_group(NodeRegistry& nodes); void upload_scene_data(const Scene& scene, const Camera& camera, float time); void ensure_objects_buffer(int num_objects); };