diff --git a/Rendering/Volume/Testing/Cxx/CMakeLists.txt b/Rendering/Volume/Testing/Cxx/CMakeLists.txt index f38078199ec9a8beb0c883e55982a9cefa473af7..aa90affefdc722cd9e7d8b49bd83f79bf7a0465c 100644 --- a/Rendering/Volume/Testing/Cxx/CMakeLists.txt +++ b/Rendering/Volume/Testing/Cxx/CMakeLists.txt @@ -54,6 +54,7 @@ endif() set (VolumeOpenGL2CxxTests TestGPURayCastCameraInside.cxx TestGPURayCastCameraInsideSmallSpacing.cxx + TestGPURayCastCellData.cxx TestGPURayCastClipping.cxx TestGPURayCastGradientOpacity.cxx TestGPURayCastPositionalLights.cxx diff --git a/Rendering/Volume/Testing/Cxx/TestGPURayCastCellData.cxx b/Rendering/Volume/Testing/Cxx/TestGPURayCastCellData.cxx new file mode 100644 index 0000000000000000000000000000000000000000..931117ecb0e6c6349bebe1005e1cce32fa506959 --- /dev/null +++ b/Rendering/Volume/Testing/Cxx/TestGPURayCastCellData.cxx @@ -0,0 +1,121 @@ + +/*========================================================================= + + Program: Visualization Toolkit + Module: TestGPURayCastVolumeUpdate.cxx + + Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen + All rights reserved. + See Copyright.txt or http://www.kitware.com/Copyright.htm for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notice for more information. + +=========================================================================*/ +// This test volume tests whether updating the volume MTime updates the , +// geometry in the volume mapper. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +int TestGPURayCastCellData(int argc, char *argv[]) +{ + cout << "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)" << endl; + + double scalarRange[2]; + + vtkNew outlineActor; + vtkNew outlineMapper; + vtkNew volumeMapper; + + vtkNew reader; + char* volumeFile = vtkTestUtilities::ExpandDataFileName( + argc, argv, "Data/vase_1comp.vti"); + reader->SetFileName(volumeFile); + delete[] volumeFile; + + vtkNew pointToCell; + pointToCell->SetInputConnection(reader->GetOutputPort()); + volumeMapper->SetInputConnection(pointToCell->GetOutputPort()); + + // Add outline filter + vtkNew outlineFilter; + outlineFilter->SetInputConnection(pointToCell->GetOutputPort()); + outlineMapper->SetInputConnection(outlineFilter->GetOutputPort()); + outlineActor->SetMapper(outlineMapper.GetPointer()); + + volumeMapper->GetInput()->GetScalarRange(scalarRange); + volumeMapper->SetSampleDistance(0.1); + volumeMapper->SetAutoAdjustSampleDistances(0); + volumeMapper->SetBlendModeToComposite(); + + vtkNew renWin; + renWin->SetMultiSamples(0); + renWin->SetSize(400, 400); + + vtkNew iren; + iren->SetRenderWindow(renWin.GetPointer()); + vtkNew style; + iren->SetInteractorStyle(style.GetPointer()); + + renWin->Render(); // make sure we have an OpenGL context. + + vtkNew ren; + ren->SetBackground(0.2, 0.2, 0.5); + renWin->AddRenderer(ren.GetPointer()); + + vtkNew scalarOpacity; + scalarOpacity->AddPoint(50, 0.0); + scalarOpacity->AddPoint(75, 1.0); + + vtkNew volumeProperty; + volumeProperty->ShadeOn(); + volumeProperty->SetInterpolationType(VTK_LINEAR_INTERPOLATION); + volumeProperty->SetScalarOpacity(scalarOpacity.GetPointer()); + + vtkNew colorTransferFunction; + colorTransferFunction->RemoveAllPoints(); + colorTransferFunction->AddRGBPoint(scalarRange[0], 0.6, 0.4, 0.1); + volumeProperty->SetColor(colorTransferFunction.GetPointer()); + + vtkNew volume; + volume->SetMapper(volumeMapper.GetPointer()); + volume->SetProperty(volumeProperty.GetPointer()); + + ren->AddVolume(volume.GetPointer()); + ren->AddActor(outlineActor.GetPointer()); + ren->ResetCamera(); + + renWin->Render(); + ren->ResetCamera(); + + iren->Initialize(); + + int retVal = vtkRegressionTestImage( renWin.GetPointer() ); + if( retVal == vtkRegressionTester::DO_INTERACTOR) + { + iren->Start(); + } + + return !retVal; +} diff --git a/Rendering/Volume/Testing/Cxx/TestGPURayCastClipping.cxx b/Rendering/Volume/Testing/Cxx/TestGPURayCastClipping.cxx index 5e7590a78727f7098c49ff7c1ed78b78ed78196b..88c7e4c039c01e84bfdc2390f6ccd140f521263c 100644 --- a/Rendering/Volume/Testing/Cxx/TestGPURayCastClipping.cxx +++ b/Rendering/Volume/Testing/Cxx/TestGPURayCastClipping.cxx @@ -81,7 +81,8 @@ int TestGPURayCastClipping(int argc, char *argv[]) clipPlane1->SetNormal(0.8, 0.0, 0.0); vtkNew clipPlane2; - clipPlane2->SetOrigin(0.0, 0.35 * (bounds[2] + bounds[3]), 0.0); + clipPlane2->SetOrigin(0.45 * (bounds[0] + bounds[1]), + 0.35 * (bounds[2] + bounds[3]), 0.0); clipPlane2->SetNormal(0.2, -0.2, 0.0); vtkNew clipPlaneCollection; diff --git a/Rendering/Volume/Testing/Data/Baseline/TestGPURayCastCellData.png.md5 b/Rendering/Volume/Testing/Data/Baseline/TestGPURayCastCellData.png.md5 new file mode 100644 index 0000000000000000000000000000000000000000..bcba6a6e4ceaaad1c491b399b4d00b144e0140e6 --- /dev/null +++ b/Rendering/Volume/Testing/Data/Baseline/TestGPURayCastCellData.png.md5 @@ -0,0 +1 @@ +e4bf697e218a4ef0d503b408d1af4448 diff --git a/Rendering/Volume/Testing/Data/Baseline/TestGPURayCastClipping.png.md5 b/Rendering/Volume/Testing/Data/Baseline/TestGPURayCastClipping.png.md5 index ea15ac0a8d0421ca315c9308bf74e6ebb099d3e0..192cec129b1def9a61c5f36c1668a106a8b13577 100644 --- a/Rendering/Volume/Testing/Data/Baseline/TestGPURayCastClipping.png.md5 +++ b/Rendering/Volume/Testing/Data/Baseline/TestGPURayCastClipping.png.md5 @@ -1 +1 @@ -8a9b985a6e629a234bc8d8d343b2c8a2 +54622bc7c096d584f32fdf60b4d6495f diff --git a/Rendering/Volume/vtkGPUVolumeRayCastMapper.cxx b/Rendering/Volume/vtkGPUVolumeRayCastMapper.cxx index ba4fd2cd9da5f7c3486b5026f532d6f9316ade08..d7df88ab8bf72b2abeaf3cde020cfe4163ec553d 100644 --- a/Rendering/Volume/vtkGPUVolumeRayCastMapper.cxx +++ b/Rendering/Volume/vtkGPUVolumeRayCastMapper.cxx @@ -45,6 +45,7 @@ vtkGPUVolumeRayCastMapper::vtkGPUVolumeRayCastMapper() this->MinimumImageSampleDistance = 1.0; this->MaximumImageSampleDistance = 10.0; this->RenderToImage = 0; + this->UseJittering = 1; this->SampleDistance = 1.0; this->SmallVolumeRender = 0; this->BigTimeToDraw = 0.0; diff --git a/Rendering/Volume/vtkGPUVolumeRayCastMapper.h b/Rendering/Volume/vtkGPUVolumeRayCastMapper.h index 66bb7a3fc7a721a485e92350913cc447d78de943..5ef856a79377e84e8b7db2c582719400311f8d7c 100644 --- a/Rendering/Volume/vtkGPUVolumeRayCastMapper.h +++ b/Rendering/Volume/vtkGPUVolumeRayCastMapper.h @@ -46,6 +46,14 @@ public: vtkGetMacro( AutoAdjustSampleDistances, int ); vtkBooleanMacro( AutoAdjustSampleDistances, int ); + // Description: + // If UseJittering is on, each ray traversal direction will be + // perturbed slightly using a noise-texture to get rid of wood-grain + // effect. + vtkSetClampMacro( UseJittering, int, 0, 1 ); + vtkGetMacro( UseJittering, int ); + vtkBooleanMacro( UseJittering, int ); + // Description: // Set/Get the distance between samples used for rendering // when AutoAdjustSampleDistances is off, or when this mapper @@ -276,6 +284,9 @@ protected: // Render to texture mode flag int RenderToImage; + // Enable / disable stochasting jittering + int UseJittering; + // The distance between sample points along the ray float SampleDistance; diff --git a/Rendering/VolumeOpenGL2/shaders/raycasterfs.glsl b/Rendering/VolumeOpenGL2/shaders/raycasterfs.glsl index f95568b7258bfa7674b71b6cd853d997bfabecce..838c3ca2849980589f1200b858fef944d42cfabf 100644 --- a/Rendering/VolumeOpenGL2/shaders/raycasterfs.glsl +++ b/Rendering/VolumeOpenGL2/shaders/raycasterfs.glsl @@ -42,6 +42,7 @@ vec3 g_dataPos; vec3 g_dirStep; vec4 g_srcColor; vec4 g_eyePosObj; +bool g_exit; uniform vec4 in_volume_scale; uniform vec4 in_volume_bias; @@ -88,6 +89,7 @@ void main() g_fragColor = vec4(0.0); g_dirStep = vec3(0.0); g_srcColor = vec4(0.0); + g_exit = false; //VTK::Base::Init @@ -102,7 +104,7 @@ void main() //VTK::RenderToImage::Depth::Init /// For all samples along the ray - while (true) + while (!g_exit) { //VTK::Base::Impl diff --git a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx index af9c3f0769a15b777a115e1248a2967f925598b8..9831ce484bc184bbb572c281d7a25976413dc479 100644 --- a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx +++ b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx @@ -731,6 +731,16 @@ bool vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::LoadVolume( // Update texture size imageData->GetExtent(this->Extents); + if (this->Parent->CellFlag) + { + int i = 1; + while (i < 6) + { + this->Extents[i]--; + i += 2; + } + } + int i = 0; while(i < 3) { @@ -929,6 +939,17 @@ void vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::ComputeBounds( input->GetOrigin(origin); input->GetExtent(this->Extents); + + if (this->Parent->CellFlag) + { + int i = 1; + while (i < 6) + { + this->Extents[i]--; + i += 2; + } + } + int swapBounds[3]; swapBounds[0] = (this->CellSpacing[0] < 0); swapBounds[1] = (this->CellSpacing[1] < 0); @@ -1790,7 +1811,7 @@ void vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateCropping( static_cast(croppingRegionPlanes[4]), static_cast(croppingRegionPlanes[5]) }; - this->ShaderProgram->SetUniform1fv("cropping_planes", 6, cropPlanes); + this->ShaderProgram->SetUniform1fv("in_croppingPlanes", 6, cropPlanes); const int numberOfRegions = 32; int cropFlagsArray[numberOfRegions]; cropFlagsArray[0] = 0; @@ -1806,7 +1827,7 @@ void vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateCropping( cropFlagsArray[i] = 0; } - this->ShaderProgram->SetUniform1iv("cropping_flags", + this->ShaderProgram->SetUniform1iv("in_croppingFlags", numberOfRegions, cropFlagsArray); } @@ -1839,11 +1860,8 @@ void vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateClipping( clippingPlanes.push_back(planeNormal[2]); } - double croppingRegionPlanes[6]; - this->Parent->GetCroppingRegionPlanes(croppingRegionPlanes); - - clippingPlanes[0] = clippingPlanes.size() > 0 ? - (clippingPlanes.size() - 1) : 0; + clippingPlanes[0] = clippingPlanes.size() > 1 ? + static_cast(clippingPlanes.size() - 1): 0; this->ShaderProgram->SetUniform1fv("in_clippingPlanes", static_cast(clippingPlanes.size()), @@ -3177,6 +3195,7 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, 1.0 / this->Impl->WindowSize[1], fvalue2); this->Impl->ShaderProgram->SetUniform2fv("in_inverseWindowSize", 1, &fvalue2); + this->Impl->ShaderProgram->SetUniformi("in_useJittering", this->GetUseJittering()); this->Impl->ShaderProgram->SetUniformi("in_cellFlag", this->CellFlag); // Updating cropping if enabled diff --git a/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h b/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h index 36a128241f93fec725c2c3848cee21b8697ed855..44dfb3a12f517b9078f01e2d5b7117066c848bf3 100644 --- a/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h +++ b/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h @@ -180,7 +180,10 @@ namespace vtkvolume \nuniform vec3 in_ambient;\ \nuniform vec3 in_specular;\ \nuniform float in_shininess;\ + \n\ + \n// Others\ \nuniform bool in_cellFlag;\ + \n uniform bool in_useJittering;\ "); if (hasGradientOpacity || lightingComplexity > 0) @@ -279,7 +282,15 @@ namespace vtkvolume \n g_dirStep = (in_inverseTextureDatasetMatrix *\ \n vec4(rayDir, 0.0)).xyz * in_sampleDistance;\ \n\ - \n g_dataPos += g_dirStep * (texture2D(in_noiseSampler, g_dataPos.xy).x);\ + \n float jitterValue = (texture2D(in_noiseSampler, g_dataPos.xy).x);\ + \n if (in_useJittering)\ + \n {\ + \n g_dataPos += g_dirStep * jitterValue;\ + \n }\ + \n else\ + \n {\ + \n g_dataPos += g_dirStep;\ + \n }\ \n\ \n // Flag to deternmine if voxel should be considered for the rendering\ \n bool l_skip = false;"); @@ -1211,7 +1222,7 @@ namespace vtkvolume { return std::string("\ \n g_srcColor = computeColor(l_maxValue,\ - computeOpacity(l_maxValue));\ + \n computeOpacity(l_maxValue));\ \n g_fragColor.rgb = g_srcColor.rgb * g_srcColor.a;\ \n g_fragColor.a = g_srcColor.a;" ); @@ -1290,13 +1301,13 @@ namespace vtkvolume { return std::string("\ \n // Minimum texture access coordinate\ - \n vec3 l_tex_min = vec3(0.0);\ - \n vec3 l_tex_max = vec3(1.0);\ + \n vec3 l_texMin = vec3(0.0);\ + \n vec3 l_texMax = vec3(1.0);\ \n if (!in_cellFlag)\ \n {\ \n vec3 delta = in_textureExtentsMax - in_textureExtentsMin;\ - \n l_tex_min = vec3(0.5) / delta;\ - \n l_tex_max = (delta - vec3(0.5)) / delta;\ + \n l_texMin = vec3(0.5) / delta;\ + \n l_texMax = (delta - vec3(0.5)) / delta;\ \n }\ \n\ \n // Flag to indicate if the raymarch loop should terminate \ @@ -1367,7 +1378,7 @@ namespace vtkvolume \n // if the difference is less than 0, 0 if equal to 0, and 1 if\ \n // above 0. So if the ray is inside the volume, dot product will\ \n // always be 3.\ - \n stop = dot(sign(g_dataPos - l_tex_min), sign(l_tex_max - g_dataPos))\ + \n stop = dot(sign(g_dataPos - l_texMin), sign(l_texMax - g_dataPos))\ \n < 3.0;\ \n\ \n // If the stopping condition is true we brek out of the ray marching\ @@ -1415,8 +1426,8 @@ namespace vtkvolume } return std::string("\ - \nuniform float cropping_planes[6];\ - \nuniform int cropping_flags [32];\ + \nuniform float in_croppingPlanes[6];\ + \nuniform int in_croppingFlags [32];\ \n// X: axis = 0, Y: axis = 1, Z: axis = 2\ \n// cp Cropping plane bounds (minX, maxX, minY, maxY, minZ, maxZ)\ \nint computeRegionCoord(float cp[6], vec3 pos, int axis)\ @@ -1460,56 +1471,56 @@ namespace vtkvolume return std::string("\ \n // Convert cropping region to texture space\ - \n float cropping_planes_ts[6];\ + \n float croppingPlanesTexture[6];\ \n mat4 datasetToTextureMat = in_inverseTextureDatasetMatrix;\ \n\ - \n vec4 temp = vec4(cropping_planes[0], 0.0, 0.0, 1.0);\ + \n vec4 temp = vec4(in_croppingPlanes[0], 0.0, 0.0, 1.0);\ \n temp = datasetToTextureMat * temp;\ \n if (temp[3] != 0.0)\ \n {\ \n temp[0] /= temp[3];\ \n }\ - \n cropping_planes_ts[0] = temp[0];\ + \n croppingPlanesTexture[0] = temp[0];\ \n\ - \n temp = vec4(cropping_planes[1], 0.0, 0.0, 1.0);\ + \n temp = vec4(in_croppingPlanes[1], 0.0, 0.0, 1.0);\ \n temp = datasetToTextureMat * temp;\ \n if (temp[3] != 0.0)\ \n {\ \n temp[0] /= temp[3];\ \n }\ - \n cropping_planes_ts[1] = temp[0];\ + \n croppingPlanesTexture[1] = temp[0];\ \n\ - \n temp = vec4(0.0, cropping_planes[2], 0.0, 1.0);\ + \n temp = vec4(0.0, in_croppingPlanes[2], 0.0, 1.0);\ \n temp = datasetToTextureMat * temp;\ \n if (temp[3] != 0.0)\ \n {\ \n temp[1] /= temp[3];\ \n }\ - \n cropping_planes_ts[2] = temp[1];\ + \n croppingPlanesTexture[2] = temp[1];\ \n\ - \n temp = vec4(0.0, cropping_planes[3], 0.0, 1.0);\ + \n temp = vec4(0.0, in_croppingPlanes[3], 0.0, 1.0);\ \n temp = datasetToTextureMat * temp;\ \n if (temp[3] != 0.0)\ \n {\ \n temp[1] /= temp[3];\ \n }\ - \n cropping_planes_ts[3] = temp[1];\ + \n croppingPlanesTexture[3] = temp[1];\ \n\ - \n temp = vec4(0.0, 0.0, cropping_planes[4], 1.0);\ + \n temp = vec4(0.0, 0.0, in_croppingPlanes[4], 1.0);\ \n temp = datasetToTextureMat * temp;\ \n if (temp[3] != 0.0)\ \n {\ \n temp[2] /= temp[3];\ \n }\ - \n cropping_planes_ts[4] = temp[2];\ + \n croppingPlanesTexture[4] = temp[2];\ \n\ - \n temp = vec4(0.0, 0.0, cropping_planes[5], 1.0);\ + \n temp = vec4(0.0, 0.0, in_croppingPlanes[5], 1.0);\ \n temp = datasetToTextureMat * temp;\ \n if (temp[3] != 0.0)\ \n {\ \n temp[2] /= temp[3];\ \n }\ - \n cropping_planes_ts[5] = temp[2];" + \n croppingPlanesTexture[5] = temp[2];" ); } @@ -1524,11 +1535,11 @@ namespace vtkvolume return std::string("\ \n // Determine region\ - \n int regionNo = computeRegion(cropping_planes_ts, g_dataPos);\ + \n int regionNo = computeRegion(croppingPlanesTexture, g_dataPos);\ \n\ \n // Do & operation with cropping flags\ \n // Pass the flag that its Ok to sample or not to sample\ - \n if (cropping_flags[regionNo] == 0)\ + \n if (in_croppingFlags[regionNo] == 0)\ \n {\ \n // Skip this voxel\ \n l_skip = true;\ @@ -1569,48 +1580,66 @@ namespace vtkvolume { return std::string(); } - else + else { return std::string("\ - \nfloat clippingPlanesTexture[48];\ - \nint clippingPlanesSize = int(in_clippingPlanes[0]);\ - \n\ - \nmat4 world_to_texture_mat = in_inverseTextureDatasetMatrix *\ - \n in_inverseVolumeMatrix;\ - \nfor (int i = 0; i < clippingPlanesSize; i = i + 6)\ - \n {\ - \n vec4 origin = vec4(in_clippingPlanes[i + 1],\ - \n in_clippingPlanes[i + 2],\ - \n in_clippingPlanes[i + 3], 1.0);\ - \n vec4 normal = vec4(in_clippingPlanes[i + 4],\ - \n in_clippingPlanes[i + 5],\ - \n in_clippingPlanes[i + 6], 0.0);\ - \n\ - \n origin = world_to_texture_mat * origin;\ - \n normal = world_to_texture_mat * normal;\ - \n\ - \n if (origin[3] != 0.0)\ - \n {\ - \n origin[0] = origin[0] / origin[3];\ - \n origin[1] = origin[1] / origin[3];\ - \n origin[2] = origin[2] / origin[3];\ - \n }\ - \n if (normal[3] != 0.0)\ + \n int clippingPlanesSize = int(in_clippingPlanes[0]);\ + \n vec4 objDataPos = vec4(0.0);\ + \n mat4 textureToObjMat = in_volumeMatrix *\ + \n in_textureDatasetMatrix;\ + \n for (int i = 0; i < clippingPlanesSize; i = i + 6)\ \n {\ - \n normal[0] = normal[0] / normal[3];\ - \n normal[1] = normal[1] / normal[3];\ - \n normal[2] = normal[2] / normal[3];\ - \n }\ - \n\ - \n clippingPlanesTexture[i] = origin[0];\ - \n clippingPlanesTexture[i + 1] = origin[1];\ - \n clippingPlanesTexture[i + 2] = origin[2];\ + \n if (in_useJittering)\ + \n {\ + \n objDataPos = textureToObjMat * vec4(g_dataPos - (g_dirStep\ + \n * jitterValue), 1.0);\ + \n }\ + \n else\ + \n {\ + \n objDataPos = textureToObjMat * vec4(g_dataPos - g_dirStep, 1.0);\ + \n }\ + \n if (objDataPos.w != 0.0)\ + \n {\ + \n objDataPos = objDataPos/objDataPos.w; objDataPos.w = 1.0;\ + \n }\ + \n vec3 planeOrigin = vec3(in_clippingPlanes[i + 1],\ + \n in_clippingPlanes[i + 2],\ + \n in_clippingPlanes[i + 3]);\ + \n vec3 planeNormal = vec3(in_clippingPlanes[i + 4],\ + \n in_clippingPlanes[i + 5],\ + \n in_clippingPlanes[i + 6]);\ + \n vec3 normalizedPlaneNormal = normalize(planeNormal);\ \n\ - \n clippingPlanesTexture[i + 3] = normal[0];\ - \n clippingPlanesTexture[i + 4] = normal[1];\ - \n clippingPlanesTexture[i + 5] = normal[2];\ - \n }" - ); + \n float planeD = -planeOrigin[0] * normalizedPlaneNormal[0] - planeOrigin[1]\ + \n * normalizedPlaneNormal[1] - planeOrigin[2] * normalizedPlaneNormal[2];\ + \n bool frontFace = dot(rayDir, normalizedPlaneNormal) > 0;\ + \n float dist = dot(rayDir, normalizedPlaneNormal);\ + \n if (dist != 0.0) { dist = (-planeD - dot(normalizedPlaneNormal, objDataPos.xyz)) / dist; }\ + \n if (frontFace && dist > 0.0 && dot(vec3(objDataPos.xyz - planeOrigin), planeNormal) < 0)\ + \n {\ + \n vec4 newObjDataPos = vec4(objDataPos.xyz + dist * rayDir, 1.0);\ + \n newObjDataPos = in_inverseTextureDatasetMatrix\ + \n * in_inverseVolumeMatrix * vec4(newObjDataPos.xyz, 1.0);\ + \n if (newObjDataPos.w != 0.0)\ + \n {\ + \n newObjDataPos /= newObjDataPos.w;\ + \n }\ + \n if (in_useJittering)\ + \n {\ + \n g_dataPos = newObjDataPos.xyz + g_dirStep * jitterValue;\ + \n }\ + \n else\ + \n {\ + \n g_dataPos = newObjDataPos.xyz + g_dirStep;\ + \n }\ + \n bool stop = dot(sign(g_dataPos - l_texMin), sign(l_texMax - g_dataPos))\ + \n < 3.0;\ + \n if (stop)\ + \n {\ + \n discard;\ + \n }\ + \n }\ + \n }"); } } @@ -1626,17 +1655,23 @@ namespace vtkvolume else { return std::string("\ - \n for (int i = 0; i < (clippingPlanesSize) && !l_skip; i = i + 6)\ + \n for (int i = 0; i < clippingPlanesSize && !l_skip; i = i + 6)\ \n {\ - \n if (dot(vec3(g_dataPos - vec3(clippingPlanesTexture[i],\ - \n clippingPlanesTexture[i + 1],\ - \n clippingPlanesTexture[i + 2])),\ - \n vec3(clippingPlanesTexture[i + 3],\ - \n clippingPlanesTexture[i + 4],\ - \n clippingPlanesTexture[i + 5])) < 0)\ + \n vec4 objDataPos = textureToObjMat * vec4(g_dataPos, 1.0);\ + \n if (objDataPos.w != 0.0)\ + \n {\ + \n objDataPos /= objDataPos.w;\ + \n }\ + \n vec3 planeOrigin = vec3(in_clippingPlanes[i + 1],\ + \n in_clippingPlanes[i + 2],\ + \n in_clippingPlanes[i + 3]);\ + \n vec3 planeNormal = vec3(in_clippingPlanes[i + 4],\ + \n in_clippingPlanes[i + 5],\ + \n in_clippingPlanes[i + 6]);\ + \n if (dot(vec3(objDataPos.xyz - planeOrigin), planeNormal) < 0 && dot(rayDir, planeNormal) < 0)\ \n {\ - \n l_skip = true;\ - \n break;\ + \n l_skip = true;\ + \n g_exit = true;\ \n }\ \n }" );