Skip to content

feat(graphic): add gbufferpass#427

Merged
ripel2 merged 23 commits into
mainfrom
gbuffer-pass
Jan 23, 2026
Merged

feat(graphic): add gbufferpass#427
ripel2 merged 23 commits into
mainfrom
gbuffer-pass

Conversation

@Miou-zora

@Miou-zora Miou-zora commented Jan 19, 2026

Copy link
Copy Markdown
Contributor

This pull request introduces a new GBuffer render pass and updates the GPU transform buffer and rendering pipeline to support it. The changes improve the handling of normal matrices in GPU buffers and shaders, and refactor the render graph initialization to include the new GBuffer pass. Additionally, there are minor improvements to resource and shader management for consistency.

Here the result textures of the gbuffer test:

Albedo texture (the color of the object) Depth texture (the depth from the camera so black = close and white = far) Normal (the direction of the face)
GBUFFER_ALBEDO GBUFFER_DEPTH GBUFFER_NORMAL

GBuffer Render Pass Integration:

  • Added a new GBuffer render pass (GBuffer.hpp) that outputs normal, albedo, and depth textures, including its shader definition and rendering logic.
  • Implemented the Create3DGraph system for initializing the render graph with the GBuffer pass and its output textures. [1] [2]
  • Registered the new Create3DGraph system in the default pipeline plugin, ensuring it runs during pipeline setup. [1] [2]

GPU Transform Buffer and Shader Updates:

  • Changed the GPU transform buffer (TransformGPUBuffer.hpp) to store the normal matrix as a full mat4 instead of three vec4 columns, updating both the struct and buffer writing logic. [1] [2]
  • Updated shader code and layouts in DefaultRenderPass.hpp to use mat4 for the normal matrix, and adjusted how normals are transformed in the vertex shader. [1] [2] [3]

Resource and Shader Management Improvements:

  • Standardized the use of ASingleExecutionRenderPass and removed legacy includes for single execution render passes. [1] [2]
  • Updated depth buffer format to Depth32Float for consistency across passes.

Summary by CodeRabbit

  • New Features

    • Added a G‑Buffer deferred render pass and a 3D render‑graph initialization.
  • Improvements

    • Broader texture format support and improved texture readback.
    • Increased depth precision using 32‑bit depth textures.
    • More robust normal‑matrix handling for GPU uploads and shader payloads.
    • Render-pass output ordering made deterministic.
  • Tests

    • Added a headless integration smoke test for the rendering pipeline.
  • Chores

    • CI test command flags adjusted.
  • Breaking Changes

    • Public event/structure types updated (window resize type and render‑pass output container).

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Jan 19, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds a G-buffer render pass and shader, creates a 3D render graph with normal/albedo/depth targets and resize-aware textures, switches normal-matrix layout to mat4, updates texture/format handling and depth formats, integrates Create3DGraph into the default pipeline, and adds a headless G-buffer test and build/test wiring.

Changes

