VTK
vtkVolumeShaderComposer.h
Go to the documentation of this file.
1/*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkVolumeShaderComposer.h
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14=========================================================================*/
15
16#ifndef vtkVolumeShaderComposer_h
17#define vtkVolumeShaderComposer_h
18
19#include "vtkVolumeMask.h"
20
21#include <vtkCamera.h>
23#include <vtkRenderer.h>
24#include <vtkVolume.h>
25#include <vtkVolumeMapper.h>
26#include <vtkVolumeProperty.h>
27
28#include <map>
29#include <sstream>
30#include <string>
31
32// NOTE:
33// In this code, we referred to various spaces described below:
34// Object space: Raw coordinates in space defined by volume matrix
35// Dataset space: Raw coordinates
36// Eye space: Coordinates in eye space (as referred in computer graphics)
37
38namespace vtkvolume
39{
40 //--------------------------------------------------------------------------
42 const std::string &replace, bool all)
43 {
44 if (replace.empty())
45 {
46 return source;
47 }
48
49 std::string::size_type pos = 0;
50 bool first = true;
51 while ((pos = source.find(search, 0)) != std::string::npos)
52 {
53 source.replace(pos, search.length(), replace);
54 pos += search.length();
55 if (first)
56 {
57 first = false;
58 if (!all)
59 {
60 return source;
61 }
62 }
63 }
64 return source;
65 }
66
67 //--------------------------------------------------------------------------
69 vtkVolumeMapper* vtkNotUsed(mapper),
70 vtkVolume* vtkNotUsed(vol))
71 {
72 return std::string("\
73 \n vec4 pos = in_projectionMatrix * in_modelViewMatrix *\
74 \n in_volumeMatrix * vec4(in_vertexPos.xyz, 1.0);\
75 \n gl_Position = pos;"
76 );
77 }
78
79 //--------------------------------------------------------------------------
81 vtkVolumeMapper* vtkNotUsed(mapper),
82 vtkVolume* vtkNotUsed(vol))
83 {
84 return std::string(
85 "\n // For point dataset, we offset the texture coordinate\
86 \n // to account for OpenGL treating voxel at the center of the cell.\
87 \n vec3 uvx = sign(in_cellSpacing) * (in_vertexPos - in_volumeExtentsMin) /\
88 \n (in_volumeExtentsMax - in_volumeExtentsMin);\
89 \n\
90 \n if (in_cellFlag)\
91 \n {\
92 \n ip_textureCoords = uvx;\
93 \n ip_inverseTextureDataAdjusted = in_inverseTextureDatasetMatrix;\
94 \n }\
95 \n else\
96 \n {\
97 \n // Transform cell tex-coordinates to point tex-coordinates\
98 \n ip_textureCoords = (in_cellToPoint * vec4(uvx, 1.0)).xyz;\
99 \n ip_inverseTextureDataAdjusted = in_cellToPoint * in_inverseTextureDatasetMatrix;\
100 \n }");
101 }
102
103 //--------------------------------------------------------------------------
105 vtkVolumeMapper* vtkNotUsed(mapper),
106 vtkVolume* vtkNotUsed(vol))
107 {
108 return std::string("\
109 \n uniform bool in_cellFlag;\
110 \n uniform vec3 in_cellSpacing;\
111 \n uniform mat4 in_modelViewMatrix;\
112 \n uniform mat4 in_projectionMatrix;\
113 \n uniform mat4 in_volumeMatrix;\
114 \n\
115 \n uniform vec3 in_volumeExtentsMin;\
116 \n uniform vec3 in_volumeExtentsMax;\
117 \n\
118 \n uniform mat4 in_inverseTextureDatasetMatrix;\
119 \n uniform mat4 in_cellToPoint;\
120 \n uniform vec3 in_textureExtentsMax;\
121 \n uniform vec3 in_textureExtentsMin;\
122 \n\
123 \n //This variable could be 'invariant varying' but it is declared\
124 \n //as 'varying' to avoid compiler compatibility issues.\
125 \n varying mat4 ip_inverseTextureDataAdjusted;");
126 }
127
128 //--------------------------------------------------------------------------
130 vtkVolumeMapper* mapper,
131 vtkVolume* vtkNotUsed(vol),
132 int vtkNotUsed(numberOfLights),
133 int lightingComplexity,
134 bool hasGradientOpacity,
135 int noOfComponents,
136 int independentComponents)
137 {
138 std::string shaderStr = std::string("\
139 \n// Volume dataset\
140 \nuniform sampler3D in_volume;\
141 \nuniform int in_noOfComponents;\
142 \nuniform int in_independentComponents;\
143 \n\
144 \nuniform sampler2D in_noiseSampler;\
145 \n#ifndef GL_ES\
146 \nuniform sampler2D in_depthSampler;\
147 \n#endif\
148 \n\
149 \n// Camera position\
150 \nuniform vec3 in_cameraPos;\
151 \n\
152 \n// view and model matrices\
153 \nuniform mat4 in_volumeMatrix;\
154 \nuniform mat4 in_inverseVolumeMatrix;\
155 \nuniform mat4 in_projectionMatrix;\
156 \nuniform mat4 in_inverseProjectionMatrix;\
157 \nuniform mat4 in_modelViewMatrix;\
158 \nuniform mat4 in_inverseModelViewMatrix;\
159 \nuniform mat4 in_textureDatasetMatrix;\
160 \nuniform mat4 in_inverseTextureDatasetMatrix;\
161 \nvarying mat4 ip_inverseTextureDataAdjusted;\
162 \nuniform vec3 in_texMin;\
163 \nuniform vec3 in_texMax;\
164 \nuniform mat4 in_texureToEyeIt;\
165 \n\
166 \n// Ray step size\
167 \nuniform vec3 in_cellStep;\
168 \nuniform vec2 in_scalarsRange[4];\
169 \nuniform vec3 in_cellSpacing;\
170 \n\
171 \n// Sample distance\
172 \nuniform float in_sampleDistance;\
173 \n\
174 \n// Scales\
175 \nuniform vec3 in_cellScale;\
176 \nuniform vec2 in_windowLowerLeftCorner;\
177 \nuniform vec2 in_inverseOriginalWindowSize;\
178 \nuniform vec2 in_inverseWindowSize;\
179 \nuniform vec3 in_textureExtentsMax;\
180 \nuniform vec3 in_textureExtentsMin;\
181 \n\
182 \n// Material and lighting\
183 \nuniform vec3 in_diffuse[4];\
184 \nuniform vec3 in_ambient[4];\
185 \nuniform vec3 in_specular[4];\
186 \nuniform float in_shininess[4];\
187 \n\
188 \n// Others\
189 \nuniform bool in_cellFlag;\
190 \n uniform bool in_useJittering;\
191 \n uniform bool in_clampDepthToBackface;\
192 \n\
193 \nuniform vec2 in_averageIPRange;"
194 );
195
196 if (lightingComplexity > 0 || hasGradientOpacity)
197 {
198 shaderStr += std::string("\
199 \nuniform bool in_twoSidedLighting;\
200 \nvec3 g_xvec;\
201 \nvec3 g_yvec;\
202 \nvec3 g_zvec;");
203 }
204
205 if (hasGradientOpacity)
206 {
207 shaderStr += std::string("\
208 \nvec3 g_aspect;\
209 \nvec3 g_cellSpacing;\
210 \nfloat g_avgSpacing;");
211 }
212
213 if (lightingComplexity == 3)
214 {
215 shaderStr += std::string("\
216 \nvec4 g_fragWorldPos;\
217 \nuniform int in_numberOfLights;\
218 \nuniform vec3 in_lightAmbientColor[6];\
219 \nuniform vec3 in_lightDiffuseColor[6];\
220 \nuniform vec3 in_lightSpecularColor[6];\
221 \nuniform vec3 in_lightDirection[6];\
222 \nuniform vec3 in_lightPosition[6];\
223 \nuniform vec3 in_lightAttenuation[6];\
224 \nuniform float in_lightConeAngle[6];\
225 \nuniform float in_lightExponent[6];\
226 \nuniform int in_lightPositional[6];\
227 ");
228 }
229 else if (lightingComplexity == 2)
230 {
231 shaderStr += std::string("\
232 \nvec4 g_fragWorldPos;\
233 \nuniform int in_numberOfLights;\
234 \nuniform vec3 in_lightAmbientColor[6];\
235 \nuniform vec3 in_lightDiffuseColor[6];\
236 \nuniform vec3 in_lightSpecularColor[6];\
237 \nuniform vec3 in_lightDirection[6];\
238 ");
239 }
240 else
241 {
242 shaderStr += std::string("\
243 \nuniform vec3 in_lightAmbientColor[1];\
244 \nuniform vec3 in_lightDiffuseColor[1];\
245 \nuniform vec3 in_lightSpecularColor[1];\
246 \nvec4 g_lightPosObj;\
247 \nvec3 g_ldir;\
248 \nvec3 g_vdir;\
249 \nvec3 g_h;");
250 }
251
252 if (noOfComponents > 1 && independentComponents)
253 {
254 shaderStr += std::string("\
255 \nuniform vec4 in_componentWeight;");
256 }
257
261 glMapper->GetUseDepthPass())
262 {
263 shaderStr += std::string("\
264 \nuniform sampler2D in_depthPassSampler;");
265 }
266
267 return shaderStr;
268 }
269
270 //--------------------------------------------------------------------------
272 vtkVolumeMapper* mapper,
273 vtkVolume* vol,
274 int lightingComplexity)
275 {
278
279 std::string shaderStr = std::string("\
280 \n bool l_adjustTextureExtents = !in_cellFlag;"
281 );
282
284 glMapper->GetUseDepthPass() && glMapper->GetBlendMode() ==
286 {
287 shaderStr += std::string("\
288 \n //\
289 \n vec2 fragTexCoord2 = (gl_FragCoord.xy - in_windowLowerLeftCorner) *\
290 \n in_inverseWindowSize;\
291 \n vec4 depthValue = texture2D(in_depthPassSampler, fragTexCoord2);\
292 \n vec4 dataPos;\
293 \n dataPos.x = (gl_FragCoord.x - in_windowLowerLeftCorner.x) * 2.0 *\
294 \n in_inverseWindowSize.x - 1.0;\
295 \n dataPos.y = (gl_FragCoord.y - in_windowLowerLeftCorner.y) * 2.0 *\
296 \n in_inverseWindowSize.y - 1.0;\
297 \n dataPos.z = (2.0 * depthValue.x - (gl_DepthRange.near +\
298 \n gl_DepthRange.far)) / gl_DepthRange.diff;\
299 \n dataPos.w = 1.0;\
300 \n\
301 \n // From normalized device coordinates to eye coordinates.\
302 \n // in_projectionMatrix is inversed because of way VT\
303 \n // From eye coordinates to texture coordinates\
304 \n dataPos = in_inverseTextureDatasetMatrix *\
305 \n in_inverseVolumeMatrix *\
306 \n in_inverseModelViewMatrix *\
307 \n in_inverseProjectionMatrix *\
308 \n dataPos;\
309 \n dataPos /= dataPos.w;\
310 \n g_dataPos = dataPos.xyz;\
311 \n l_adjustTextureExtents = true;"
312 );
313 }
314 else
315 {
316 shaderStr += std::string("\
317 \n // Get the 3D texture coordinates for lookup into the in_volume dataset\
318 \n g_dataPos = ip_textureCoords.xyz;"
319 );
320 }
321
322 shaderStr += std::string("\
323 \n\
324 \n // Eye position in dataset space\
325 \n g_eyePosObj = (in_inverseVolumeMatrix * vec4(in_cameraPos, 1.0));\
326 \n if (g_eyePosObj.w != 0.0)\
327 \n {\
328 \n g_eyePosObj.x /= g_eyePosObj.w;\
329 \n g_eyePosObj.y /= g_eyePosObj.w;\
330 \n g_eyePosObj.z /= g_eyePosObj.w;\
331 \n g_eyePosObj.w = 1.0;\
332 \n }\
333 \n\
334 \n // Getting the ray marching direction (in dataset space);\
335 \n vec3 rayDir = computeRayDirection();\
336 \n\
337 \n // Multiply the raymarching direction with the step size to get the\
338 \n // sub-step size we need to take at each raymarching step\
339 \n g_dirStep = (ip_inverseTextureDataAdjusted *\
340 \n vec4(rayDir, 0.0)).xyz * in_sampleDistance;\
341 \n\
342 \n // 2D Texture fragment coordinates [0,1] from fragment coordinates.\
343 \n // The frame buffer texture has the size of the plain buffer but \
344 \n // we use a fraction of it. The texture coordinate is less than 1 if\
345 \n // the reduction factor is less than 1.\
346 \n // Device coordinates are between -1 and 1. We need texture\
347 \n // coordinates between 0 and 1. The in_noiseSampler and in_depthSampler\
348 \n // buffers have the original size buffer.\
349 \n vec2 fragTexCoord = (gl_FragCoord.xy - in_windowLowerLeftCorner) *\
350 \n in_inverseWindowSize;\
351 \n\
352 \n float jitterValue = 0;\
353 \n if (in_useJittering)\
354 \n {\
355 \n jitterValue = texture2D(in_noiseSampler, fragTexCoord).x;\
356 \n g_dataPos += g_dirStep * jitterValue;\
357 \n }\
358 \n else\
359 \n {\
360 \n g_dataPos += g_dirStep;\
361 \n }\
362 \n\
363 \n // Flag to deternmine if voxel should be considered for the rendering\
364 \n bool l_skip = false;");
365
366 if (vol->GetProperty()->GetShade() && lightingComplexity == 1)
367 {
368 shaderStr += std::string("\
369 \n // Light position in dataset space\
370 \n g_lightPosObj = (in_inverseVolumeMatrix *\
371 \n vec4(in_cameraPos, 1.0));\
372 \n if (g_lightPosObj.w != 0.0)\
373 \n {\
374 \n g_lightPosObj.x /= g_lightPosObj.w;\
375 \n g_lightPosObj.y /= g_lightPosObj.w;\
376 \n g_lightPosObj.z /= g_lightPosObj.w;\
377 \n g_lightPosObj.w = 1.0;\
378 \n }\
379 \n g_ldir = normalize(g_lightPosObj.xyz - ip_vertexPos);\
380 \n g_vdir = normalize(g_eyePosObj.xyz - ip_vertexPos);\
381 \n g_h = normalize(g_ldir + g_vdir);"
382 );
383 }
384 if ( (vol->GetProperty()->GetShade() ||
385 vol->GetProperty()->HasGradientOpacity()) &&
387 {
388 shaderStr += std::string("\
389 \n g_xvec = vec3(in_cellStep[0], 0.0, 0.0);\
390 \n g_yvec = vec3(0.0, in_cellStep[1], 0.0);\
391 \n g_zvec = vec3(0.0, 0.0, in_cellStep[2]);"
392 );
393 }
394
395 if (vol->GetProperty()->HasGradientOpacity())
396 {
397 shaderStr += std::string("\
398 \n g_cellSpacing = vec3(in_cellSpacing[0],\
399 \n in_cellSpacing[1],\
400 \n in_cellSpacing[2]);\
401 \n g_avgSpacing = (g_cellSpacing[0] +\
402 \n g_cellSpacing[1] +\
403 \n g_cellSpacing[2])/3.0;\
404 \n // Adjust the aspect\
405 \n g_aspect.x = g_cellSpacing[0] * 2.0 / g_avgSpacing;\
406 \n g_aspect.y = g_cellSpacing[1] * 2.0 / g_avgSpacing;\
407 \n g_aspect.z = g_cellSpacing[2] * 2.0 / g_avgSpacing;"
408 );
409 }
410
411 return shaderStr;
412 }
413
414 //--------------------------------------------------------------------------
416 vtkVolumeMapper* vtkNotUsed(mapper),
417 vtkVolume* vtkNotUsed(vol))
418 {
419 return std::string("\
420 \n l_skip = false;"
421 );
422 }
423
424 //--------------------------------------------------------------------------
426 vtkVolumeMapper* vtkNotUsed(mapper),
427 vtkVolume* vtkNotUsed(vol))
428 {
429 return std::string();
430 }
431
432 //--------------------------------------------------------------------------
434 vtkVolumeMapper* vtkNotUsed(mapper),
435 vtkVolume* vol,
436 int noOfComponents,
437 int independentComponents,
438 std::map<int, std::string>
439 gradientTableMap)
440 {
441 std::string shaderStr;
442 if (vol->GetProperty()->HasGradientOpacity() &&
443 (noOfComponents == 1 || !independentComponents))
444 {
445 shaderStr += std::string("\
446 \nuniform sampler2D in_gradientTransferFunc;\
447 \nfloat computeGradientOpacity(vec4 grad)\
448 \n {\
449 \n return texture2D("+gradientTableMap[0]+", vec2(grad.w, 0.0)).r;\
450 \n }"
451 );
452 }
453 else if (noOfComponents > 1 && independentComponents &&
455 {
456 std::ostringstream toString;
457 for (int i = 0; i < noOfComponents; ++i)
458 {
459 shaderStr += std::string("\n uniform sampler2D ") +
460 gradientTableMap[i] + std::string(";");
461 }
462
463 shaderStr += std::string("\
464 \nfloat computeGradientOpacity(vec4 grad, int component)\
465 \n {");
466
467 for (int i = 0; i < noOfComponents; ++i)
468 {
469 toString << i;
470 shaderStr += std::string("\
471 \n if (component == " + toString.str() + ")");
472
473 shaderStr += std::string("\
474 \n {\
475 \n return texture2D("+ gradientTableMap[i] + ", vec2(grad.w, 0.0)).r;\
476 \n }"
477 );
478
479 // Reset
480 toString.str("");
481 toString.clear();
482 }
483
484 shaderStr += std::string("\
485 \n }");
486 }
487
488 if (vol->GetProperty()->GetShade() &&
490 {
491 shaderStr += std::string("\
492 \n// c is short for component\
493 \nvec4 computeGradient(int c)\
494 \n {\
495 \n vec3 g1;\
496 \n vec3 g2;\
497 \n g1.x = texture3D(in_volume, vec3(g_dataPos + g_xvec)).x;\
498 \n g1.y = texture3D(in_volume, vec3(g_dataPos + g_yvec)).x;\
499 \n g1.z = texture3D(in_volume, vec3(g_dataPos + g_zvec)).x;\
500 \n g2.x = texture3D(in_volume, vec3(g_dataPos - g_xvec)).x;\
501 \n g2.y = texture3D(in_volume, vec3(g_dataPos - g_yvec)).x;\
502 \n g2.z = texture3D(in_volume, vec3(g_dataPos - g_zvec)).x;\
503 \n g1 = g1 * in_volume_scale.r + in_volume_bias.r;\
504 \n g2 = g2 * in_volume_scale.r + in_volume_bias.r;\
505 \n return vec4((g1 - g2), -1.0);\
506 \n }"
507 );
508 }
509 else if (vol->GetProperty()->HasGradientOpacity())
510 {
511 shaderStr += std::string("\
512 \n// c is short for component\
513 \nvec4 computeGradient(int c)\
514 \n {\
515 \n vec3 g1;\
516 \n vec4 g2;\
517 \n g1.x = texture3D(in_volume, vec3(g_dataPos + g_xvec)).x;\
518 \n g1.y = texture3D(in_volume, vec3(g_dataPos + g_yvec)).x;\
519 \n g1.z = texture3D(in_volume, vec3(g_dataPos + g_zvec)).x;\
520 \n g2.x = texture3D(in_volume, vec3(g_dataPos - g_xvec)).x;\
521 \n g2.y = texture3D(in_volume, vec3(g_dataPos - g_yvec)).x;\
522 \n g2.z = texture3D(in_volume, vec3(g_dataPos - g_zvec)).x;\
523 \n g1 = g1 * in_volume_scale.r + in_volume_bias.r;\
524 \n g2 = g2 * in_volume_scale.r + in_volume_bias.r;\
525 \n g1.x = in_scalarsRange[c][0] + (\
526 \n in_scalarsRange[c][1] - in_scalarsRange[c][0]) * g1.x;\
527 \n g1.y = in_scalarsRange[c][0] + (\
528 \n in_scalarsRange[c][1] - in_scalarsRange[c][0]) * g1.y;\
529 \n g1.z = in_scalarsRange[c][0] + (\
530 \n in_scalarsRange[c][1] - in_scalarsRange[c][0]) * g1.z;\
531 \n g2.x = in_scalarsRange[c][0] + (\
532 \n in_scalarsRange[c][1] - in_scalarsRange[c][0]) * g2.x;\
533 \n g2.y = in_scalarsRange[c][0] + (\
534 \n in_scalarsRange[c][1] - in_scalarsRange[c][0]) * g2.y;\
535 \n g2.z = in_scalarsRange[c][0] + (\
536 \n in_scalarsRange[c][1] - in_scalarsRange[c][0]) * g2.z;\
537 \n g2.xyz = g1 - g2.xyz;\
538 \n g2.x /= g_aspect.x;\
539 \n g2.y /= g_aspect.y;\
540 \n g2.z /= g_aspect.z;\
541 \n g2.w = 0.0;\
542 \n float grad_mag = length(g2);\
543 \n if (grad_mag > 0.0)\
544 \n {\
545 \n g2.x /= grad_mag;\
546 \n g2.y /= grad_mag;\
547 \n g2.z /= grad_mag;\
548 \n }\
549 \n else\
550 \n {\
551 \n g2.xyz = vec3(0.0, 0.0, 0.0);\
552 \n }\
553 \n grad_mag = grad_mag * 1.0 / (0.25 * (in_scalarsRange[c][1] -\
554 \n (in_scalarsRange[c][0])));\
555 \n grad_mag = clamp(grad_mag, 0.0, 1.0);\
556 \n g2.w = grad_mag;\
557 \n return g2;\
558 \n }"
559 );
560 }
561 else
562 {
563 shaderStr += std::string("\
564 \nvec4 computeGradient(int component)\
565 \n {\
566 \n return vec4(0.0);\
567 \n }");
568 }
569
570 return shaderStr;
571 }
572
573 //--------------------------------------------------------------------------
575 vtkVolumeMapper* mapper,
576 vtkVolume* vol,
577 int noOfComponents,
578 int independentComponents,
579 int vtkNotUsed(numberOfLights),
580 int lightingComplexity)
581 {
582 vtkVolumeProperty* volProperty = vol->GetProperty();
583 std::string shaderStr = std::string("\
584 \nvec4 computeLighting(vec4 color, int component)\
585 \n {\
586 \n vec4 finalColor = vec4(0.0);"
587 );
588
589 // Shading for composite blending only
590 int shadeReqd = volProperty->GetShade() &&
591 (mapper->GetBlendMode() ==
593
594 if (shadeReqd || volProperty->HasGradientOpacity())
595 {
596 shaderStr += std::string("\
597 \n // Compute gradient function only once\
598 \n vec4 gradient = computeGradient(component);"
599 );
600 }
601
602 if (shadeReqd)
603 {
604 if (lightingComplexity == 1)
605 {
606 shaderStr += std::string("\
607 \n vec3 diffuse = vec3(0.0);\
608 \n vec3 specular = vec3(0.0);\
609 \n vec3 normal = gradient.xyz / in_cellSpacing;\
610 \n float normalLength = length(normal);\
611 \n if (normalLength > 0.0)\
612 \n {\
613 \n normal = normalize(normal);\
614 \n }\
615 \n else\
616 \n {\
617 \n normal = vec3(0.0, 0.0, 0.0);\
618 \n }\
619 \n float nDotL = dot(normal, g_ldir);\
620 \n float nDotH = dot(normal, g_h);\
621 \n if (nDotL < 0.0 && in_twoSidedLighting)\
622 \n {\
623 \n nDotL = -nDotL;\
624 \n }\
625 \n if (nDotH < 0.0 && in_twoSidedLighting)\
626 \n {\
627 \n nDotH = -nDotH;\
628 \n }\
629 \n if (nDotL > 0.0)\
630 \n {\
631 \n diffuse = nDotL * in_diffuse[component] *\
632 \n in_lightDiffuseColor[0] * color.rgb;\
633 \n }\
634 \n specular = pow(nDotH, in_shininess[component]) *\
635 \n in_specular[component] *\
636 \n in_lightSpecularColor[0];\
637 \n // For the headlight, ignore the light's ambient color\
638 \n // for now as it is causing the old mapper tests to fail\
639 \n finalColor.xyz = in_ambient[component] * color.rgb +\
640 \n diffuse + specular;"
641 );
642 }
643 else if (lightingComplexity == 2)
644 {
645 shaderStr += std::string("\
646 \n g_fragWorldPos = in_modelViewMatrix * in_volumeMatrix *\
647 \n in_textureDatasetMatrix * vec4(-g_dataPos, 1.0);\
648 \n if (g_fragWorldPos.w != 0.0)\
649 \n {\
650 \n g_fragWorldPos /= g_fragWorldPos.w;\
651 \n }\
652 \n vec3 vdir = normalize(g_fragWorldPos.xyz);\
653 \n vec3 normal = gradient.xyz;\
654 \n vec3 ambient = vec3(0.0);\
655 \n vec3 diffuse = vec3(0.0);\
656 \n vec3 specular = vec3(0.0);\
657 \n float normalLength = length(normal);\
658 \n if (normalLength > 0.0)\
659 \n {\
660 \n normal = normalize((in_texureToEyeIt * vec4(normal, 0.0)).xyz);\
661 \n }\
662 \n else\
663 \n {\
664 \n normal = vec3(0.0, 0.0, 0.0);\
665 \n }\
666 \n for (int lightNum = 0; lightNum < in_numberOfLights; lightNum++)\
667 \n {\
668 \n vec3 ldir = in_lightDirection[lightNum].xyz;\
669 \n vec3 h = normalize(ldir + vdir);\
670 \n float nDotH = dot(normal, h);\
671 \n if (nDotH < 0.0 && in_twoSidedLighting)\
672 \n {\
673 \n nDotH = -nDotH;\
674 \n }\
675 \n float nDotL = dot(normal, ldir);\
676 \n if (nDotL < 0.0 && in_twoSidedLighting)\
677 \n {\
678 \n nDotL = -nDotL;\
679 \n }\
680 \n if (nDotL > 0.0)\
681 \n {\
682 \n diffuse += in_lightDiffuseColor[lightNum] * nDotL;\
683 \n }\
684 \n if (nDotH > 0.0)\
685 \n {\
686 \n specular = in_lightSpecularColor[lightNum] *\
687 \n pow(nDotH, in_shininess[component]);\
688 \n }\
689 \n ambient += in_lightAmbientColor[lightNum];\
690 \n }\
691 \n finalColor.xyz = in_ambient[component] * ambient +\
692 \n in_diffuse[component] * diffuse * color.rgb +\
693 \n in_specular[component] * specular;"
694 );
695 }
696 else if (lightingComplexity == 3)
697 {
698 shaderStr += std::string("\
699 \n g_fragWorldPos = in_modelViewMatrix * in_volumeMatrix *\
700 \n in_textureDatasetMatrix * vec4(g_dataPos, 1.0);\
701 \n if (g_fragWorldPos.w != 0.0)\
702 \n {\
703 \n g_fragWorldPos /= g_fragWorldPos.w;\
704 \n }\
705 \n vec3 viewDirection = normalize(-g_fragWorldPos.xyz);\
706 \n vec3 ambient = vec3(0,0,0);\
707 \n vec3 diffuse = vec3(0,0,0);\
708 \n vec3 specular = vec3(0,0,0);\
709 \n vec3 vertLightDirection;\
710 \n vec3 normal = normalize((in_texureToEyeIt * vec4(gradient.xyz, 0.0)).xyz);\
711 \n vec3 lightDir;\
712 \n for (int lightNum = 0; lightNum < in_numberOfLights; lightNum++)\
713 \n {\
714 \n float attenuation = 1.0;\
715 \n // directional\
716 \n lightDir = in_lightDirection[lightNum];\
717 \n if (in_lightPositional[lightNum] == 0)\
718 \n {\
719 \n vertLightDirection = lightDir;\
720 \n }\
721 \n else\
722 \n {\
723 \n vertLightDirection = (g_fragWorldPos.xyz - in_lightPosition[lightNum]);\
724 \n float distance = length(vertLightDirection);\
725 \n vertLightDirection = normalize(vertLightDirection);\
726 \n attenuation = 1.0 /\
727 \n (in_lightAttenuation[lightNum].x\
728 \n + in_lightAttenuation[lightNum].y * distance\
729 \n + in_lightAttenuation[lightNum].z * distance * distance);\
730 \n // per OpenGL standard cone angle is 90 or less for a spot light\
731 \n if (in_lightConeAngle[lightNum] <= 90.0)\
732 \n {\
733 \n float coneDot = dot(vertLightDirection, lightDir);\
734 \n // if inside the cone\
735 \n if (coneDot >= cos(radians(in_lightConeAngle[lightNum])))\
736 \n {\
737 \n attenuation = attenuation * pow(coneDot, in_lightExponent[lightNum]);\
738 \n }\
739 \n else\
740 \n {\
741 \n attenuation = 0.0;\
742 \n }\
743 \n }\
744 \n }\
745 \n // diffuse and specular lighting\
746 \n float nDotL = dot(normal, vertLightDirection);\
747 \n if (nDotL < 0.0 && in_twoSidedLighting)\
748 \n {\
749 \n nDotL = -nDotL;\
750 \n }\
751 \n if (nDotL > 0.0)\
752 \n {\
753 \n float df = max(0.0, attenuation * nDotL);\
754 \n diffuse += (df * in_lightDiffuseColor[lightNum]);\
755 \n }\
756 \n vec3 h = normalize(vertLightDirection + viewDirection);\
757 \n float nDotH = dot(normal, h);\
758 \n if (nDotH < 0.0 && in_twoSidedLighting)\
759 \n {\
760 \n nDotH = -nDotH;\
761 \n }\
762 \n if (nDotH > 0.0)\
763 \n {\
764 \n float sf = attenuation * pow(nDotH, in_shininess[component]);\
765 \n specular += (sf * in_lightSpecularColor[lightNum]);\
766 \n }\
767 \n ambient += in_lightAmbientColor[lightNum];\
768 \n }\
769 \n finalColor.xyz = in_ambient[component] * ambient +\
770 \n in_diffuse[component] * diffuse * color.rgb +\
771 \n in_specular[component] * specular;\
772 ");
773 }
774 }
775 else
776 {
777 shaderStr += std::string(
778 "\n finalColor = vec4(color.rgb, 0.0);"
779 );
780 }
781
782 if (volProperty->HasGradientOpacity() &&
783 (noOfComponents == 1 || !independentComponents))
784 {
785 shaderStr += std::string("\
786 \n if (gradient.w >= 0.0)\
787 \n {\
788 \n color.a = color.a *\
789 \n computeGradientOpacity(gradient);\
790 \n }"
791 );
792 }
793 else if (noOfComponents > 1 && independentComponents &&
794 volProperty->HasGradientOpacity())
795 {
796 shaderStr += std::string("\
797 \n if (gradient.w >= 0.0)\
798 \n {\
799 \n for (int i = 0; i < in_noOfComponents; ++i)\
800 \n {\
801 \n color.a = color.a *\
802 \n computeGradientOpacity(gradient, i) * in_componentWeight[i];\
803 \n }\
804 \n }"
805 );
806 }
807
808 shaderStr += std::string("\
809 \n finalColor.a = color.a;\
810 \n return finalColor;\
811 \n }"
812 );
813
814 return shaderStr;
815 }
816
817 //--------------------------------------------------------------------------
819 vtkVolumeMapper* vtkNotUsed(mapper),
820 vtkVolume* vtkNotUsed(vol),
821 int vtkNotUsed(noOfComponents))
822 {
824 {
825 return std::string("\
826 \nvec3 computeRayDirection()\
827 \n {\
828 \n return normalize(ip_vertexPos.xyz - g_eyePosObj.xyz);\
829 \n }");
830 }
831 else
832 {
833 return std::string("\
834 \nuniform vec3 in_projectionDirection;\
835 \nvec3 computeRayDirection()\
836 \n {\
837 \n return normalize((in_inverseVolumeMatrix *\
838 \n vec4(in_projectionDirection, 0.0)).xyz);\
839 \n }");
840 }
841 }
842
843 //--------------------------------------------------------------------------
845 vtkVolumeMapper* vtkNotUsed(mapper),
846 vtkVolume* vtkNotUsed(vol),
847 int noOfComponents,
848 int independentComponents,
849 std::map<int, std::string> colorTableMap)
850 {
851 if (noOfComponents == 1)
852 {
853 return std::string("\
854 \nuniform sampler2D in_colorTransferFunc;\
855 \nvec4 computeColor(vec4 scalar, float opacity)\
856 \n {\
857 \n return computeLighting(vec4(texture2D(in_colorTransferFunc,\
858 \n vec2(scalar.w, 0.0)).xyz, opacity), 0);\
859 \n }");
860 }
861 else if (noOfComponents > 1 && independentComponents)
862 {
863 std::string shaderStr;
864 std::ostringstream toString;
865 for (int i = 0; i < noOfComponents; ++i)
866 {
867 shaderStr += std::string("\n uniform sampler2D ") +
868 colorTableMap[i] + std::string(";");
869 }
870
871 shaderStr += std::string("\
872 \nvec4 computeColor(vec4 scalar, float opacity, int component)\
873 \n {");
874
875 for (int i = 0; i < noOfComponents; ++i)
876 {
877 toString << i;
878 shaderStr += std::string("\
879 \n if (component == " + toString.str() + ")");
880
881 shaderStr += std::string("\
882 \n {\
883 \n return computeLighting(vec4(texture2D(\
884 \n "+colorTableMap[i]);
885 shaderStr += std::string(", vec2(\
886 \n scalar[" + toString.str() + "],0.0)).xyz,\
887 \n opacity),"+toString.str()+");\
888 \n }");
889
890 // Reset
891 toString.str("");
892 toString.clear();
893 }
894
895 shaderStr += std::string("\n }");
896 return shaderStr;
897 }
898 else if (noOfComponents == 2 && !independentComponents)
899 {
900 return std::string("\
901 \nuniform sampler2D in_colorTransferFunc;\
902 \nvec4 computeColor(vec4 scalar, float opacity)\
903 \n {\
904 \n return computeLighting(vec4(texture2D(in_colorTransferFunc,\
905 \n vec2(scalar.x, 0.0)).xyz,\
906 \n opacity), 0);\
907 \n }");
908 }
909 else
910 {
911 return std::string("\
912 \nvec4 computeColor(vec4 scalar, float opacity)\
913 \n {\
914 \n return computeLighting(vec4(scalar.xyz, opacity), 0);\
915 \n }");
916 }
917 }
918
919 //--------------------------------------------------------------------------
921 vtkVolumeMapper* vtkNotUsed(mapper),
922 vtkVolume* vtkNotUsed(vol),
923 int noOfComponents,
924 int independentComponents,
925 std::map<int, std::string> opacityTableMap)
926 {
927 if (noOfComponents > 1 && independentComponents)
928 {
929 std::string shaderStr;
930 std::ostringstream toString;
931
932 for (int i = 0; i < noOfComponents; ++i)
933 {
934 shaderStr += std::string("\n uniform sampler2D ") +
935 opacityTableMap[i] + std::string(";");
936
937 }
938
939 shaderStr += std::string("\
940 \nfloat computeOpacity(vec4 scalar, int component)\
941 \n {");
942
943 for (int i = 0; i < noOfComponents; ++i)
944 {
945 toString << i;
946 shaderStr += std::string("\
947 \n if (component == " + toString.str() + ")");
948
949 shaderStr += std::string("\
950 \n {\
951 \n return texture2D(in_opacityTransferFunc");
952 shaderStr += (i == 0 ? "" : toString.str());
953 shaderStr += std::string(",vec2(scalar[" + toString.str() + "],0)).r;\
954 \n }");
955
956 // Reset
957 toString.str("");
958 toString.clear();
959 }
960
961 shaderStr += std::string("\n }");
962 return shaderStr;
963 }
964 else if (noOfComponents == 2 && !independentComponents)
965 {
966 return std::string("\
967 \nuniform sampler2D in_opacityTransferFunc;\
968 \nfloat computeOpacity(vec4 scalar)\
969 \n {\
970 \n return texture2D(in_opacityTransferFunc, vec2(scalar.y, 0)).r;\
971 \n }");
972 }
973 else
974 {
975 return std::string("\
976 \nuniform sampler2D in_opacityTransferFunc;\
977 \nfloat computeOpacity(vec4 scalar)\
978 \n {\
979 \n return texture2D(in_opacityTransferFunc, vec2(scalar.w, 0)).r;\
980 \n }");
981 }
982 }
983
984 //--------------------------------------------------------------------------
986 vtkVolumeMapper* vtkNotUsed(mapper),
987 vtkVolume* vtkNotUsed(vol))
988 {
989 return std::string();
990 }
991
992 //--------------------------------------------------------------------------
994 vtkVolumeMapper* vtkNotUsed(mapper),
995 vtkVolume* vtkNotUsed(vol))
996 {
997 return std::string();
998 }
999
1000 //--------------------------------------------------------------------------
1002 vtkVolumeMapper* mapper,
1003 vtkVolume* vtkNotUsed(vol))
1004 {
1006 {
1007 return std::string("\
1008 \n // We get data between 0.0 - 1.0 range\
1009 \n bool l_firstValue = true;\
1010 \n vec4 l_maxValue = vec4(0.0);"
1011 );
1012 }
1013 else if (mapper->GetBlendMode() ==
1015 {
1016 return std::string("\
1017 \n //We get data between 0.0 - 1.0 range\
1018 \n bool l_firstValue = true;\
1019 \n vec4 l_minValue = vec4(1.0);"
1020 );
1021 }
1023 {
1024 return std::string("\
1025 \n //We get data between 0.0 - 1.0 range\
1026 \n vec4 l_avgValue = vec4(0.0);\
1027 \n // Keep track of number of samples\
1028 \n uvec4 l_numSamples = uvec4(0);"
1029 );
1030 }
1031 else if (mapper->GetBlendMode() == vtkVolumeMapper::ADDITIVE_BLEND)
1032 {
1033 return std::string("\
1034 \n //We get data between 0.0 - 1.0 range\
1035 \n vec4 l_sumValue = vec4(0.0);"
1036 );
1037 }
1038 else
1039 {
1040 return std::string();
1041 }
1042 }
1043
1044 //--------------------------------------------------------------------------
1046 vtkVolumeMapper* mapper,
1047 vtkVolume* vtkNotUsed(vol),
1048 vtkImageData* maskInput,
1049 vtkVolumeMask* mask, int maskType,
1050 int noOfComponents,
1051 int independentComponents = 0)
1052 {
1055 std::string shaderStr = std::string("\
1056 \n if (!l_skip)\
1057 \n {\
1058 \n vec4 scalar = texture3D(in_volume, g_dataPos);"
1059 );
1060
1061 // simulate old intensity textures
1062 if (noOfComponents == 1)
1063 {
1064 shaderStr += std::string("\
1065 \n scalar.r = scalar.r*in_volume_scale.r + in_volume_bias.r;\
1066 \n scalar = vec4(scalar.r,scalar.r,scalar.r,scalar.r);"
1067 );
1068 }
1069 else
1070 {
1071 // handle bias and scale
1072 shaderStr += std::string("\
1073 \n scalar = scalar*in_volume_scale + in_volume_bias;"
1074 );
1075 }
1076
1078 {
1079 if (noOfComponents > 1)
1080 {
1081 if (!independentComponents)
1082 {
1083 shaderStr += std::string("\
1084 \n if (l_maxValue.w < scalar.w || l_firstValue)\
1085 \n {\
1086 \n l_maxValue = scalar;\
1087 \n }\
1088 \n\
1089 \n if (l_firstValue)\
1090 \n {\
1091 \n l_firstValue = false;\
1092 \n }"
1093 );
1094 }
1095 else
1096 {
1097 shaderStr += std::string("\
1098 \n for (int i = 0; i < in_noOfComponents; ++i)\
1099 \n {\
1100 \n if (l_maxValue[i] < scalar[i] || l_firstValue)\
1101 \n {\
1102 \n l_maxValue[i] = scalar[i];\
1103 \n }\
1104 \n }\
1105 \n if (l_firstValue)\
1106 \n {\
1107 \n l_firstValue = false;\
1108 \n }"
1109 );
1110 }
1111 }
1112 else
1113 {
1114 shaderStr += std::string("\
1115 \n if (l_maxValue.w < scalar.x || l_firstValue)\
1116 \n {\
1117 \n l_maxValue.w = scalar.x;\
1118 \n }\
1119 \n\
1120 \n if (l_firstValue)\
1121 \n {\
1122 \n l_firstValue = false;\
1123 \n }"
1124 );
1125 }
1126 }
1128 {
1129 if (noOfComponents > 1)
1130 {
1131 if (!independentComponents)
1132 {
1133 shaderStr += std::string("\
1134 \n if (l_minValue.w > scalar.w || l_firstValue)\
1135 \n {\
1136 \n l_minValue = scalar;\
1137 \n }\
1138 \n\
1139 \n if (l_firstValue)\
1140 \n {\
1141 \n l_firstValue = false;\
1142 \n }"
1143 );
1144 }
1145 else
1146 {
1147 shaderStr += std::string("\
1148 \n for (int i = 0; i < in_noOfComponents; ++i)\
1149 \n {\
1150 \n if (l_minValue[i] < scalar[i] || l_firstValue)\
1151 \n {\
1152 \n l_minValue[i] = scalar[i];\
1153 \n }\
1154 \n }\
1155 \n if (l_firstValue)\
1156 \n {\
1157 \n l_firstValue = false;\
1158 \n }"
1159 );
1160 }
1161 }
1162 else
1163 {
1164 shaderStr += std::string("\
1165 \n if (l_minValue.w > scalar.x || l_firstValue)\
1166 \n {\
1167 \n l_minValue.w = scalar.x;\
1168 \n }\
1169 \n\
1170 \n if (l_firstValue)\
1171 \n {\
1172 \n l_firstValue = false;\
1173 \n }"
1174 );
1175 }
1176 }
1178 {
1179 if (noOfComponents > 1 && independentComponents)
1180 {
1181 shaderStr += std::string("\
1182 \n for (int i = 0; i < in_noOfComponents; ++i)\
1183 \n {\
1184 \n // Get the intensity in volume scalar range\
1185 \n float intensity = in_scalarsRange[i][0] +\
1186 \n (in_scalarsRange[i][1] -\
1187 \n in_scalarsRange[i][0]) * scalar[i];\
1188 \n if (in_averageIPRange.x <= intensity &&\
1189 \n intensity <= in_averageIPRange.y)\
1190 \n {\
1191 \n l_avgValue[i] += computeOpacity(scalar, i) * scalar[i];\
1192 \n ++l_numSamples[i];\
1193 \n }\
1194 \n }"
1195 );
1196 }
1197 else
1198 {
1199 shaderStr += std::string("\
1200 \n // Get the intensity in volume scalar range\
1201 \n float intensity = in_scalarsRange[0][0] +\
1202 \n (in_scalarsRange[0][1] -\
1203 \n in_scalarsRange[0][0]) * scalar.x;\
1204 \n if (in_averageIPRange.x <= intensity &&\
1205 \n intensity <= in_averageIPRange.y)\
1206 \n {\
1207 \n l_avgValue.x += computeOpacity(scalar) * scalar.x;\
1208 \n ++l_numSamples.x;\
1209 \n }"
1210 );
1211 }
1212 }
1213 else if (mapper->GetBlendMode() == vtkVolumeMapper::ADDITIVE_BLEND)
1214 {
1215 if (noOfComponents > 1 && independentComponents)
1216 {
1217 shaderStr += std::string("\
1218 \n for (int i = 0; i < in_noOfComponents; ++i)\
1219 \n {\
1220 \n float opacity = computeOpacity(scalar, i);\
1221 \n l_sumValue[i] = l_sumValue[i] + opacity * scalar[i];\
1222 \n }"
1223 );
1224 }
1225 else
1226 {
1227 shaderStr += std::string("\
1228 \n float opacity = computeOpacity(scalar);\
1229 \n l_sumValue.x = l_sumValue.x + opacity * scalar.x;"
1230 );
1231 }
1232 }
1233 else if (mapper->GetBlendMode() == vtkVolumeMapper::COMPOSITE_BLEND)
1234 {
1235 if (noOfComponents > 1 && independentComponents)
1236 {
1237 shaderStr += std::string("\
1238 \n vec4 color[4]; vec4 tmp = vec4(0.0);\
1239 \n float totalAlpha = 0.0;\
1240 \n for (int i = 0; i < in_noOfComponents; ++i)\
1241 \n {\
1242 ");
1243 if (glMapper->GetUseDepthPass() && glMapper->GetCurrentPass() ==
1245 {
1246 shaderStr += std::string("\
1247 \n // Data fetching from the red channel of volume texture\
1248 \n float opacity = computeOpacity(scalar, i);\
1249 \n if (opacity > 0.0)\
1250 \n {\
1251 \n g_srcColor.a = opacity;\
1252 \n }\
1253 \n }"
1254 );
1255 }
1256 else if (!mask || !maskInput ||
1258 {
1259 shaderStr += std::string("\
1260 \n // Data fetching from the red channel of volume texture\
1261 \n color[i][3] = computeOpacity(scalar, i);\
1262 \n color[i] = computeColor(scalar, color[i][3], i);\
1263 \n totalAlpha += color[i][3] * in_componentWeight[i];\
1264 \n }\
1265 \n if (totalAlpha > 0.0)\
1266 \n {\
1267 \n for (int i = 0; i < in_noOfComponents; ++i)\
1268 \n {\
1269 \n // Only let visible components contribute to the final color\
1270 \n if (in_componentWeight[i] <= 0) continue;\
1271 \n\
1272 \n tmp.x += color[i].x * color[i].w * in_componentWeight[i];\
1273 \n tmp.y += color[i].y * color[i].w * in_componentWeight[i];\
1274 \n tmp.z += color[i].z * color[i].w * in_componentWeight[i];\
1275 \n tmp.w += ((color[i].w * color[i].w)/totalAlpha);\
1276 \n }\
1277 \n }\
1278 \n g_fragColor = (1.0f - g_fragColor.a) * tmp + g_fragColor;"
1279 );
1280 }
1281 }
1282 else if (glMapper->GetUseDepthPass() && glMapper->GetCurrentPass() ==
1284 {
1285 shaderStr += std::string("\
1286 \n g_srcColor = vec4(0.0);\
1287 \n g_srcColor.a = computeOpacity(scalar);"
1288 );
1289 }
1290 else
1291 {
1292 if (!mask || !maskInput ||
1294 {
1295 shaderStr += std::string("\
1296 \n g_srcColor = vec4(0.0);\
1297 \n g_srcColor.a = computeOpacity(scalar);\
1298 \n if (g_srcColor.a > 0.0)\
1299 \n {\
1300 \n g_srcColor = computeColor(scalar, g_srcColor.a);"
1301 );
1302 }
1303
1304 shaderStr += std::string("\
1305 \n // Opacity calculation using compositing:\
1306 \n // Here we use front to back compositing scheme whereby\
1307 \n // the current sample value is multiplied to the\
1308 \n // currently accumulated alpha and then this product\
1309 \n // is subtracted from the sample value to get the\
1310 \n // alpha from the previous steps. Next, this alpha is\
1311 \n // multiplied with the current sample colour\
1312 \n // and accumulated to the composited colour. The alpha\
1313 \n // value from the previous steps is then accumulated\
1314 \n // to the composited colour alpha.\
1315 \n g_srcColor.rgb *= g_srcColor.a;\
1316 \n g_fragColor = (1.0f - g_fragColor.a) * g_srcColor + g_fragColor;"
1317 );
1318
1319 if (!mask || !maskInput ||
1321 {
1322 shaderStr += std::string("\
1323 \n }"
1324 );
1325 }
1326 }
1327 }
1328 else
1329 {
1330 shaderStr += std::string();
1331 }
1332
1333 shaderStr += std::string("\
1334 \n }"
1335 );
1336 return shaderStr;
1337 }
1338
1339 //--------------------------------------------------------------------------
1341 vtkVolumeMapper* vtkNotUsed(mapper), vtkVolume* vtkNotUsed(vol))
1342 {
1343 return std::string("\
1344 \n // Special coloring mode which renders the Prop Id in fragments that\
1345 \n // have accumulated certain level of opacity. Used during the selection\
1346 \n // pass vtkHardwareSelection::ACTOR_PASS.\
1347 \n if (g_fragColor.a > 3.0/ 255.0)\
1348 \n {\
1349 \n gl_FragData[0] = vec4(in_propId, 1.0);\
1350 \n }\
1351 \n else\
1352 \n {\
1353 \n gl_FragData[0] = vec4(0.0);\
1354 \n }\
1355 \n return;");
1356 };
1357
1358 //--------------------------------------------------------------------------
1360 vtkVolumeMapper* vtkNotUsed(mapper), vtkVolume* vtkNotUsed(vol))
1361 {
1362 return std::string("\
1363 \n // Special coloring mode which renders the voxel index in fragments that\
1364 \n // have accumulated certain level of opacity. Used during the selection\
1365 \n // pass vtkHardwareSelection::ID_LOW24.\
1366 \n if (g_fragColor.a > 3.0/ 255.0)\
1367 \n {\
1368 \n uvec3 volumeDim = uvec3(in_textureExtentsMax - in_textureExtentsMin);\
1369 \n uvec3 voxelCoords = uvec3(volumeDim * g_dataPos);\
1370 \n // vtkHardwareSelector assumes index 0 to be empty space, so add uint(1).\
1371 \n uint idx = volumeDim.x * volumeDim.y * voxelCoords.z +\
1372 \n volumeDim.x * voxelCoords.y + voxelCoords.x + uint(1);\
1373 \n gl_FragData[0] = vec4(float(idx % uint(256)) / 255.0,\
1374 \n float((idx / uint(256)) % uint(256)) / 255.0,\
1375 \n float((idx / uint(65536)) % uint(256)) / 255.0, 1.0);\
1376 \n }\
1377 \n else\
1378 \n {\
1379 \n gl_FragData[0] = vec4(0.0);\
1380 \n }\
1381 \n return;");
1382 };
1383
1384 //--------------------------------------------------------------------------
1386 vtkVolumeMapper* vtkNotUsed(mapper), vtkVolume* vtkNotUsed(vol))
1387 {
1388 return std::string("\
1389 \n // Special coloring mode which renders the voxel index in fragments that\
1390 \n // have accumulated certain level of opacity. Used during the selection\
1391 \n // pass vtkHardwareSelection::ID_MID24.\
1392 \n if (g_fragColor.a > 3.0/ 255.0)\
1393 \n {\
1394 \n uvec3 volumeDim = uvec3(in_textureExtentsMax - in_textureExtentsMin);\
1395 \n uvec3 voxelCoords = uvec3(volumeDim * g_dataPos);\
1396 \n // vtkHardwareSelector assumes index 0 to be empty space, so add uint(1).\
1397 \n uint idx = volumeDim.x * volumeDim.y * voxelCoords.z +\
1398 \n volumeDim.x * voxelCoords.y + voxelCoords.x + uint(1);\
1399 \n idx = ((idx & 0xff000000) >> 24);\
1400 \n gl_FragData[0] = vec4(float(idx % uint(256)) / 255.0,\
1401 \n float((idx / uint(256)) % uint(256)) / 255.0,\
1402 \n float(idx / uint(65536)) / 255.0, 1.0);\
1403 \n }\
1404 \n else\
1405 \n {\
1406 \n gl_FragData[0] = vec4(0.0);\
1407 \n }\
1408 \n return;");
1409 };
1410
1411 //--------------------------------------------------------------------------
1413 vtkVolumeMapper* mapper,
1414 vtkVolume* vtkNotUsed(vol),
1415 int noOfComponents,
1416 int independentComponents = 0)
1417 {
1420
1421 if (glMapper->GetUseDepthPass() && glMapper->GetCurrentPass() ==
1424 {
1425 return std::string();
1426 }
1428 {
1429 if (noOfComponents > 1 && independentComponents)
1430 {
1431 return std::string("\
1432 \n g_srcColor = vec4(0);\
1433 \n for (int i = 0; i < in_noOfComponents; ++i)\
1434 \n {\
1435 \n vec4 tmp = computeColor(l_maxValue, computeOpacity(l_maxValue, i), i);\
1436 \n g_srcColor[0] += tmp[0] * tmp[3] * in_componentWeight[i];\
1437 \n g_srcColor[1] += tmp[1] * tmp[3] * in_componentWeight[i];\
1438 \n g_srcColor[2] += tmp[2] * tmp[3] * in_componentWeight[i];\
1439 \n g_srcColor[3] += tmp[3] * in_componentWeight[i];\
1440 \n }\
1441 \n g_fragColor = g_srcColor;"
1442 );
1443 }
1444 else
1445 {
1446 return std::string("\
1447 \n g_srcColor = computeColor(l_maxValue,\
1448 \n computeOpacity(l_maxValue));\
1449 \n g_fragColor.rgb = g_srcColor.rgb * g_srcColor.a;\
1450 \n g_fragColor.a = g_srcColor.a;"
1451 );
1452 }
1453 }
1455 {
1456 if (noOfComponents > 1 && independentComponents)
1457 {
1458 return std::string("\
1459 \n g_srcColor = vec4(0);\
1460 \n for (int i = 0; i < in_noOfComponents; ++i)\
1461 \n {\
1462 \n vec4 tmp = computeColor(l_minValue, computeOpacity(l_minValue, i), i);\
1463 \n g_srcColor[0] += tmp[0] * tmp[3] * in_componentWeight[i];\
1464 \n g_srcColor[1] += tmp[1] * tmp[3] * in_componentWeight[i];\
1465 \n g_srcColor[2] += tmp[2] * tmp[3] * in_componentWeight[i];\
1466 \n g_srcColor[2] += tmp[3] * tmp[3] * in_componentWeight[i];\
1467 \n }\
1468 \n g_fragColor = g_srcColor;"
1469 );
1470 }
1471 else
1472 {
1473 return std::string("\
1474 \n g_srcColor = computeColor(l_minValue,\
1475 \n computeOpacity(l_minValue));\
1476 \n g_fragColor.rgb = g_srcColor.rgb * g_srcColor.a;\
1477 \n g_fragColor.a = g_srcColor.a;"
1478 );
1479 }
1480 }
1482 {
1483 if (noOfComponents > 1 && independentComponents)
1484 {
1485 return std::string("\
1486 \n for (int i = 0; i < in_noOfComponents; ++i)\
1487 \n {\
1488 \n if (l_numSamples[i] == uint(0))\
1489 \n {\
1490 \n continue;\
1491 \n }\
1492 \n l_avgValue[i] = l_avgValue[i] * in_componentWeight[i] /\
1493 \n l_numSamples[i];\
1494 \n if (i > 0)\
1495 \n {\
1496 \n l_avgValue[0] += l_avgValue[i];\
1497 \n }\
1498 \n }\
1499 \n l_avgValue[0] = clamp(l_avgValue[0], 0.0, 1.0);\
1500 \n g_fragColor = vec4(vec3(l_avgValue[0]), 1.0);"
1501 );
1502 }
1503 else
1504 {
1505 return std::string("\
1506 \n if (l_numSamples.x == uint(0))\
1507 \n {\
1508 \n discard;\
1509 \n }\
1510 \n else\
1511 \n {\
1512 \n l_avgValue.x /= l_numSamples.x;\
1513 \n l_avgValue.x = clamp(l_avgValue.x, 0.0, 1.0);\
1514 \n g_fragColor = vec4(vec3(l_avgValue.x), 1.0);\
1515 \n }"
1516 );
1517 }
1518 }
1519 else if (mapper->GetBlendMode() == vtkVolumeMapper::ADDITIVE_BLEND)
1520 {
1521 if (noOfComponents > 1 && independentComponents)
1522 {
1523 // Add all the components to get final color
1524 return std::string("\
1525 \n l_sumValue.x *= in_componentWeight.x;\
1526 \n for (int i = 1; i < in_noOfComponents; ++i)\
1527 \n {\
1528 \n l_sumValue.x += l_sumValue[i] * in_componentWeight[i];\
1529 \n }\
1530 \n l_sumValue.x = clamp(l_sumValue.x, 0.0, 1.0);\
1531 \n g_fragColor = vec4(vec3(l_sumValue.x), 1.0);"
1532 );
1533 }
1534 else
1535 {
1536 return std::string("\
1537 \n l_sumValue.x = clamp(l_sumValue.x, 0.0, 1.0);\
1538 \n g_fragColor = vec4(vec3(l_sumValue.x), 1.0);"
1539 );
1540 }
1541 }
1542 else
1543 {
1544 return std::string();
1545 }
1546 }
1547
1548 //--------------------------------------------------------------------------
1550 vtkVolumeMapper* vtkNotUsed(mapper),
1551 vtkVolume* vtkNotUsed(vol))
1552 {
1553 return std::string();
1554 }
1555
1556 //--------------------------------------------------------------------------
1558 vtkVolumeMapper* vtkNotUsed(mapper),
1559 vtkVolume* vtkNotUsed(vol))
1560 {
1561 return std::string();
1562 }
1563
1564 //--------------------------------------------------------------------------
1566 vtkVolumeMapper* vtkNotUsed(mapper), vtkVolume* vtkNotUsed(vol))
1567 {
1568 return std::string("\
1569 \n uniform vec3 in_propId;");
1570 };
1571
1572 //--------------------------------------------------------------------------
1574 vtkVolumeMapper* vtkNotUsed(mapper),
1575 vtkVolume* vtkNotUsed(vol))
1576 {
1577 return std::string("\
1578 \n // Flag to indicate if the raymarch loop should terminate \
1579 \n bool stop = false;\
1580 \n\
1581 \n float l_terminatePointMax = 0.0;\
1582 \n\
1583 \n#ifdef GL_ES\
1584 \n vec4 l_depthValue = vec4(1.0,1.0,1.0,1.0);\
1585 \n#else\
1586 \n vec4 l_depthValue = texture2D(in_depthSampler, fragTexCoord);\
1587 \n#endif\
1588 \n // Depth test\
1589 \n if(gl_FragCoord.z >= l_depthValue.x)\
1590 \n {\
1591 \n discard;\
1592 \n }\
1593 \n\
1594 \n // color buffer or max scalar buffer have a reduced size.\
1595 \n fragTexCoord = (gl_FragCoord.xy - in_windowLowerLeftCorner) *\
1596 \n in_inverseOriginalWindowSize;\
1597 \n\
1598 \n // Compute max number of iterations it will take before we hit\
1599 \n // the termination point\
1600 \n\
1601 \n // Abscissa of the point on the depth buffer along the ray.\
1602 \n // point in texture coordinates\
1603 \n vec4 terminatePoint;\
1604 \n terminatePoint.x = (gl_FragCoord.x - in_windowLowerLeftCorner.x) * 2.0 *\
1605 \n in_inverseWindowSize.x - 1.0;\
1606 \n terminatePoint.y = (gl_FragCoord.y - in_windowLowerLeftCorner.y) * 2.0 *\
1607 \n in_inverseWindowSize.y - 1.0;\
1608 \n terminatePoint.z = (2.0 * l_depthValue.x - (gl_DepthRange.near +\
1609 \n gl_DepthRange.far)) / gl_DepthRange.diff;\
1610 \n terminatePoint.w = 1.0;\
1611 \n\
1612 \n // From normalized device coordinates to eye coordinates.\
1613 \n // in_projectionMatrix is inversed because of way VT\
1614 \n // From eye coordinates to texture coordinates\
1615 \n terminatePoint = ip_inverseTextureDataAdjusted *\
1616 \n in_inverseVolumeMatrix *\
1617 \n in_inverseModelViewMatrix *\
1618 \n in_inverseProjectionMatrix *\
1619 \n terminatePoint;\
1620 \n terminatePoint /= terminatePoint.w;\
1621 \n\
1622 \n l_terminatePointMax = length(terminatePoint.xyz - g_dataPos.xyz) /\
1623 \n length(g_dirStep);\
1624 \n float l_currentT = 0.0;");
1625 }
1626
1627 //--------------------------------------------------------------------------
1629 vtkVolumeMapper* vtkNotUsed(mapper),
1630 vtkVolume* vtkNotUsed(vol))
1631 {
1632 return std::string("\
1633 \n if(any(greaterThan(g_dataPos, in_texMax)) ||\
1634 \n any(lessThan(g_dataPos, in_texMin)))\
1635 \n {\
1636 \n break;\
1637 \n }\
1638 \n\
1639 \n // Early ray termination\
1640 \n // if the currently composited colour alpha is already fully saturated\
1641 \n // we terminated the loop or if we have hit an obstacle in the\
1642 \n // direction of they ray (using depth buffer) we terminate as well.\
1643 \n if((g_fragColor.a > (1.0 - 1.0/255.0)) || \
1644 \n l_currentT >= l_terminatePointMax)\
1645 \n {\
1646 \n break;\
1647 \n }\
1648 \n ++l_currentT;"
1649 );
1650 }
1651
1652 //--------------------------------------------------------------------------
1654 vtkVolumeMapper* vtkNotUsed(mapper),
1655 vtkVolume* vtkNotUsed(vol))
1656 {
1657 return std::string();
1658 }
1659
1660 //--------------------------------------------------------------------------
1662 vtkVolumeMapper* vtkNotUsed(mapper),
1663 vtkVolume* vtkNotUsed(vol))
1664 {
1665 return std::string();
1666 }
1667
1668 //--------------------------------------------------------------------------
1670 vtkVolumeMapper* mapper,
1671 vtkVolume* vtkNotUsed(vol))
1672 {
1673 if (!mapper->GetCropping()) {
1674 return std::string();
1675 }
1676
1677 return std::string("\
1678 \nuniform float in_croppingPlanes[6];\
1679 \nuniform int in_croppingFlags [32];\
1680 \n// X: axis = 0, Y: axis = 1, Z: axis = 2\
1681 \n// cp Cropping plane bounds (minX, maxX, minY, maxY, minZ, maxZ)\
1682 \nint computeRegionCoord(float cp[6], vec3 pos, int axis)\
1683 \n {\
1684 \n int cpmin = axis * 2;\
1685 \n int cpmax = cpmin + 1;\
1686 \n\
1687 \n if (pos[axis] < cp[cpmin])\
1688 \n {\
1689 \n return 1;\
1690 \n }\
1691 \n else if (pos[axis] >= cp[cpmin] &&\
1692 \n pos[axis] < cp[cpmax])\
1693 \n {\
1694 \n return 2;\
1695 \n }\
1696 \n else if (pos[axis] >= cp[cpmax])\
1697 \n {\
1698 \n return 3;\
1699 \n }\
1700 \n return 0;\
1701 \n }\
1702 \n\
1703 \nint computeRegion(float cp[6], vec3 pos)\
1704 \n {\
1705 \n return (computeRegionCoord(cp, pos, 0) +\
1706 \n (computeRegionCoord(cp, pos, 1) - 1) * 3 +\
1707 \n (computeRegionCoord(cp, pos, 2) - 1) * 9);\
1708 \n }"
1709 );
1710 }
1711
1712 //--------------------------------------------------------------------------
1714 vtkVolumeMapper* mapper,
1715 vtkVolume* vtkNotUsed(vol))
1716 {
1717 if (!mapper->GetCropping()) {
1718 return std::string();
1719 }
1720
1721 return std::string("\
1722 \n // Convert cropping region to texture space\
1723 \n float croppingPlanesTexture[6];\
1724 \n mat4 datasetToTextureMat = in_inverseTextureDatasetMatrix;\
1725 \n\
1726 \n vec4 temp = vec4(in_croppingPlanes[0], 0.0, 0.0, 1.0);\
1727 \n temp = datasetToTextureMat * temp;\
1728 \n if (temp[3] != 0.0)\
1729 \n {\
1730 \n temp[0] /= temp[3];\
1731 \n }\
1732 \n croppingPlanesTexture[0] = temp[0];\
1733 \n\
1734 \n temp = vec4(in_croppingPlanes[1], 0.0, 0.0, 1.0);\
1735 \n temp = datasetToTextureMat * temp;\
1736 \n if (temp[3] != 0.0)\
1737 \n {\
1738 \n temp[0] /= temp[3];\
1739 \n }\
1740 \n croppingPlanesTexture[1] = temp[0];\
1741 \n\
1742 \n temp = vec4(0.0, in_croppingPlanes[2], 0.0, 1.0);\
1743 \n temp = datasetToTextureMat * temp;\
1744 \n if (temp[3] != 0.0)\
1745 \n {\
1746 \n temp[1] /= temp[3];\
1747 \n }\
1748 \n croppingPlanesTexture[2] = temp[1];\
1749 \n\
1750 \n temp = vec4(0.0, in_croppingPlanes[3], 0.0, 1.0);\
1751 \n temp = datasetToTextureMat * temp;\
1752 \n if (temp[3] != 0.0)\
1753 \n {\
1754 \n temp[1] /= temp[3];\
1755 \n }\
1756 \n croppingPlanesTexture[3] = temp[1];\
1757 \n\
1758 \n temp = vec4(0.0, 0.0, in_croppingPlanes[4], 1.0);\
1759 \n temp = datasetToTextureMat * temp;\
1760 \n if (temp[3] != 0.0)\
1761 \n {\
1762 \n temp[2] /= temp[3];\
1763 \n }\
1764 \n croppingPlanesTexture[4] = temp[2];\
1765 \n\
1766 \n temp = vec4(0.0, 0.0, in_croppingPlanes[5], 1.0);\
1767 \n temp = datasetToTextureMat * temp;\
1768 \n if (temp[3] != 0.0)\
1769 \n {\
1770 \n temp[2] /= temp[3];\
1771 \n }\
1772 \n croppingPlanesTexture[5] = temp[2];"
1773 );
1774 }
1775
1776 //--------------------------------------------------------------------------
1778 vtkVolumeMapper* mapper,
1779 vtkVolume* vtkNotUsed(vol))
1780 {
1781 if (!mapper->GetCropping()) {
1782 return std::string();
1783 }
1784
1785 return std::string("\
1786 \n // Determine region\
1787 \n int regionNo = computeRegion(croppingPlanesTexture, g_dataPos);\
1788 \n\
1789 \n // Do & operation with cropping flags\
1790 \n // Pass the flag that its Ok to sample or not to sample\
1791 \n if (in_croppingFlags[regionNo] == 0)\
1792 \n {\
1793 \n // Skip this voxel\
1794 \n l_skip = true;\
1795 \n }"
1796 );
1797 }
1798
1799 //--------------------------------------------------------------------------
1801 vtkVolumeMapper* vtkNotUsed(mapper),
1802 vtkVolume* vtkNotUsed(vol))
1803 {
1804 return std::string();
1805 }
1806
1807 //--------------------------------------------------------------------------
1809 vtkVolumeMapper* vtkNotUsed(mapper),
1810 vtkVolume* vtkNotUsed(vol))
1811 {
1812 return std::string();
1813 }
1814
1815 //--------------------------------------------------------------------------
1817 vtkVolumeMapper* vtkNotUsed(mapper),
1818 vtkVolume* vtkNotUsed(vol))
1819 {
1820 return std::string();
1821 }
1822
1823 //--------------------------------------------------------------------------
1825 vtkVolumeMapper* mapper,
1826 vtkVolume* vtkNotUsed(vol))
1827 {
1828 if (!mapper->GetClippingPlanes())
1829 {
1830 return std::string();
1831 }
1832
1833 std::string shaderStr;
1835 {
1836 shaderStr = std::string("\
1837 vec4 temp = in_volumeMatrix * vec4(rayDir, 0.0);\
1838 \n if (temp.w != 0.0)\
1839 \n {\
1840 \n temp = temp/temp.w;\
1841 \n temp.w = 1.0;\
1842 \n }\
1843 vec3 objRayDir = temp.xyz;");
1844 }
1845 else
1846 {
1847 shaderStr = std::string("\
1848 vec3 objRayDir = normalize(in_projectionDirection);");
1849 }
1850
1851 shaderStr += std::string("\
1852 \n int clippingPlanesSize = int(in_clippingPlanes[0]);\
1853 \n vec4 objDataPos = vec4(0.0);\
1854 \n mat4 textureToObjMat = in_volumeMatrix *\
1855 \n in_textureDatasetMatrix;\
1856 \n\
1857 \n vec4 terminatePointObj = textureToObjMat * terminatePoint;\
1858 \n if (terminatePointObj.w != 0.0)\
1859 \n {\
1860 \n terminatePointObj = terminatePointObj/ terminatePointObj.w ;\
1861 \n terminatePointObj.w = 1.0;\
1862 \n }\
1863 \n\
1864 \n for (int i = 0; i < clippingPlanesSize; i = i + 6)\
1865 \n {\
1866 \n if (in_useJittering)\
1867 \n {\
1868 \n objDataPos = textureToObjMat * vec4(g_dataPos - (g_dirStep\
1869 \n * jitterValue), 1.0);\
1870 \n }\
1871 \n else\
1872 \n {\
1873 \n objDataPos = textureToObjMat * vec4(g_dataPos - g_dirStep, 1.0);\
1874 \n }\
1875 \n if (objDataPos.w != 0.0)\
1876 \n {\
1877 \n objDataPos = objDataPos/objDataPos.w; objDataPos.w = 1.0;\
1878 \n }\
1879 \n vec3 planeOrigin = vec3(in_clippingPlanes[i + 1],\
1880 \n in_clippingPlanes[i + 2],\
1881 \n in_clippingPlanes[i + 3]);\
1882 \n vec3 planeNormal = vec3(in_clippingPlanes[i + 4],\
1883 \n in_clippingPlanes[i + 5],\
1884 \n in_clippingPlanes[i + 6]);\
1885 \n vec3 normalizedPlaneNormal = normalize(planeNormal);\
1886 \n\
1887 \n float rayDotNormal = dot(objRayDir, normalizedPlaneNormal);\
1888 \n bool frontFace = rayDotNormal > 0;\
1889 \n float distance = dot(normalizedPlaneNormal, planeOrigin - objDataPos.xyz);\
1890 \n\
1891 \n if (frontFace && // Observing from the clipped side (plane's front face)\
1892 \n distance > 0.0) // Ray-entry lies on the clipped side.\
1893 \n {\
1894 \n // Scale the point-plane distance to the ray direction and update the\
1895 \n // entry point.\
1896 \n float rayScaledDist = distance / rayDotNormal;\
1897 \n vec4 newObjDataPos = vec4(objDataPos.xyz + rayScaledDist * objRayDir, 1.0);\
1898 \n newObjDataPos = in_inverseTextureDatasetMatrix\
1899 \n * in_inverseVolumeMatrix * vec4(newObjDataPos.xyz, 1.0);\
1900 \n if (newObjDataPos.w != 0.0)\
1901 \n {\
1902 \n newObjDataPos /= newObjDataPos.w;\
1903 \n }\
1904 \n if (in_useJittering)\
1905 \n {\
1906 \n g_dataPos = newObjDataPos.xyz + g_dirStep * jitterValue;\
1907 \n }\
1908 \n else\
1909 \n {\
1910 \n g_dataPos = newObjDataPos.xyz + g_dirStep;\
1911 \n }\
1912 \n\
1913 \n bool stop = any(greaterThan(g_dataPos, in_texMax)) ||\
1914 \n any(lessThan(g_dataPos, in_texMin));\
1915 \n if (stop)\
1916 \n {\
1917 \n // The ray exits the bounding box before ever intersecting the plane (only\
1918 \n // the clipped space is hit).\
1919 \n discard;\
1920 \n }\
1921 \n\
1922 \n bool behindGeometry = dot(terminatePointObj.xyz - planeOrigin.xyz, normalizedPlaneNormal) < 0.0;\
1923 \n if (behindGeometry)\
1924 \n {\
1925 \n // Geometry appears in front of the plane.\
1926 \n discard;\
1927 \n }\
1928 \n\
1929 \n // Update the number of ray marching steps to account for the clipped entry point (\
1930 \n // this is necessary in case the ray hits geometry after marching behind the plane,\
1931 \n // given that the number of steps was assumed to be from the not-clipped entry).\
1932 \n l_terminatePointMax = length(terminatePoint.xyz - g_dataPos.xyz) /\
1933 \n length(g_dirStep);\
1934 \n }\
1935 \n }");
1936
1937 return shaderStr;
1938 }
1939
1940 //--------------------------------------------------------------------------
1942 vtkVolumeMapper* mapper,
1943 vtkVolume* vtkNotUsed(vol))
1944 {
1945 if (!mapper->GetClippingPlanes())
1946 {
1947 return std::string();
1948 }
1949 else
1950 {
1951 return std::string("\
1952 \n for (int i = 0; i < clippingPlanesSize && !l_skip; i = i + 6)\
1953 \n {\
1954 \n vec4 objDataPos = textureToObjMat * vec4(g_dataPos, 1.0);\
1955 \n if (objDataPos.w != 0.0)\
1956 \n {\
1957 \n objDataPos /= objDataPos.w;\
1958 \n }\
1959 \n vec3 planeOrigin = vec3(in_clippingPlanes[i + 1],\
1960 \n in_clippingPlanes[i + 2],\
1961 \n in_clippingPlanes[i + 3]);\
1962 \n vec3 planeNormal = vec3(in_clippingPlanes[i + 4],\
1963 \n in_clippingPlanes[i + 5],\
1964 \n in_clippingPlanes[i + 6]);\
1965 \n if (dot(vec3(objDataPos.xyz - planeOrigin), planeNormal) < 0 && dot(objRayDir, planeNormal) < 0)\
1966 \n {\
1967 \n l_skip = true;\
1968 \n g_exit = true;\
1969 \n }\
1970 \n }"
1971 );
1972 }
1973 }
1974
1975 //--------------------------------------------------------------------------
1977 vtkVolumeMapper* vtkNotUsed(mapper),
1978 vtkVolume* vtkNotUsed(vol))
1979 {
1980 return std::string();
1981 }
1982
1983 //--------------------------------------------------------------------------
1985 vtkVolumeMapper* vtkNotUsed(mapper),
1986 vtkVolume* vtkNotUsed(vol),
1987 vtkImageData* maskInput,
1988 vtkVolumeMask* mask,
1989 int vtkNotUsed(maskType))
1990 {
1991 if (!mask || !maskInput)
1992 {
1993 return std::string();
1994 }
1995 else
1996 {
1997 return std::string("uniform sampler3D in_mask;");
1998 }
1999 }
2000
2001 //--------------------------------------------------------------------------
2003 vtkVolumeMapper* vtkNotUsed(mapper),
2004 vtkVolume* vtkNotUsed(vol),
2005 vtkImageData* maskInput,
2006 vtkVolumeMask* mask,
2007 int maskType)
2008 {
2009 if (!mask || !maskInput ||
2011 {
2012 return std::string();
2013 }
2014 else
2015 {
2016 return std::string("\
2017 \nvec4 maskValue = texture3D(in_mask, g_dataPos);\
2018 \nif(maskValue.r <= 0.0)\
2019 \n {\
2020 \n l_skip = true;\
2021 \n }"
2022 );
2023 }
2024 }
2025
2026 //--------------------------------------------------------------------------
2028 vtkVolumeMapper* vtkNotUsed(mapper),
2029 vtkVolume* vtkNotUsed(vol),
2030 vtkImageData* maskInput,
2031 vtkVolumeMask* mask,
2032 int maskType)
2033 {
2034 if (!mask || !maskInput ||
2036 {
2037 return std::string();
2038 }
2039 else
2040 {
2041 return std::string("\
2042 \nuniform float in_maskBlendFactor;\
2043 \nuniform sampler2D in_mask1;\
2044 \nuniform sampler2D in_mask2;"
2045 );
2046 }
2047 }
2048
2049 //--------------------------------------------------------------------------
2051 vtkVolumeMapper* vtkNotUsed(mapper),
2052 vtkVolume* vtkNotUsed(vol),
2053 vtkImageData* maskInput,
2054 vtkVolumeMask* mask,
2055 int maskType,
2056 int noOfComponents)
2057 {
2058 if (!mask || !maskInput ||
2060 {
2061 return std::string();
2062 }
2063 else
2064 {
2065 std::string shaderStr = std::string("\
2066 \nvec4 scalar = texture3D(in_volume, g_dataPos);");
2067
2068 // simulate old intensity textures
2069 if (noOfComponents == 1)
2070 {
2071 shaderStr += std::string("\
2072 \n scalar.r = scalar.r*in_volume_scale.r + in_volume_bias.r;\
2073 \n scalar = vec4(scalar.r,scalar.r,scalar.r,scalar.r);"
2074 );
2075 }
2076 else
2077 {
2078 // handle bias and scale
2079 shaderStr += std::string("\
2080 \n scalar = scalar*in_volume_scale + in_volume_bias;"
2081 );
2082 }
2083
2084 return shaderStr + std::string("\
2085 \nif (in_maskBlendFactor == 0.0)\
2086 \n {\
2087 \n g_srcColor = computeColor(scalar, computeOpacity(scalar));\
2088 \n }\
2089 \nelse\
2090 \n {\
2091 \n float opacity = computeOpacity(scalar);\
2092 \n // Get the mask value at this same location\
2093 \n vec4 maskValue = texture3D(in_mask, g_dataPos);\
2094 \n if(maskValue.r == 0.0)\
2095 \n {\
2096 \n g_srcColor = computeColor(scalar, opacity);\
2097 \n }\
2098 \n else\
2099 \n {\
2100 \n if (maskValue.r == 1.0/255.0)\
2101 \n {\
2102 \n g_srcColor = texture2D(in_mask1, vec2(scalar.w,0.0));\
2103 \n }\
2104 \n else\
2105 \n {\
2106 \n // maskValue.r == 2.0/255.0\
2107 \n g_srcColor = texture2D(in_mask2, vec2(scalar.w,0.0));\
2108 \n }\
2109 \n g_srcColor.a = 1.0;\
2110 \n if(in_maskBlendFactor < 1.0)\
2111 \n {\
2112 \n g_srcColor = (1.0 - in_maskBlendFactor) *\
2113 \n computeColor(scalar, opacity) +\
2114 \n in_maskBlendFactor * g_srcColor;\
2115 \n }\
2116 \n }\
2117 \n g_srcColor.a = opacity;\
2118 \n }"
2119 );
2120 }
2121 }
2122
2123 //--------------------------------------------------------------------------
2125 vtkVolumeMapper* vtkNotUsed(mapper),
2126 vtkVolume* vtkNotUsed(vol))
2127 {
2128 return std::string("\
2129 \n vec3 l_opaqueFragPos = vec3(-1.0);\
2130 \n if(in_clampDepthToBackface)\
2131 \n {\
2132 \n l_opaqueFragPos = g_dataPos;\
2133 \n }\
2134 \n bool l_updateDepth = true;"
2135 );
2136 }
2137
2138 //--------------------------------------------------------------------------
2140 vtkRenderer* vtkNotUsed(ren), vtkVolumeMapper* vtkNotUsed(mapper),
2141 vtkVolume* vtkNotUsed(vol))
2142 {
2143 return std::string("\
2144 \n if(!l_skip && g_srcColor.a > 0.0 && l_updateDepth)\
2145 \n {\
2146 \n l_opaqueFragPos = g_dataPos;\
2147 \n l_updateDepth = false;\
2148 \n }"
2149 );
2150 }
2151
2152 //--------------------------------------------------------------------------
2154 vtkVolumeMapper* vtkNotUsed(mapper),
2155 vtkVolume* vtkNotUsed(vol))
2156 {
2157 return std::string("\
2158 \n if (l_opaqueFragPos == vec3(-1.0))\
2159 \n {\
2160 \n gl_FragData[1] = vec4(1.0);\
2161 \n }\
2162 \n else\
2163 \n {\
2164 \n vec4 depthValue = in_projectionMatrix * in_modelViewMatrix *\
2165 \n in_volumeMatrix * in_textureDatasetMatrix *\
2166 \n vec4(l_opaqueFragPos, 1.0);\
2167 \n depthValue /= depthValue.w;\
2168 \n gl_FragData[1] = vec4(vec3(0.5 * (gl_DepthRange.far -\
2169 \n gl_DepthRange.near) * depthValue.z + 0.5 *\
2170 \n (gl_DepthRange.far + gl_DepthRange.near)), 1.0);\
2171 \n }"
2172 );
2173 }
2174
2175 //--------------------------------------------------------------------------
2177 vtkVolumeMapper* vtkNotUsed(mapper),
2178 vtkVolume* vtkNotUsed(vol))
2179 {
2180 return std::string("\
2181 \n vec3 l_isoPos = g_dataPos;"
2182 );
2183 }
2184
2185 //--------------------------------------------------------------------------
2187 vtkRenderer* vtkNotUsed(ren), vtkVolumeMapper* vtkNotUsed(mapper),
2188 vtkVolume* vtkNotUsed(vol))
2189 {
2190 return std::string("\
2191 \n if(!l_skip && g_srcColor.a > 0.0)\
2192 \n {\
2193 \n l_isoPos = g_dataPos;\
2194 \n g_exit = true; l_skip = true;\
2195 \n }"
2196 );
2197 }
2198
2199 //--------------------------------------------------------------------------
2201 vtkVolumeMapper* vtkNotUsed(mapper),
2202 vtkVolume* vtkNotUsed(vol))
2203 {
2204 return std::string("\
2205 \n vec4 depthValue = in_projectionMatrix * in_modelViewMatrix *\
2206 \n in_volumeMatrix * in_textureDatasetMatrix *\
2207 \n vec4(l_isoPos, 1.0);\
2208 \n gl_FragData[0] = vec4(l_isoPos, 1.0);\
2209 \n gl_FragData[1] = vec4(vec3((depthValue.z/depthValue.w) * 0.5 + 0.5),\
2210 \n 1.0);"
2211 );
2212 }
2213}
2214
2215#endif // vtkVolumeShaderComposer_h
2216// VTK-HeaderTest-Exclude: vtkVolumeShaderComposer.h
virtual vtkPlaneCollection * GetClippingPlanes()
virtual int GetParallelProjection()
virtual int GetUseDepthPass()
topologically and geometrically regular array of data
Definition: vtkImageData.h:46
static vtkOpenGLGPUVolumeRayCastMapper * SafeDownCast(vtkObjectBase *o)
abstract specification for renderers
Definition: vtkRenderer.h:64
vtkCamera * GetActiveCamera()
Get the current camera.
Abstract class for a volume mapper.
virtual int GetBlendMode()
virtual int GetCropping()
represents the common properties for rendering a volume.
bool HasGradientOpacity(int index=0)
Check whether or not we have the gradient opacity.
int GetShade(int index)
represents a volume (data & properties) in a rendered scene
Definition: vtkVolume.h:51
vtkVolumeProperty * GetProperty()
@ string
Definition: vtkX3D.h:490
std::string ClippingImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *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 BinaryMaskImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), vtkImageData *maskInput, vtkVolumeMask *mask, int 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 BaseImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(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 replace(std::string source, const std::string &search, const std::string &replace, bool all)
std::string TerminationInit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string PickingIdMid24PassExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
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 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 ClippingExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string BinaryMaskDeclaration(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), vtkImageData *maskInput, vtkVolumeMask *mask, int vtkNotUsed(maskType))
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 RenderToImageExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ShadingDeclarationVertex(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ShadingDeclarationFragment(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
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 ShadingImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol), vtkImageData *maskInput, vtkVolumeMask *mask, int maskType, int noOfComponents, int independentComponents=0)
std::string CompositeMaskDeclarationFragment(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), vtkImageData *maskInput, vtkVolumeMask *mask, int maskType)
std::string CroppingDeclarationVertex(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string CroppingInit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol))
std::string ComputeGradientDeclaration(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vol, int noOfComponents, int independentComponents, std::map< int, std::string > gradientTableMap)
std::string CroppingExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ClippingInit(vtkRenderer *ren, vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol))
std::string BaseInit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vol, int lightingComplexity)
std::string CompositeMaskImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), vtkImageData *maskInput, vtkVolumeMask *mask, int maskType, int noOfComponents)
std::string BaseDeclarationVertex(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string TerminationDeclarationFragment(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(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 DepthPassExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ClippingDeclarationFragment(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string BaseDeclarationFragment(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol), int vtkNotUsed(numberOfLights), int lightingComplexity, bool hasGradientOpacity, int noOfComponents, int independentComponents)
boost::graph_traits< vtkGraph * >::vertex_descriptor source(boost::graph_traits< vtkGraph * >::edge_descriptor e, vtkGraph *)