mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
102.98k stars 35.4k forks source link

Rendering issue using a 3D texture workaround #9937

Closed jonathanlurie closed 8 years ago

jonathanlurie commented 8 years ago

I am developping a tool for performing oblique slicing of neuro images, I am using shaders for the image projection. The projection seems to work well but I have some strange rendering artifacts in shapes of dashes. This occurs only when the projection is oblique (or at least not in the native ortho). Here is the image I use as a texture, it's 64 images and each is 64x64px, for a total of 64x4096px.

The workaround I use is the solution suggested by gman on SO. I also tried my own version, that uses simple nearest neighbor, but I have exactly the same issue. Note that, depending on the camera positioning, the dashes appear with a different frequency, this is why I am thinking of a rendering issue rather than a sampling issue. Also, these dashes seem to show in-between the native slices (when in oblique projection).

screenshot from 2016-10-25 11 15 18

screenshot from 2016-10-25 11 15 29

I made a fiddle.

Do you think it's a shader issue? Or maybe there is some OpenGL ES thingy to enable/disable?

Three.js version
jonathanlurie commented 8 years ago

I managed to make it work by just using the nearest neighbor interpolation:

var texture = new THREE.TextureLoader().load( texFile );
texture.magFilter = THREE.NearestFilter;
texture.minFilter = THREE.NearestFilter;

It works for my case but is not really a fix.

makc commented 8 years ago

well, what do you expect, you're jumping across many tiles and mipmaps try to mix them all together. see here for the workaround (involves 4x larger texture)

makc commented 8 years ago

also I think @spite had the shader somewhere where he used derivatives to figure out correct bias

NicolasRannou commented 8 years ago

FYI I ran in similar problems and as far as I can remember it was rounding issues in my case.

I also wanted to comment that you could consider using AMI/reslicing that already addresses the problem you are facing.

AMI is not part of the ThreeJS examples/demos because it would just be too much code.

AMI is a Medical Imaging Javascript toolkit build on top and for ThreeJS. Main difference with ALL existing Medical Imaging frameworks is that is relies on WebGL (not 2D canvas) for visualization, which results in a huge performance gain. It follows same API conventions as ThreeJS and provide loaders so you can already load common file formats (Dicom, nifti, nrrd, etc.) out of the box.

Please let me know if you'd like to contribute!

jonathanlurie commented 8 years ago

Thanks @makc for the link! It looks like I am not the only one facing this issue :)

jonathanlurie commented 8 years ago

@NicolasRannou AMI looks like a pretty well advance project! I had a glance at the slice code and it looks like you are loading 56 dicom images of 384x512x16bits, did you try with higher resolution?
The project I have is to create a multiresolution 3D viewer for large neuro imaging data (the BigBrain, which is about 7000x7000x7000 at 20μm), using an octree and a 3d texture workaround with dynamic fetching/loading. The cube I showed in the fiddle is only one of the chunks.

NicolasRannou commented 8 years ago

Nice @jonathanlurie, sounds like a very interesting project!

Yes I tried bigger but 7000x7000x7000 is definitely too big to be loaded all at once. Right now, we can only load 14x4096x4096 16 bits voxels at once in the shaders.

Yes fetching the right data/resolution from the server on demand could work. Please do not hesitate to post on Stackoverflow if you have questions or open issues on https://github.com/FNNDSC/ami/issues to continue the conversation! (threejs/issues is probably not the right place for it)

jonathanlurie commented 8 years ago

@NicolasRannou I'll keep you updated! if it works, it might be an interesting feature for AMI, and it's gonna be open source anyway :)