[vtkusers] Opacity discrepancy with downscaled volume despite opacity unit distance == spacing
Elvis Stansvik
elvis.stansvik at orexplore.com
Sun Feb 12 11:51:02 EST 2017
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.
>
Ah, good idea. However, if I set the opacity unit distance to such a small
value, both volumes appear as completely opaque red. This makes sense to
me, since with so many accumulations, the opacity value in my opacity
function (0.1) will add up very quickly..
If I, just as a test, try to "compensate" by using 0.001 instead of 0.1 in
my opacity function, the volumes appear non-opaque as expected, but again
there's a discrepancy between the small-spaced and large-spaced volume
(shown in attached screenshot).
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/634d811b/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: new-result2.png
Type: image/png
Size: 8011 bytes
Desc: not available
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20170212/634d811b/attachment.png>
More information about the vtkusers
mailing list