Skip to content

Comments

feat: add render target blit func#1298

Merged
yiiqii merged 2 commits intofeat/2.8from
feat/RT-blit-func
Dec 5, 2025
Merged

feat: add render target blit func#1298
yiiqii merged 2 commits intofeat/2.8from
feat/RT-blit-func

Conversation

@wumaolinmaoan
Copy link
Contributor

@wumaolinmaoan wumaolinmaoan commented Dec 2, 2025

  • refactor post process pass using blit function

Summary by CodeRabbit

Release Notes

  • New Features

    • Added texture blitting API enabling direct texture-to-framebuffer operations with optional custom materials for advanced rendering workflows.
  • Improvements

    • Enhanced bloom effect with multi-pass pipeline (threshold extraction, multi-level sampling, and reconstruction) for superior visual quality.
    • Simplified post-processing architecture improving rendering efficiency.

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

@wumaolinmaoan wumaolinmaoan requested a review from yiiqii December 2, 2025 05:23
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 2, 2025

Walkthrough

The PR refactors the bloom post-processing pipeline by consolidating a multi-pass manual implementation into a new BloomPass class encapsulating threshold extraction, hierarchical down-sampling, and up-sampling stages. A new blit API is added to the Renderer for texture-to-framebuffer copying, with WebGL-specific implementation provided. Supporting texture dimension handling is updated in framebuffer attachment updates.

Changes

Cohort / File(s) Summary
Bloom Pipeline Refactoring
packages/effects-core/src/render/post-process-pass.ts, packages/effects-core/src/render/render-frame.ts
Replaces BloomThresholdPass with BloomPass featuring multi-stage bloom: threshold extraction, horizontal/vertical down-sampling iterations, and reverse up-sampling. Introduces new materials (threshold, down-sample H/V, up-sample), manages temporary render targets internally, and accepts iterationCount parameter (default 4). Simplifies render-frame pipeline by replacing manual pass chain with single BloomPass instance.
Blit API Addition
packages/effects-core/src/render/renderer.ts, packages/effects-webgl/src/gl-renderer.ts
Adds public blit(source: Texture, destination: Framebuffer | null, material?: Material): void API to Renderer base class. GLRenderer implements full blit functionality with lazy-initialized quad geometry and default blit material, supporting custom materials and framebuffer/screen targets, with proper resource cleanup on dispose.
Texture Dimension Handling
packages/effects-webgl/src/gl-framebuffer.ts
Extracts explicit framebuffer viewport width/height and initializes color/depth textures with correct dimensional data (Uint8Array/Uint16Array buffers) during attachment updates, ensuring texture buffers align with current viewport dimensions.
Formatting
packages/effects-core/src/render/render-target-pool.ts
Adds blank line between color attachment creation and Framebuffer instantiation for improved code organization.

Sequence Diagram

sequenceDiagram
    participant Renderer
    participant BloomPass
    participant Materials as Materials<br/>(Threshold/Down/Up)
    participant RTs as Render Targets<br/>(Pool)
    participant Tonemap as ToneMappingPass

    Renderer->>BloomPass: configure(scene texture from framebuffer)
    
    BloomPass->>Materials: Threshold pass
    Materials->>RTs: render to threshold RT
    
    loop Down-sample iterations
        BloomPass->>Materials: Horizontal down-sample
        Materials->>RTs: render to down-sample H RT
        BloomPass->>Materials: Vertical down-sample
        Materials->>RTs: render to down-sample V RT
    end
    
    loop Up-sample iterations (reverse)
        BloomPass->>Materials: Up-sample with accumulated texture
        Materials->>RTs: render to up-sample RT
    end
    
    BloomPass->>RTs: release intermediate RTs
    BloomPass->>Tonemap: pass final bloom texture
    Tonemap->>Renderer: complete post-process pipeline
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • post-process-pass.ts: Dense multi-stage bloom logic with material initialization, render target sequencing (threshold → down-sample H/V loops → up-sample reverse loop), and resource lifecycle management requires careful tracing
  • render-frame.ts: Pipeline restructuring from manual multi-pass chain to encapsulated BloomPass needs verification of pass ordering and texture handle flow
  • gl-renderer.ts: New blit implementation handles framebuffer setup, viewport configuration, and cleanup—correctness critical for texture copying
  • Material and render target management: Verify no resource leaks and proper cleanup in all code paths

Poem

🐰 Bloom cascades through passes fine,
Down and up in rhythm's line,
Threshold glows, then shrinks and grows,
Blit the light where it flows—
Post-process gleams divine!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main addition: a new render target blit function that is implemented across multiple files and enables refactoring of the post-processing pipeline.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/RT-blit-func

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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
packages/effects-webgl/src/gl-framebuffer.ts (1)

74-95: Attachment textures now sized from viewport (good), but there’s some redundant work

Using this.viewport[2/3] to size color/depth textures and calling tex.update({ data }) here is correct and helps ensure Texture.getWidth()/getHeight() work for framebuffer-backed textures used in post-process (e.g., bloom).

