Skip to content

Conversation

suryadas-trenser
Copy link

Context

This PR introduces a GPU-based image smoothing feature using a dynamically generated Gaussian kernel. The smoothing intensity is controlled by the user, allowing for flexible and strong blur effects. This addresses requests for more effective image smoothing in the rendering pipeline.
Fixes issue: #246

Changes & Results

  • Added a utility function createGaussianKernel to generate normalized Gaussian kernels of arbitrary size and blur strength.
  • Updated the render pass logic to use a large (e.g., 15x15) Gaussian kernel for smoothing, with intensity controlling the blend between identity and full smooth.

Testing

  • Set a negative intensity value in the rendering engine to activate smoothing.
  • Verify that images become increasingly blurred as intensity decreases.

Checklist

PR

  • My Pull Request title is descriptive, accurate and follows the
    semantic-release format and guidelines.

Code

  • My code has been well-documented (function documentation, inline comments,
    etc.)

Public Documentation Updates

  • The documentation page has been updated as necessary for any public API
    additions or removals.

Tested Environment

  • "OS: Windows 10
  • "Node version: 22.11.0
  • "Browser: Chrome 140.0.7339.208

@suryadas-trenser
Copy link
Author

@sedghi could you please review this?

@daker
Copy link
Contributor

daker commented Sep 30, 2025

+1, maybe @IbrahimCSAE can have look?

@sedghi sedghi requested a review from Copilot September 30, 2025 13:44
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces GPU-based image smoothing functionality for stack and volume viewports using dynamically generated Gaussian kernels. The feature allows users to control smoothing intensity through negative values, providing flexible blur effects to reduce noise and soften edges in medical images.

Key changes include:

  • Added createGaussianKernel utility function for generating normalized Gaussian blur kernels
  • Implemented smoothing render pass with configurable intensity control
  • Extended viewport properties and rendering logic to support smoothing alongside existing sharpening

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
utils/ExampleRunner/example-info.json Added smoothing example entry to demo configuration
packages/core/src/types/ViewportProperties.ts Added smoothing property to viewport properties interface
packages/core/src/RenderingEngine/renderPasses/smoothingRenderPass.ts New render pass implementation with Gaussian kernel generation
packages/core/src/RenderingEngine/renderPasses/index.ts Exported new smoothing render pass function
packages/core/src/RenderingEngine/StackViewport.ts Integrated smoothing support into stack viewport rendering
packages/core/src/RenderingEngine/BaseVolumeViewport.ts Integrated smoothing support into volume viewport rendering
packages/core/examples/smoothing/index.ts Complete example demonstrating smoothing functionality

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@IbrahimCSAE
Copy link
Collaborator

Im confused with the latest change, if i understood correctly, you made it so if sharpening is a negative value you apply smoothing?

I don't like that because it's a bit confusing, my initial comment suggested if there's a way to apply both at the same time, for ex sharpening 0.5, smoothing 0.5, and then use both render passes.

If you have tried this and it wasn't possible, then let me know

 protected shouldUseCustomRenderPass(): boolean {
    return !this.useCPURendering;
  }

  /**
   * Get render passes for this viewport.
   * If sharpening is enabled, returns appropriate render passes.
   * @returns Array of VTK render passes or null if no custom passes are needed
   */
  public getRenderPasses = () => {
    if (!this.shouldUseCustomRenderPass()) {
      return null;
    }
    
    const renderPasses = []

    try {
      if (this.smoothing > 0) {
        renderPasses.push(createSmoothingRenderPass(this.smoothing))
      }
     if (this.sharpening > 0) {
       renderPasses.push(createSharpeningRenderPass(this.sharpening))
      } 
 
    return renderPasses.length ? renderPasses : null
    } catch (e) {
      console.warn('Failed to create custom render passes:', e);
      return null;
    }

@IbrahimCSAE IbrahimCSAE requested a review from sedghi October 7, 2025 13:11
@suryadas-trenser
Copy link
Author

Im confused with the latest change, if i understood correctly, you made it so if sharpening is a negative value you apply smoothing?

I don't like that because it's a bit confusing, my initial comment suggested if there's a way to apply both at the same time, for ex sharpening 0.5, smoothing 0.5, and then use both render passes.

If you have tried this and it wasn't possible, then let me know

 protected shouldUseCustomRenderPass(): boolean {
    return !this.useCPURendering;
  }

  /**
   * Get render passes for this viewport.
   * If sharpening is enabled, returns appropriate render passes.
   * @returns Array of VTK render passes or null if no custom passes are needed
   */
  public getRenderPasses = () => {
    if (!this.shouldUseCustomRenderPass()) {
      return null;
    }
    
    const renderPasses = []

    try {
      if (this.smoothing > 0) {
        renderPasses.push(createSmoothingRenderPass(this.smoothing))
      }
     if (this.sharpening > 0) {
       renderPasses.push(createSharpeningRenderPass(this.sharpening))
      } 
 
    return renderPasses.length ? renderPasses : null
    } catch (e) {
      console.warn('Failed to create custom render passes:', e);
      return null;
    }

Im confused with the latest change, if i understood correctly, you made it so if sharpening is a negative value you apply smoothing?

I don't like that because it's a bit confusing, my initial comment suggested if there's a way to apply both at the same time, for ex sharpening 0.5, smoothing 0.5, and then use both render passes.

If you have tried this and it wasn't possible, then let me know

 protected shouldUseCustomRenderPass(): boolean {
    return !this.useCPURendering;
  }

  /**
   * Get render passes for this viewport.
   * If sharpening is enabled, returns appropriate render passes.
   * @returns Array of VTK render passes or null if no custom passes are needed
   */
  public getRenderPasses = () => {
    if (!this.shouldUseCustomRenderPass()) {
      return null;
    }
    
    const renderPasses = []

    try {
      if (this.smoothing > 0) {
        renderPasses.push(createSmoothingRenderPass(this.smoothing))
      }
     if (this.sharpening > 0) {
       renderPasses.push(createSharpeningRenderPass(this.sharpening))
      } 
 
    return renderPasses.length ? renderPasses : null
    } catch (e) {
      console.warn('Failed to create custom render passes:', e);
      return null;
    }

Changes have been made as per the above comment. Please check @IbrahimCSAE

@suryadas-trenser
Copy link
Author

@IbrahimCSAE , could you please review this PR again?
CC: @sedghi

@sedghi sedghi requested a review from IbrahimCSAE October 16, 2025 13:09
@IbrahimCSAE
Copy link
Collaborator

merge after CI

@sedghi
Copy link
Member

sedghi commented Oct 17, 2025

git pull origin main -> so that ci is fixed

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.

4 participants