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 
38 namespace 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  //--------------------------------------------------------------------------
271  std::string BaseInit(vtkRenderer* vtkNotUsed(ren),
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  //--------------------------------------------------------------------------
425  std::string BaseExit(vtkRenderer* vtkNotUsed(ren),
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() &&
489  !vol->GetProperty()->HasGradientOpacity())
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  {
823  if (!ren->GetActiveCamera()->GetParallelProjection())
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;
1834  if (!ren->GetActiveCamera()->GetParallelProjection())
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
std::string ShadingExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol), int noOfComponents, int independentComponents=0)
std::string RenderToImageImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string BaseImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
represents a volume (data & properties) in a rendered scene
Definition: vtkVolume.h:50
std::string CroppingDeclarationVertex(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string CompositeMaskImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), vtkImageData *maskInput, vtkVolumeMask *mask, int maskType, int noOfComponents)
Abstract class for a volume mapper.
std::string BinaryMaskDeclaration(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), vtkImageData *maskInput, vtkVolumeMask *mask, int vtkNotUsed(maskType))
virtual int GetUseDepthPass()
If UseDepthPass is on, the mapper will use two passes.
std::string DepthPassInit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
virtual int GetBlendMode()
Set/Get the blend mode.
std::string PickingActorPassDeclaration(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string RenderToImageExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
abstract specification for renderers
Definition: vtkRenderer.h:63
std::string CroppingDeclarationFragment(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol))
std::string ShadingDeclarationFragment(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string TerminationExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ShadingDeclarationVertex(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 replace(std::string source, const std::string &search, const std::string &replace, bool all)
virtual vtkPlaneCollection * GetClippingPlanes()
Get/Set the vtkPlaneCollection which specifies the clipping planes.
vtkCamera * GetActiveCamera()
Get the current camera.
int GetShade(int index)
Set/Get the shading of a volume.
std::string PickingActorPassExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ClippingImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol))
std::string ComputeLightingDeclaration(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vol, int noOfComponents, int independentComponents, int vtkNotUsed(numberOfLights), int lightingComplexity)
OpenGL subclass that draws the image to the screen.
static vtkOpenGLGPUVolumeRayCastMapper * SafeDownCast(vtkObjectBase *o)
std::string TerminationInit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string CroppingImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol))
std::string TerminationImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ClippingDeclarationVertex(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ClippingExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string CompositeMaskDeclarationFragment(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), vtkImageData *maskInput, vtkVolumeMask *mask, int maskType)
topologically and geometrically regular array of data
Definition: vtkImageData.h:45
bool HasGradientOpacity(int index=0)
Check whether or not we have the gradient opacity.
std::string ShadingImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol), vtkImageData *maskInput, vtkVolumeMask *mask, int maskType, int noOfComponents, int independentComponents=0)
virtual int GetParallelProjection()
Set/Get the value of the ParallelProjection instance variable.
std::string ComputeClipPositionImplementation(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 ShadingInit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol))
represents the common properties for rendering a volume.
std::string CroppingExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ClippingInit(vtkRenderer *ren, vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol))
std::string ClippingDeclarationFragment(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ComputeTextureCoordinates(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
boost::graph_traits< vtkGraph * >::vertex_descriptor source(boost::graph_traits< vtkGraph * >::edge_descriptor e, vtkGraph *)
std::string ComputeGradientDeclaration(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vol, int noOfComponents, int independentComponents, std::map< int, std::string > gradientTableMap)
std::string PickingIdLow24PassExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string CroppingInit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol))
vtkVolumeProperty * GetProperty()
Set/Get the volume property.
virtual int GetCropping()
Turn On/Off orthogonal cropping.
std::string TerminationDeclarationVertex(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string BaseDeclarationVertex(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string DepthPassExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string DepthPassImplementation(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string BaseExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string BaseInit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vol, int lightingComplexity)
std::string BaseDeclarationFragment(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol), int vtkNotUsed(numberOfLights), int lightingComplexity, bool hasGradientOpacity, int noOfComponents, int independentComponents)
std::string TerminationDeclarationFragment(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 ComputeColorDeclaration(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), int noOfComponents, int independentComponents, std::map< int, std::string > colorTableMap)
std::string RenderToImageInit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string PickingIdMid24PassExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))