diff options
Diffstat (limited to 'cnn_v3/src')
| -rw-r--r-- | cnn_v3/src/gbuf_deferred_effect.cc | 140 | ||||
| -rw-r--r-- | cnn_v3/src/gbuf_deferred_effect.h | 23 | ||||
| -rw-r--r-- | cnn_v3/src/gbuf_view_effect.cc | 4 | ||||
| -rw-r--r-- | cnn_v3/src/gbuffer_effect.cc | 168 | ||||
| -rw-r--r-- | cnn_v3/src/gbuffer_effect.h | 4 |
5 files changed, 235 insertions, 104 deletions
diff --git a/cnn_v3/src/gbuf_deferred_effect.cc b/cnn_v3/src/gbuf_deferred_effect.cc new file mode 100644 index 0000000..de6bd29 --- /dev/null +++ b/cnn_v3/src/gbuf_deferred_effect.cc @@ -0,0 +1,140 @@ +// GBufDeferredEffect — simple deferred render: albedo * shadow from packed G-buffer. + +#include "gbuf_deferred_effect.h" +#include "gpu/gpu.h" +#include "gpu/shader_composer.h" +#include "util/fatal_error.h" + +extern const char* gbuf_deferred_wgsl; + +struct GBufDeferredUniforms { + float resolution[2]; +}; +static_assert(sizeof(GBufDeferredUniforms) == 8, "GBufDeferredUniforms must be 8 bytes"); + +static WGPUBindGroupLayoutEntry bgl_uint_tex(uint32_t binding) { + WGPUBindGroupLayoutEntry e = {}; + e.binding = binding; + e.visibility = WGPUShaderStage_Fragment; + e.texture.sampleType = WGPUTextureSampleType_Uint; + e.texture.viewDimension = WGPUTextureViewDimension_2D; + return e; +} + +static WGPUBindGroupLayoutEntry bgl_uniform(uint32_t binding, uint64_t min_size) { + WGPUBindGroupLayoutEntry e = {}; + e.binding = binding; + e.visibility = WGPUShaderStage_Fragment; + e.buffer.type = WGPUBufferBindingType_Uniform; + e.buffer.minBindingSize = min_size; + return e; +} + +GBufDeferredEffect::GBufDeferredEffect(const GpuContext& ctx, + const std::vector<std::string>& inputs, + const std::vector<std::string>& outputs, + float start_time, float end_time) + : Effect(ctx, inputs, outputs, start_time, end_time) { + HEADLESS_RETURN_IF_NULL(ctx_.device); + + WGPUBindGroupLayoutEntry entries[3] = { + bgl_uint_tex(0), + bgl_uint_tex(1), + bgl_uniform(2, sizeof(GBufDeferredUniforms)), + }; + WGPUBindGroupLayoutDescriptor bgl_desc = {}; + bgl_desc.entryCount = 3; + bgl_desc.entries = entries; + WGPUBindGroupLayout bgl = wgpuDeviceCreateBindGroupLayout(ctx_.device, &bgl_desc); + + WGPUPipelineLayoutDescriptor pl_desc = {}; + pl_desc.bindGroupLayoutCount = 1; + pl_desc.bindGroupLayouts = &bgl; + WGPUPipelineLayout pl = wgpuDeviceCreatePipelineLayout(ctx_.device, &pl_desc); + + WGPUShaderSourceWGSL wgsl_src = {}; + wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL; + const std::string composed = ShaderComposer::Get().Compose({}, gbuf_deferred_wgsl); + wgsl_src.code = str_view(composed.c_str()); + WGPUShaderModuleDescriptor shader_desc = {}; + shader_desc.nextInChain = &wgsl_src.chain; + WGPUShaderModule shader = wgpuDeviceCreateShaderModule(ctx_.device, &shader_desc); + + WGPUColorTargetState target = {}; + target.format = WGPUTextureFormat_RGBA8Unorm; + target.writeMask = WGPUColorWriteMask_All; + + WGPUFragmentState frag = {}; + frag.module = shader; + frag.entryPoint = str_view("fs_main"); + frag.targetCount = 1; + frag.targets = ⌖ + + WGPURenderPipelineDescriptor pipe_desc = {}; + pipe_desc.layout = pl; + pipe_desc.vertex.module = shader; + pipe_desc.vertex.entryPoint = str_view("vs_main"); + pipe_desc.fragment = &frag; + pipe_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; + pipe_desc.multisample.count = 1; + pipe_desc.multisample.mask = UINT32_MAX; + + pipeline_.set(wgpuDeviceCreateRenderPipeline(ctx_.device, &pipe_desc)); + + wgpuShaderModuleRelease(shader); + wgpuPipelineLayoutRelease(pl); + wgpuBindGroupLayoutRelease(bgl); +} + +void GBufDeferredEffect::render(WGPUCommandEncoder encoder, + const UniformsSequenceParams& params, + NodeRegistry& nodes) { + WGPUTextureView feat0_view = nodes.get_view(input_nodes_[0]); + WGPUTextureView feat1_view = nodes.get_view(input_nodes_[1]); + WGPUTextureView output_view = nodes.get_view(output_nodes_[0]); + + // Upload resolution uniform into the base class uniforms buffer (first 8 bytes). + GBufDeferredUniforms u; + u.resolution[0] = params.resolution.x; + u.resolution[1] = params.resolution.y; + wgpuQueueWriteBuffer(ctx_.queue, uniforms_buffer_.get().buffer, 0, + &u, sizeof(u)); + + WGPUBindGroupLayout bgl = + wgpuRenderPipelineGetBindGroupLayout(pipeline_.get(), 0); + + WGPUBindGroupEntry bg_entries[3] = {}; + bg_entries[0].binding = 0; + bg_entries[0].textureView = feat0_view; + bg_entries[1].binding = 1; + bg_entries[1].textureView = feat1_view; + bg_entries[2].binding = 2; + bg_entries[2].buffer = uniforms_buffer_.get().buffer; + bg_entries[2].size = sizeof(GBufDeferredUniforms); + + WGPUBindGroupDescriptor bg_desc = {}; + bg_desc.layout = bgl; + bg_desc.entryCount = 3; + bg_desc.entries = bg_entries; + bind_group_.replace(wgpuDeviceCreateBindGroup(ctx_.device, &bg_desc)); + wgpuBindGroupLayoutRelease(bgl); + + WGPURenderPassColorAttachment color_att = {}; + color_att.view = output_view; + color_att.loadOp = WGPULoadOp_Clear; + color_att.storeOp = WGPUStoreOp_Store; + color_att.clearValue = {0.0f, 0.0f, 0.0f, 1.0f}; + color_att.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED; + + WGPURenderPassDescriptor pass_desc = {}; + pass_desc.colorAttachmentCount = 1; + pass_desc.colorAttachments = &color_att; + + WGPURenderPassEncoder pass = + wgpuCommandEncoderBeginRenderPass(encoder, &pass_desc); + wgpuRenderPassEncoderSetPipeline(pass, pipeline_.get()); + wgpuRenderPassEncoderSetBindGroup(pass, 0, bind_group_.get(), 0, nullptr); + wgpuRenderPassEncoderDraw(pass, 3, 1, 0, 0); + wgpuRenderPassEncoderEnd(pass); + wgpuRenderPassEncoderRelease(pass); +} diff --git a/cnn_v3/src/gbuf_deferred_effect.h b/cnn_v3/src/gbuf_deferred_effect.h new file mode 100644 index 0000000..4daf13d --- /dev/null +++ b/cnn_v3/src/gbuf_deferred_effect.h @@ -0,0 +1,23 @@ +// GBufDeferredEffect — simple deferred render from packed G-buffer. +// Inputs: feat_tex0, feat_tex1 (rgba32uint). Output: albedo * shadow (rgba8unorm). + +#pragma once +#include "gpu/effect.h" +#include "gpu/uniform_helper.h" +#include "gpu/wgpu_resource.h" + +class GBufDeferredEffect : public Effect { + public: + GBufDeferredEffect(const GpuContext& ctx, + const std::vector<std::string>& inputs, + const std::vector<std::string>& outputs, + float start_time, float end_time); + + void render(WGPUCommandEncoder encoder, + const UniformsSequenceParams& params, + NodeRegistry& nodes) override; + + private: + RenderPipeline pipeline_; + BindGroup bind_group_; +}; diff --git a/cnn_v3/src/gbuf_view_effect.cc b/cnn_v3/src/gbuf_view_effect.cc index 180919d..ccf80b0 100644 --- a/cnn_v3/src/gbuf_view_effect.cc +++ b/cnn_v3/src/gbuf_view_effect.cc @@ -10,6 +10,7 @@ #endif #include "gpu/gpu.h" +#include "gpu/shader_composer.h" #include "util/asset_manager.h" #include "util/fatal_error.h" @@ -63,7 +64,8 @@ GBufViewEffect::GBufViewEffect(const GpuContext& ctx, // Shader module WGPUShaderSourceWGSL wgsl_src = {}; wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL; - wgsl_src.code = str_view(gbuf_view_wgsl); + const std::string composed = ShaderComposer::Get().Compose({}, gbuf_view_wgsl); + wgsl_src.code = str_view(composed.c_str()); WGPUShaderModuleDescriptor shader_desc = {}; shader_desc.nextInChain = &wgsl_src.chain; WGPUShaderModule shader = diff --git a/cnn_v3/src/gbuffer_effect.cc b/cnn_v3/src/gbuffer_effect.cc index 89ed8fc..b059915 100644 --- a/cnn_v3/src/gbuffer_effect.cc +++ b/cnn_v3/src/gbuffer_effect.cc @@ -42,18 +42,6 @@ struct GBufGlobalUniforms { static_assert(sizeof(GBufGlobalUniforms) == sizeof(float) * 44, "GBufGlobalUniforms must be 176 bytes"); -// Create bilinear sampler. -static WGPUSampler create_bilinear_sampler(WGPUDevice device) { - WGPUSamplerDescriptor desc = {}; - desc.addressModeU = WGPUAddressMode_ClampToEdge; - desc.addressModeV = WGPUAddressMode_ClampToEdge; - desc.magFilter = WGPUFilterMode_Linear; - desc.minFilter = WGPUFilterMode_Linear; - desc.mipmapFilter = WGPUMipmapFilterMode_Linear; - desc.maxAnisotropy = 1; - return wgpuDeviceCreateSampler(device, &desc); -} - // ---- GBufferEffect ---- GBufferEffect::GBufferEffect(const GpuContext& ctx, @@ -70,9 +58,6 @@ GBufferEffect::GBufferEffect(const GpuContext& ctx, node_depth_ = prefix + "_depth"; node_shadow_ = prefix + "_shadow"; node_transp_ = prefix + "_transp"; - node_feat0_ = outputs.size() > 0 ? outputs[0] : prefix + "_feat0"; - node_feat1_ = outputs.size() > 1 ? outputs[1] : prefix + "_feat1"; - // Allocate GPU buffers for scene data. global_uniforms_buf_ = gpu_create_buffer(ctx_.device, sizeof(GBufGlobalUniforms), @@ -89,6 +74,8 @@ GBufferEffect::GBufferEffect(const GpuContext& ctx, create_raster_pipeline(); create_shadow_pipeline(); create_pack_pipeline(); + + set_scene(); } void GBufferEffect::declare_nodes(NodeRegistry& registry) { @@ -99,11 +86,11 @@ void GBufferEffect::declare_nodes(NodeRegistry& registry) { registry.declare_node(node_transp_, NodeType::GBUF_R8, -1, -1); // feat_tex0 / feat_tex1 are the declared output_nodes_ — they get registered // by the sequence infrastructure; declare them here as well if not already. - if (!registry.has_node(node_feat0_)) { - registry.declare_node(node_feat0_, NodeType::GBUF_RGBA32UINT, -1, -1); + if (!registry.has_node(output_nodes_[0])) { + registry.declare_node(output_nodes_[0], NodeType::GBUF_RGBA32UINT, -1, -1); } - if (!registry.has_node(node_feat1_)) { - registry.declare_node(node_feat1_, NodeType::GBUF_RGBA32UINT, -1, -1); + if (!registry.has_node(output_nodes_[1])) { + registry.declare_node(output_nodes_[1], NodeType::GBUF_RGBA32UINT, -1, -1); } } @@ -122,50 +109,29 @@ void GBufferEffect::set_scene() { }; auto rrange = [&](float lo, float hi) { return lo + rnd() * (hi - lo); }; - // 20 small cubes scattered in a [-2,2]×[-1.5,1.5]×[-1.5,1.5] volume. - static const int kNumCubes = 20; - for (int i = 0; i < kNumCubes; ++i) { + // 2 large cubes. + // 2 large static cubes for shadow debugging. + { Object3D obj(ObjectType::CUBE); - obj.position = vec3(rrange(-2.0f, 2.0f), - rrange(-1.5f, 1.5f), - rrange(-1.5f, 1.5f)); - const float s = rrange(0.10f, 0.25f); - obj.scale = vec3(s, s, s); - obj.color = vec4(rrange(0.4f, 1.0f), - rrange(0.4f, 1.0f), - rrange(0.4f, 1.0f), 1.0f); - - // Random rotation axis (avoid degenerate zero-length axis). - vec3 axis = vec3(rrange(-1.0f, 1.0f), - rrange(-1.0f, 1.0f), - rrange(-1.0f, 1.0f)); - if (axis.len() < 0.01f) axis = vec3(0.0f, 1.0f, 0.0f); - axis = axis.normalize(); - const float speed = rrange(0.3f, 1.5f) * (rnd() > 0.5f ? 1.0f : -1.0f); - + obj.position = vec3(-1.0f, 0.0f, 0.0f); + obj.scale = vec3(0.6f, 0.6f, 0.6f); + obj.color = vec4(0.9f, 0.5f, 0.3f, 1.0f); scene_.add_object(obj); - cube_anims_.push_back({axis, speed}); + cube_anims_.push_back({{0.0f, 1.0f, 0.0f}, 0.0f}); } - - // 4 pumping spheres at fixed positions; radius modulated by audio_intensity. - static const vec3 kSpherePos[4] = { - { 0.0f, 0.0f, 0.0f}, - { 1.5f, 0.5f, -0.5f}, - {-1.5f, -0.5f, 0.5f}, - { 0.0f, 1.0f, 1.0f}, - }; - static const float kBaseSphereRadius[4] = {0.35f, 0.28f, 0.30f, 0.25f}; - for (int i = 0; i < 4; ++i) { + { Object3D obj(ObjectType::SPHERE); - obj.position = kSpherePos[i]; - const float r = kBaseSphereRadius[i]; - obj.scale = vec3(r, r, r); - obj.color = vec4(0.85f, 0.60f, 0.95f, 1.0f); + obj.position = vec3(1.0f, 0.0f, 0.0f); + const float r = 0.9f; + obj.scale = vec3(r, r, r); + obj.color = vec4(0.3f, 0.6f, 0.9f, 1.0f); const int idx = (int)scene_.objects.size(); scene_.add_object(obj); sphere_anims_.push_back({idx, r}); } + // (sphere removed for shadow debugging) + // Camera: above and in front of the scene, looking at origin. camera_.set_look_at(vec3(0.0f, 2.5f, 6.0f), vec3(0.0f, 0.0f, 0.0f), @@ -178,6 +144,22 @@ void GBufferEffect::set_scene() { scene_ready_ = true; } +static void clear_r8_node(WGPUCommandEncoder encoder, WGPUTextureView view, + float value) { + WGPURenderPassColorAttachment att = {}; + att.view = view; + att.loadOp = WGPULoadOp_Clear; + att.storeOp = WGPUStoreOp_Store; + att.clearValue = {value, value, value, value}; + att.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED; + WGPURenderPassDescriptor pd = {}; + pd.colorAttachmentCount = 1; + pd.colorAttachments = &att; + WGPURenderPassEncoder p = wgpuCommandEncoderBeginRenderPass(encoder, &pd); + wgpuRenderPassEncoderEnd(p); + wgpuRenderPassEncoderRelease(p); +} + void GBufferEffect::render(WGPUCommandEncoder encoder, const UniformsSequenceParams& params, NodeRegistry& nodes) { @@ -188,6 +170,13 @@ void GBufferEffect::render(WGPUCommandEncoder encoder, // Update camera aspect ratio from current resolution. camera_.aspect_ratio = params.aspect_ratio; + // Slowly orbit around the scene. + const float angle = params.time * 0.3f; + const float R = 6.0f; + camera_.set_look_at(vec3(R * sinf(angle), 2.5f, R * cosf(angle)), + vec3(0.0f, 0.0f, 0.0f), + vec3(0.0f, 1.0f, 0.0f)); + // Animate cubes: axis-angle rotation driven by physical time. for (int i = 0; i < (int)cube_anims_.size(); ++i) { const CubeAnim& a = cube_anims_[(size_t)i]; @@ -203,13 +192,13 @@ void GBufferEffect::render(WGPUCommandEncoder encoder, // Upload two directional lights. { GBufLightsUniforms lu = {}; - lu.params = vec4(2.0f, 0.0f, 0.0f, 0.0f); + lu.params = vec4(1.0f, 0.0f, 0.0f, 0.0f); // Key: warm sun, upper-right-front. lu.lights[0].direction = vec4(0.408f, 0.816f, 0.408f, 0.0f); // norm(1,2,1) lu.lights[0].color = vec4(1.00f, 0.92f, 0.78f, 1.0f); - // Fill: cool sky, upper-left-back. - lu.lights[1].direction = vec4(-0.577f, 0.577f, -0.577f, 0.0f); // norm(-1,1,-1) - lu.lights[1].color = vec4(0.40f, 0.45f, 0.80f, 0.4f); + // Fill: cool sky, upper-left-back. (disabled for debugging) + // lu.lights[1].direction = vec4(-0.577f, 0.577f, -0.577f, 0.0f); + // lu.lights[1].color = vec4(0.40f, 0.45f, 0.80f, 0.4f); lights_uniform_.update(ctx_.queue, lu); } @@ -225,8 +214,8 @@ void GBufferEffect::render(WGPUCommandEncoder encoder, WGPUTextureView albedo_view = nodes.get_view(node_albedo_); WGPUTextureView normal_mat_view = nodes.get_view(node_normal_mat_); WGPUTextureView depth_view = nodes.get_view(node_depth_); - WGPUTextureView feat0_view = nodes.get_view(node_feat0_); - WGPUTextureView feat1_view = nodes.get_view(node_feat1_); + WGPUTextureView feat0_view = nodes.get_view(output_nodes_[0]); + WGPUTextureView feat1_view = nodes.get_view(output_nodes_[1]); // prev_cnn: first input node if available, else dummy. WGPUTextureView prev_view = nullptr; @@ -291,7 +280,7 @@ void GBufferEffect::render(WGPUCommandEncoder encoder, // --- Pass 2: SDF shadow raymarching --- if (shadow_pipeline_.get() != nullptr) { - WGPUBindGroupEntry shadow_entries[4] = {}; + WGPUBindGroupEntry shadow_entries[5] = {}; shadow_entries[0].binding = 0; shadow_entries[0].buffer = global_uniforms_buf_.buffer; shadow_entries[0].size = sizeof(GBufGlobalUniforms); @@ -307,12 +296,15 @@ void GBufferEffect::render(WGPUCommandEncoder encoder, shadow_entries[3].buffer = lights_uniform_.get().buffer; shadow_entries[3].size = sizeof(GBufLightsUniforms); + shadow_entries[4].binding = 4; + shadow_entries[4].textureView = normal_mat_view; + WGPUBindGroupLayout shadow_bgl = wgpuRenderPipelineGetBindGroupLayout(shadow_pipeline_.get(), 0); WGPUBindGroupDescriptor shadow_bg_desc = {}; shadow_bg_desc.layout = shadow_bgl; - shadow_bg_desc.entryCount = 4; + shadow_bg_desc.entryCount = 5; shadow_bg_desc.entries = shadow_entries; WGPUBindGroup shadow_bg = @@ -340,36 +332,11 @@ void GBufferEffect::render(WGPUCommandEncoder encoder, wgpuBindGroupRelease(shadow_bg); } else { // Fallback: clear to 1.0 (fully lit) if pipeline not ready. - WGPURenderPassColorAttachment att = {}; - att.view = nodes.get_view(node_shadow_); - att.loadOp = WGPULoadOp_Clear; - att.storeOp = WGPUStoreOp_Store; - att.clearValue = {1.0f, 1.0f, 1.0f, 1.0f}; - att.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED; - WGPURenderPassDescriptor pd = {}; - pd.colorAttachmentCount = 1; - pd.colorAttachments = &att; - WGPURenderPassEncoder p = wgpuCommandEncoderBeginRenderPass(encoder, &pd); - wgpuRenderPassEncoderEnd(p); - wgpuRenderPassEncoderRelease(p); + clear_r8_node(encoder, nodes.get_view(node_shadow_), 1.0f); } // Pass 3: Transparency — TODO (deferred; opaque scenes only) - // Clear transp node to 0.0 (fully opaque) until pass 3 is implemented. - { - WGPURenderPassColorAttachment att = {}; - att.view = nodes.get_view(node_transp_); - att.loadOp = WGPULoadOp_Clear; - att.storeOp = WGPUStoreOp_Store; - att.clearValue = {0.0f, 0.0f, 0.0f, 0.0f}; - att.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED; - WGPURenderPassDescriptor pd = {}; - pd.colorAttachmentCount = 1; - pd.colorAttachments = &att; - WGPURenderPassEncoder p = wgpuCommandEncoderBeginRenderPass(encoder, &pd); - wgpuRenderPassEncoderEnd(p); - wgpuRenderPassEncoderRelease(p); - } + clear_r8_node(encoder, nodes.get_view(node_transp_), 0.0f); // --- Pass 4: Pack compute --- // Rebuild pack bind group with current node views. @@ -463,7 +430,8 @@ void GBufferEffect::upload_scene_data(const Scene& scene, : (size_t)kGBufMaxObjects); const mat4 view = camera.get_view_matrix(); - const mat4 proj = camera.get_projection_matrix(); + mat4 proj = camera.get_projection_matrix(); + proj.m[5] = -proj.m[5]; // undo post-process Y flip: G-buffer uses integer reads const mat4 vp = proj * view; GBufGlobalUniforms gu = {}; @@ -509,7 +477,7 @@ void GBufferEffect::create_raster_pipeline() { } const std::string composed = - ShaderComposer::Get().Compose({"common_uniforms"}, src); + ShaderComposer::Get().Compose({}, src); WGPUShaderSourceWGSL wgsl_src = {}; wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL; @@ -567,8 +535,9 @@ void GBufferEffect::create_raster_pipeline() { pipe_desc.vertex.entryPoint = str_view("vs_main"); pipe_desc.fragment = &frag; pipe_desc.depthStencil = &ds; - pipe_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; - pipe_desc.primitive.cullMode = WGPUCullMode_Back; + pipe_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; + pipe_desc.primitive.cullMode = WGPUCullMode_Back; + pipe_desc.primitive.frontFace = WGPUFrontFace_CCW; // standard (no Y flip) pipe_desc.multisample.count = 1; pipe_desc.multisample.mask = 0xFFFFFFFF; @@ -598,7 +567,7 @@ void GBufferEffect::create_shadow_pipeline() { WGPUShaderModule shader = wgpuDeviceCreateShaderModule(ctx_.device, &shader_desc); // BGL: B0=GlobalUniforms, B1=ObjectsBuffer, B2=texture_depth_2d, B3=GBufLightsUniforms - WGPUBindGroupLayoutEntry bgl_entries[4] = {}; + WGPUBindGroupLayoutEntry bgl_entries[5] = {}; bgl_entries[0].binding = 0; bgl_entries[0].visibility = @@ -621,8 +590,13 @@ void GBufferEffect::create_shadow_pipeline() { bgl_entries[3].buffer.type = WGPUBufferBindingType_Uniform; bgl_entries[3].buffer.minBindingSize = sizeof(GBufLightsUniforms); + bgl_entries[4].binding = 4; + bgl_entries[4].visibility = WGPUShaderStage_Fragment; + bgl_entries[4].texture.sampleType = WGPUTextureSampleType_Float; + bgl_entries[4].texture.viewDimension = WGPUTextureViewDimension_2D; + WGPUBindGroupLayoutDescriptor bgl_desc = {}; - bgl_desc.entryCount = 4; + bgl_desc.entryCount = 5; bgl_desc.entries = bgl_entries; WGPUBindGroupLayout bgl = wgpuDeviceCreateBindGroupLayout(ctx_.device, &bgl_desc); @@ -793,7 +767,3 @@ void GBufferEffect::update_raster_bind_group(NodeRegistry& nodes) { wgpuBindGroupLayoutRelease(bgl); } -void GBufferEffect::update_pack_bind_group(NodeRegistry& nodes) { - (void)nodes; - // Pack bind group is rebuilt inline in render() to use current node views. -} diff --git a/cnn_v3/src/gbuffer_effect.h b/cnn_v3/src/gbuffer_effect.h index c39219b..13d394d 100644 --- a/cnn_v3/src/gbuffer_effect.h +++ b/cnn_v3/src/gbuffer_effect.h @@ -68,8 +68,6 @@ class GBufferEffect : public Effect { std::string node_depth_; std::string node_shadow_; std::string node_transp_; - std::string node_feat0_; - std::string node_feat1_; // Owned scene and camera — populated by set_scene() Scene scene_; @@ -88,7 +86,6 @@ class GBufferEffect : public Effect { // Pass 4: Pack compute pipeline ComputePipeline pack_pipeline_; - BindGroup pack_bind_group_; UniformBuffer<GBufResUniforms> pack_res_uniform_; UniformBuffer<GBufLightsUniforms> lights_uniform_; @@ -102,7 +99,6 @@ class GBufferEffect : public Effect { 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); |
