google / neuroglancer

WebGL-based viewer for volumetric data
Apache License 2.0
1.07k stars 295 forks source link

neuroglancer default framebuffer size artificially limits resolution #520

Open fcollman opened 8 months ago

fcollman commented 8 months ago

When taking screenshots it seems that in many cases neuroglancer in many cases downsamples the underlying data it has in doing its rendering. Currently I use a hacky workaround to solve this, which is 'zooming out' using the browser functionality in chrome with command - to go to 25% zoom or so. This seems to cause neuroglancer to believe that my monitor has more pixels and the WebGL canvas is larger, and so it uses more voxels to do the rendering resulting in crisper meshes and higher resolution images.

Here for example are two images of a cutout of the same screenshot of the same data from the same overall view, which only has 1 downsampling level available. image

It's not very noticeable for images until you zoom in/crop them, but its quite noticeable for meshes.

image

vs

image

I wonder if this is

  1. an error in the framebuffer calculation size
  2. intentional, but an option that should be modifiable in the state
  3. intentional, but an option that should be modifiable as a build time option for different deployments

this 'zoom out' hack is a) not intuitive for users, and make the UI generally unusable, so I do it just for screenshots and then zoom back in. It would be nice if the visualization looked better all the time though while making the UI still usable. It might need adjustment to how some annotations/skeletons are 'rendered' in that they are too small if the buffer is larger, but that can be fixed by just scaling up the size of the points/lines.

jbms commented 8 months ago

Currently Neuroglancer sizes the framebuffer according to the resolution in CSS pixels. This differs from the real display resolution according to https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio

Arguably the framebuffer should be sized to the real display resolution and line widths could still be set based on css pixels. This would make rendering slower, though.

Note that for screenshots you can use the Python API or neuroglancer.tool.screenshot to capture at any desired resolution.

jbms commented 8 months ago

Note that browser zoom level also affects the devicePixelRatio, but there are ways to cancel that out in order to retain the current behavior as far as browser zoom.

fcollman commented 8 months ago

I get a lot of complaints from non programmer users about neuroglancer not offering "full resolution" views, so i don't think the python api is a good solution for those users. I'd like to offer some kind of path where those users can get slower but higher quality renders if they desire without having to program anything... could this be a configuration option, and different deployments could turn it on/off by default?

fcollman commented 8 months ago

Or could we build a simple dependent project that would add a screenshot function that lets users explicit set the desired rendering resolution they want and neuroglancer does it for them. Pointing users to a deployed website to self service really is much better solution than telling them to download and install python just to take a screenshot, this really becomes a barrier for many people.

fcollman commented 8 months ago

Note that browser zoom level also affects the devicePixelRatio, but there are ways to cancel that out in order to retain the current behavior as far as browser zoom.

wouldn't this result in the lower quality mesh rendering at all zooms? this seems like the opposite behavior than I was advocating for, but maybe i misunderstand.

dyf commented 8 months ago

I get a lot of complaints from non programmer users about neuroglancer not offering "full resolution" views, so i don't think the python api is a good solution for those users. I'd like to offer some kind of path where those users can get slower but higher quality renders if they desire without having to program anything... could this be a configuration option, and different deployments could turn it on/off by default?

Just adding my support for finding a way to address this issue - the inability to view data at full resolution is a very significant. Multiple scientists have asked for neuroglancer alternatives for this reason.

jbms commented 8 months ago

I get a lot of complaints from non programmer users about neuroglancer not offering "full resolution" views, so i don't think the python api is a good solution for those users. I'd like to offer some kind of path where those users can get slower but higher quality renders if they desire without having to program anything... could this be a configuration option, and different deployments could turn it on/off by default?

To be clear, I am definitely considering changing Neuroglancer to just use the real display resolution. There are already the "Resolution" settings for each layer. I suppose there could be a global setting as well. Mobile browsers are one case where using the real display resolution may be undesirable, since you have the combination of lower performance and very high dpi.

In general while I don't have time to address all issues that are raised, it is helpful to open issues like this one as problems come up. I don't think anyone raised this issue before.

As far as the Python screenshot functionality, that does provide a way to collect a screenshot at any desired resolution, including extremely large resolutions that are too large to be rendered all at once, in which case it automatically produces it by combining multiple tiles. But indeed that approach is not as convenient for simple use cases as just capturing a screenshot of the already-open browser.

wouldn't this result in the lower quality mesh rendering at all zooms? this seems like the opposite behavior than I was advocating for, but maybe i misunderstand.

When you use the browser zoom function (as opposed to the Neuroglancer zoom setting) it changes the number of real device pixels that correspond to a CSS pixel, and therefore changes the number of CSS pixels that fit within the window. Since currently Neuroglancer uses CSS pixels, changing the browser zoom changes the size of the framebuffer and the level of detail that Neuroglancer chooses. If instead the framebuffer was sized based on device pixels, then changing the browser zoom would only affect the size of lines but not the framebuffer size or level of detail chosen.

Or could we build a simple dependent project that would add a screenshot function that lets users explicit set the desired rendering resolution they want and neuroglancer does it for them. Pointing users to a deployed website to self service really is much better solution than telling them to download and install python just to take a screenshot, this really becomes a barrier for many people.

I'd also be happy to accept a change like this into Neuroglancer itself.