[vtkusers] Opacity discrepancy with downscaled volume despite opacity unit distance == spacing
Elvis Stansvik
elvis.stansvik at orexplore.com
Sun Feb 12 12:01:02 EST 2017
2017-02-12 17:56 GMT+01:00 Elvis Stansvik <elvis.stansvik at orexplore.com>:
> 2017-02-12 17:31 GMT+01:00 David Gobbi <david.gobbi at gmail.com>:
>
>> Hi Elvis,
>>
>> Here is something you can do as a check: set the sample distance for the
>> ray casting to a very small value, so that it takes around 1000 steps for
>> the ray to traverse the volume from front to back. The thickness of your
>> volume is 29*0.006 = 0.174, so you can try a sample spacing of 1.74e-04:
>>
>> mapper->AutoAdjustSampleDistancesOff();
>> mapper->SetSampleDistance(1.74e-04);
>>
>> If the two volumes look the same when you use a small sample distance,
>> then the difference you were seeing was probably just due to discretization.
>>
>
> That indeed did the trick, thanks David!
>
And to clarify: The small difference I was seeing when I had the sample
distance left to auto-adjusted isn't really a problem for my application. I
was just surprised there was still a small difference even when both
volumes were rendered with the same opacity unit distance, and I wanted to
find the explanation for it. The discretization error coming into play
makes sense.
Elvis
>
> Elvis
>
>
>>
>> - David
>>
>>
>>
>> On Thu, Feb 9, 2017 at 6:45 AM, Elvis Stansvik <
>> elvis.stansvik at orexplore.com> wrote:
>>
>>> Hi all,
>>>
>>> The following example shows a 30x30x30 volume rendered, and next to it a
>>> downscaled version of it (but using an identical opacity/transfer
>>> function). Notice how in the result (attached), the downscaled version is
>>> less opaque. This is despite me using
>>>
>>> SetScalarOpacityUnitDistance(image->GetSpacing()[0])
>>>
>>> to set the scalar opacity unit distance to the spacing of the respective
>>> image. I would thought calling SetScalarOpacityUnitDistance like this would
>>> ensure both volumes look the same (apart from resolution).
>>>
>>> How can I make both volumes look the same opacity-wise when using the
>>> same transfer functions?
>>>
>>> Thanks in advance,
>>> Elvis
>>>
>>> main.cpp:
>>>
>>>
>>> #include <algorithm>
>>>
>>> #include <vtkCamera.h>
>>> #include <vtkColorTransferFunction.h>
>>> #include <vtkGPUVolumeRayCastMapper.h>
>>> #include <vtkImageData.h>
>>> #include <vtkImageResize.h>
>>> #include <vtkPiecewiseFunction.h>
>>> #include <vtkRenderer.h>
>>> #include <vtkRenderWindow.h>
>>> #include <vtkRenderWindowInteractor.h>
>>> #include <vtkSmartPointer.h>
>>> #include <vtkVolume.h>
>>> #include <vtkVolumeProperty.h>
>>>
>>> // Create a volume from the given image
>>> vtkSmartPointer<vtkVolume> createVolume(vtkSmartPointer<vtkImageData>
>>> image) {
>>> auto color = vtkSmartPointer<vtkColorTransferFunction>::New();
>>> color->AddRGBPoint(0.0, 1.0, 0.0, 0.0);
>>> color->AddRGBPoint(1.0, 1.0, 0.0, 0.0);
>>>
>>> auto opacity = vtkSmartPointer<vtkPiecewiseFunction>::New();
>>> opacity->AddPoint(0.0, 0.1);
>>> opacity->AddPoint(1.0, 0.1);
>>>
>>> auto property = vtkSmartPointer<vtkVolumeProperty>::New();
>>> property->SetColor(color);
>>> property->SetScalarOpacity(opacity);
>>> property->SetInterpolationTypeToLinear();
>>> property->ShadeOff();
>>> property->SetScalarOpacityUnitDistance(image->GetSpacing()[0]);
>>>
>>> auto mapper = vtkSmartPointer<vtkGPUVolumeRayCastMapper>::New();
>>> mapper->SetInputData(image);
>>>
>>> auto volume = vtkSmartPointer<vtkVolume>::New();
>>> volume->SetMapper(mapper);
>>> volume->SetProperty(property);
>>>
>>> return volume;
>>> }
>>>
>>> int main(int argc, char *argv[]) {
>>>
>>> // Create a 30x30x30 volume
>>> auto image = vtkSmartPointer<vtkImageData>::New();
>>> image->SetDimensions(30, 30, 30);
>>> image->SetSpacing(0.006, 0.006, 0.006);
>>> image->AllocateScalars(VTK_FLOAT, 1);
>>>
>>> auto imagePtr = static_cast<float *>(image->GetScalarPointer());
>>> std::fill_n(imagePtr, 30 * 30 * 30, 1.0);
>>>
>>> auto volume = createVolume(image);
>>>
>>> // Create a smaller (10x10x10) version
>>> auto resize = vtkSmartPointer<vtkImageResize>::New();
>>> resize->SetInputData(image);
>>> resize->SetOutputDimensions(10, 10, 10);
>>> resize->Update();
>>>
>>> auto smallVolume = createVolume(resize->GetOutput());
>>> smallVolume->SetPosition(0.2, 0, 0);
>>>
>>> // Render the two volumes
>>> auto renderer = vtkSmartPointer<vtkRenderer>::New();
>>> renderer->SetBackground(1.0, 1.0, 1.0);
>>> renderer->AddVolume(volume);
>>> renderer->AddVolume(smallVolume);
>>> renderer->ResetCamera();
>>>
>>> auto camera = renderer->GetActiveCamera();
>>> camera->SetParallelProjection(1);
>>>
>>> auto window = vtkSmartPointer<vtkRenderWindow>::New();
>>> window->AddRenderer(renderer);
>>> window->SetSize(800, 400);
>>>
>>> auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
>>> interactor->SetRenderWindow(window);
>>> interactor->Start();
>>>
>>> return 0;
>>> }
>>>
>>>
>>> CMakeLists.txt:
>>>
>>>
>>> cmake_minimum_required(VERSION 3.1)
>>>
>>> project(TestCase)
>>>
>>> set(CMAKE_CXX_STANDARD 11)
>>> set(CMAKE_CXX_STANDARD_REQUIRED ON)
>>>
>>> find_package(VTK COMPONENTS
>>> vtkCommonCore
>>> vtkCommonDataModel
>>> vtkCommonExecutionModel
>>> vtkInteractionStyle
>>> vtkImagingCore
>>> vtkRenderingCore
>>> vtkRenderingOpenGL2
>>> vtkRenderingVolume
>>> vtkRenderingVolumeOpenGL2
>>> )
>>>
>>> add_executable(TestCase main.cpp)
>>>
>>> target_link_libraries(TestCase PUBLIC
>>> vtkCommonCore
>>> vtkCommonDataModel
>>> vtkCommonExecutionModel
>>> vtkImagingCore
>>> vtkInteractionStyle
>>> vtkRenderingCore
>>> vtkRenderingOpenGL2
>>> vtkRenderingVolume
>>> vtkRenderingVolumeOpenGL2
>>> )
>>>
>>> target_include_directories(TestCase PUBLIC
>>> ${VTK_INCLUDE_DIRS}
>>> )
>>>
>>>
>>> target_compile_definitions(TestCase PUBLIC
>>> ${VTK_DEFINITIONS}
>>> )
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20170212/501b4102/attachment.html>
More information about the vtkusers
mailing list