Skip to content

volume box boundary and half pixel multires shift #24

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

ekatrukha
Copy link
Contributor

@ekatrukha ekatrukha commented May 10, 2025

This request is made to illustrate that:

  1. The rendering volume box needs to be expanded to the interval from (-0.5 * pixel size) till (Npixels+0.5*pixel size).
    At the moment it is rendered from sourcemin till sourcemax, i.e. for a two pixels wide volume, from 0 to 1. While it should be from -0.5 till 1.5.
    This should be corrected in all three sample_volume_... shaders.
    Correcting this issue will allow to display volumes with a single plane (2D XY image).

  2. There is a half-pixel shift (+crop) in rendering for multi-resolution datasets (compared to SimpleStack, which is rendered correctly).

The example code to reproduce the issue is src/test/java/bvv/debug/DebugHalfPixel.java

Right now it is fixed by introducing "fake" interpolation
at the boundaries of the volume (where coordinates are negative).

@ekatrukha ekatrukha mentioned this pull request May 12, 2025
@NicoKiaru
Copy link

I just noticed a weird disappearing behavior for the thinest one:

ThinVolumes2.mp4

But it's really really great, I need to test this with ABBA: 2D planes on a 3D volume, all lazy loaded and multiresolutions.

@ekatrukha
Copy link
Contributor Author

ekatrukha commented May 12, 2025

In my opinion, this issue is related to the volume's sampling step size along the view ray.

In the current implementation, the step is flexible and fast,
optimized for relatively large volumes:
the step is small closer to the viewer and becomes larger as we go deeper.

But this flexible sampling does not always hit the volume's front and back boundaries properly.
This becomes apparent for very thin volumes.

Another example: you can make an "empty" zero-intensity cube volume with
one of its faces being 255 (bright) intensity.
When this face is "at the back of the viewer", you are going to see all kinds of sampling artifacts.
Since the step size becomes larger "at the back", it does not always hits this max intensity face.

Here is an example (from some time ago):

bvv_error2-2024-06-28_10.36.57.mp4

Maybe we should provide an option for "detailed" render,
when we sample the view ray more carefully.

This is how it is done in napari and ClearVolume,
user can choose a degree of rendering load/sampling.

From my experience fiddling with this parameter,
loading data to GPU is the most time-consuming step,
rather than sampling it.
But we need some more careful testing to confirm it.

I can submit another PR to illustrate this issue,
if someone is interested.

Cheers,
Eugene

@NicoKiaru
Copy link

NicoKiaru commented May 13, 2025

Understood. FYI here's how it looks on ABBA:

Sections2D.mp4

(there's a weird super bright edge - I'm not sure what's the source of it)

I also hit the shader size limit you mentioned before when there are too many volumes. So I have to select a subset of slices.

I was wondering: in your example, if you disable the interpolation in the sampling (you showed this on bsky AFAIR), do you get the same artifact ?

@imagesc-bot
Copy link

This pull request has been mentioned on Image.sc Forum. There might be relevant details there:

https://forum.image.sc/t/fiji-friends-weekly-dev-update-thread/103718/93

@ekatrukha
Copy link
Contributor Author

Hello @NicoKiaru,

Yes, with disabled interpolation, this artifact is the same.
With disabled interpolation we sample the "true" space at the same points.
After transforming them to corresponding storage array coordinates,
we just round up (floor()) this last coordinate (and sampling the texture that stores the volume).

Now I see your problem. It stems from the fact, that right now
BVV calculates view ray intersection with all volumes bounding boxes
and the result is stored as tnear and tfar. These are two points on the ray.
And then BVV goes from tnear to tfar with a gradually increasing step.
(This is how I understand it from the code and discussions with @tpietzsch ).

So if your single plane is "at the back", i.e. close to tfar, the chances
are higher that it would not be "hit", so it disappears.

Interesting, interesting. This means that if we have a volume with large
voxel size and a volume with small voxel size, the "large voxel" would be
sampled differently depending on the presence of "small voxel".

The solution in this case is the same as with exploding number of uniforms/textures:
make a separate shader for each volume.
Then at least tnear and tfar will "hit" front and back of each volume.
So it should solve two problems.

I will try to work on it in the coming time and submit a draft PR.

Cheers,
Eugene

@NicoKiaru NicoKiaru mentioned this pull request May 27, 2025
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.

3 participants