Skip to content

feat: add channel prop support to the volume layer#587

Merged
seankmartin merged 6 commits into
mainfrom
seankmartin-aranega/volume-rendering-channel-props
Feb 24, 2026
Merged

feat: add channel prop support to the volume layer#587
seankmartin merged 6 commits into
mainfrom
seankmartin-aranega/volume-rendering-channel-props

Conversation

@seankmartin

Copy link
Copy Markdown
Collaborator

Summary

One thing is common to both #564 and #583 - which is that there needs to be some way to define the properties of the channels for volume rendering. We've extracted that common piece here, as it is more self contained and would be helpful to get feedback on so then #564 and #583 can be adding on top of that.

The VolumeLayer has copied some of the channelProps functionality from the other image layers with the callbacks on channel change, how to set channels etc. And how the VolumeRenderable sets those as a uniform is similar to the ImageRenderable. This also helps in moving towards #555 and removing uniforms from the volume layer. In this only the first channel would be supported for passing the uniforms, but it lays the framework for using channel props for multi-channel rendering.

Tests & Checks

I manually tested the volume rendering examples and checked other examples to see if still working. Visually this shouldn't really change much, outside of the transfer function bounds being a little different for the invlerp mapping.

New:
image

Old:
image

in this only the first channel would be supported
but lays the framework for using channel props for multi-channel rendering

@shlomnissan shlomnissan left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks good! I'm blocking to get more information on:

}
}

public setChannelProps(newProps: ChannelProps[]) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nit: If copied over, might as well use same naming (i.e. channelProps instead of newProps).

@seankmartin seankmartin Feb 22, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Thank you for spotting this, changing it. This came from the fact that we actually wrote this setChannelProps quite a while ago before realising there was an established structure and then essentially copying that code over from the chunked image layer instead. Forgot to update this one in the process, thanks for noticing. The same applies to #587 (comment), so fixing that also

this.channelProps_ = newProps;
this.currentChunks_.forEach((chunk) => {
chunk.setChannelProps(newProps);
});

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The chunked image layer invokes callbacks when channel props are set:

this.channelChangeCallbacks_.forEach((callback) => {
    callback();
});

Why did we skip it here?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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


public setChannelProps(newProps: ChannelProps[]) {
this.channelProps_ = newProps;
this.currentChunks_.forEach((chunk) => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

When we get a pooled image in the chunked image layer, we set its channel props:

if (pooled) {
  const texture = pooled.textures[0] as Texture2DArray;
  texture.updateWithChunk(chunk, this.getDataForImage(chunk));
  this.updateImageChunk(pooled, chunk);
  if (this.channelProps_) {
    pooled.setChannelProps(this.channelProps_);
  }
  return pooled;
}

Why did we skip it here?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

No reason for skipping, glad you noticed it and apologies for missing in the first place, fixing that problem

this.programName = dataTypeToVolumeShader(texture.dataType);
this.cullFaceMode = "front";
this.depthTest = false;
// TODO handle visibility property of channels

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Is it a TODO because you still want to limit the scope of this PR to one channel? So this PR only covers the plumbing of channel props?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yes exactly, we could plumb it so that visibility is available as a uniform. But I think that might be better not to do right now as OIT and non-OIT would want to handle that visibility differently.

OIT would want to avoid rendering the chunk for that channel altogether if the channel is not visible, so this would be in the renderer. While non-OIT would have access to all the textures in the shader and conditionally sample based on the visibility of the channel, so having a uniform would be useful (it could also compile and use a different shader altogether to avoid the conditional in the shader but that's a bit of overhead to introduce right now)

@seankmartin seankmartin Feb 22, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

In general that is also why this PR isn't further updating getUniforms right now, as for OIT and without OIT the getUniforms would look fairly different

@shlomnissan shlomnissan left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM

@seankmartin seankmartin merged commit 55a8ade into main Feb 24, 2026
9 checks passed
@seankmartin seankmartin deleted the seankmartin-aranega/volume-rendering-channel-props branch February 24, 2026 16:51
@czi-github-helper

Copy link
Copy Markdown

🎉 This PR is included in version 0.11.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants