16#ifndef vtkVolumeShaderComposer_h
17#define vtkVolumeShaderComposer_h
38 for (
auto& item : inputs)
51 for (
auto& item : inputs)
54 const bool lighting = volProp->
GetShade() == 1;
63 for (
auto& item : inputs)
67 if (useClippedVoxelIntensity)
77 const std::string base = arrayName.substr(0, arrayName.length() - 3);
95 " //Transform vertex (data coordinates) to clip coordinates\n"
96 " // p_clip = T_ProjViewModel * T_dataToWorld * p_data\n"
97 " vec4 pos = in_projectionMatrix * in_modelViewMatrix * in_volumeMatrix[0] *\n"
98 " vec4(in_vertexPos.xyz, 1.0);\n"
99 " gl_Position = pos;\n");
107 " // Transform vertex (data coordinates) to texture coordinates.\n"
108 " // p_texture = T_dataToTex * p_data\n"
109 " vec3 uvx = sign(in_cellSpacing[0]) * (in_inverseTextureDatasetMatrix[0] *\n"
110 " vec4(in_vertexPos, 1.0)).xyz;\n"
112 " // For point dataset, we offset the texture coordinate\n"
113 " // to account for OpenGL treating voxel at the center of the cell.\n"
114 " // Transform cell tex-coordinates to point tex-coordinates (cellToPoint\n"
115 " // is an identity matrix in the case of cell data).\n"
116 " ip_textureCoords = (in_cellToPoint[0] * vec4(uvx, 1.0)).xyz;\n"
117 " ip_inverseTextureDataAdjusted = in_cellToPoint[0] * in_inverseTextureDatasetMatrix[0];\n");
122 vtkVolume* vtkNotUsed(vol),
bool multipleInputs)
125 const int numInputs = gpuMapper->GetInputCount();
127 std::ostringstream ss;
128 ss <<
"uniform vec3 in_cellSpacing[" << numInputs
130 "uniform mat4 in_modelViewMatrix;\n"
131 "uniform mat4 in_projectionMatrix;\n";
133 const int numTransf = multipleInputs ? numInputs + 1 : 1;
134 ss <<
"uniform mat4 in_volumeMatrix[" << numTransf
136 "uniform mat4 in_inverseTextureDatasetMatrix["
139 "uniform mat4 in_cellToPoint["
143 "//This variable could be 'invariant varying' but it is declared\n"
144 "//as 'varying' to avoid compiler compatibility issues.\n"
145 "out mat4 ip_inverseTextureDataAdjusted;\n";
153 int lightingComplexity,
int noOfComponents,
int independentComponents)
155 const int numInputs =
static_cast<int>(inputs.size());
157 std::ostringstream toShaderStr;
158 toShaderStr <<
"uniform sampler3D in_volume[" << numInputs <<
"];\n";
160 toShaderStr <<
"uniform vec4 in_volume_scale[" << numInputs
162 "uniform vec4 in_volume_bias["
163 << numInputs <<
"];\n";
167 toShaderStr <<
"uniform sampler1D in_coordTexs;\n";
168 toShaderStr <<
"uniform vec3 in_coordTexSizes;\n";
169 toShaderStr <<
"uniform vec3 in_coordsScale;\n";
170 toShaderStr <<
"uniform vec3 in_coordsBias;\n";
175 toShaderStr <<
"uniform sampler3D in_blanking;\n";
178 toShaderStr <<
"uniform int in_noOfComponents;\n"
180 "uniform sampler2D in_depthSampler;\n"
182 "// Camera position\n"
183 "uniform vec3 in_cameraPos;\n";
188 toShaderStr <<
"uniform sampler2D in_noiseSampler;\n";
193 const int numTransf = (numInputs > 1) ? numInputs + 1 : 1;
194 toShaderStr <<
"uniform mat4 in_volumeMatrix[" << numTransf
196 "uniform mat4 in_inverseVolumeMatrix["
199 "uniform mat4 in_textureDatasetMatrix["
202 "uniform mat4 in_inverseTextureDatasetMatrix["
205 "uniform mat4 in_textureToEye["
208 "uniform vec3 in_texMin["
211 "uniform vec3 in_texMax["
214 "uniform mat4 in_cellToPoint["
215 << numTransf <<
"];\n";
217 toShaderStr <<
"// view and model matrices\n"
218 "uniform mat4 in_projectionMatrix;\n"
219 "uniform mat4 in_inverseProjectionMatrix;\n"
220 "uniform mat4 in_modelViewMatrix;\n"
221 "uniform mat4 in_inverseModelViewMatrix;\n"
222 "in mat4 ip_inverseTextureDataAdjusted;\n"
225 "uniform vec3 in_cellStep["
226 << numInputs <<
"];\n";
228 toShaderStr <<
"uniform vec2 in_scalarsRange[" << numInputs * 4
230 "uniform vec3 in_cellSpacing["
234 "// Sample distance\n"
235 "uniform float in_sampleDistance;\n"
238 "uniform vec2 in_windowLowerLeftCorner;\n"
239 "uniform vec2 in_inverseOriginalWindowSize;\n"
240 "uniform vec2 in_inverseWindowSize;\n"
241 "uniform vec3 in_textureExtentsMax;\n"
242 "uniform vec3 in_textureExtentsMin;\n"
244 "// Material and lighting\n"
245 "uniform vec3 in_diffuse[4];\n"
246 "uniform vec3 in_ambient[4];\n"
247 "uniform vec3 in_specular[4];\n"
248 "uniform float in_shininess[4];\n"
251 "vec3 g_rayJitter = vec3(0.0);\n"
253 "uniform vec2 in_averageIPRange;\n";
255 toShaderStr <<
"vec4 g_eyePosObjs[" << numInputs <<
"];\n";
257 const bool hasGradientOpacity = HasGradientOpacity(inputs);
258 if (lightingComplexity > 0 || hasGradientOpacity)
260 toShaderStr <<
"uniform bool in_twoSidedLighting;\n";
263 if (lightingComplexity == 3)
265 toShaderStr <<
"vec4 g_fragWorldPos;\n"
266 "uniform int in_numberOfLights;\n"
267 "uniform vec3 in_lightAmbientColor[6];\n"
268 "uniform vec3 in_lightDiffuseColor[6];\n"
269 "uniform vec3 in_lightSpecularColor[6];\n"
270 "uniform vec3 in_lightDirection[6];\n"
271 "uniform vec3 in_lightPosition[6];\n"
272 "uniform vec3 in_lightAttenuation[6];\n"
273 "uniform float in_lightConeAngle[6];\n"
274 "uniform float in_lightExponent[6];\n"
275 "uniform int in_lightPositional[6];\n";
277 else if (lightingComplexity == 2)
279 toShaderStr <<
"vec4 g_fragWorldPos;\n"
280 "uniform int in_numberOfLights;\n"
281 "uniform vec3 in_lightAmbientColor[6];\n"
282 "uniform vec3 in_lightDiffuseColor[6];\n"
283 "uniform vec3 in_lightSpecularColor[6];\n"
284 "uniform vec3 in_lightDirection[6];\n";
288 toShaderStr <<
"uniform vec3 in_lightAmbientColor[1];\n"
289 "uniform vec3 in_lightDiffuseColor[1];\n"
290 "uniform vec3 in_lightSpecularColor[1];\n"
291 "vec4 g_lightPosObj["
301 << numInputs <<
"];\n";
304 if (noOfComponents > 1 && independentComponents)
306 toShaderStr <<
"uniform vec4 in_componentWeight;\n";
312 toShaderStr <<
"uniform sampler2D in_depthPassSampler;\n";
317 toShaderStr <<
"#if NUMBER_OF_CONTOURS\n"
318 "uniform float in_isosurfacesValues[NUMBER_OF_CONTOURS];\n"
320 "int findIsoSurfaceIndex(float scalar, float array[NUMBER_OF_CONTOURS+2])\n"
322 " int index = NUMBER_OF_CONTOURS >> 1;\n"
323 " while (scalar > array[index]) ++index;\n"
324 " while (scalar < array[index]) --index;\n"
331 vtkVolume* vol = inputs.begin()->second.Volume;
334 if (func && func->
IsA(
"vtkPlane"))
337 <<
"uniform vec3 in_slicePlaneOrigin;\n"
338 "uniform vec3 in_slicePlaneNormal;\n"
339 "vec3 g_intersection;\n"
341 "float intersectRayPlane(vec3 rayOrigin, vec3 rayDir)\n"
343 " vec4 planeNormal = in_inverseVolumeMatrix[0] * vec4(in_slicePlaneNormal, 0.0);\n"
344 " float denom = dot(planeNormal.xyz, rayDir);\n"
345 " if (abs(denom) > 1e-6)\n"
347 " vec4 planeOrigin = in_inverseVolumeMatrix[0] * vec4(in_slicePlaneOrigin, 1.0);\n"
348 " return dot(planeOrigin.xyz - rayOrigin, planeNormal.xyz) / denom;\n"
355 return toShaderStr.str();
363 vtkVolume* vol = inputs.begin()->second.Volume;
364 const int numInputs =
static_cast<int>(inputs.size());
366 std::ostringstream shaderStr;
372 \n vec2 fragTexCoord2 = (gl_FragCoord.xy - in_windowLowerLeftCorner) *\
373 \n in_inverseWindowSize;\
374 \n vec4 depthValue = texture2D(in_depthPassSampler, fragTexCoord2);\
375 \n vec4 rayOrigin = WindowToNDC(gl_FragCoord.x, gl_FragCoord.y, depthValue.x);\
377 \n // From normalized device coordinates to eye coordinates.\
378 \n // in_projectionMatrix is inversed because of way VT\
379 \n // From eye coordinates to texture coordinates\
380 \n rayOrigin = in_inverseTextureDatasetMatrix[0] *\
381 \n in_inverseVolumeMatrix[0] *\
382 \n in_inverseModelViewMatrix *\
383 \n in_inverseProjectionMatrix *\
385 \n rayOrigin /= rayOrigin.w;\
386 \n g_rayOrigin = rayOrigin.xyz;";
391 \n // Get the 3D texture coordinates for lookup into the in_volume dataset\
392 \n g_rayOrigin = ip_textureCoords.xyz;";
397 \n // Eye position in dataset space\
398 \n g_eyePosObj = in_inverseVolumeMatrix[0] * vec4(in_cameraPos, 1.0);";
399 for (
int i = 0; i < numInputs; ++i)
404 << i <<
"] = in_inverseVolumeMatrix[" << (numInputs > 1 ? i + 1 : i)
405 <<
"] * vec4(in_cameraPos, 1.0);";
408 \n // Getting the ray marching direction (in dataset space)\
409 \n vec3 rayDir = computeRayDirection();\
411 \n // 2D Texture fragment coordinates [0,1] from fragment coordinates.\
412 \n // The frame buffer texture has the size of the plain buffer but \
413 \n // we use a fraction of it. The texture coordinate is less than 1 if\
414 \n // the reduction factor is less than 1.\
415 \n // Device coordinates are between -1 and 1. We need texture\
416 \n // coordinates between 0 and 1. The in_depthSampler\
417 \n // buffer has the original size buffer.\
418 \n vec2 fragTexCoord = (gl_FragCoord.xy - in_windowLowerLeftCorner) *\
419 \n in_inverseWindowSize;\
421 \n // Multiply the raymarching direction with the step size to get the\
422 \n // sub-step size we need to take at each raymarching step\
423 \n g_dirStep = (ip_inverseTextureDataAdjusted *\
424 \n vec4(rayDir, 0.0)).xyz * in_sampleDistance;\
433 \n float jitterValue = texture2D(in_noiseSampler, gl_FragCoord.xy /\
434 vec2(textureSize(in_noiseSampler, 0))).x;\
435 \n g_rayJitter = g_dirStep * jitterValue;\
441 \n g_rayJitter = g_dirStep;\
445 \n g_rayOrigin += g_rayJitter;\
450 \n // Flag to determine if voxel should be considered for the rendering\
456 \n // Light position in dataset space";
457 for (
int i = 0; i < numInputs; ++i)
462 << i <<
"] = (in_inverseVolumeMatrix[" << (numInputs > 1 ? i + 1 : i) <<
"] *\
463 \n vec4(in_cameraPos, 1.0));\
465 << i <<
"] = normalize(g_lightPosObj[" << i <<
"].xyz - ip_vertexPos);\
467 << i <<
"] = normalize(g_eyePosObjs[" << i <<
"].xyz - ip_vertexPos);\
469 << i <<
"] = normalize(g_ldir[" << i <<
"] + g_vdir[" << i <<
"]);";
473 return shaderStr.str();
483 \n g_skip = false;");
489 if (blankPoints || blankCells)
492 \n // Check whether the neighboring points/cells are blank.\
493 \n // Note the half cellStep because texels are point centered.\
494 \n vec3 xvec = vec3(in_cellStep[0].x/2.0, 0.0, 0.0);\
495 \n vec3 yvec = vec3(0.0, in_cellStep[0].y/2.0, 0.0);\
496 \n vec3 zvec = vec3(0.0, 0.0, in_cellStep[0].z/2.0);\
497 \n vec3 texPosPVec[3];\
498 \n texPosPVec[0] = g_dataPos + xvec;\
499 \n texPosPVec[1] = g_dataPos + yvec;\
500 \n texPosPVec[2] = g_dataPos + zvec;\
501 \n vec3 texPosNVec[3];\
502 \n texPosNVec[0] = g_dataPos - xvec;\
503 \n texPosNVec[1] = g_dataPos - yvec;\
504 \n texPosNVec[2] = g_dataPos - zvec;\
505 \n vec4 blankValue = texture3D(in_blanking, g_dataPos);\
506 \n vec4 blankValueXP = texture3D(in_blanking, texPosPVec[0]);\
507 \n vec4 blankValueYP = texture3D(in_blanking, texPosPVec[1]);\
508 \n vec4 blankValueZP = texture3D(in_blanking, texPosPVec[2]);\
509 \n vec4 blankValueXN = texture3D(in_blanking, texPosNVec[0]);\
510 \n vec4 blankValueYN = texture3D(in_blanking, texPosNVec[1]);\
511 \n vec4 blankValueZN = texture3D(in_blanking, texPosNVec[2]);\
512 \n vec3 blankValuePx;\
513 \n blankValuePx[0] = blankValueXP.x;\
514 \n blankValuePx[1] = blankValueYP.x;\
515 \n blankValuePx[2] = blankValueZP.x;\
516 \n vec3 blankValuePy;\
517 \n blankValuePy[0] = blankValueXP.y;\
518 \n blankValuePy[1] = blankValueYP.y;\
519 \n blankValuePy[2] = blankValueZP.y;\
520 \n vec3 blankValueNx;\
521 \n blankValueNx[0] = blankValueXN.x;\
522 \n blankValueNx[1] = blankValueYN.x;\
523 \n blankValueNx[2] = blankValueZN.x;\
524 \n vec3 blankValueNy;\
525 \n blankValueNy[0] = blankValueXN.y;\
526 \n blankValueNy[1] = blankValueYN.y;\
527 \n blankValueNy[2] = blankValueZN.y;\
532 \n // If the current or neighboring points\
533 \n // (that belong to cells that share this texel) are blanked,\
534 \n // skip the texel. In other words, if point 1 were blank,\
535 \n // texels 0, 1 and 2 would have to be skipped.\
536 \n if (blankValue.x > 0.0 ||\
537 \n any(greaterThan(blankValueNx, vec3(0.0))) ||\
538 \n any(greaterThan(blankValuePx, vec3(0.0))))\
540 \n // skip this texel\
547 \n // If the current or previous cells (that share this texel)\
548 \n // are blanked, skip the texel. In other words, if cell 1\
549 \n // is blanked, texels 1 and 2 would have to be skipped.\
550 \n else if (blankValue.y > 0.0 ||\
551 \n any(greaterThan(blankValuePy, vec3(0.0))) ||\
552 \n any(greaterThan(blankValueNy, vec3(0.0))))\
554 \n // skip this texel\
563 \n // If the current or previous cells (that share this texel)\
564 \n // are blanked, skip the texel. In other words, if cell 1\
565 \n // is blanked, texels 1 and 2 would have to be skipped.\
566 \n if (blankValue.x > 0.0 ||\
567 \n any(greaterThan(blankValueNx, vec3(0.0))) ||\
568 \n any(greaterThan(blankValuePx, vec3(0.0))))\
570 \n // skip this texel\
580 \n g_dataPos = g_intersection;\
596 int independentComponents, std::map<int, std::string> gradientTableMap)
599 std::ostringstream ss;
600 if (volProperty->HasGradientOpacity())
602 ss <<
"uniform sampler2D " << ArrayBaseName(gradientTableMap[0]) <<
"[" << noOfComponents
605 bool useLabelGradientOpacity =
606 (volProperty->HasLabelGradientOpacity() && (noOfComponents == 1 || !independentComponents));
607 if (useLabelGradientOpacity)
609 ss <<
"uniform sampler2D in_labelMapGradientOpacity;\n";
613 if (volProperty->HasGradientOpacity() && (noOfComponents == 1 || !independentComponents))
616 \nfloat computeGradientOpacity(vec4 grad)\
618 \n return texture2D(" +
619 gradientTableMap[0] +
", vec2(grad.w, 0.0)).r;\
622 else if (noOfComponents > 1 && independentComponents && volProperty->HasGradientOpacity())
625 \nfloat computeGradientOpacity(vec4 grad, int component)\
628 for (
int i = 0; i < noOfComponents; ++i)
630 std::ostringstream toString;
633 \n if (component == " +
634 toString.str() +
")");
638 \n return texture2D(" +
639 gradientTableMap[i] +
", vec2(grad.w, 0.0)).r;\
647 if (useLabelGradientOpacity)
650 \nfloat computeGradientOpacityForLabel(vec4 grad, float label)\
652 \n return texture2D(in_labelMapGradientOpacity, vec2(grad.w, label)).r;\
663 const bool hasLighting = HasLighting(inputs);
664 const bool hasGradientOp = HasGradientOpacity(inputs);
667 if (hasLighting || hasGradientOp)
670 "// c is short for component\n"
671 "vec4 computeGradient(in vec3 texPos, in int c, in sampler3D volume,in int index)\n"
673 " // Approximate Nabla(F) derivatives with central differences.\n"
674 " vec3 g1; // F_front\n"
675 " vec3 g2; // F_back\n"
676 " vec3 xvec = vec3(in_cellStep[index].x, 0.0, 0.0);\n"
677 " vec3 yvec = vec3(0.0, in_cellStep[index].y, 0.0);\n"
678 " vec3 zvec = vec3(0.0, 0.0, in_cellStep[index].z);\n"
679 " vec3 texPosPvec[3];\n"
680 " texPosPvec[0] = texPos + xvec;\n"
681 " texPosPvec[1] = texPos + yvec;\n"
682 " texPosPvec[2] = texPos + zvec;\n"
683 " vec3 texPosNvec[3];\n"
684 " texPosNvec[0] = texPos - xvec;\n"
685 " texPosNvec[1] = texPos - yvec;\n"
686 " texPosNvec[2] = texPos - zvec;\n"
687 " g1.x = texture3D(volume, vec3(texPosPvec[0]))[c];\n"
688 " g1.y = texture3D(volume, vec3(texPosPvec[1]))[c];\n"
689 " g1.z = texture3D(volume, vec3(texPosPvec[2]))[c];\n"
690 " g2.x = texture3D(volume, vec3(texPosNvec[0]))[c];\n"
691 " g2.y = texture3D(volume, vec3(texPosNvec[1]))[c];\n"
692 " g2.z = texture3D(volume, vec3(texPosNvec[2]))[c];\n"
697 std::string(
" vec4 g1ObjDataPos[3], g2ObjDataPos[3];\n"
698 " for (int i = 0; i < 3; ++i)\n"
700 " g1ObjDataPos[i] = clip_texToObjMat * vec4(texPosPvec[i], 1.0);\n"
701 " if (g1ObjDataPos[i].w != 0.0)\n"
703 " g1ObjDataPos[i] /= g1ObjDataPos[i].w;\n"
705 " g2ObjDataPos[i] = clip_texToObjMat * vec4(texPosNvec[i], 1.0);\n"
706 " if (g2ObjDataPos[i].w != 0.0)\n"
708 " g2ObjDataPos[i] /= g2ObjDataPos[i].w;\n"
712 " for (int i = 0; i < clip_numPlanes && !g_skip; i = i + 6)\n"
714 " vec3 planeOrigin = vec3(in_clippingPlanes[i + 1],\n"
715 " in_clippingPlanes[i + 2],\n"
716 " in_clippingPlanes[i + 3]);\n"
717 " vec3 planeNormal = normalize(vec3(in_clippingPlanes[i + 4],\n"
718 " in_clippingPlanes[i + 5],\n"
719 " in_clippingPlanes[i + 6]));\n"
720 " for (int j = 0; j < 3; ++j)\n"
722 " if (dot(vec3(planeOrigin - g1ObjDataPos[j].xyz), planeNormal) > 0)\n"
724 " g1[j] = in_clippedVoxelIntensity;\n"
726 " if (dot(vec3(planeOrigin - g2ObjDataPos[j].xyz), planeNormal) > 0)\n"
728 " g2[j] = in_clippedVoxelIntensity;\n"
734 shaderStr +=
std::string(
" // Apply scale and bias to the fetched values.\n"
735 " g1 = g1 * in_volume_scale[index][c] + in_volume_bias[index][c];\n"
736 " g2 = g2 * in_volume_scale[index][c] + in_volume_bias[index][c];\n"
741 std::string(
" // Central differences: (F_front - F_back) / 2h\n"
742 " // This version of computeGradient() is only used for lighting\n"
743 " // calculations (only direction matters), hence the difference is\n"
744 " // not scaled by 2h and a dummy gradient mag is returned (-1.).\n"
745 " return vec4((g1 - g2) / in_cellSpacing[index], -1.0);\n"
751 " // Scale values the actual scalar range.\n"
752 " float range = in_scalarsRange[4*index+c][1] - in_scalarsRange[4*index+c][0];\n"
753 " g1 = in_scalarsRange[4*index+c][0] + range * g1;\n"
754 " g2 = in_scalarsRange[4*index+c][0] + range * g2;\n"
756 " // Central differences: (F_front - F_back) / 2h\n"
759 " float avgSpacing = (in_cellSpacing[index].x +\n"
760 " in_cellSpacing[index].y + in_cellSpacing[index].z) / 3.0;\n"
761 " vec3 aspect = in_cellSpacing[index] * 2.0 / avgSpacing;\n"
763 " float grad_mag = length(g2);\n"
765 " // Handle normalizing with grad_mag == 0.0\n"
766 " g2 = grad_mag > 0.0 ? normalize(g2) : vec3(0.0);\n"
768 " // Since the actual range of the gradient magnitude is unknown,\n"
769 " // assume it is in the range [0, 0.25 * dataRange].\n"
770 " range = range != 0 ? range : 1.0;\n"
771 " grad_mag = grad_mag / (0.25 * range);\n"
772 " grad_mag = clamp(grad_mag, 0.0, 1.0);\n"
774 " return vec4(g2.xyz, grad_mag);\n"
781 "vec4 computeGradient(in vec3 texPos, in int c, in sampler3D volume, in int index)\n"
783 " return vec4(0.0);\n"
792 vtkVolume* vol,
int noOfComponents,
int independentComponents,
int vtkNotUsed(numberOfLights),
793 int lightingComplexity)
797 \nvec4 computeLighting(vec4 color, int component, float label)\
799 \n vec4 finalColor = vec4(0.0);");
802 int const shadeReqd = volProperty->
GetShade() &&
811 switch (transferMode)
815 " // Compute gradient function only once\n"
816 " vec4 gradient = computeGradient(g_dataPos, component, in_volume[0], 0);\n");
819 shaderStr +=
std::string(
" // TransferFunction2D is enabled so the gradient for\n"
820 " // each component has already been cached\n"
821 " vec4 gradient = g_gradients_0[component];\n");
828 if (lightingComplexity == 1)
831 \n vec3 diffuse = vec3(0.0);\
832 \n vec3 specular = vec3(0.0);\
833 \n vec3 normal = gradient.xyz;\
834 \n float normalLength = length(normal);\
835 \n if (normalLength > 0.0)\
837 \n normal = normalize(normal);\
841 \n normal = vec3(0.0, 0.0, 0.0);\
843 \n float nDotL = dot(normal, g_ldir[0]);\
844 \n float nDotH = dot(normal, g_h[0]);\
845 \n if (nDotL < 0.0 && in_twoSidedLighting)\
849 \n if (nDotH < 0.0 && in_twoSidedLighting)\
855 \n diffuse = nDotL * in_diffuse[component] *\
856 \n in_lightDiffuseColor[0] * color.rgb;\
858 \n specular = pow(nDotH, in_shininess[component]) *\
859 \n in_specular[component] *\
860 \n in_lightSpecularColor[0];\
861 \n // For the headlight, ignore the light's ambient color\
862 \n // for now as it is causing the old mapper tests to fail\
863 \n finalColor.xyz = in_ambient[component] * color.rgb +\
864 \n diffuse + specular;\
867 else if (lightingComplexity == 2)
870 \n g_fragWorldPos = in_modelViewMatrix * in_volumeMatrix[0] *\
871 \n in_textureDatasetMatrix[0] * vec4(-g_dataPos, 1.0);\
872 \n if (g_fragWorldPos.w != 0.0)\
874 \n g_fragWorldPos /= g_fragWorldPos.w;\
876 \n vec3 vdir = normalize(g_fragWorldPos.xyz);\
877 \n vec3 normal = gradient.xyz;\
878 \n vec3 ambient = vec3(0.0);\
879 \n vec3 diffuse = vec3(0.0);\
880 \n vec3 specular = vec3(0.0);\
881 \n float normalLength = length(normal);\
882 \n if (normalLength > 0.0)\
884 \n normal = normalize((in_textureToEye[0] * vec4(normal, 0.0)).xyz);\
888 \n normal = vec3(0.0, 0.0, 0.0);\
890 \n for (int lightNum = 0; lightNum < in_numberOfLights; lightNum++)\
892 \n vec3 ldir = in_lightDirection[lightNum].xyz;\
893 \n vec3 h = normalize(ldir + vdir);\
894 \n float nDotH = dot(normal, h);\
895 \n if (nDotH < 0.0 && in_twoSidedLighting)\
899 \n float nDotL = dot(normal, ldir);\
900 \n if (nDotL < 0.0 && in_twoSidedLighting)\
906 \n diffuse += in_lightDiffuseColor[lightNum] * nDotL;\
910 \n specular = in_lightSpecularColor[lightNum] *\
911 \n pow(nDotH, in_shininess[component]);\
913 \n ambient += in_lightAmbientColor[lightNum];\
915 \n finalColor.xyz = in_ambient[component] * ambient +\
916 \n in_diffuse[component] * diffuse * color.rgb +\
917 \n in_specular[component] * specular;");
919 else if (lightingComplexity == 3)
922 \n g_fragWorldPos = in_modelViewMatrix * in_volumeMatrix[0] *\
923 \n in_textureDatasetMatrix[0] * vec4(g_dataPos, 1.0);\
924 \n if (g_fragWorldPos.w != 0.0)\
926 \n g_fragWorldPos /= g_fragWorldPos.w;\
928 \n vec3 viewDirection = normalize(-g_fragWorldPos.xyz);\
929 \n vec3 ambient = vec3(0,0,0);\
930 \n vec3 diffuse = vec3(0,0,0);\
931 \n vec3 specular = vec3(0,0,0);\
932 \n vec3 vertLightDirection;\
933 \n vec3 normal = normalize((in_textureToEye[0] * vec4(gradient.xyz, 0.0)).xyz);\
935 \n for (int lightNum = 0; lightNum < in_numberOfLights; lightNum++)\
937 \n float attenuation = 1.0;\
939 \n lightDir = in_lightDirection[lightNum];\
940 \n if (in_lightPositional[lightNum] == 0)\
942 \n vertLightDirection = lightDir;\
946 \n vertLightDirection = (g_fragWorldPos.xyz - in_lightPosition[lightNum]);\
947 \n float distance = length(vertLightDirection);\
948 \n vertLightDirection = normalize(vertLightDirection);\
949 \n attenuation = 1.0 /\
950 \n (in_lightAttenuation[lightNum].x\
951 \n + in_lightAttenuation[lightNum].y * distance\
952 \n + in_lightAttenuation[lightNum].z * distance * distance);\
953 \n // per OpenGL standard cone angle is 90 or less for a spot light\
954 \n if (in_lightConeAngle[lightNum] <= 90.0)\
956 \n float coneDot = dot(vertLightDirection, lightDir);\
957 \n // if inside the cone\
958 \n if (coneDot >= cos(radians(in_lightConeAngle[lightNum])))\
960 \n attenuation = attenuation * pow(coneDot, in_lightExponent[lightNum]);\
964 \n attenuation = 0.0;\
968 \n // diffuse and specular lighting\
969 \n float nDotL = dot(normal, vertLightDirection);\
970 \n if (nDotL < 0.0 && in_twoSidedLighting)\
976 \n float df = max(0.0, attenuation * nDotL);\
977 \n diffuse += (df * in_lightDiffuseColor[lightNum]);\
979 \n vec3 h = normalize(vertLightDirection + viewDirection);\
980 \n float nDotH = dot(normal, h);\
981 \n if (nDotH < 0.0 && in_twoSidedLighting)\
987 \n float sf = attenuation * pow(nDotH, in_shininess[component]);\
988 \n specular += (sf * in_lightSpecularColor[lightNum]);\
990 \n ambient += in_lightAmbientColor[lightNum];\
992 \n finalColor.xyz = in_ambient[component] * ambient +\
993 \n in_diffuse[component] * diffuse * color.rgb +\
994 \n in_specular[component] * specular;\
1000 shaderStr +=
std::string(
"\n finalColor = vec4(color.rgb, 0.0);");
1010 if (noOfComponents == 1 || !independentComponents)
1015 \n if (gradient.w >= 0.0 && label == 0.0)\
1017 \n color.a *= computeGradientOpacity(gradient);\
1023 \n if (gradient.w >= 0.0 && label > 0.0)\
1025 \n color.a *= computeGradientOpacityForLabel(gradient, label);\
1029 else if (noOfComponents > 1 && independentComponents && volProperty->
HasGradientOpacity())
1032 \n if (gradient.w >= 0.0)\
1034 \n for (int i = 0; i < in_noOfComponents; ++i)\
1036 \n color.a = color.a *\
1037 \n computeGradientOpacity(gradient, i) * in_componentWeight[i];\
1044 \n finalColor.a = color.a;\
1045 \n return finalColor;\
1053 vtkVolume* vol,
int noOfComponents,
int independentComponents,
int vtkNotUsed(numberOfLights),
1054 int lightingComplexity)
1064 \nvec4 computeLighting(vec3 texPos, vec4 color, const in sampler2D gradientTF, const in sampler3D volume, const int volIdx, int component)\
1066 \n vec4 finalColor = vec4(0.0);");
1071 \nvec4 computeLighting(vec3 texPos, vec4 color, const in sampler3D volume, const int volIdx, int component)\
1073 \n vec4 finalColor = vec4(0.0);");
1077 int const shadeReqd = volProperty->
GetShade() &&
1086 std::string(
" // Compute gradient function only once\n"
1087 " vec4 gradient = computeGradient(texPos, component, volume, volIdx);\n");
1090 if (shadeReqd && lightingComplexity == 1)
1093 \n vec3 diffuse = vec3(0.0);\
1094 \n vec3 specular = vec3(0.0);\
1095 \n vec3 normal = gradient.xyz;\
1096 \n float normalLength = length(normal);\
1097 \n if (normalLength > 0.0)\
1099 \n normal = normalize(normal);\
1103 \n normal = vec3(0.0, 0.0, 0.0);\
1105 \n float nDotL = dot(normal, g_ldir[volIdx]);\
1106 \n float nDotH = dot(normal, g_h[volIdx]);\
1107 \n if (nDotL < 0.0 && in_twoSidedLighting)\
1111 \n if (nDotH < 0.0 && in_twoSidedLighting)\
1115 \n if (nDotL > 0.0)\
1117 \n diffuse = nDotL * in_diffuse[component] *\
1118 \n in_lightDiffuseColor[0] * color.rgb;\
1120 \n specular = pow(nDotH, in_shininess[component]) *\
1121 \n in_specular[component] *\
1122 \n in_lightSpecularColor[0];\
1123 \n // For the headlight, ignore the light's ambient color\
1124 \n // for now as it is causing the old mapper tests to fail\
1125 \n finalColor.xyz = in_ambient[component] * color.rgb +\
1126 \n diffuse + specular;\
1131 shaderStr +=
std::string(
"\n finalColor = vec4(color.rgb, 0.0);");
1138 if (volProperty->
HasGradientOpacity() && (noOfComponents == 1 || !independentComponents))
1141 \n if (gradient.w >= 0.0)\
1143 \n color.a = color.a *\
1144 \n computeGradientOpacity(gradient, gradientTF);\
1150 \n finalColor.a = color.a;\
1151 \n return clamp(finalColor, 0.0, 1.0);\
1159 vtkVolume* vtkNotUsed(vol),
int vtkNotUsed(noOfComponents))
1164 \nvec3 computeRayDirection()\
1166 \n return normalize(ip_vertexPos.xyz - g_eyePosObj.xyz);\
1172 \nuniform vec3 in_projectionDirection;\
1173 \nvec3 computeRayDirection()\
1175 \n return normalize((in_inverseVolumeMatrix[0] *\
1176 \n vec4(in_projectionDirection, 0.0)).xyz);\
1184 int independentComponents, std::map<int, std::string> colorTableMap)
1186 std::ostringstream ss;
1187 ss <<
"uniform sampler2D " << ArrayBaseName(colorTableMap[0]) <<
"[" << noOfComponents <<
"];\n";
1190 if (noOfComponents == 1)
1193 \nvec4 computeColor(vec4 scalar, float opacity)\
1195 \n return clamp(computeLighting(vec4(texture2D(" +
1196 colorTableMap[0] +
",\
1197 \n vec2(scalar.w, 0.0)).xyz, opacity), 0, 0.0), 0.0, 1.0);\
1201 else if (noOfComponents > 1 && independentComponents)
1203 std::ostringstream toString;
1206 \nvec4 computeColor(vec4 scalar, float opacity, int component)\
1209 for (
int i = 0; i < noOfComponents; ++i)
1213 \n if (component == " +
1214 toString.str() +
")");
1218 \n return clamp(computeLighting(vec4(texture2D(\
1223 toString.str() +
"],0.0)).xyz,\
1225 toString.str() +
", 0.0), 0.0, 1.0);\
1236 else if (noOfComponents == 2 && !independentComponents)
1239 \nvec4 computeColor(vec4 scalar, float opacity)\
1241 \n return clamp(computeLighting(vec4(texture2D(" +
1242 colorTableMap[0] +
",\
1243 \n vec2(scalar.x, 0.0)).xyz,\
1244 \n opacity), 0, 0.0), 0.0, 1.0);\
1251 \nvec4 computeColor(vec4 scalar, float opacity)\
1253 \n return clamp(computeLighting(vec4(scalar.xyz, opacity), 0, 0.0), 0.0, 1.0);\
1263 std::ostringstream ss;
1266 std::map<int, std::string> lastColorTableMap;
1267 for (
auto& item : inputs)
1269 auto prop = item.second.Volume->GetProperty();
1273 auto& map = item.second.RGBTablesMap;
1274 const auto numComp = map.size();
1275 ss <<
"uniform sampler2D " << ArrayBaseName(map[0]) <<
"[" << numComp <<
"];\n";
1277 lastComponentMode = item.second.ComponentMode;
1278 lastColorTableMap = map;
1284 ss <<
"vec4 computeColor(vec4 scalar, const in sampler2D colorTF)\
1286 \n return clamp(computeLighting(vec4(texture2D(colorTF,\
1287 \n vec2(scalar.w, 0.0)).xyz, opacity), 0), 0.0, 1.0);\
1295 <<
"vec4 computeColor(vec3 texPos, vec4 scalar, float opacity, const in sampler2D colorTF, "
1296 "const in sampler2D gradientTF, const in sampler3D volume, const int volIdx)\n"
1298 " return clamp(computeLighting(texPos, vec4(texture2D(colorTF,\n"
1299 " vec2(scalar.w, 0.0)).xyz, opacity), gradientTF, volume, "
1300 "volIdx, 0), 0.0, 1.0);\n"
1306 <<
"vec4 computeColor(vec3 texPos, vec4 scalar, float opacity, const in sampler2D colorTF, "
1307 "const in sampler3D volume, const int volIdx)\n"
1309 " return clamp(computeLighting(texPos, vec4(texture2D(colorTF,\n"
1310 " vec2(scalar.w, 0.0)).xyz, opacity), volume, "
1311 "volIdx, 0), 0.0, 1.0);\n"
1322 std::ostringstream ss;
1324 for (
auto& item : inputs)
1326 auto prop = item.second.Volume->GetProperty();
1330 auto& map = item.second.OpacityTablesMap;
1331 const auto numComp = map.size();
1332 ss <<
"uniform sampler2D " << ArrayBaseName(map[0]) <<
"[" << numComp <<
"];\n";
1336 ss <<
"float computeOpacity(vec4 scalar, const in sampler2D opacityTF)\n"
1338 " return texture2D(opacityTF, vec2(scalar.w, 0)).r;\n"
1347 std::ostringstream ss;
1350 for (
auto& item : inputs)
1352 auto prop = item.second.Volume->GetProperty();
1356 auto& map = item.second.GradientOpacityTablesMap;
1357 const auto numComp = map.size();
1358 ss <<
"uniform sampler2D " << ArrayBaseName(map[0]) <<
"[" << numComp <<
"];\n";
1362 ss <<
"float computeGradientOpacity(vec4 grad, const in sampler2D gradientTF)\n"
1364 " return texture2D(gradientTF, vec2(grad.w, 0.0)).r;\n"
1372 int independentComponents, std::map<int, std::string> opacityTableMap)
1374 std::ostringstream ss;
1375 ss <<
"uniform sampler2D " << ArrayBaseName(opacityTableMap[0]) <<
"[" << noOfComponents
1379 if (noOfComponents > 1 && independentComponents)
1382 \nfloat computeOpacity(vec4 scalar, int component)\
1385 for (
int i = 0; i < noOfComponents; ++i)
1387 std::ostringstream toString;
1390 \n if (component == " +
1391 toString.str() +
")");
1395 \n return texture2D(" +
1396 opacityTableMap[i]);
1398 shaderStr +=
std::string(
",vec2(scalar[" + toString.str() +
"], 0)).r;\
1405 else if (noOfComponents == 2 && !independentComponents)
1408 \nfloat computeOpacity(vec4 scalar)\
1410 \n return texture2D(" +
1411 opacityTableMap[0] +
", vec2(scalar.y, 0)).r;\
1418 \nfloat computeOpacity(vec4 scalar)\
1420 \n return texture2D(" +
1421 opacityTableMap[0] +
", vec2(scalar.w, 0)).r;\
1429 int vtkNotUsed(independentComponents), std::map<int, std::string> colorTableMap)
1431 if (noOfComponents == 1)
1435 "vec4 computeColor(vec4 scalar, float opacity)\n"
1437 " vec4 yscalar = texture3D(in_transfer2DYAxis, g_dataPos);\n"
1438 " yscalar.r = yscalar.r * in_transfer2DYAxis_scale.r + in_transfer2DYAxis_bias.r;\n"
1439 " yscalar = vec4(yscalar.r);\n"
1440 " vec4 color = texture2D(" +
1443 " vec2(scalar.w, yscalar.w));\n"
1444 " return computeLighting(color, 0, 0);\n"
1447 return std::string(
"vec4 computeColor(vec4 scalar, float opacity)\n"
1449 " return vec4(0, 0, 0, 0)\n"
1456 int independentComponents, std::map<int, std::string> colorTableMap,
int useGradient)
1462 if (noOfComponents == 1)
1465 return std::string(
"vec4 computeColor(vec4 scalar, float opacity)\n"
1467 " vec4 color = texture2D(" +
1470 " vec2(scalar.w, g_gradients_0[0].w));\n"
1471 " return computeLighting(color, 0, 0);\n"
1474 else if (noOfComponents > 1 && independentComponents)
1478 shaderStr +=
std::string(
"vec4 computeColor(vec4 scalar, float opacity, int component)\n"
1481 for (
int i = 0; i < noOfComponents; ++i)
1483 std::ostringstream toString;
1486 shaderStr +=
std::string(
" if (component == " + num +
1489 " vec4 color = texture2D(" +
1493 num +
"], g_gradients_0[" + num +
1495 " return computeLighting(color, " +
1504 else if (noOfComponents == 2 && !independentComponents)
1507 return std::string(
"vec4 computeColor(vec4 scalar, float opacity)\n"
1509 " vec4 color = texture2D(" +
1512 " vec2(scalar.x, g_gradients_0[0].w));\n"
1513 " return computeLighting(color, 0, 0.0);\n"
1518 return std::string(
"vec4 computeColor(vec4 scalar, float opacity)\n"
1520 " return computeLighting(vec4(scalar.xyz, opacity), 0, 0.0);\n"
1528 std::ostringstream ss;
1530 for (
auto& item : inputs)
1532 auto prop = item.second.Volume->GetProperty();
1536 auto& map = item.second.TransferFunctions2DMap;
1537 const auto numComp = map.size();
1538 ss <<
"uniform sampler2D " << ArrayBaseName(map[0]) <<
"[" << numComp <<
"];\n";
1543 std::string(
"uniform sampler3D in_transfer2DYAxis;\n"
1544 "uniform vec4 in_transfer2DYAxis_scale;\n"
1545 "uniform vec4 in_transfer2DYAxis_bias;\n");
1553 int independentComponents, std::map<int, std::string> opacityTableMap,
int useGradient)
1555 std::ostringstream toString;
1556 if (noOfComponents > 1 && independentComponents)
1559 toString <<
"float computeOpacity(vec4 scalar, int component)\n"
1564 <<
"vec4 yscalar = texture3D(in_transfer2DYAxis, g_dataPos);\n"
1565 "for (int i = 0; i < 4; ++i)\n"
1567 " yscalar[i] = yscalar[i] * in_transfer2DYAxis_scale[i] + in_transfer2DYAxis_bias[i];\n"
1569 if (noOfComponents == 1)
1571 toString <<
"yscalar = vec4(yscalar.r);\n";
1575 for (
int i = 0; i < noOfComponents; ++i)
1579 toString <<
" if (component == " << i
1582 " return texture2D("
1583 << opacityTableMap[i]
1586 << i <<
"], g_gradients_0[" << i
1592 toString <<
" if (component == " << i
1595 " return texture2D("
1596 << opacityTableMap[i]
1599 << i <<
"], yscalar[" << i
1608 else if (noOfComponents == 2 && !independentComponents)
1613 toString <<
"float computeOpacity(vec4 scalar)\n"
1615 " return texture2D(" +
1616 opacityTableMap[0] +
1618 " vec2(scalar.y, g_gradients_0[0].w)).a;\n"
1624 toString <<
"float computeOpacity(vec4 scalar)\n"
1626 " return texture2D(" +
1627 opacityTableMap[0] +
1629 " vec2(scalar.y, yscalar.y)).a;\n"
1639 toString <<
"float computeOpacity(vec4 scalar)\n"
1641 " return texture2D(" +
1642 opacityTableMap[0] +
1644 " vec2(scalar.a, g_gradients_0[0].w)).a;\n"
1651 <<
"float computeOpacity(vec4 scalar)\n"
1653 " vec4 yscalar = texture3D(in_transfer2DYAxis, g_dataPos);\n"
1654 " yscalar.r = yscalar.r * in_transfer2DYAxis_scale.r + in_transfer2DYAxis_bias.r;\n"
1655 " yscalar = vec4(yscalar.r);\n"
1656 " return texture2D(" +
1657 opacityTableMap[0] +
1659 " vec2(scalar.a, yscalar.w)).a;\n"
1663 return toString.str();
1680 \n bool l_firstValue;\
1681 \n vec4 l_maxValue;");
1686 \n bool l_firstValue;\
1687 \n vec4 l_minValue;");
1692 \n uvec4 l_numSamples;\
1693 \n vec4 l_avgValue;");
1698 \n vec4 l_sumValue;");
1703 \n int l_initialIndex = 0;\
1704 \n float l_normValues[NUMBER_OF_CONTOURS + 2];");
1719 \n // We get data between 0.0 - 1.0 range\
1720 \n l_firstValue = true;\
1721 \n l_maxValue = vec4(0.0);");
1726 \n //We get data between 0.0 - 1.0 range\
1727 \n l_firstValue = true;\
1728 \n l_minValue = vec4(1.0);");
1733 \n //We get data between 0.0 - 1.0 range\
1734 \n l_avgValue = vec4(0.0);\
1735 \n // Keep track of number of samples\
1736 \n l_numSamples = uvec4(0);");
1741 \n //We get data between 0.0 - 1.0 range\
1742 \n l_sumValue = vec4(0.0);");
1747 \n#if NUMBER_OF_CONTOURS\
1748 \n l_normValues[0] = -1e20; //-infinity\
1749 \n l_normValues[NUMBER_OF_CONTOURS+1] = +1e20; //+infinity\
1750 \n for (int i = 0; i < NUMBER_OF_CONTOURS; i++)\
1752 \n l_normValues[i+1] = (in_isosurfacesValues[i] - in_scalarsRange[0].x) / \
1753 \n (in_scalarsRange[0].y - in_scalarsRange[0].x);\
1768 const int numInputs =
static_cast<int>(inputs.size());
1769 const int comp = numInputs == 1 ?
1771 (!independentComponents ? 1 : numInputs)
1776 std::ostringstream toShader;
1777 for (
const auto& item : inputs)
1779 auto& input = item.second;
1780 if (input.Volume->GetProperty()->HasGradientOpacity())
1782 toShader <<
"vec4 " << input.GradientCacheName <<
"[" << comp <<
"];\n";
1786 return toShader.str();
1791 int noOfComponents = 1,
int independentComponents = 0)
1793 std::ostringstream shader;
1794 if (independentComponents)
1796 if (noOfComponents == 1)
1798 shader <<
"g_gradients_0[0] = computeGradient(g_dataPos, 0, in_volume[0], 0);\n";
1803 shader <<
"for (int comp = 0; comp < in_noOfComponents; comp++)\n"
1805 " g_gradients_0[comp] = computeGradient(g_dataPos, comp, in_volume[0], 0);\n"
1811 shader <<
"g_gradients_0[0] = computeGradient(g_dataPos, 0, in_volume[0], 0);\n";
1814 return shader.str();
1821 std::ostringstream toShaderStr;
1822 toShaderStr <<
" if (!g_skip)\n"
1832 for (
auto& item : inputs)
1834 auto& input = item.second;
1835 auto property = input.Volume->GetProperty();
1837 const auto idx = i + 1;
1842 " texPos = (in_cellToPoint[" << idx <<
"] * in_inverseTextureDatasetMatrix[" << idx
1843 <<
"] * in_inverseVolumeMatrix[" << idx
1845 " in_volumeMatrix[0] * in_textureDatasetMatrix[0] * "
1846 "vec4(g_dataPos.xyz, 1.0)).xyz;\n"
1847 " if ((all(lessThanEqual(texPos, vec3(1.0))) &&\n"
1848 " all(greaterThanEqual(texPos, vec3(0.0)))))\n"
1850 " vec4 scalar = texture3D(in_volume["
1853 " scalar = scalar * in_volume_scale["
1854 << i <<
"] + in_volume_bias[" << i
1856 " scalar = vec4(scalar.r);\n"
1857 " g_srcColor = vec4(0.0);\n";
1861 std::string gradientopacity_param = (
property->HasGradientOpacity())
1862 ? input.GradientOpacityTablesMap[0] +
std::string(
", ")
1865 toShaderStr <<
" g_srcColor.a = computeOpacity(scalar,"
1866 << input.OpacityTablesMap[0]
1868 " if (g_srcColor.a > 0.0)\n"
1870 " g_srcColor = computeColor(texPos, scalar, g_srcColor.a, "
1871 << input.RGBTablesMap[0] <<
", " << gradientopacity_param <<
"in_volume[" << i
1872 <<
"], " << i <<
");\n";
1874 if (property->HasGradientOpacity())
1876 const auto& grad = input.GradientCacheName;
1877 toShaderStr <<
" " << grad <<
"[0] = computeGradient(texPos, 0, "
1878 <<
"in_volume[" << i <<
"], " << i
1882 <<
"[0].w >= 0.0)\n"
1884 " g_srcColor.a *= computeGradientOpacity("
1885 << grad <<
"[0], " << input.GradientOpacityTablesMap[0]
1892 const auto& grad = input.GradientCacheName;
1895 " " << grad <<
"[0] = computeGradient(texPos, 0, "
1896 <<
"in_volume[" << i <<
"], " << i
1898 " g_srcColor = texture2D("
1899 << input.TransferFunctions2DMap[0] <<
", vec2(scalar.r, "
1900 << input.GradientCacheName
1902 " if (g_srcColor.a > 0.0)\n"
1907 <<
" g_srcColor.rgb *= g_srcColor.a;\n"
1908 " g_fragColor = (1.0f - g_fragColor.a) * g_srcColor + g_fragColor;\n"
1917 toShaderStr <<
" }\n";
1919 return toShaderStr.str();
1925 int noOfComponents,
int independentComponents = 0)
1939 \n // Compute IJK vertex position for current sample in the rectilinear grid\
1940 \n vec4 dataPosWorld = in_volumeMatrix[0] * in_textureDatasetMatrix[0] * vec4(g_dataPos, 1.0);\
1941 \n dataPosWorld = dataPosWorld / dataPosWorld.w;\
1942 \n dataPosWorld.w = 1.0;\
1943 \n ivec3 ijk = ivec3(0);\
1944 \n vec3 ijkTexCoord = vec3(0.0);\
1945 \n vec3 pCoords = vec3(0.0);\
1946 \n vec3 xPrev, xNext, tmp;\
1947 \n int sz = textureSize(in_coordTexs, 0);\
1948 \n vec4 dataPosWorldScaled = dataPosWorld * vec4(in_coordsScale, 1.0) +\
1949 \n vec4(in_coordsBias, 1.0);\
1950 \n for (int j = 0; j < 3; ++j)\
1952 \n xPrev = texture1D(in_coordTexs, 0.0).xyz;\
1953 \n xNext = texture1D(in_coordTexs, (in_coordTexSizes[j] - 1) / sz).xyz;\
1954 \n if (xNext[j] < xPrev[j])\
1960 \n for (int i = 0; i < int(in_coordTexSizes[j]); i++)\
1962 \n xNext = texture1D(in_coordTexs, (i + 0.5) / sz).xyz;\
1963 \n if (dataPosWorldScaled[j] >= xPrev[j] && dataPosWorldScaled[j] < xNext[j])\
1966 \n pCoords[j] = (dataPosWorldScaled[j] - xPrev[j]) / (xNext[j] - xPrev[j]);\
1969 \n else if (dataPosWorldScaled[j] == xNext[j])\
1972 \n pCoords[j] = 1.0;\
1977 \n ijkTexCoord[j] = (ijk[j] + pCoords[j]) / in_coordTexSizes[j];\
1979 \n scalar = texture3D(in_volume[0], sign(in_cellSpacing[0]) * ijkTexCoord);\
1985 \n scalar = texture3D(in_volume[0], g_dataPos);\
1990 if (noOfComponents == 1)
1993 \n scalar.r = scalar.r * in_volume_scale[0].r + in_volume_bias[0].r;\
1994 \n scalar = vec4(scalar.r);");
2000 \n scalar = scalar * in_volume_scale[0] + in_volume_bias[0];");
2005 if (noOfComponents > 1)
2007 if (!independentComponents)
2010 \n if (l_maxValue.w < scalar.w || l_firstValue)\
2012 \n l_maxValue = scalar;\
2015 \n if (l_firstValue)\
2017 \n l_firstValue = false;\
2023 \n for (int i = 0; i < in_noOfComponents; ++i)\
2025 \n if (l_maxValue[i] < scalar[i] || l_firstValue)\
2027 \n l_maxValue[i] = scalar[i];\
2030 \n if (l_firstValue)\
2032 \n l_firstValue = false;\
2039 \n if (l_maxValue.w < scalar.x || l_firstValue)\
2041 \n l_maxValue.w = scalar.x;\
2044 \n if (l_firstValue)\
2046 \n l_firstValue = false;\
2052 if (noOfComponents > 1)
2054 if (!independentComponents)
2057 \n if (l_minValue.w > scalar.w || l_firstValue)\
2059 \n l_minValue = scalar;\
2062 \n if (l_firstValue)\
2064 \n l_firstValue = false;\
2070 \n for (int i = 0; i < in_noOfComponents; ++i)\
2072 \n if (l_minValue[i] < scalar[i] || l_firstValue)\
2074 \n l_minValue[i] = scalar[i];\
2077 \n if (l_firstValue)\
2079 \n l_firstValue = false;\
2086 \n if (l_minValue.w > scalar.x || l_firstValue)\
2088 \n l_minValue.w = scalar.x;\
2091 \n if (l_firstValue)\
2093 \n l_firstValue = false;\
2099 if (noOfComponents > 1 && independentComponents)
2102 \n for (int i = 0; i < in_noOfComponents; ++i)\
2104 \n // Get the intensity in volume scalar range\
2105 \n float intensity = in_scalarsRange[i][0] +\
2106 \n (in_scalarsRange[i][1] -\
2107 \n in_scalarsRange[i][0]) * scalar[i];\
2108 \n if (in_averageIPRange.x <= intensity &&\
2109 \n intensity <= in_averageIPRange.y)\
2111 \n l_avgValue[i] += computeOpacity(scalar, i) * scalar[i];\
2112 \n ++l_numSamples[i];\
2119 \n // Get the intensity in volume scalar range\
2120 \n float intensity = in_scalarsRange[0][0] +\
2121 \n (in_scalarsRange[0][1] -\
2122 \n in_scalarsRange[0][0]) * scalar.x;\
2123 \n if (in_averageIPRange.x <= intensity &&\
2124 \n intensity <= in_averageIPRange.y)\
2126 \n l_avgValue.x += computeOpacity(scalar) * scalar.x;\
2127 \n ++l_numSamples.x;\
2133 if (noOfComponents > 1 && independentComponents)
2136 \n for (int i = 0; i < in_noOfComponents; ++i)\
2138 \n float opacity = computeOpacity(scalar, i);\
2139 \n l_sumValue[i] = l_sumValue[i] + opacity * scalar[i];\
2145 \n float opacity = computeOpacity(scalar);\
2146 \n l_sumValue.x = l_sumValue.x + opacity * scalar.x;");
2152 \n#if NUMBER_OF_CONTOURS\
2153 \n int maxComp = 0;");
2156 if (noOfComponents > 1 && independentComponents)
2159 \n for (int i = 1; i < in_noOfComponents; ++i)\
2161 \n if (in_componentWeight[i] > in_componentWeight[maxComp])\
2164 compParamStr =
", maxComp";
2167 \n if (g_currentT == 0)\
2169 \n l_initialIndex = findIsoSurfaceIndex(scalar[maxComp], l_normValues);\
2174 \n bool shade = false;\
2175 \n l_initialIndex = clamp(l_initialIndex, 0, NUMBER_OF_CONTOURS);\
2176 \n if (scalar[maxComp] < l_normValues[l_initialIndex])\
2178 \n s = l_normValues[l_initialIndex];\
2179 \n l_initialIndex--;\
2182 \n if (scalar[maxComp] > l_normValues[l_initialIndex+1])\
2184 \n s = l_normValues[l_initialIndex+1];\
2185 \n l_initialIndex++;\
2188 \n if (shade == true)\
2190 \n vec4 vs = vec4(s);\
2191 \n g_srcColor.a = computeOpacity(vs " +
2193 \n g_srcColor = computeColor(vs, g_srcColor.a " +
2195 \n g_srcColor.rgb *= g_srcColor.a;\
2196 \n g_fragColor = (1.0f - g_fragColor.a) * g_srcColor + g_fragColor;\
2204 \n // test if the intersection is inside the volume bounds\
2205 \n if (any(greaterThan(g_dataPos, vec3(1.0))) || any(lessThan(g_dataPos, vec3(0.0))))\
2209 \n float opacity = computeOpacity(scalar);\
2210 \n g_fragColor = computeColor(scalar, opacity);\
2211 \n g_fragColor.rgb *= opacity;\
2212 \n g_exit = true;");
2216 if (noOfComponents > 1 && independentComponents)
2219 \n vec4 color[4]; vec4 tmp = vec4(0.0);\
2220 \n float totalAlpha = 0.0;\
2221 \n for (int i = 0; i < in_noOfComponents; ++i)\
2224 if (glMapper->GetUseDepthPass() &&
2228 \n // Data fetching from the red channel of volume texture\
2229 \n float opacity = computeOpacity(scalar, i);\
2230 \n if (opacity > 0.0)\
2232 \n g_srcColor.a = opacity;\
2239 \n // Data fetching from the red channel of volume texture\
2240 \n color[i][3] = computeOpacity(scalar, i);\
2241 \n color[i] = computeColor(scalar, color[i][3], i);\
2242 \n totalAlpha += color[i][3] * in_componentWeight[i];\
2244 \n if (totalAlpha > 0.0)\
2246 \n for (int i = 0; i < in_noOfComponents; ++i)\
2248 \n // Only let visible components contribute to the final color\
2249 \n if (in_componentWeight[i] <= 0) continue;\
2251 \n tmp.x += color[i].x * color[i].w * in_componentWeight[i];\
2252 \n tmp.y += color[i].y * color[i].w * in_componentWeight[i];\
2253 \n tmp.z += color[i].z * color[i].w * in_componentWeight[i];\
2254 \n tmp.w += ((color[i].w * color[i].w)/totalAlpha);\
2257 \n g_fragColor = (1.0f - g_fragColor.a) * tmp + g_fragColor;");
2260 else if (glMapper->GetUseDepthPass() &&
2264 \n g_srcColor = vec4(0.0);\
2265 \n g_srcColor.a = computeOpacity(scalar);");
2272 \n g_srcColor = vec4(0.0);\
2273 \n g_srcColor.a = computeOpacity(scalar);\
2274 \n if (g_srcColor.a > 0.0)\
2276 \n g_srcColor = computeColor(scalar, g_srcColor.a);");
2280 \n // Opacity calculation using compositing:\
2281 \n // Here we use front to back compositing scheme whereby\
2282 \n // the current sample value is multiplied to the\
2283 \n // currently accumulated alpha and then this product\
2284 \n // is subtracted from the sample value to get the\
2285 \n // alpha from the previous steps. Next, this alpha is\
2286 \n // multiplied with the current sample colour\
2287 \n // and accumulated to the composited colour. The alpha\
2288 \n // value from the previous steps is then accumulated\
2289 \n // to the composited colour alpha.\
2290 \n g_srcColor.rgb *= g_srcColor.a;\
2291 \n g_fragColor = (1.0f - g_fragColor.a) * g_srcColor + g_fragColor;");
2315 \n // Special coloring mode which renders the Prop Id in fragments that\
2316 \n // have accumulated certain level of opacity. Used during the selection\
2317 \n // pass vtkHardwareSelection::ACTOR_PASS.\
2318 \n if (g_fragColor.a > 3.0/ 255.0)\
2320 \n gl_FragData[0] = vec4(in_propId, 1.0);\
2324 \n gl_FragData[0] = vec4(0.0);\
2334 \n // Special coloring mode which renders the voxel index in fragments that\
2335 \n // have accumulated certain level of opacity. Used during the selection\
2336 \n // pass vtkHardwareSelection::ID_LOW24.\
2337 \n if (g_fragColor.a > 3.0/ 255.0)\
2339 \n uvec3 volumeDim = uvec3(in_textureExtentsMax - in_textureExtentsMin);\
2340 \n uvec3 voxelCoords = uvec3(volumeDim * g_dataPos);\
2341 \n // vtkHardwareSelector assumes index 0 to be empty space, so add uint(1).\
2342 \n uint idx = volumeDim.x * volumeDim.y * voxelCoords.z +\
2343 \n volumeDim.x * voxelCoords.y + voxelCoords.x + uint(1);\
2344 \n gl_FragData[0] = vec4(float(idx % uint(256)) / 255.0,\
2345 \n float((idx / uint(256)) % uint(256)) / 255.0,\
2346 \n float((idx / uint(65536)) % uint(256)) / 255.0, 1.0);\
2350 \n gl_FragData[0] = vec4(0.0);\
2360 \n // Special coloring mode which renders the voxel index in fragments that\
2361 \n // have accumulated certain level of opacity. Used during the selection\
2362 \n // pass vtkHardwareSelection::ID_MID24.\
2363 \n if (g_fragColor.a > 3.0/ 255.0)\
2365 \n uvec3 volumeDim = uvec3(in_textureExtentsMax - in_textureExtentsMin);\
2366 \n uvec3 voxelCoords = uvec3(volumeDim * g_dataPos);\
2367 \n // vtkHardwareSelector assumes index 0 to be empty space, so add uint(1).\
2368 \n uint idx = volumeDim.x * volumeDim.y * voxelCoords.z +\
2369 \n volumeDim.x * voxelCoords.y + voxelCoords.x + uint(1);\
2370 \n idx = ((idx & 0xff000000) >> 24);\
2371 \n gl_FragData[0] = vec4(float(idx % uint(256)) / 255.0,\
2372 \n float((idx / uint(256)) % uint(256)) / 255.0,\
2373 \n float(idx / uint(65536)) / 255.0, 1.0);\
2377 \n gl_FragData[0] = vec4(0.0);\
2384 vtkVolume* vtkNotUsed(vol),
int noOfComponents,
int independentComponents = 0)
2396 if (noOfComponents > 1 && independentComponents)
2399 \n g_srcColor = vec4(0);\
2400 \n for (int i = 0; i < in_noOfComponents; ++i)\
2402 \n vec4 tmp = computeColor(l_maxValue, computeOpacity(l_maxValue, i), i);\
2403 \n g_srcColor[0] += tmp[0] * tmp[3] * in_componentWeight[i];\
2404 \n g_srcColor[1] += tmp[1] * tmp[3] * in_componentWeight[i];\
2405 \n g_srcColor[2] += tmp[2] * tmp[3] * in_componentWeight[i];\
2406 \n g_srcColor[3] += tmp[3] * in_componentWeight[i];\
2408 \n g_fragColor = g_srcColor;");
2413 \n g_srcColor = computeColor(l_maxValue,\
2414 \n computeOpacity(l_maxValue));\
2415 \n g_fragColor.rgb = g_srcColor.rgb * g_srcColor.a;\
2416 \n g_fragColor.a = g_srcColor.a;");
2421 if (noOfComponents > 1 && independentComponents)
2424 \n g_srcColor = vec4(0);\
2425 \n for (int i = 0; i < in_noOfComponents; ++i)\
2427 \n vec4 tmp = computeColor(l_minValue, computeOpacity(l_minValue, i), i);\
2428 \n g_srcColor[0] += tmp[0] * tmp[3] * in_componentWeight[i];\
2429 \n g_srcColor[1] += tmp[1] * tmp[3] * in_componentWeight[i];\
2430 \n g_srcColor[2] += tmp[2] * tmp[3] * in_componentWeight[i];\
2431 \n g_srcColor[2] += tmp[3] * tmp[3] * in_componentWeight[i];\
2433 \n g_fragColor = g_srcColor;");
2438 \n g_srcColor = computeColor(l_minValue,\
2439 \n computeOpacity(l_minValue));\
2440 \n g_fragColor.rgb = g_srcColor.rgb * g_srcColor.a;\
2441 \n g_fragColor.a = g_srcColor.a;");
2446 if (noOfComponents > 1 && independentComponents)
2449 \n for (int i = 0; i < in_noOfComponents; ++i)\
2451 \n if (l_numSamples[i] == uint(0))\
2455 \n l_avgValue[i] = l_avgValue[i] * in_componentWeight[i] /\
2456 \n l_numSamples[i];\
2459 \n l_avgValue[0] += l_avgValue[i];\
2462 \n l_avgValue[0] = clamp(l_avgValue[0], 0.0, 1.0);\
2463 \n g_fragColor = vec4(vec3(l_avgValue[0]), 1.0);");
2468 \n if (l_numSamples.x == uint(0))\
2474 \n l_avgValue.x /= l_numSamples.x;\
2475 \n l_avgValue.x = clamp(l_avgValue.x, 0.0, 1.0);\
2476 \n g_fragColor = vec4(vec3(l_avgValue.x), 1.0);\
2482 if (noOfComponents > 1 && independentComponents)
2486 \n l_sumValue.x *= in_componentWeight.x;\
2487 \n for (int i = 1; i < in_noOfComponents; ++i)\
2489 \n l_sumValue.x += l_sumValue[i] * in_componentWeight[i];\
2491 \n l_sumValue.x = clamp(l_sumValue.x, 0.0, 1.0);\
2492 \n g_fragColor = vec4(vec3(l_sumValue.x), 1.0);");
2497 \n l_sumValue.x = clamp(l_sumValue.x, 0.0, 1.0);\
2498 \n g_fragColor = vec4(vec3(l_sumValue.x), 1.0);");
2519 \n const float g_opacityThreshold = 1.0 - 1.0 / 255.0;");
2527 \n uniform vec3 in_propId;");
2535 \n // Flag to indicate if the raymarch loop should terminate \
2536 \n bool stop = false;\
2538 \n g_terminatePointMax = 0.0;\
2540 \n vec4 l_depthValue = texture2D(in_depthSampler, fragTexCoord);\
2542 \n if(gl_FragCoord.z >= l_depthValue.x)\
2547 \n // color buffer or max scalar buffer have a reduced size.\
2548 \n fragTexCoord = (gl_FragCoord.xy - in_windowLowerLeftCorner) *\
2549 \n in_inverseOriginalWindowSize;\
2557 if (sliceFunc->
IsA(
"vtkPlane"))
2561 \n // Intersection with plane\
2562 \n float t = intersectRayPlane(ip_vertexPos, rayDir);\
2563 \n vec4 intersection = vec4(ip_vertexPos + t * rayDir, 1.0);\
2564 \n g_intersection = (in_inverseTextureDatasetMatrix[0] * intersection).xyz;\
2565 \n vec4 intersDC = in_projectionMatrix * in_modelViewMatrix * in_volumeMatrix[0] * intersection;\
2566 \n intersDC.xyz /= intersDC.w;\
2567 \n vec4 intersWin = NDCToWindow(intersDC.x, intersDC.y, intersDC.z);\
2568 \n if(intersWin.z >= l_depthValue.x)\
2576 vtkErrorWithObjectMacro(
2577 sliceFunc,
"Implicit function type is not supported by this mapper.");
2583 \n // Compute max number of iterations it will take before we hit\
2584 \n // the termination point\
2586 \n // Abscissa of the point on the depth buffer along the ray.\
2587 \n // point in texture coordinates\
2588 \n vec4 rayTermination = WindowToNDC(gl_FragCoord.x, gl_FragCoord.y, l_depthValue.x);\
2590 \n // From normalized device coordinates to eye coordinates.\
2591 \n // in_projectionMatrix is inversed because of way VT\
2592 \n // From eye coordinates to texture coordinates\
2593 \n rayTermination = ip_inverseTextureDataAdjusted *\
2594 \n in_inverseVolumeMatrix[0] *\
2595 \n in_inverseModelViewMatrix *\
2596 \n in_inverseProjectionMatrix *\
2598 \n g_rayTermination = rayTermination.xyz / rayTermination.w;\
2600 \n // Setup the current segment:\
2601 \n g_dataPos = g_rayOrigin;\
2602 \n g_terminatePos = g_rayTermination;\
2604 \n g_terminatePointMax = length(g_terminatePos.xyz - g_dataPos.xyz) /\
2605 \n length(g_dirStep);\
2606 \n g_currentT = 0.0;");
2616 \n if(any(greaterThan(max(g_dirStep, vec3(0.0))*(g_dataPos - in_texMax[0]),vec3(0.0))) ||\
2617 \n any(greaterThan(min(g_dirStep, vec3(0.0))*(g_dataPos - in_texMin[0]),vec3(0.0))))\
2622 \n // Early ray termination\
2623 \n // if the currently composited colour alpha is already fully saturated\
2624 \n // we terminated the loop or if we have hit an obstacle in the\
2625 \n // direction of they ray (using depth buffer) we terminate as well.\
2626 \n if((g_fragColor.a > g_opacityThreshold) || \
2627 \n g_currentT >= g_terminatePointMax)\
2658 \nuniform float in_croppingPlanes[6];\
2659 \nuniform int in_croppingFlags [32];\
2660 \nfloat croppingPlanesTexture[6];\
2662 \n// X: axis = 0, Y: axis = 1, Z: axis = 2\
2663 \n// cp Cropping plane bounds (minX, maxX, minY, maxY, minZ, maxZ)\
2664 \nint computeRegionCoord(float cp[6], vec3 pos, int axis)\
2666 \n int cpmin = axis * 2;\
2667 \n int cpmax = cpmin + 1;\
2669 \n if (pos[axis] < cp[cpmin])\
2673 \n else if (pos[axis] >= cp[cpmin] &&\
2674 \n pos[axis] < cp[cpmax])\
2678 \n else if (pos[axis] >= cp[cpmax])\
2685 \nint computeRegion(float cp[6], vec3 pos)\
2687 \n return (computeRegionCoord(cp, pos, 0) +\
2688 \n (computeRegionCoord(cp, pos, 1) - 1) * 3 +\
2689 \n (computeRegionCoord(cp, pos, 2) - 1) * 9);\
2703 \n // Convert cropping region to texture space\
2704 \n mat4 datasetToTextureMat = in_inverseTextureDatasetMatrix[0];\
2706 \n vec4 tempCrop = vec4(in_croppingPlanes[0], 0.0, 0.0, 1.0);\
2707 \n tempCrop = datasetToTextureMat * tempCrop;\
2708 \n if (tempCrop[3] != 0.0)\
2710 \n tempCrop[0] /= tempCrop[3];\
2712 \n croppingPlanesTexture[0] = tempCrop[0];\
2714 \n tempCrop = vec4(in_croppingPlanes[1], 0.0, 0.0, 1.0);\
2715 \n tempCrop = datasetToTextureMat * tempCrop;\
2716 \n if (tempCrop[3] != 0.0)\
2718 \n tempCrop[0] /= tempCrop[3];\
2720 \n croppingPlanesTexture[1] = tempCrop[0];\
2722 \n tempCrop = vec4(0.0, in_croppingPlanes[2], 0.0, 1.0);\
2723 \n tempCrop = datasetToTextureMat * tempCrop;\
2724 \n if (tempCrop[3] != 0.0)\
2726 \n tempCrop[1] /= tempCrop[3];\
2728 \n croppingPlanesTexture[2] = tempCrop[1];\
2730 \n tempCrop = vec4(0.0, in_croppingPlanes[3], 0.0, 1.0);\
2731 \n tempCrop = datasetToTextureMat * tempCrop;\
2732 \n if (tempCrop[3] != 0.0)\
2734 \n tempCrop[1] /= tempCrop[3];\
2736 \n croppingPlanesTexture[3] = tempCrop[1];\
2738 \n tempCrop = vec4(0.0, 0.0, in_croppingPlanes[4], 1.0);\
2739 \n tempCrop = datasetToTextureMat * tempCrop;\
2740 \n if (tempCrop[3] != 0.0)\
2742 \n tempCrop[2] /= tempCrop[3];\
2744 \n croppingPlanesTexture[4] = tempCrop[2];\
2746 \n tempCrop = vec4(0.0, 0.0, in_croppingPlanes[5], 1.0);\
2747 \n tempCrop = datasetToTextureMat * tempCrop;\
2748 \n if (tempCrop[3] != 0.0)\
2750 \n tempCrop[2] /= tempCrop[3];\
2752 \n croppingPlanesTexture[5] = tempCrop[2];");
2765 \n // Determine region\
2766 \n int regionNo = computeRegion(croppingPlanesTexture, g_dataPos);\
2768 \n // Do & operation with cropping flags\
2769 \n // Pass the flag that its Ok to sample or not to sample\
2770 \n if (in_croppingFlags[regionNo] == 0)\
2772 \n // Skip this voxel\
2801 \n /// We support only 8 clipping planes for now\
2802 \n /// The first value is the size of the data array for clipping\
2803 \n /// planes (origin, normal)\
2804 \n uniform float in_clippingPlanes[49];\
2805 \n uniform float in_clippedVoxelIntensity;\
2807 \n int clip_numPlanes;\
2808 \n vec3 clip_rayDirObj;\
2809 \n mat4 clip_texToObjMat;\
2810 \n mat4 clip_objToTexMat;\
2812 \n// Tighten the sample range as needed to account for clip planes. \
2813 \n// Arguments are in texture coordinates. \
2814 \n// Returns true if the range is at all valid after clipping. If not, \
2815 \n// the fragment should be discarded. \
2816 \nbool AdjustSampleRangeForClipping(inout vec3 startPosTex, inout vec3 stopPosTex) \
2818 \n vec4 startPosObj = vec4(0.0);\
2820 \n startPosObj = clip_texToObjMat * vec4(startPosTex - g_rayJitter, 1.0);\
2821 \n startPosObj = startPosObj / startPosObj.w;\
2822 \n startPosObj.w = 1.0;\
2825 \n vec4 stopPosObj = vec4(0.0);\
2827 \n stopPosObj = clip_texToObjMat * vec4(stopPosTex, 1.0);\
2828 \n stopPosObj = stopPosObj / stopPosObj.w;\
2829 \n stopPosObj.w = 1.0;\
2832 \n for (int i = 0; i < clip_numPlanes; i = i + 6)\
2834 \n vec3 planeOrigin = vec3(in_clippingPlanes[i + 1],\
2835 \n in_clippingPlanes[i + 2],\
2836 \n in_clippingPlanes[i + 3]);\
2837 \n vec3 planeNormal = normalize(vec3(in_clippingPlanes[i + 4],\
2838 \n in_clippingPlanes[i + 5],\
2839 \n in_clippingPlanes[i + 6]));\
2841 \n // Abort if the entire segment is clipped:\
2842 \n // (We can do this before adjusting the term point, since it'll \
2843 \n // only move further into the clipped area)\
2844 \n float startDistance = dot(planeNormal, planeOrigin - startPosObj.xyz);\
2845 \n float stopDistance = dot(planeNormal, planeOrigin - stopPosObj.xyz);\
2846 \n bool startClipped = startDistance > 0.0;\
2847 \n bool stopClipped = stopDistance > 0.0;\
2848 \n if (startClipped && stopClipped)\
2853 \n float rayDotNormal = dot(clip_rayDirObj, planeNormal);\
2854 \n bool frontFace = rayDotNormal > 0.0;\
2856 \n // Move the start position further from the eye if needed:\
2857 \n if (frontFace && // Observing from the clipped side (plane's front face)\
2858 \n startDistance > 0.0) // Ray-entry lies on the clipped side.\
2860 \n // Scale the point-plane distance to the ray direction and update the\
2862 \n float rayScaledDist = startDistance / rayDotNormal;\
2863 \n startPosObj = vec4(startPosObj.xyz + rayScaledDist * clip_rayDirObj, 1.0);\
2864 \n vec4 newStartPosTex = clip_objToTexMat * vec4(startPosObj.xyz, 1.0);\
2865 \n newStartPosTex /= newStartPosTex.w;\
2866 \n startPosTex = newStartPosTex.xyz;\
2867 \n startPosTex += g_rayJitter;\
2870 \n // Move the end position closer to the eye if needed:\
2871 \n if (!frontFace && // Observing from the unclipped side (plane's back face)\
2872 \n stopDistance > 0.0) // Ray-entry lies on the unclipped side.\
2874 \n // Scale the point-plane distance to the ray direction and update the\
2875 \n // termination point.\
2876 \n float rayScaledDist = stopDistance / rayDotNormal;\
2877 \n stopPosObj = vec4(stopPosObj.xyz + rayScaledDist * clip_rayDirObj, 1.0);\
2878 \n vec4 newStopPosTex = clip_objToTexMat * vec4(stopPosObj.xyz, 1.0);\
2879 \n newStopPosTex /= newStopPosTex.w;\
2880 \n stopPosTex = newStopPosTex.xyz;\
2884 \n if (any(greaterThan(startPosTex, in_texMax[0])) ||\
2885 \n any(lessThan(startPosTex, in_texMin[0])))\
2907 \n vec4 tempClip = in_volumeMatrix[0] * vec4(rayDir, 0.0);\
2908 \n if (tempClip.w != 0.0)\
2910 \n tempClip = tempClip/tempClip.w;\
2911 \n tempClip.w = 1.0;\
2913 \n clip_rayDirObj = normalize(tempClip.xyz);");
2918 clip_rayDirObj = normalize(in_projectionDirection);");
2922 \n clip_numPlanes = int(in_clippingPlanes[0]);\
2923 \n clip_texToObjMat = in_volumeMatrix[0] * in_textureDatasetMatrix[0];\
2924 \n clip_objToTexMat = in_inverseTextureDatasetMatrix[0] * in_inverseVolumeMatrix[0];\
2926 \n // Adjust for clipping.\
2927 \n if (!AdjustSampleRangeForClipping(g_rayOrigin, g_rayTermination))\
2928 \n { // entire ray is clipped.\
2932 \n // Update the segment post-clip:\
2933 \n g_dataPos = g_rayOrigin;\
2934 \n g_terminatePos = g_rayTermination;\
2935 \n g_terminatePointMax = length(g_terminatePos.xyz - g_dataPos.xyz) /\
2936 \n length(g_dirStep);\
2959 int vtkNotUsed(maskType))
2961 if (!mask || !maskInput)
2983 \nvec4 maskValue = texture3D(in_mask, g_dataPos);\
2984 \nif(maskValue.r <= 0.0)\
3003 \nuniform float in_maskBlendFactor;\
3004 \nuniform sampler2D in_labelMapTransfer;\
3005 \nuniform float in_mask_scale;\
3006 \nuniform float in_mask_bias;\
3007 \nuniform int in_labelMapNumLabels;\
3024 \nvec4 scalar = texture3D(in_volume[0], g_dataPos);");
3027 if (noOfComponents == 1)
3030 \n scalar.r = scalar.r * in_volume_scale[0].r + in_volume_bias[0].r;\
3031 \n scalar = vec4(scalar.r);");
3037 \n scalar = scalar * in_volume_scale[0] + in_volume_bias[0];");
3044 \nif (in_maskBlendFactor == 0.0)\
3046 \n g_srcColor.a = computeOpacity(scalar);\
3047 \n if (g_srcColor.a > 0)\
3049 \n g_srcColor = computeColor(scalar, g_srcColor.a);\
3054 \n float opacity = computeOpacity(scalar);\
3055 \n // Get the mask value at this same location\
3056 \n vec4 maskValue = texture3D(in_mask, g_dataPos);\
3057 \n maskValue.r = maskValue.r * in_mask_scale + in_mask_bias;\
3058 \n // Quantize the height of the labelmap texture over number of labels\
3059 \n if (in_labelMapNumLabels > 0)\
3062 \n floor(maskValue.r * in_labelMapNumLabels) /\
3063 \n in_labelMapNumLabels;\
3067 \n maskValue.r = 0.0;\
3069 \n if(maskValue.r == 0.0)\
3071 \n g_srcColor.a = opacity;\
3072 \n if (g_srcColor.a > 0)\
3074 \n g_srcColor = computeColor(scalar, g_srcColor.a);\
3079 \n g_srcColor = texture2D(in_labelMapTransfer,\
3080 \n vec2(scalar.r, maskValue.r));\
3081 \n if (g_srcColor.a > 0)\
3083 \n g_srcColor = computeLighting(g_srcColor, 0, maskValue.r);\
3085 \n if (in_maskBlendFactor < 1.0)\
3087 \n vec4 color = opacity > 0 ? computeColor(scalar, opacity) : vec4(0);\
3088 \n g_srcColor = (1.0 - in_maskBlendFactor) * color +\
3089 \n in_maskBlendFactor * g_srcColor;\
3100 return std::string(
"uniform bool in_clampDepthToBackface;\n"
3101 "vec3 l_opaqueFragPos;\n"
3102 "bool l_updateDepth;\n");
3110 \n l_opaqueFragPos = vec3(-1.0);\
3111 \n if(in_clampDepthToBackface)\
3113 \n l_opaqueFragPos = g_dataPos;\
3115 \n l_updateDepth = true;");
3123 \n if(!g_skip && g_srcColor.a > 0.0 && l_updateDepth)\
3125 \n l_opaqueFragPos = g_dataPos;\
3126 \n l_updateDepth = false;\
3135 \n if (l_opaqueFragPos == vec3(-1.0))\
3137 \n gl_FragData[1] = vec4(1.0);\
3141 \n vec4 depthValue = in_projectionMatrix * in_modelViewMatrix *\
3142 \n in_volumeMatrix[0] * in_textureDatasetMatrix[0] *\
3143 \n vec4(l_opaqueFragPos, 1.0);\
3144 \n depthValue /= depthValue.w;\
3145 \n gl_FragData[1] = vec4(vec3(0.5 * (gl_DepthRange.far -\
3146 \n gl_DepthRange.near) * depthValue.z + 0.5 *\
3147 \n (gl_DepthRange.far + gl_DepthRange.near)), 1.0);\
3156 \n vec3 l_isoPos = g_dataPos;");
3164 \n if(!g_skip && g_srcColor.a > 0.0)\
3166 \n l_isoPos = g_dataPos;\
3167 \n g_exit = true; g_skip = true;\
3176 \n vec4 depthValue = in_projectionMatrix * in_modelViewMatrix *\
3177 \n in_volumeMatrix[0] * in_textureDatasetMatrix[0] *\
3178 \n vec4(l_isoPos, 1.0);\
3179 \n gl_FragData[0] = vec4(l_isoPos, 1.0);\
3180 \n gl_FragData[1] = vec4(vec3((depthValue.z/depthValue.w) * 0.5 + 0.5),\
3189 \n initializeRayCast();\
3190 \n castRay(-1.0, -1.0);\
3191 \n finalizeRayCast();");
3196 const std::vector<std::string>& varNames,
const size_t usedNames)
3199 for (
size_t i = 0; i < usedNames; i++)
3201 shader +=
"uniform sampler2D " + varNames[i] +
";\n";
3208 const std::vector<std::string>& varNames,
const size_t usedNames)
3211 for (
size_t i = 0; i < usedNames; i++)
3213 std::stringstream ss;
3215 shader +=
" gl_FragData[" + ss.str() +
"] = texture2D(" + varNames[i] +
", texCoord);\n";
3217 shader +=
" return;\n";
virtual vtkPlaneCollection * GetClippingPlanes()
Get/Set the vtkPlaneCollection which specifies the clipping planes.
virtual vtkTypeBool GetParallelProjection()
Set/Get the value of the ParallelProjection instance variable.
static vtkDataSet * SafeDownCast(vtkObjectBase *o)
vtkUnsignedCharArray * GetCellGhostArray()
Get the array that defines the ghost type of each cell.
vtkUnsignedCharArray * GetPointGhostArray()
Gets the array that defines the ghost type of each point.
virtual vtkTypeBool GetUseDepthPass()
If UseDepthPass is on, the mapper will use two passes.
virtual vtkTypeBool GetUseJittering()
If UseJittering is on, each ray traversal direction will be perturbed slightly using a noise-texture ...
static vtkGPUVolumeRayCastMapper * SafeDownCast(vtkObjectBase *o)
topologically and geometrically regular array of data
abstract interface for implicit functions
virtual vtkTypeBool IsA(const char *type)
Return 1 if this class is the same type of (or a subclass of) the named class.
OpenGL implementation of volume rendering through ray-casting.
static vtkOpenGLGPUVolumeRayCastMapper * SafeDownCast(vtkObjectBase *o)
std::map< int, vtkVolumeInputHelper > VolumeInputMap
virtual int GetCurrentPass()
static vtkRectilinearGrid * SafeDownCast(vtkObjectBase *o)
abstract specification for renderers
vtkCamera * GetActiveCamera()
Get the current camera.
Abstract class for a volume mapper.
virtual vtkDataSet * GetInput()
Set/Get the input data.
virtual vtkTypeBool GetCropping()
Turn On/Off orthogonal cropping.
@ AVERAGE_INTENSITY_BLEND
@ MAXIMUM_INTENSITY_BLEND
@ MINIMUM_INTENSITY_BLEND
virtual int GetBlendMode()
Set/Get the blend mode.
represents the common properties for rendering a volume.
virtual int GetDisableGradientOpacity(int index)
Enable/Disable the gradient opacity function for the given component.
bool HasLabelGradientOpacity()
virtual int GetUseClippedVoxelIntensity()
Set/Get whether to use a fixed intensity value for voxels in the clipped space for gradient calculati...
bool HasGradientOpacity(int index=0)
Check whether or not we have the gradient opacity.
int GetShade(int index)
Set/Get the shading of a volume.
virtual int GetTransferFunctionMode()
Color-opacity transfer function mode.
Creates and manages the volume texture rendered by vtkOpenGLGPUVolumeRayCastMapper.
represents a volume (data & properties) in a rendered scene
virtual vtkVolumeProperty * GetProperty()
Set/Get the volume property.
std::string ClippingDeclarationFragment(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol))
std::string ComputeGradientOpacity1DDecl(vtkVolume *vol, int noOfComponents, int independentComponents, std::map< int, std::string > gradientTableMap)
std::string WorkerImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string TerminationExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ClippingDeclarationVertex(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string TerminationImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ComputeLightingMultiDeclaration(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vol, int noOfComponents, int independentComponents, int vtkNotUsed(numberOfLights), int lightingComplexity)
std::string BinaryMaskDeclaration(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), vtkImageData *maskInput, vtkVolumeTexture *mask, int vtkNotUsed(maskType))
std::string PickingIdLow24PassExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ComputeLightingDeclaration(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vol, int noOfComponents, int independentComponents, int vtkNotUsed(numberOfLights), int lightingComplexity)
std::string CroppingDeclarationFragment(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol))
std::string ComputeColorDeclaration(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), int noOfComponents, int independentComponents, std::map< int, std::string > colorTableMap)
std::string CroppingImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol))
std::string ShadingExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol), int noOfComponents, int independentComponents=0)
std::string BaseExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ImageSampleDeclarationFrag(const std::vector< std::string > &varNames, const size_t usedNames)
std::string ComputeOpacityMultiDeclaration(vtkOpenGLGPUVolumeRayCastMapper::VolumeInputMap &inputs)
std::string BaseDeclarationVertex(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol), bool multipleInputs)
std::string ComputeTextureCoordinates(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string DepthPassInit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string TerminationInit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vol)
std::string RenderToImageInit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ComputeClipPositionImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string RenderToImageImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ComputeOpacityDeclaration(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), int noOfComponents, int independentComponents, std::map< int, std::string > opacityTableMap)
std::string PreComputeGradientsImpl(vtkRenderer *vtkNotUsed(ren), vtkVolume *vtkNotUsed(vol), int noOfComponents=1, int independentComponents=0)
std::string ClippingExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ComputeGradientDeclaration(vtkOpenGLGPUVolumeRayCastMapper *mapper, vtkOpenGLGPUVolumeRayCastMapper::VolumeInputMap &inputs)
std::string BaseInit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkOpenGLGPUVolumeRayCastMapper::VolumeInputMap &inputs, int lightingComplexity)
std::string PickingIdHigh24PassExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string TerminationDeclarationVertex(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string PickingActorPassExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string RenderToImageDeclarationFragment(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string BaseImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol))
std::string RenderToImageExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ShadingDeclarationVertex(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ShadingSingleInput(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol), vtkImageData *maskInput, vtkVolumeTexture *mask, int maskType, int noOfComponents, int independentComponents=0)
std::string ShadingMultipleInputs(vtkVolumeMapper *mapper, vtkOpenGLGPUVolumeRayCastMapper::VolumeInputMap &inputs)
std::string CompositeMaskDeclarationFragment(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), vtkImageData *maskInput, vtkVolumeTexture *mask, int maskType)
std::string ComputeRayDirectionDeclaration(vtkRenderer *ren, vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), int vtkNotUsed(noOfComponents))
std::string DepthPassImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string GradientCacheDec(vtkRenderer *vtkNotUsed(ren), vtkVolume *vtkNotUsed(vol), vtkOpenGLGPUVolumeRayCastMapper::VolumeInputMap &inputs, int independentComponents=0)
std::string Transfer2DDeclaration(vtkOpenGLGPUVolumeRayCastMapper::VolumeInputMap &inputs)
std::string ClippingImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string CroppingDeclarationVertex(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ComputeColorMultiDeclaration(vtkOpenGLGPUVolumeRayCastMapper::VolumeInputMap &inputs, bool useGradientTF)
std::string CroppingInit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol))
std::string CompositeMaskImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), vtkImageData *maskInput, vtkVolumeTexture *mask, int maskType, int noOfComponents)
std::string ComputeColor2DYAxisDeclaration(int noOfComponents, int vtkNotUsed(independentComponents), std::map< int, std::string > colorTableMap)
std::string ImageSampleImplementationFrag(const std::vector< std::string > &varNames, const size_t usedNames)
std::string CroppingExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ClippingInit(vtkRenderer *ren, vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol))
std::string TerminationDeclarationFragment(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ShadingDeclarationFragment(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol))
std::string PickingActorPassDeclaration(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ShadingInit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol))
std::string BinaryMaskImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), vtkImageData *maskInput, vtkVolumeTexture *mask, int maskType)
std::string DepthPassExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ComputeOpacity2DDeclaration(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), int noOfComponents, int independentComponents, std::map< int, std::string > opacityTableMap, int useGradient)
std::string ComputeColor2DDeclaration(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), int noOfComponents, int independentComponents, std::map< int, std::string > colorTableMap, int useGradient)
std::string ComputeGradientOpacityMulti1DDecl(vtkOpenGLGPUVolumeRayCastMapper::VolumeInputMap &inputs)
std::string BaseDeclarationFragment(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkOpenGLGPUVolumeRayCastMapper::VolumeInputMap &inputs, int vtkNotUsed(numberOfLights), int lightingComplexity, int noOfComponents, int independentComponents)