Cohort / File(s) Summary
G-buffer Render Pass
src/plugin/default-pipeline/src/resource/pass/GBuffer.hpp
New GBuffer render pass: per-entity render callback, camera/model/material bind-group handling, embedded WGSL shader, outputs for normal, albedo, depth.
Render-Graph Creation System
src/plugin/default-pipeline/src/system/initialization/Create3DGraph.hpp, src/plugin/default-pipeline/src/system/initialization/Create3DGraph.cpp
New Create3DGraph(core) builds RenderGraph with GBuffer pass; creates RGBA16Float normal, BGRA8Unorm albedo, Depth32Float depth textures; registers OnResize callbacks to recreate textures; stores graph in RenderGraphContainer.
Pipeline Integration & Plugin
src/plugin/default-pipeline/src/DefaultPipeline.hpp, src/plugin/default-pipeline/src/plugin/PluginDefaultPipeline.cpp
Added includes for GBuffer.hpp and Create3DGraph.hpp; inserted Create3DGraph into RenderingPipeline::Setup sequence after CreateDefaultRenderPipeline and before material/light setup; added documentation block.
Transform / Normal Matrix Layout
src/plugin/default-pipeline/src/resource/buffer/TransformGPUBuffer.hpp, src/plugin/default-pipeline/src/utils/DefaultRenderPass.hpp
Replaced per-column normalMatrix vec4 fields with a single glm::mat4 normalMatrix; GPU computation updated to use transpose(inverse(modelMatrix)); shader payload and vertex normal calculation updated; model bind-group min size adjusted.
Render Pass Base & Includes
src/plugin/default-pipeline/src/system/initialization/CreateDefaultRenderPipeline.cpp, src/plugin/graphic/src/Graphic.hpp
Switched include usage from SingleExecutionRenderPass.hpp to ASingleExecutionRenderPass.hpp.
Texture Readback & Formats
src/plugin/graphic/src/resource/Texture.hpp, src/plugin/graphic/src/utils/GetBytesPerPixel.cpp, src/plugin/graphic/src/system/preparation/PrepareEndRenderTexture.cpp
Added support for RGBA16Float and Depth32Float in texture retrieval and bytes-per-pixel; depth texture creation for end-render switched to Depth32Float; RetrieveImage updated to select DepthOnly aspect for depth formats.
RenderPass Output Container
src/plugin/graphic/src/resource/ARenderPass.hpp
OutputContainer::colorBuffers changed from std::unordered_map to std::map (deterministic ordering).
Window Resize Event
src/plugin/window/src/event/OnResize.hpp
OnResize::newSize type changed from glm::ivec2 to glm::uvec2.
Tests & Build
src/plugin/default-pipeline/tests/shader/GBufferTest.cpp, src/plugin/default-pipeline/xmake.lua
New headless G-buffer smoke test; added PluginGraphicTests test dependency and exported src/(resource/pass/*.hpp) public header path.
Docs / Minor Edits
src/plugin/graphic/src/resource/ShaderDescriptor.hpp
Added/expanded documentation comment in ShaderDescriptor::validate and minor formatting.

Sequence Diagram(s)

sequenceDiagram
    participant App as Application
    participant Sys as Create3DGraph
    participant Core as Engine::Core
    participant Tex as TextureContainer
    participant Graph as RenderGraph
    participant Pass as GBufferPass
    participant GPU as GPU

    App->>Sys: Create3DGraph(core)
    Sys->>Core: access containers & context
    Sys->>Tex: create Normal (RGBA16Float), Albedo (BGRA8Unorm), Depth (Depth32Float)
    Sys->>Core: register OnResize -> recreate textures
    Sys->>Graph: register GBuffer shader & pass
    Graph->>Core: store RenderGraph

    Note over App,GPU: At render time
    App->>Pass: Execute UniqueRenderCallback
    Pass->>Core: select active camera
    loop per entity (Transform + Mesh)
        Pass->>Pass: bind camera, model, material bind-groups
        Pass->>GPU: bind vertex/index buffers
        Pass->>GPU: draw indexed
    end
    GPU->>Tex: write Normal, Albedo, Depth outputs
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

enhancement

Suggested reviewers

  • Divengerss

Poem

🐇 I stitched a G-buffer, layer by layer,
Normals, albedo, depth — a tasty fare,
Mat4 now dances where vecs once played,
Resize-aware textures neatly laid,
Hopping frames forward with a carrot flare 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 69.23% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(graphic): add gbufferpass' directly relates to the main change—adding a new GBuffer render pass with supporting infrastructure.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Miou-zora

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jan 21, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/plugin/default-pipeline/src/resource/buffer/TransformGPUBuffer.hpp (1)

17-29: Update outdated documentation and comment.

The struct documentation (lines 20-23) and the inline comment (line 27) still reference the old mat3x3<f32> layout with 112 bytes total. The struct now uses mat4 for normalMatrix, making the total size 128 bytes (64 + 64).

📝 Proposed documentation fix
 /**
  * `@brief` GPU buffer structure for model transform data
  *
  * Contains the model matrix and normal matrix for proper vertex/normal transformations.
  * The normal matrix (inverse transpose of the upper-left 3x3 of modelMatrix) is required
  * for correct normal transformation when the model has non-uniform scaling.
  *
  * Layout (WGSL std140 alignment):
  * - modelMatrix: mat4x4<f32> (64 bytes, offset 0)
- * - normalMatrix: mat3x3<f32> (48 bytes, offset 64) - each column is 16-byte aligned
- * Total: 112 bytes
+ * - normalMatrix: mat4x4<f32> (64 bytes, offset 64)
+ * Total: 128 bytes
  */
 struct TransformGPUData {
     glm::mat4 modelMatrix;
-    // mat3x3 in WGSL has each column aligned to 16 bytes, so we use vec4 for each column
+    // Normal matrix stored as mat4 for shader compatibility
     glm::mat4 normalMatrix;
 };
🤖 Fix all issues with AI agents
In `@src/plugin/default-pipeline/src/plugin/PluginDefaultPipeline.cpp`:
- Around line 32-34: The two setup systems CreateDefaultRenderPipeline and
Create3DGraph both call renderPassContainer.SetDefault(), and because
RegisterSystems<RenderingPipeline::Setup> registers Create3DGraph after
CreateDefaultRenderPipeline its SetDefault() overwrites the earlier default; fix
by either removing the redundant renderPassContainer.SetDefault() call from
CreateDefaultRenderPipeline (if the GBuffer 3D graph should be the primary
default) or by removing CreateDefaultRenderPipeline from the registration (if
it’s no longer needed), or alternatively change registration order and document
the intended fallback behavior so the default is set only once and intentionally
(update CreateDefaultRenderPipeline, Create3DGraph, and the
RegisterSystems<RenderingPipeline::Setup> registration accordingly).

In `@src/plugin/default-pipeline/src/resource/pass/GBuffer.hpp`:
- Around line 73-76: The normal is being transformed with a w=1.0 which applies
translation; in the GBuffer shader change the normal transformation in the line
that assigns output.fragNormal (the normalize((object.normal * vec4(normal,
1.0)).xyz) expression) to use vec4(normal, 0.0) instead so the normal is treated
as a direction (no translation) before normalization.

In `@src/plugin/default-pipeline/src/system/initialization/Create3DGraph.cpp`:
- Around line 73-84: The OnResize callback for the depth texture is
removing/adding the NORMAL ID by mistake; locate the lambda registered on
eventManager for Window::Event::OnResize in Create3DGraph.cpp that uses
CreateGBufferPassOutputDepthTextureDescriptor and textureContainer, and change
the calls that reference
DefaultPipeline::Resource::GBUFFER_PASS_OUTPUT_NORMAL_ID to use
DefaultPipeline::Resource::GBUFFER_PASS_OUTPUT_DEPTH_ID instead (both the Remove
and Add calls) so the depth texture is resized and stored under the correct
DEPTH ID.
- Around line 61-72: The resize callback in Create3DGraph.cpp mistakenly removes
and re-adds DefaultPipeline::Resource::GBUFFER_PASS_OUTPUT_NORMAL_ID instead of
the albedo ID, causing the albedo texture to not be recreated and the normal
texture to be overwritten; update the lambda registered via
eventManager.RegisterCallback<Window::Event::OnResize> to call
textureContainer.Remove(DefaultPipeline::Resource::GBUFFER_PASS_OUTPUT_ALBEDO_ID)
and
textureContainer.Add(DefaultPipeline::Resource::GBUFFER_PASS_OUTPUT_ALBEDO_ID,
std::move(resizedTexture)) so the albedo texture (created by
CreateGBufferPassOutputAlbedoTextureDescriptor and managed in textureContainer)
is replaced on resize rather than the normal texture.
- Around line 31-40: The depth texture descriptor in
CreateGBufferPassOutputDepthTextureDescriptor omits
wgpu::TextureUsage::TextureBinding; update the descriptor. In the function
CreateGBufferPassOutputDepthTextureDescriptor (resource label
DefaultPipeline::Resource::GBUFFER_PASS_OUTPUT_DEPTH) add TextureBinding to
descriptor.usage so it matches the normal and albedo outputs (RenderAttachment |
CopySrc | CopyDst | TextureBinding), enabling sampling of the depth buffer for
deferred shading or other uses.

In
`@src/plugin/default-pipeline/src/system/initialization/CreateDefaultRenderPipeline.cpp`:
- Line 3: Remove the unused include "resource/ASingleExecutionRenderPass.hpp"
from CreateDefaultRenderPipeline.cpp; the function only uses
Utils::DefaultRenderPass and Graphic::Resource types (no references to
ASingleExecutionRenderPass), so delete that include line to clean up unused
headers.
🧹 Nitpick comments (8)
src/plugin/graphic/src/resource/Texture.hpp (3)

47-64: Consider combining identical switch cases.

The RGBA8UnormSrgb and RGBA8Unorm cases have identical handling. Use fallthrough to reduce duplication.

♻️ Proposed fix
         switch (data->format)
         {
         case wgpu::TextureFormat::RGBA8UnormSrgb:
-            pixel.r = mapped[i * 4 + 0];
-            pixel.g = mapped[i * 4 + 1];
-            pixel.b = mapped[i * 4 + 2];
-            pixel.a = mapped[i * 4 + 3];
-            break;
-        case wgpu::TextureFormat::RGBA8Unorm:
+        case wgpu::TextureFormat::RGBA8Unorm: // fallthrough
             pixel.r = mapped[i * 4 + 0];
             pixel.g = mapped[i * 4 + 1];
             pixel.b = mapped[i * 4 + 2];
             pixel.a = mapped[i * 4 + 3];
             break;

65-82: Endianness assumption in bit_cast.

The std::bit_cast from std::array<uint8_t, N> to numeric types assumes little-endian byte order. This is typically fine for WebGPU targets but worth noting in a comment for maintainability.


208-216: Consider adding Depth16Unorm to depth format check.

The depth format detection is missing wgpu::TextureFormat::Depth16Unorm. If this format is used, the copy would fail or produce incorrect results.

♻️ Proposed fix
         if (_webgpuTexture.getFormat() == wgpu::TextureFormat::Depth24Plus ||
             _webgpuTexture.getFormat() == wgpu::TextureFormat::Depth24PlusStencil8 ||
             _webgpuTexture.getFormat() == wgpu::TextureFormat::Depth32Float ||
-            _webgpuTexture.getFormat() == wgpu::TextureFormat::Depth32FloatStencil8)
+            _webgpuTexture.getFormat() == wgpu::TextureFormat::Depth32FloatStencil8 ||
+            _webgpuTexture.getFormat() == wgpu::TextureFormat::Depth16Unorm)
src/plugin/default-pipeline/src/utils/DefaultRenderPass.hpp (1)

224-230: Stale comment: Update to reflect actual buffer layout.

The comment says "mat4 modelMatrix (64 bytes) + 3 * vec4 normalMatrix columns (48 bytes) = 112 bytes" but the actual layout is now two mat4 matrices (128 bytes total), matching the sizeof(glm::mat4) + sizeof(glm::mat4) on line 228.

📝 Suggested fix
-        // Model buffer contains: mat4 modelMatrix (64 bytes) + 3 * vec4 normalMatrix columns (48 bytes) = 112 bytes
+        // Model buffer contains: mat4 modelMatrix (64 bytes) + mat4 normalMatrix (64 bytes) = 128 bytes
         auto modelLayout = Graphic::Utils::BindGroupLayout("ModelLayout")
src/plugin/default-pipeline/tests/shader/GBufferTest.cpp (1)

29-47: Consider adding basic assertions to validate extracted textures.

The extracted textures (normalImage, albedoImage, depthImage) are retrieved but never validated. Even for a smoke test, consider adding minimal assertions to ensure the textures have expected dimensions or are non-empty.

💡 Example assertions
void ExtractTextures(Engine::Core &core)
{
    auto &context = core.GetResource<Graphic::Resource::Context>();
    auto &textures = core.GetResource<Graphic::Resource::TextureContainer>();

    auto &normalTexture = textures.Get(DefaultPipeline::Resource::GBUFFER_PASS_OUTPUT_NORMAL_ID);
    auto normalImage = normalTexture.RetrieveImage(context);
+   EXPECT_GT(normalImage.width, 0);
+   EXPECT_GT(normalImage.height, 0);

    auto &albedoTexture = textures.Get(DefaultPipeline::Resource::GBUFFER_PASS_OUTPUT_ALBEDO_ID);
    auto albedoImage = albedoTexture.RetrieveImage(context);
+   EXPECT_GT(albedoImage.width, 0);

    auto &depthTexture = textures.Get(DefaultPipeline::Resource::GBUFFER_PASS_OUTPUT_DEPTH_ID);
    auto depthImage = depthTexture.RetrieveImage(context);
+   EXPECT_GT(depthImage.width, 0);

    // Uncomment to save the images
    // ...
}
src/plugin/default-pipeline/src/resource/pass/GBuffer.hpp (1)

158-164: Stale comment: same issue as in DefaultRenderPass.hpp.

The comment references the old layout "3 * vec4 normalMatrix columns (48 bytes) = 112 bytes" but the actual buffer is now two mat4 matrices (128 bytes).

📝 Suggested fix
-        // Model buffer contains: mat4 modelMatrix (64 bytes) + 3 * vec4 normalMatrix columns (48 bytes) = 112 bytes
+        // Model buffer contains: mat4 modelMatrix (64 bytes) + mat4 normalMatrix (64 bytes) = 128 bytes
         auto modelLayout = Graphic::Utils::BindGroupLayout("Model").addEntry(
src/plugin/default-pipeline/src/system/initialization/Create3DGraph.cpp (2)

42-47: Stale TODO comment.

The TODO says "resize on window resize" but resize handling is already implemented via the OnResize callbacks below.

📝 Suggested fix
 static void CreateGBufferTextures(Engine::Core &core)
 {
-    // TODO: resize on window resize
     const auto &context = core.GetResource<Graphic::Resource::Context>();

50-60: Consider extracting hardcoded texture size to a constant.

The initial texture size {800, 800} is hardcoded in three places. Consider extracting to a named constant for maintainability and to make it clear this is an initial/default size before the first resize event.

📝 Example
static constexpr glm::uvec2 DEFAULT_GBUFFER_SIZE{800, 800};

// Then use:
auto descriptor = CreateGBufferPassOutputNormalTextureDescriptor(DEFAULT_GBUFFER_SIZE);

Also applies to: 62-64, 74-76

Comment thread src/plugin/default-pipeline/src/plugin/PluginDefaultPipeline.cpp
Comment thread src/plugin/default-pipeline/src/resource/pass/GBuffer.hpp
@Miou-zora

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jan 23, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jan 23, 2026

Copy link
Copy Markdown
Contributor

Note

Docstrings generation - SUCCESS
Generated docstrings for this pull request at #430

coderabbitai Bot added a commit that referenced this pull request Jan 23, 2026
Docstrings generation was requested by @Miou-zora.

* #427 (comment)

The following files were modified:

* `src/plugin/default-pipeline/src/plugin/PluginDefaultPipeline.cpp`
* `src/plugin/default-pipeline/src/resource/buffer/TransformGPUBuffer.hpp`
* `src/plugin/default-pipeline/src/resource/pass/GBuffer.hpp`
* `src/plugin/default-pipeline/src/system/initialization/Create3DGraph.cpp`
* `src/plugin/default-pipeline/src/utils/DefaultRenderPass.hpp`
* `src/plugin/graphic/src/resource/ShaderDescriptor.hpp`
* `src/plugin/graphic/src/resource/Texture.hpp`
* `src/plugin/graphic/src/system/preparation/PrepareEndRenderTexture.cpp`
* `src/plugin/graphic/src/utils/GetBytesPerPixel.cpp`
Docstrings generation was requested by @Miou-zora.

*
#427 (comment)

The following files were modified:

* `src/plugin/default-pipeline/src/plugin/PluginDefaultPipeline.cpp`
*
`src/plugin/default-pipeline/src/resource/buffer/TransformGPUBuffer.hpp`
* `src/plugin/default-pipeline/src/resource/pass/GBuffer.hpp`
*
`src/plugin/default-pipeline/src/system/initialization/Create3DGraph.cpp`
* `src/plugin/default-pipeline/src/utils/DefaultRenderPass.hpp`
* `src/plugin/graphic/src/resource/ShaderDescriptor.hpp`
* `src/plugin/graphic/src/resource/Texture.hpp`
*
`src/plugin/graphic/src/system/preparation/PrepareEndRenderTexture.cpp`
* `src/plugin/graphic/src/utils/GetBytesPerPixel.cpp`

<details>
<summary>These files were ignored</summary>

* `src/plugin/default-pipeline/tests/shader/GBufferTest.cpp`

</details>

<details>
<summary>These file types are not supported</summary>

* `.github/workflows/ci.yml`

</details>

<details>
<summary>ℹ️ Note</summary><blockquote>

CodeRabbit cannot perform edits on its own pull requests yet.

</blockquote></details>

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/plugin/default-pipeline/src/utils/DefaultRenderPass.hpp (1)

218-271: Update the model-buffer size comment (now 128 bytes).
The comment still describes the old 3×vec4 layout, which no longer matches the mat4+mat4 buffer size.

💡 Suggested update
-        // Model buffer contains: mat4 modelMatrix (64 bytes) + 3 * vec4 normalMatrix columns (48 bytes) = 112 bytes
+        // Model buffer contains: mat4 modelMatrix (64 bytes) + mat4 normalMatrix (64 bytes) = 128 bytes
🤖 Fix all issues with AI agents
In `@src/plugin/default-pipeline/src/resource/pass/GBuffer.hpp`:
- Around line 159-165: The inline comment above modelLayout is outdated
(mentions 3×vec4 = 112 bytes) but the code uses sizeof(glm::mat4) +
sizeof(glm::mat4) = 128 bytes; update the comment to state the model buffer is
now 128 bytes (two mat4: modelMatrix + normalMatrix or equivalent) and remove
the old 3×vec4 wording so it matches the BindGroup created by
Graphic::Utils::BindGroupLayout("Model") and the
BufferBindGroupLayoutEntry("model").setMinBindingSize(sizeof(glm::mat4) +
sizeof(glm::mat4)) call.

In `@src/plugin/default-pipeline/src/system/initialization/Create3DGraph.cpp`:
- Around line 44-87: CreateGBufferTextures currently creates default GBuffer
textures at 800×800; instead query the current window size at initialization and
use it for the descriptor sizes. In CreateGBufferTextures, get the Window
resource (e.g. auto &window = core.GetResource<Window::Resource::Window>()) and
call window.GetSize(), then pass that size into
CreateGBufferPassOutputNormalTextureDescriptor /
CreateGBufferPassOutputAlbedoTextureDescriptor /
CreateGBufferPassOutputDepthTextureDescriptor for the initial texture creation;
keep the existing Window::Event::OnResize callbacks as-is.
🧹 Nitpick comments (1)
src/plugin/default-pipeline/tests/shader/GBufferTest.cpp (1)

61-66: Make the smoke test fail if the GBuffer pass is missing.
Right now the test succeeds even when the pass isn’t registered, so regressions won’t be caught.

💡 Suggested tweak
     core.RegisterSystem<RenderingPipeline::CommandCreation>([](Engine::Core &core) {
         auto &renderPassContainer = core.GetResource<Graphic::Resource::RenderGraphContainer>();
-        if (renderPassContainer.Contains(DefaultPipeline::Resource::GBUFFER_PASS_ID))
-        {
-            renderPassContainer.Get(DefaultPipeline::Resource::GBUFFER_PASS_ID).Execute(core);
-        }
+        ASSERT_TRUE(renderPassContainer.Contains(DefaultPipeline::Resource::GBUFFER_PASS_ID))
+            << "GBuffer pass not registered";
+        renderPassContainer.Get(DefaultPipeline::Resource::GBUFFER_PASS_ID).Execute(core);
     });

Comment thread src/plugin/default-pipeline/src/resource/pass/GBuffer.hpp Outdated
@Miou-zora Miou-zora marked this pull request as ready for review January 23, 2026 13:37

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/plugin/default-pipeline/src/utils/DefaultRenderPass.hpp`:
- Around line 236-240: The inline comment above the modelLayout binding is stale
(mentions 112 bytes) while the code uses sizeof(glm::mat4) + sizeof(glm::mat4) =
128 bytes; update or remove that comment in DefaultRenderPass.hpp so it matches
the current TransformGPUData layout. Locate the modelLayout creation
(Graphic::Utils::BindGroupLayout("ModelLayout") and
BufferBindGroupLayoutEntry("model")) and change the comment to state 128 bytes
(or describe the fields generically) to reflect the actual size computed by
sizeof(glm::mat4) + sizeof(glm::mat4).

In `@src/plugin/graphic/src/resource/Texture.hpp`:
- Around line 65-99: RetrieveImage selects Depth24Plus, Depth24PlusStencil8, and
Depth32FloatStencil8 as depth-only, but TextureRetrieveCallback (the switch
handling in Texture.hpp) only supports wgpu::TextureFormat::Depth32Float and
throws for other depth formats; update them to be consistent. Add switch cases
for wgpu::TextureFormat::Depth24Plus, wgpu::TextureFormat::Depth24PlusStencil8,
and wgpu::TextureFormat::Depth32FloatStencil8 in the TextureRetrieveCallback
readback switch (alongside Depth32Float) and convert their packed depth bytes
into a normalized float/byte like the Depth32Float path (or extract the 24-bit
depth component and scale to 0..255), and/or adjust RetrieveImage and its doc
comment to restrict accepted depth formats to only Depth32Float if you prefer
narrowing; ensure the changes reference TextureRetrieveCallback and
RetrieveImage so both selection/aspect logic and the switch cases remain in
sync.
♻️ Duplicate comments (5)
src/plugin/default-pipeline/src/plugin/PluginDefaultPipeline.cpp (1)

45-47: Registration order looks correct.

Based on the current implementation in Create3DGraph.cpp (line 183), Create3DGraph calls renderPassContainer.Add(GBUFFER_PASS_ID, ...) rather than SetDefault(), so it adds a named render graph without overwriting the default set by CreateDefaultRenderPipeline. This is the expected behavior for having both a default render pipeline and a GBuffer-based 3D graph available.

src/plugin/default-pipeline/src/system/initialization/Create3DGraph.cpp (2)

54-64: LGTM! Depth texture now includes TextureBinding usage.

The depth texture descriptor correctly includes TextureBinding | RenderAttachment | CopySrc | CopyDst, enabling sampling for deferred shading passes.


75-119: LGTM! GBuffer texture creation and resize handling looks correct.

The implementation now:

  • Uses window.GetSize() for initial texture dimensions instead of hardcoded values
  • Correctly uses the matching texture IDs in each resize callback (NORMAL, ALBEDO, DEPTH respectively)
src/plugin/default-pipeline/src/resource/pass/GBuffer.hpp (2)

33-93: LGTM! GBuffer shader is well-structured.

The shader correctly:

  • Uses mat4x4<f32> for the normal matrix
  • Transforms normals with vec4(normal, 0.0) to exclude translation
  • Outputs normalized world-space normals and albedo to the G-buffer

177-257: LGTM! CreateShader is correctly configured.

The shader descriptor properly sets up:

  • Camera, model (128 bytes), and material bind group layouts
  • Vertex layout with position/normal/uv attributes
  • RGBA16Float for normal output, BGRA8Unorm for albedo
  • Depth32Float with depth write enabled
🧹 Nitpick comments (1)
src/plugin/graphic/src/system/preparation/PrepareEndRenderTexture.cpp (1)

108-120: Consider using designated initializers for consistency.

The existing EnsurePlaceholderEndRenderTexture function (line 16) uses designated initializers for wgpu::Extent3D:

textureDesc.size = {.width = 1920u, .height = 1080u, .depthOrArrayLayers = 1};

For consistency and improved readability, consider using the same style here.

♻️ Suggested change
-    textureDesc.size = {requiredSize.x, requiredSize.y, 1};
+    textureDesc.size = {.width = requiredSize.x, .height = requiredSize.y, .depthOrArrayLayers = 1};

Comment thread src/plugin/default-pipeline/src/utils/DefaultRenderPass.hpp
Comment thread src/plugin/graphic/src/resource/Texture.hpp

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/plugin/default-pipeline/src/system/initialization/Create3DGraph.cpp`:
- Around line 67-73: Update the docstring above the G-buffer setup in
Create3DGraph.cpp to reflect that textures are initialized to the current window
size (using Window::GetSize() or equivalent) with a fallback/default of 800×800,
rather than always being created at 800×800; mention that the textures (normal
RGBA16F, albedo BGRA8Unorm, depth Depth32Float) are stored in the engine's
TextureContainer under the pipeline G-buffer IDs and that
Window::Event::OnResize handlers recreate/replace them when the window size
changes.

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
9.6% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@ripel2

ripel2 commented Jan 23, 2026

Copy link
Copy Markdown
Contributor

duplicated code seems to only be for docs ?? so it will be merged as is even though sonar is not happy

@ripel2 ripel2 merged commit 55a95d0 into main Jan 23, 2026
14 of 15 checks passed
@ripel2 ripel2 deleted the gbuffer-pass branch January 23, 2026 19:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants