[vtkusers] Strange rendering with 2-voxel thick volume

Aashish Chaudhary aashish.chaudhary at kitware.com
Thu Oct 5 10:34:09 EDT 2017


Thanks we are looking into it, earlier we moved the math from the shader to
a matrix that now we are forming in C++ so at this point we are looking at
the equation carefully. But yes, I thought you may have found a bug.

- aashish

On Thu, Oct 5, 2017 at 8:39 AM Elvis Stansvik <elvis.stansvik at orexplore.com>
wrote:

> 2017-10-05 10:38 GMT+02:00 Elvis Stansvik <elvis.stansvik at orexplore.com>:
> > 2017-10-04 18:12 GMT+02:00 Aashish Chaudhary <
> aashish.chaudhary at kitware.com>:
> >> Got it, thanks!
> >
> > Although I'm not familiar at all with the code, I suspect this is what
> > happens with my 200x200x2 volume:
> >
> > In void
> vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::ComputeCellToPointMatrix()
> > {
> >   this->CellToPointMatrix->Identity();
> >   this->AdjustedTexMin[0] = this->AdjustedTexMin[1] =
> > this->AdjustedTexMin[2] = 0.0f;
> >   this->AdjustedTexMin[3] = 1.0f;
> >   this->AdjustedTexMax[0] = this->AdjustedTexMax[1] =
> > this->AdjustedTexMax[2] = 1.0f;
> >   this->AdjustedTexMax[3] = 1.0f;
> >
> >   if (!this->Parent->CellFlag) // point data
> >   {
> >     float delta[3];
> >     delta[0] = this->Extents[1] - this->Extents[0];
> >     delta[1] = this->Extents[3] - this->Extents[2];
> >     delta[2] = this->Extents[5] - this->Extents[4];
> >
> >     float min[3];
> >     min[0] = 0.5f / delta[0];
> >     min[1] = 0.5f / delta[1];
> >     min[2] = 0.5f / delta[2];
> >
> >     float range[3]; // max - min
> >     range[0] = (delta[0] - 0.5f) / delta[0] - min[0];
> >     range[1] = (delta[1] - 0.5f) / delta[1] - min[1];
> >     range[2] = (delta[2] - 0.5f) / delta[2] - min[2];
> >
> >     this->CellToPointMatrix->SetElement(0, 0, range[0]); // Scale diag
> >     this->CellToPointMatrix->SetElement(1, 1, range[1]);
> >     this->CellToPointMatrix->SetElement(2, 2, range[2]);
> >     this->CellToPointMatrix->SetElement(0, 3, min[0]);   // t vector
> >     this->CellToPointMatrix->SetElement(1, 3, min[1]);
> >     this->CellToPointMatrix->SetElement(2, 3, min[2]);
> >
> >     // Adjust limit coordinates for texture access.
> >     float const zeros[4] = {0.0f, 0.0f, 0.0f, 1.0f}; // GL tex min
> >     float const ones[4]  = {1.0f, 1.0f, 1.0f, 1.0f}; // GL tex max
> >     this->CellToPointMatrix->MultiplyPoint(zeros, this->AdjustedTexMin);
> >     this->CellToPointMatrix->MultiplyPoint(ones, this->AdjustedTexMax);
> >   }
> > }
> >
> > delta[2] = 1 ==> min[2] = 0.5 ==> range[2] = 0
> >
> > So the scale factor in the third dimension will be 0 in
> > CellToPointMatrix, right? I guess this could be what accounts for the
> > strange rendering?
> >
> > Could/should this code be updated to take into account when the extent
> > delta is just 1, so that volumes 2 data points thick can be rendered?
>
> I've only tested it briefly, but this seems to give the correct
> rendering even with a 2 point thick input:
>
> diff --git a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx
> b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx
> index 8767bd0..88bbcba 100644
> --- a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx
> +++ b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx
> @@ -1495,9 +1495,9 @@ void
> vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::ComputeCellToPointMatrix()
>    if (!this->Parent->CellFlag) // point data
>    {
>      float delta[3];
> -    delta[0] = this->Extents[1] - this->Extents[0];
> -    delta[1] = this->Extents[3] - this->Extents[2];
> -    delta[2] = this->Extents[5] - this->Extents[4];
> +    delta[0] = std::max(2, this->Extents[1] - this->Extents[0]);
> +    delta[1] = std::max(2, this->Extents[3] - this->Extents[2]);
> +    delta[2] = std::max(2, this->Extents[5] - this->Extents[4]);
>
>      float min[3];
>      min[0] = 0.5f / delta[0];
>
> This ensures the texture does not collapse into 0 when the extent
> delta is 1. Would you consider this a correct fix?
>
> Elvis
>
> >
> > Elvis
> >
> >>
> >> On Wed, Oct 4, 2017 at 12:07 PM Elvis Stansvik
> >> <elvis.stansvik at orexplore.com> wrote:
> >>>
> >>> 2017-10-04 17:43 GMT+02:00 Aashish Chaudhary
> >>> <aashish.chaudhary at kitware.com>:
> >>> > thanks..I just wanted to make sure that we remove that as one of the
> >>> > culprit. I am wondering if it is something to do with the geometry
> >>> > (bbox) or
> >>> > something to do with some edge case (calculation that is going off
> >>> > because
> >>> > of very small delta). Although in the past we have tried very think
> >>> > volumes
> >>> >
> >>> > Is it possible for you to send a sample dataset to us?
> >>>
> >>> My test case includes the data used. It's simply a 200x200x2 volume
> >>> filled with all data points set to 0.01.
> >>>
> >>> Elvis
> >>>
> >>> >
> >>> > On Wed, Oct 4, 2017 at 10:09 AM Elvis Stansvik
> >>> > <elvis.stansvik at orexplore.com> wrote:
> >>> >>
> >>> >> Hi Aashish,
> >>> >>
> >>> >> 2017-10-04 15:47 GMT+02:00 Aashish Chaudhary
> >>> >> <aashish.chaudhary at kitware.com>:
> >>> >> > Please make sure that your sampling distance is less than < 2. You
> >>> >> > can
> >>> >> > set
> >>> >> > the sampling distance manually in the API.
> >>> >>
> >>> >> Hm. I don't think it's related to sampling distance. In the test
> case
> >>> >> I'm not setting sampling distance at all, so I think it should
> default
> >>> >> to 1, and then be automatically adjusted during interaction.
> >>> >>
> >>> >> In any case, even if I amend the test case with e.g.:
> >>> >>
> >>> >>     volumeMapper->AutoAdjustSampleDistancesOff();
> >>> >>     volumeMapper->SetSampleDistance(0.2);
> >>> >>     ...
> >>> >>     volumeMapper2->AutoAdjustSampleDistancesOff();
> >>> >>     volumeMapper2->SetSampleDistance(0.2);
> >>> >>
> >>> >> The result is the same.
> >>> >>
> >>> >> Elvis
> >>> >>
> >>> >> >
> >>> >> > On Wed, Oct 4, 2017 at 8:23 AM Elvis Stansvik
> >>> >> > <elvis.stansvik at orexplore.com>
> >>> >> > wrote:
> >>> >> >>
> >>> >> >> Hi all,
> >>> >> >>
> >>> >> >> In the test case below, I render one 200x200x2 volume and one
> >>> >> >> 200x200x3 volume, both with the same settings.
> >>> >> >>
> >>> >> >> The 200x200x3 volume looks as expected (the light gray one in the
> >>> >> >> attached screenshot), while the 200x200x2 one looks strange (too
> >>> >> >> dark,
> >>> >> >> and with some kind of gradient artifact).
> >>> >> >>
> >>> >> >> Is there some limitation on rendering a volume that is only 2
> thick
> >>> >> >> in
> >>> >> >> one of the dimensions? I can understand why a volume of
> thickness 1
> >>> >> >> can't be rendered properly, since VTK must have values to
> >>> >> >> interpolate
> >>> >> >> between, but 2 should be OK right?
> >>> >> >>
> >>> >> >> Thanks for any help.
> >>> >> >>
> >>> >> >> Elvis
> >>> >> >>
> >>> >> >>
> >>> >> >> main.cpp:
> >>> >> >>
> >>> >> >> #include <algorithm>
> >>> >> >>
> >>> >> >> #include <vtkColorTransferFunction.h>
> >>> >> >> #include <vtkGenericOpenGLRenderWindow.h>
> >>> >> >> #include <vtkGPUVolumeRayCastMapper.h>
> >>> >> >> #include <vtkImageData.h>
> >>> >> >> #include <vtkNew.h>
> >>> >> >> #include <vtkPiecewiseFunction.h>
> >>> >> >> #include <vtkProperty.h>
> >>> >> >> #include <vtkRenderer.h>
> >>> >> >> #include <vtkRenderWindow.h>
> >>> >> >> #include <vtkRenderWindowInteractor.h>
> >>> >> >> #include <vtkVolume.h>
> >>> >> >> #include <vtkVolumeProperty.h>
> >>> >> >>
> >>> >> >> int main(int argc, char *argv[])
> >>> >> >> {
> >>> >> >>     vtkNew<vtkColorTransferFunction> colorFunction;
> >>> >> >>     colorFunction->AddRGBPoint(0.0, 0.0, 0.0, 0.0);
> >>> >> >>     colorFunction->AddRGBPoint(1.0, 0.0, 0.0, 0.0);
> >>> >> >>
> >>> >> >>     vtkNew<vtkPiecewiseFunction> opacityFunction;
> >>> >> >>     opacityFunction->AddPoint(0.0, 0.0);
> >>> >> >>     opacityFunction->AddPoint(1.0, 1.0);
> >>> >> >>
> >>> >> >>     // A 200x200x2 volume
> >>> >> >>     vtkNew<vtkImageData> imageData;
> >>> >> >>     imageData->SetExtent(0, 199, 0, 199, 0, 1);
> >>> >> >>     imageData->AllocateScalars(VTK_FLOAT, 1);
> >>> >> >>     std::fill_n(static_cast<float
> *>(imageData->GetScalarPointer()),
> >>> >> >> 200 * 200 * 2, 0.01);
> >>> >> >>
> >>> >> >>     vtkNew<vtkGPUVolumeRayCastMapper> volumeMapper;
> >>> >> >>     volumeMapper->SetInputData(imageData.Get());
> >>> >> >>
> >>> >> >>     vtkNew<vtkVolumeProperty> volumeProperty;
> >>> >> >>     volumeProperty->SetScalarOpacity(opacityFunction.Get());
> >>> >> >>     volumeProperty->SetColor(colorFunction.Get());
> >>> >> >>     volumeProperty->ShadeOff();
> >>> >> >>
> >>> >> >>     vtkNew<vtkVolume> volume;
> >>> >> >>     volume->SetMapper(volumeMapper.Get());
> >>> >> >>     volume->SetProperty(volumeProperty.Get());
> >>> >> >>     volume->SetPosition(120, 0, 0);
> >>> >> >>
> >>> >> >>     // A 200x200x3 volume
> >>> >> >>     vtkNew<vtkImageData> imageData2;
> >>> >> >>     imageData2->SetExtent(0, 199, 0, 199, 0, 2);
> >>> >> >>     imageData2->AllocateScalars(VTK_FLOAT, 1);
> >>> >> >>     std::fill_n(static_cast<float
> >>> >> >> *>(imageData2->GetScalarPointer()),
> >>> >> >> 200 * 200 * 3, 0.01);
> >>> >> >>
> >>> >> >>     vtkNew<vtkGPUVolumeRayCastMapper> volumeMapper2;
> >>> >> >>     volumeMapper2->SetInputData(imageData2.Get());
> >>> >> >>
> >>> >> >>     vtkNew<vtkVolumeProperty> volumeProperty2;
> >>> >> >>     volumeProperty2->SetScalarOpacity(opacityFunction.Get());
> >>> >> >>     volumeProperty2->SetColor(colorFunction.Get());
> >>> >> >>     volumeProperty2->ShadeOff();
> >>> >> >>
> >>> >> >>     vtkNew<vtkVolume> volume2;
> >>> >> >>     volume2->SetMapper(volumeMapper2.Get());
> >>> >> >>     volume2->SetProperty(volumeProperty2.Get());
> >>> >> >>     volume2->SetPosition(-120, 0, 0);
> >>> >> >>
> >>> >> >>     vtkNew<vtkRenderer> renderer;
> >>> >> >>     renderer->AddVolume(volume.Get());
> >>> >> >>     renderer->AddVolume(volume2.Get());
> >>> >> >>     renderer->SetBackground(1.0, 1.0, 1.0);
> >>> >> >>
> >>> >> >>     // Render with "plain" render window / interactor
> >>> >> >>     vtkNew<vtkRenderWindow> window;
> >>> >> >>     window->SetMultiSamples(0);
> >>> >> >>     window->AddRenderer(renderer.Get());
> >>> >> >>
> >>> >> >>     vtkNew<vtkRenderWindowInteractor> interactor;
> >>> >> >>     interactor->SetRenderWindow(window.Get());
> >>> >> >>     interactor->Start();
> >>> >> >>
> >>> >> >>     return 0;
> >>> >> >> }
> >>> >> >>
> >>> >> >>
> >>> >> >> CMakeLists.txt:
> >>> >> >>
> >>> >> >> cmake_minimum_required(VERSION 3.1)
> >>> >> >>
> >>> >> >> project(TestCase)
> >>> >> >>
> >>> >> >> find_package(VTK 8.0 COMPONENTS
> >>> >> >>     vtkCommonCore
> >>> >> >>     vtkCommonDataModel
> >>> >> >>     vtkCommonExecutionModel
> >>> >> >>     vtkCommonMath
> >>> >> >>     vtkFiltersSources
> >>> >> >>     vtkGUISupportQt
> >>> >> >>     vtkInteractionStyle
> >>> >> >>     vtkRenderingCore
> >>> >> >>     vtkRenderingOpenGL2
> >>> >> >>     vtkRenderingVolume
> >>> >> >>     vtkRenderingVolumeOpenGL2
> >>> >> >>     REQUIRED
> >>> >> >> )
> >>> >> >>
> >>> >> >> add_executable(TestCase main.cpp)
> >>> >> >>
> >>> >> >> target_link_libraries(TestCase PUBLIC
> >>> >> >>     vtkCommonCore
> >>> >> >>     vtkCommonDataModel
> >>> >> >>     vtkCommonExecutionModel
> >>> >> >>     vtkCommonMath
> >>> >> >>     vtkFiltersSources
> >>> >> >>     vtkInteractionStyle
> >>> >> >>     vtkRenderingCore
> >>> >> >>     vtkRenderingOpenGL2
> >>> >> >>     vtkRenderingVolume
> >>> >> >>     vtkRenderingVolumeOpenGL2
> >>> >> >> )
> >>> >> >>
> >>> >> >> target_include_directories(TestCase PUBLIC
> >>> >> >>     ${VTK_INCLUDE_DIRS}
> >>> >> >> )
> >>> >> >>
> >>> >> >> target_compile_definitions(TestCase PUBLIC
> >>> >> >>     ${VTK_DEFINITIONS}
> >>> >> >> )
> >>> >> >>
> >>> >> >> set_target_properties(TestCase PROPERTIES
> >>> >> >>     CXX_STANDARD 14
> >>> >> >>     CXX_STANDARD_REQUIRED ON
> >>> >> >> )
> >>> >> >> _______________________________________________
> >>> >> >> Powered by www.kitware.com
> >>> >> >>
> >>> >> >> Visit other Kitware open-source projects at
> >>> >> >> http://www.kitware.com/opensource/opensource.html
> >>> >> >>
> >>> >> >> Please keep messages on-topic and check the VTK FAQ at:
> >>> >> >> http://www.vtk.org/Wiki/VTK_FAQ
> >>> >> >>
> >>> >> >> Search the list archives at:
> http://markmail.org/search/?q=vtkusers
> >>> >> >>
> >>> >> >> Follow this link to subscribe/unsubscribe:
> >>> >> >> http://public.kitware.com/mailman/listinfo/vtkusers
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20171005/c60aab68/attachment.html>


More information about the vtkusers mailing list