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