Two small nits you may want to clean up later:

  • resetColorTextures already calls tex.update({ data }); updateAttachmentTextures then calls update again for the same color textures, which is redundant GPU work. You could limit updateAttachmentTextures to rebuilding attachmentTextures or add a flag/parameter to skip the extra updates when the caller already resized textures.
  • For depth_24_stencil_8_texture, depthTexture and stencilTexture reference the same GLTexture, so its textureBuffer gets pushed twice into attachmentTextures. It’s harmless but unnecessary; an identity check (if (this.depthTexture !== this.stencilTexture)) would avoid duplication.
packages/effects-core/src/render/render-frame.ts (1)

12-13: Bloom–ToneMapping wiring looks correct; consider making gaussianStep configurable

The new pipeline:

  • DrawObjectPass → BloomPass (using sceneTextureHandle to capture the pre‑bloom scene texture),
  • then ToneMappingPass consuming both the scene texture and Bloom’s result,

is wired correctly and matches how BloomPass.configure/execute and ToneMappingPass use sceneTextureHandle and mainTexture.

const gaussianStep = 7 hard‑codes a relatively high iteration count, which may be expensive on low‑end/mobile GPUs and can’t be tuned per effect/volume. Consider deriving the iteration count from post-process settings (e.g., volume bloom options) or at least exposing it via RenderFrameOptions so applications can adjust quality vs. performance.

Also applies to: 121-135

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aad7a7c and 1c6e2e2.

📒 Files selected for processing (6)
  • packages/effects-core/src/render/post-process-pass.ts (1 hunks)
  • packages/effects-core/src/render/render-frame.ts (2 hunks)
  • packages/effects-core/src/render/render-target-pool.ts (1 hunks)
  • packages/effects-core/src/render/renderer.ts (2 hunks)
  • packages/effects-webgl/src/gl-framebuffer.ts (1 hunks)
  • packages/effects-webgl/src/gl-renderer.ts (5 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-10-18T09:15:08.038Z
Learnt from: wumaolinmaoan
Repo: galacean/effects-runtime PR: 691
File: packages/effects-core/src/plugins/timeline/playables/color-property-mixer-playable.ts:39-42
Timestamp: 2024-10-18T09:15:08.038Z
Learning: In `packages/effects-core/src/plugins/timeline/playables/color-property-mixer-playable.ts`, when accumulating color components, avoid using `clone()` methods because it can cause additional garbage collection overhead.

Applied to files:

  • packages/effects-core/src/render/render-target-pool.ts
  • packages/effects-webgl/src/gl-renderer.ts
  • packages/effects-core/src/render/render-frame.ts
  • packages/effects-core/src/render/post-process-pass.ts
🧬 Code graph analysis (4)
packages/effects-core/src/render/renderer.ts (3)
plugin-packages/editor-gizmo/src/shape.ts (1)
  • Texture (139-160)
packages/effects-core/src/render/framebuffer.ts (1)
  • Framebuffer (28-82)
plugin-packages/model/src/gltf/loader-impl.ts (1)
  • material (1479-1562)
packages/effects-webgl/src/gl-renderer.ts (1)
packages/effects-core/src/gl/index.ts (1)
  • glContext (8-8)
packages/effects-core/src/render/render-frame.ts (1)
packages/effects-core/src/render/post-process-pass.ts (1)
  • BloomPass (18-171)
packages/effects-core/src/render/post-process-pass.ts (4)
packages/effects-core/src/render/render-pass.ts (3)
  • RenderPass (217-309)
  • RenderTargetHandle (100-176)
  • RenderPassDestroyOptions (206-210)
packages/effects-core/src/render/framebuffer.ts (1)
  • Framebuffer (28-82)
packages/effects-core/src/render/renderer.ts (1)
  • Renderer (14-145)
packages/effects-core/src/render/render-frame.ts (1)
  • getTextureSize (217-219)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (2)
packages/effects-core/src/render/render-target-pool.ts (1)

87-95: No functional change in RT creation block

The added blank line only separates texture creation from framebuffer creation; behavior and resource handling remain unchanged.

packages/effects-core/src/render/post-process-pass.ts (1)

17-36: BloomPass construction and configuration are consistent with the new pipeline

  • Materials for threshold, down-sample H/V, and up-sample are created with the correct screen-space vertex shader and appropriate fragment shaders, and render state (no blending, no depth, no culling) is appropriate for full-screen passes.
  • sceneTextureHandle wiring in configure correctly captures the pre-bloom scene texture for ToneMappingPass to use later as _SceneTex.

No functional issues here; this setup matches how RenderFrame and ToneMappingPass expect BloomPass to behave.

Also applies to: 48-86, 88-92

@yiiqii yiiqii merged commit 9e80800 into feat/2.8 Dec 5, 2025
2 checks passed
@yiiqii yiiqii deleted the feat/RT-blit-func branch December 5, 2025 01:54
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