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>
22 #include <vtkRenderer.h>
23 #include <vtkVolume.h>
24 #include <vtkVolumeMapper.h>
25 #include <vtkVolumeProperty.h>
26 
27 #include <map>
28 #include <string>
29 
30 namespace vtkvolume
31 {
32  //--------------------------------------------------------------------------
34  const std::string replace, bool all)
35  {
36  std::string::size_type pos = 0;
37  bool first = true;
38  while ((pos = source.find(search, 0)) != std::string::npos)
39  {
40  source.replace(pos, search.length(), replace);
41  pos += search.length();
42  if (first)
43  {
44  first = false;
45  if (!all)
46  {
47  return source;
48  }
49  }
50  }
51  return source;
52  }
53 
54  //--------------------------------------------------------------------------
56  vtkVolumeMapper* vtkNotUsed(mapper),
57  vtkVolume* vtkNotUsed(vol))
58  {
59  return std::string("\
60  \n vec4 pos = in_projectionMatrix * in_modelViewMatrix *\
61  \n in_volumeMatrix * vec4(in_vertexPos.xyz, 1.0);\
62  \n gl_Position = pos;"
63  );
64  }
65 
66  //--------------------------------------------------------------------------
68  vtkVolumeMapper* vtkNotUsed(mapper),
69  vtkVolume* vtkNotUsed(vol))
70  {
71  return std::string(
72  "\n // Assuming point data only. Also, we offset the texture coordinate\
73  \n // to account for OpenGL treating voxel at the center of the cell.\
74  \n vec3 uvx = (in_vertexPos - in_volumeExtentsMin) /\
75  \n (in_volumeExtentsMax - in_volumeExtentsMin);\
76  \n vec3 delta = in_textureExtentsMax - in_textureExtentsMin;\
77  \n ip_textureCoords = (uvx * (delta - vec3(1.0)) + vec3(0.5)) / delta;"
78  );
79  }
80 
81  //--------------------------------------------------------------------------
83  vtkVolumeMapper* vtkNotUsed(mapper),
84  vtkVolume* vtkNotUsed(vol))
85  {
86  return std::string("\
87  \n uniform mat4 in_modelViewMatrix;\
88  \n uniform mat4 in_projectionMatrix;\
89  \n uniform mat4 in_volumeMatrix;\
90  \n\
91  \n uniform vec3 in_volumeExtentsMin;\
92  \n uniform vec3 in_volumeExtentsMax;\
93  \n\
94  \n uniform vec3 in_textureExtentsMax;\
95  \n uniform vec3 in_textureExtentsMin;"
96  );
97  }
98 
99  //--------------------------------------------------------------------------
101  vtkVolumeMapper* vtkNotUsed(mapper),
102  vtkVolume* vtkNotUsed(vol),
103  int vtkNotUsed(numberOfLights),
104  int lightingComplexity,
105  int noOfComponents,
106  int independentComponents)
107  {
108  std::string shaderStr = std::string("\
109  \n// Volume dataset\
110  \nuniform sampler3D in_volume;\
111  \nuniform int in_noOfComponents;\
112  \nuniform int in_independentComponents;\
113  \n\
114  \nuniform sampler2D in_noiseSampler;\
115  \nuniform sampler2D in_depthSampler;\
116  \n\
117  \n// Camera position\
118  \nuniform vec3 in_cameraPos;\
119  \n\
120  \n// view and model matrices\
121  \nuniform mat4 in_volumeMatrix;\
122  \nuniform mat4 in_inverseVolumeMatrix;\
123  \nuniform mat4 in_projectionMatrix;\
124  \nuniform mat4 in_inverseProjectionMatrix;\
125  \nuniform mat4 in_modelViewMatrix;\
126  \nuniform mat4 in_inverseModelViewMatrix;\
127  \nuniform mat4 in_textureDatasetMatrix;\
128  \nuniform mat4 in_inverseTextureDatasetMatrix;\
129  \nuniform mat3 in_texureToEyeIt;\
130  \n\
131  \n// Ray step size\
132  \nuniform vec3 in_cellStep;\
133  \nuniform vec2 in_scalarsRange;\
134  \nuniform vec3 in_cellSpacing;\
135  \n\
136  \n// Sample distance\
137  \nuniform float in_sampleDistance;\
138  \n\
139  \n// Scales\
140  \nuniform vec3 in_cellScale;\
141  \nuniform vec2 in_windowLowerLeftCorner;\
142  \nuniform vec2 in_inverseOriginalWindowSize;\
143  \nuniform vec2 in_inverseWindowSize;\
144  \nuniform vec3 in_textureExtentsMax;\
145  \nuniform vec3 in_textureExtentsMin;\
146  \nuniform float in_volumeScale;\
147  \nuniform float in_volumeBias;\
148  \n\
149  \n// Material and lighting\
150  \nuniform vec3 in_diffuse;\
151  \nuniform vec3 in_ambient;\
152  \nuniform vec3 in_specular;\
153  \nuniform float in_shininess;\
154  ");
155 
156  if (lightingComplexity > 0)
157  {
158  shaderStr += std::string("\
159  \nuniform bool in_twoSidedLighting;"
160  );
161  }
162 
163  if (lightingComplexity == 3)
164  {
165  shaderStr += std::string("\
166  \nuniform int in_numberOfLights;\
167  \nuniform vec3 in_lightAmbientColor[6];\
168  \nuniform vec3 in_lightDiffuseColor[6];\
169  \nuniform vec3 in_lightSpecularColor[6];\
170  \nuniform vec3 in_lightDirection[6];\
171  \nuniform vec3 in_lightPosition[6];\
172  \nuniform vec3 in_lightAttenuation[6];\
173  \nuniform float in_lightConeAngle[6];\
174  \nuniform float in_lightExponent[6];\
175  \nuniform int in_lightPositional[6];\
176  ");
177  }
178  else if (lightingComplexity == 2)
179  {
180  shaderStr += std::string("\
181  \nuniform int in_numberOfLights;\
182  \nuniform vec3 in_lightAmbientColor[6];\
183  \nuniform vec3 in_lightDiffuseColor[6];\
184  \nuniform vec3 in_lightSpecularColor[6];\
185  \nuniform vec3 in_lightDirection[6];\
186  ");
187  }
188  else
189  {
190  shaderStr += std::string("\
191  \nuniform vec3 in_lightAmbientColor[1];\
192  \nuniform vec3 in_lightDiffuseColor[1];\
193  \nuniform vec3 in_lightSpecularColor[1];\
194  ");
195  }
196 
197  if (noOfComponents > 1 && independentComponents)
198  {
199  shaderStr += std::string("\
200  \nuniform vec4 in_componentWeight;");
201  }
202 
203  return shaderStr;
204  }
205 
206  //--------------------------------------------------------------------------
208  vtkVolumeMapper* vtkNotUsed(mapper),
209  vtkVolume* vtkNotUsed(vol))
210  {
211  return std::string("\
212  \n // Get the 3D texture coordinates for lookup into the in_volume dataset\
213  \n g_dataPos = ip_textureCoords.xyz;\
214  \n\
215  \n // Eye position in object space\
216  \n g_eyePosObj = (in_inverseVolumeMatrix * vec4(in_cameraPos, 1.0));\
217  \n if (g_eyePosObj.w != 0.0)\
218  \n {\
219  \n g_eyePosObj.x /= g_eyePosObj.w;\
220  \n g_eyePosObj.y /= g_eyePosObj.w;\
221  \n g_eyePosObj.z /= g_eyePosObj.w;\
222  \n g_eyePosObj.w = 1.0;\
223  \n }\
224  \n\
225  \n // Getting the ray marching direction (in object space);\
226  \n vec3 rayDir = computeRayDirection();\
227  \n\
228  \n // Multiply the raymarching direction with the step size to get the\
229  \n // sub-step size we need to take at each raymarching step\
230  \n g_dirStep = (in_inverseTextureDatasetMatrix *\
231  \n vec4(rayDir, 0.0)).xyz * in_sampleDistance;\
232  \n\
233  \n g_dataPos += g_dirStep * (texture2D(in_noiseSampler, g_dataPos.xy).x);\
234  \n\
235  \n // Flag to deternmine if voxel should be considered for the rendering\
236  \n bool l_skip = false;");
237  }
238 
239  //--------------------------------------------------------------------------
241  vtkVolumeMapper* vtkNotUsed(mapper),
242  vtkVolume* vtkNotUsed(vol))
243  {
244  return std::string("\
245  \n l_skip = false;"
246  );
247  }
248 
249  //--------------------------------------------------------------------------
251  vtkVolumeMapper* vtkNotUsed(mapper),
252  vtkVolume* vtkNotUsed(vol))
253  {
254  return std::string();
255  }
256 
257  //--------------------------------------------------------------------------
259  vtkVolumeMapper* vtkNotUsed(mapper),
260  vtkVolume* vol,
261  int noOfComponents,
262  int independentComponents,
263  std::map<int, std::string> gradientTableMap)
264  {
265  std::string shaderStr;
266  if (noOfComponents == 1 && vol->GetProperty()->HasGradientOpacity())
267  {
268  shaderStr += std::string("\
269  \nuniform sampler1D in_gradientTransferFunc;\
270  \nfloat computeGradientOpacity(vec4 grad)\
271  \n {\
272  \n return texture1D(in_gradientTransferFunc, grad.w).w;\
273  \n }"
274  );
275  }
276  else if (noOfComponents > 1 && independentComponents &&
278  {
279  for (int i = 0; i < noOfComponents; ++i)
280  {
281  shaderStr += std::string("\n uniform sampler1D ") +
282  gradientTableMap[i] + std::string(";");
283  }
284 
285  shaderStr += std::string("\
286  \nfloat computeGradientOpacity(vec4 grad, int component)\
287  \n {\
288  \n if (component == 0)\
289  \n {\
290  \n return texture1D(in_gradientTransferFunc, grad.w).w;\
291  \n }\
292  \n if (component == 1)\
293  \n {\
294  \n return texture1D(in_gradientTransferFunc1, grad.w).w;\
295  \n }\
296  \n if (component == 2)\
297  \n {\
298  \n return texture1D(in_gradientTransferFunc2, grad.w).w;\
299  \n }\
300  \n if (component == 3)\
301  \n {\
302  \n return texture1D(in_gradientTransferFunc3, grad.w).w;\
303  \n }\
304  \n }"
305  );
306  }
307 
308  if (vol->GetProperty()->GetShade() &&
309  !vol->GetProperty()->HasGradientOpacity())
310  {
311  shaderStr += std::string("\
312  \nvec4 computeGradient()\
313  \n {\
314  \n vec3 g1;\
315  \n vec3 g2;\
316  \n vec3 xvec = vec3(in_cellStep[0], 0.0, 0.0);\
317  \n vec3 yvec = vec3(0.0, in_cellStep[1], 0.0);\
318  \n vec3 zvec = vec3(0.0, 0.0, in_cellStep[2]);\
319  \n g1.x = texture3D(in_volume, vec3(g_dataPos + xvec)).x;\
320  \n g1.y = texture3D(in_volume, vec3(g_dataPos + yvec)).x;\
321  \n g1.z = texture3D(in_volume, vec3(g_dataPos + zvec)).x;\
322  \n g2.x = texture3D(in_volume, vec3(g_dataPos - xvec)).x;\
323  \n g2.y = texture3D(in_volume, vec3(g_dataPos - yvec)).x;\
324  \n g2.z = texture3D(in_volume, vec3(g_dataPos - zvec)).x;\
325  \n return vec4((g1 - g2), -1.0);\
326  \n }"
327  );
328  }
329  else if (vol->GetProperty()->GetShade() &&
331  {
332  shaderStr += std::string("\
333  \nvec4 computeGradient()\
334  \n {\
335  \n vec3 g1;\
336  \n vec4 g2;\
337  \n vec3 xvec = vec3(in_cellStep[0], 0.0, 0.0);\
338  \n vec3 yvec = vec3(0.0, in_cellStep[1], 0.0);\
339  \n vec3 zvec = vec3(0.0, 0.0, in_cellStep[2]);\
340  \n g1.x = texture3D(in_volume, vec3(g_dataPos + xvec)).x;\
341  \n g1.y = texture3D(in_volume, vec3(g_dataPos + yvec)).x;\
342  \n g1.z = texture3D(in_volume, vec3(g_dataPos + zvec)).x;\
343  \n g2.x = texture3D(in_volume, vec3(g_dataPos - xvec)).x;\
344  \n g2.y = texture3D(in_volume, vec3(g_dataPos - yvec)).x;\
345  \n g2.z = texture3D(in_volume, vec3(g_dataPos - zvec)).x;\
346  \n g1.x = in_scalarsRange[0] + (\
347  \n in_scalarsRange[1] - in_scalarsRange[0]) * g1.x;\
348  \n g1.y = in_scalarsRange[0] + (\
349  \n in_scalarsRange[1] - in_scalarsRange[0]) * g1.y;\
350  \n g1.z = in_scalarsRange[0] + (\
351  \n in_scalarsRange[1] - in_scalarsRange[0]) * g1.z;\
352  \n g2.x = in_scalarsRange[0] + (\
353  \n in_scalarsRange[1] - in_scalarsRange[0]) * g2.x;\
354  \n g2.y = in_scalarsRange[0] + (\
355  \n in_scalarsRange[1] - in_scalarsRange[0]) * g2.y;\
356  \n g2.z = in_scalarsRange[0] + (\
357  \n in_scalarsRange[1] - in_scalarsRange[0]) * g2.z;\
358  \n g2.xyz = g1 - g2.xyz;\
359  \n vec3 cellSpacing = vec3(in_cellSpacing[0],\
360  \n in_cellSpacing[1],\
361  \n in_cellSpacing[2]);\
362  \n vec3 aspect;\
363  \n float avgSpacing = (cellSpacing[0] +\
364  \n cellSpacing[1] +\
365  \n cellSpacing[2])/3.0;\
366  \n // Adjust the aspect\
367  \n aspect.x = cellSpacing[0] * 2.0 / avgSpacing;\
368  \n aspect.y = cellSpacing[1] * 2.0 / avgSpacing;\
369  \n aspect.z = cellSpacing[2] * 2.0 / avgSpacing;\
370  \n g2.x /= aspect.x;\
371  \n g2.y /= aspect.y;\
372  \n g2.z /= aspect.z;\
373  \n float grad_mag = sqrt(g2.x * g2.x +\
374  \n g2.y * g2.y +\
375  \n g2.z * g2.z);\
376  \n if (grad_mag > 0.0)\
377  \n {\
378  \n g2.x /= grad_mag;\
379  \n g2.y /= grad_mag;\
380  \n g2.z /= grad_mag;\
381  \n }\
382  \n else\
383  \n {\
384  \n g2.xyz = vec3(0.0, 0.0, 0.0);\
385  \n }\
386  \n grad_mag = grad_mag * 1.0 / (0.25 * (in_scalarsRange[1] -\
387  \n (in_scalarsRange[0])));\
388  \n grad_mag = clamp(grad_mag, 0.0, 1.0);\
389  \n g2.w = grad_mag;\
390  \n return g2;\
391  \n }"
392  );
393  }
394  else
395  {
396  shaderStr += std::string("\
397  \nvec4 computeGradient()\
398  \n {\
399  \n return vec4(0.0);\
400  \n }");
401  }
402 
403  return shaderStr;
404  }
405 
406  //--------------------------------------------------------------------------
408  vtkVolumeMapper* vtkNotUsed(mapper),
409  vtkVolume* vol,
410  int noOfComponents,
411  int independentComponents,
412  int vtkNotUsed(numberOfLights),
413  int lightingComplexity)
414  {
415  vtkVolumeProperty* volProperty = vol->GetProperty();
416  std::string shaderStr = std::string("\
417  \nvec4 computeLighting(vec4 color)\
418  \n {"
419  );
420 
421  if (volProperty->GetShade() || volProperty->HasGradientOpacity())
422  {
423  shaderStr += std::string("\
424  \n // Compute gradient function only once\
425  \n vec4 gradient = computeGradient();"
426  );
427  }
428 
429  if (volProperty->GetShade())
430  {
431  if (lightingComplexity == 1)
432  {
433  shaderStr += std::string("\
434  \n // Light position in object space\
435  \n vec4 lightPosObj = (in_inverseVolumeMatrix *\
436  \n vec4(in_cameraPos, 1.0));\
437  \n if (lightPosObj.w != 0.0)\
438  \n {\
439  \n lightPosObj.x /= lightPosObj.w;\
440  \n lightPosObj.y /= lightPosObj.w;\
441  \n lightPosObj.z /= lightPosObj.w;\
442  \n lightPosObj.w = 1.0;\
443  \n }\
444  \n vec3 diffuse = vec3(0.0);\
445  \n vec3 specular = vec3(0.0);\
446  \n vec3 ldir = normalize(lightPosObj.xyz - ip_vertexPos);\
447  \n vec3 vdir = normalize(g_eyePosObj.xyz - ip_vertexPos);\
448  \n vec3 h = normalize(ldir + vdir);\
449  \n vec3 g2 = gradient.xyz;\
450  \n g2 = (1.0/in_cellSpacing) * g2;\
451  \n float normalLength = length(g2);\
452  \n if (normalLength > 0.0)\
453  \n {\
454  \n g2 = normalize(g2);\
455  \n }\
456  \n else\
457  \n {\
458  \n g2 = vec3(0.0, 0.0, 0.0);\
459  \n }\
460  \n float nDotL = dot(g2, ldir);\
461  \n float nDotH = dot(g2, h);\
462  \n if (nDotL < 0.0 && in_twoSidedLighting)\
463  \n {\
464  \n nDotL = -nDotL;\
465  \n }\
466  \n if (nDotH < 0.0 && in_twoSidedLighting)\
467  \n {\
468  \n nDotH = -nDotH;\
469  \n }\
470  \n if (nDotL > 0)\
471  \n {\
472  \n diffuse = nDotL * in_diffuse * in_lightDiffuseColor[0]\
473  \n * color.rgb;\
474  \n }\
475  \n if (nDotH > 0)\
476  \n {\
477  \n specular = pow(nDotH, in_shininess) * in_specular *\
478  \n in_lightSpecularColor[0];\
479  \n }\
480  \n // For the headlight, ignore the light's ambient color\
481  \n // for now as it is causing the old mapper tests to fail\
482  \n vec3 finalColor = (in_ambient * color.rgb +\
483  \n diffuse + specular);"
484  );
485  }
486  else if (lightingComplexity == 2)
487  {
488  shaderStr += std::string("\
489  \n vec4 fragWorldPos = in_modelViewMatrix * in_volumeMatrix *\
490  \n in_textureDatasetMatrix * vec4(-g_dataPos, 1.0);\
491  \n if (fragWorldPos.w != 0.0)\
492  \n {\
493  \n fragWorldPos /= fragWorldPos.w;\
494  \n }\
495  \n vec3 vdir = normalize(fragWorldPos.xyz);\
496  \n vec3 normal = gradient.xyz;\
497  \n vec3 ambient = vec3(0.0);\
498  \n vec3 diffuse = vec3(0.0);\
499  \n vec3 specular = vec3(0.0);\
500  \n float normalLength = length(normal);\
501  \n if (normalLength > 0.0)\
502  \n {\
503  \n normal = normalize(in_texureToEyeIt * normal);\
504  \n }\
505  \n else\
506  \n {\
507  \n normal = vec3(0.0, 0.0, 0.0);\
508  \n }\
509  \n for (int lightNum = 0; lightNum < in_numberOfLights; lightNum++)\
510  \n {\
511  \n vec3 ldir = in_lightDirection[lightNum].xyz;\
512  \n vec3 h = normalize(ldir + vdir);\
513  \n float nDotH = dot(normal, h);\
514  \n if (nDotH < 0.0 && in_twoSidedLighting)\
515  \n {\
516  \n nDotH = -nDotH;\
517  \n }\
518  \n float nDotL = dot(normal, ldir);\
519  \n if (nDotL < 0.0 && in_twoSidedLighting)\
520  \n {\
521  \n nDotL = -nDotL;\
522  \n }\
523  \n if (nDotL > 0)\
524  \n {\
525  \n diffuse += in_lightDiffuseColor[lightNum] * nDotL;\
526  \n }\
527  \n if (nDotH > 0)\
528  \n {\
529  \n specular = in_lightSpecularColor[lightNum] * pow(nDotH, in_shininess);\
530  \n }\
531  \n ambient += in_lightAmbientColor[lightNum];\
532  \n }\
533  \n vec3 finalColor = in_ambient * ambient +\
534  \n in_diffuse * diffuse * color.rgb +\
535  \n in_specular * specular;"
536  );
537  }
538  else if (lightingComplexity == 3)
539  {
540  shaderStr += std::string("\
541  \n vec4 fragWorldPos = in_modelViewMatrix * in_volumeMatrix *\
542  \n in_textureDatasetMatrix * vec4(g_dataPos, 1.0);\
543  \n if (fragWorldPos.w != 0.0)\
544  \n {\
545  \n fragWorldPos /= fragWorldPos.w;\
546  \n }\
547  \n vec3 viewDirection = normalize(-fragWorldPos.xyz);\
548  \n vec3 ambient = vec3(0,0,0);\
549  \n vec3 diffuse = vec3(0,0,0);\
550  \n vec3 specular = vec3(0,0,0);\
551  \n vec3 vertLightDirection;\
552  \n vec3 normal = normalize(in_texureToEyeIt * gradient.xyz);\
553  \n vec3 lightDir;\
554  \n for (int lightNum = 0; lightNum < in_numberOfLights; lightNum++)\
555  \n {\
556  \n float attenuation = 1.0;\
557  \n // directional\
558  \n lightDir = in_lightDirection[lightNum];\
559  \n if (in_lightPositional[lightNum] == 0)\
560  \n {\
561  \n vertLightDirection = lightDir;\
562  \n }\
563  \n else\
564  \n {\
565  \n vertLightDirection = (fragWorldPos.xyz - in_lightPosition[lightNum]);\
566  \n float distance = length(vertLightDirection);\
567  \n vertLightDirection = normalize(vertLightDirection);\
568  \n attenuation = 1.0 /\
569  \n (in_lightAttenuation[lightNum].x\
570  \n + in_lightAttenuation[lightNum].y * distance\
571  \n + in_lightAttenuation[lightNum].z * distance * distance);\
572  \n // per OpenGL standard cone angle is 90 or less for a spot light\
573  \n if (in_lightConeAngle[lightNum] <= 90.0)\
574  \n {\
575  \n float coneDot = dot(vertLightDirection, lightDir);\
576  \n // if inside the cone\
577  \n if (coneDot >= cos(radians(in_lightConeAngle[lightNum])))\
578  \n {\
579  \n attenuation = attenuation * pow(coneDot, in_lightExponent[lightNum]);\
580  \n }\
581  \n else\
582  \n {\
583  \n attenuation = 0.0;\
584  \n }\
585  \n }\
586  \n }\
587  \n // diffuse and specular lighting\
588  \n float nDotL = dot(normal, vertLightDirection);\
589  \n if (nDotL < 0.0 && in_twoSidedLighting)\
590  \n {\
591  \n nDotL = -nDotL;\
592  \n }\
593  \n if (nDotL > 0)\
594  \n {\
595  \n float df = max(0.0, attenuation * nDotL);\
596  \n diffuse += (df * in_lightDiffuseColor[lightNum]);\
597  \n }\
598  \n vec3 h = normalize(vertLightDirection + viewDirection);\
599  \n float nDotH = dot(normal, h);\
600  \n if (nDotH < 0.0 && in_twoSidedLighting)\
601  \n {\
602  \n nDotH = -nDotH;\
603  \n }\
604  \n if (nDotH > 0)\
605  \n {\
606  \n float sf = attenuation * pow(nDotH, in_shininess);\
607  \n specular += (sf * in_lightSpecularColor[lightNum]);\
608  \n }\
609  \n ambient += in_lightAmbientColor[lightNum];\
610  \n }\
611  \n vec3 finalColor = in_ambient * ambient + in_diffuse *\
612  \n diffuse * color.rgb + in_specular * specular;\
613  ");
614  }
615  }
616  else
617  {
618  shaderStr += std::string(
619  "\n vec3 finalColor = color.rgb;"
620  );
621  }
622 
623  if (noOfComponents == 1 && volProperty->HasGradientOpacity())
624  {
625  shaderStr += std::string("\
626  \n if (gradient.w >= 0.0)\
627  \n {\
628  \n color.a = color.a *\
629  \n computeGradientOpacity(gradient);\
630  \n }"
631  );
632  }
633  else if (noOfComponents > 1 && independentComponents &&
634  volProperty->HasGradientOpacity())
635  {
636  shaderStr += std::string("\
637  \n if (gradient.w >= 0.0)\
638  \n {\
639  \n for (int i = 0; i < in_noOfComponents; ++i)\
640  \n {\
641  \n color.a = color.a *\
642  \n computeGradientOpacity(gradient, i) * in_componentWeight[i];\
643  \n }"
644  );
645  }
646 
647  shaderStr += std::string("\
648  \n return vec4(finalColor, color.a);\
649  \n }"
650  );
651 
652  return shaderStr;
653  }
654 
655  //--------------------------------------------------------------------------
657  vtkVolumeMapper* vtkNotUsed(mapper),
658  vtkVolume* vtkNotUsed(vol),
659  int vtkNotUsed(noOfComponents))
660  {
661  if (!ren->GetActiveCamera()->GetParallelProjection())
662  {
663  return std::string("\
664  \nvec3 computeRayDirection()\
665  \n {\
666  \n return normalize(ip_vertexPos.xyz - g_eyePosObj.xyz);\
667  \n }");
668  }
669  else
670  {
671  return std::string("\
672  \nuniform vec3 in_projectionDirection;\
673  \nvec3 computeRayDirection()\
674  \n {\
675  \n return normalize((in_inverseVolumeMatrix *\
676  \n vec4(in_projectionDirection, 0.0)).xyz);\
677  \n }");
678  }
679  }
680 
681  //--------------------------------------------------------------------------
683  vtkVolumeMapper* vtkNotUsed(mapper),
684  vtkVolume* vtkNotUsed(vol),
685  int noOfComponents,
686  int independentComponents,
687  std::map<int, std::string> colorTableMap)
688  {
689  if (noOfComponents == 1)
690  {
691  return std::string("\
692  \nuniform sampler1D in_colorTransferFunc;\
693  \nvec4 computeColor(vec4 scalar)\
694  \n {\
695  \n return computeLighting(vec4(texture1D(in_colorTransferFunc,\
696  \n scalar.w).xyz,\
697  \n computeOpacity(scalar)));\
698  \n }");
699  }
700  else if (noOfComponents > 1 && independentComponents)
701  {
702  std::string shaderStr;
703  for (int i = 0; i < noOfComponents; ++i)
704  {
705  shaderStr += std::string("\n uniform sampler1D ") +
706  colorTableMap[i] + std::string(";");
707  }
708 
709  shaderStr += std::string("\
710  \nvec4 computeColor(vec4 scalar, int component)\
711  \n {\
712  \n if (component == 0)\
713  \n {\
714  \n return computeLighting(vec4(texture1D(\
715  \n in_colorTransferFunc,\
716  \n scalar[component]).xyz,\
717  \n computeOpacity(scalar, component)));\
718  \n }\
719  \n if (component == 1)\
720  \n {\
721  \n return computeLighting(vec4(texture1D(\
722  \n in_colorTransferFunc1,\
723  \n scalar[component]).xyz,\
724  \n computeOpacity(scalar, component)));\
725  \n }\
726  \n if (component == 2)\
727  \n {\
728  \n return computeLighting(vec4(texture1D(\
729  \n in_colorTransferFunc2,\
730  \n scalar[component]).xyz,\
731  \n computeOpacity(scalar, component)));\
732  \n }\
733  \n if (component == 3)\
734  \n {\
735  \n return computeLighting(vec4(texture1D(\
736  \n in_colorTransferFunc3,\
737  \n scalar[component]).xyz,\
738  \n computeOpacity(scalar, component)));\
739  \n }\
740  \n }");
741 
742  return shaderStr;
743  }
744 
745  return std::string("\
746  \nvec4 computeColor(vec4 scalar)\
747  \n {\
748  \n return computeLighting(vec4(scalar.xyz, computeOpacity(scalar)));\
749  \n }");
750  }
751 
752  //--------------------------------------------------------------------------
754  vtkVolumeMapper* vtkNotUsed(mapper),
755  vtkVolume* vtkNotUsed(vol),
756  int noOfComponents,
757  int independentComponents,
758  std::map<int, std::string> opacityTableMap)
759  {
760  if (noOfComponents > 1 && independentComponents)
761  {
762  std::string shaderStr;
763  for (int i = 0; i < noOfComponents; ++i)
764  {
765  shaderStr += std::string("\n uniform sampler1D ") +
766  opacityTableMap[i] + std::string(";");
767  }
768 
769  shaderStr += std::string("\
770  \nfloat computeOpacity(vec4 scalar, int component)\
771  \n {\
772  \n if (component == 0)\
773  \n {\
774  \n return texture1D(in_opacityTransferFunc,\
775  \n scalar[component]).w;\
776  \n }\
777  \n if (component == 1)\
778  \n {\
779  \n return texture1D(in_opacityTransferFunc1,\
780  \n scalar[component]).w;\
781  \n }\
782  \n if (component == 2)\
783  \n {\
784  \n return texture1D(in_opacityTransferFunc2,\
785  \n scalar[component]).w;\
786  \n }\
787  \n if (component == 3)\
788  \n {\
789  \n return texture1D(in_opacityTransferFunc3,\
790  \n scalar[component]).w;\
791  \n }\
792  \n }");
793 
794  return shaderStr;
795  }
796  else
797  {
798  return std::string("\
799  \nuniform sampler1D in_opacityTransferFunc;\
800  \nfloat computeOpacity(vec4 scalar)\
801  \n {\
802  \n return texture1D(in_opacityTransferFunc, scalar.w).w;\
803  \n }");
804  }
805  }
806 
807  //--------------------------------------------------------------------------
809  vtkVolumeMapper* vtkNotUsed(mapper),
810  vtkVolume* vtkNotUsed(vol))
811  {
812  return std::string();
813  }
814 
815  //--------------------------------------------------------------------------
817  vtkVolumeMapper* vtkNotUsed(mapper),
818  vtkVolume* vtkNotUsed(vol))
819  {
820  return std::string();
821  }
822 
823  //--------------------------------------------------------------------------
825  vtkVolumeMapper* mapper,
826  vtkVolume* vtkNotUsed(vol))
827  {
829  {
830  return std::string("\
831  \n // We get data between 0.0 - 1.0 range\
832  \n bool l_firstValue = true;\
833  \n vec4 l_maxValue = vec4(0.0);"
834  );
835  }
837  {
838  return std::string("\
839  \n //We get data between 0.0 - 1.0 range\
840  \n bool l_firstValue = true;\
841  \n vec4 l_minValue = vec4(1.0);"
842  );
843  }
844  else if (mapper->GetBlendMode() == vtkVolumeMapper::ADDITIVE_BLEND)
845  {
846  return std::string("\
847  \n //We get data between 0.0 - 1.0 range\
848  \n float l_sumValue = 0.0;"
849  );
850  }
851  else
852  {
853  return std::string();
854  }
855  }
856 
857  //--------------------------------------------------------------------------
859  vtkVolumeMapper* mapper,
860  vtkVolume* vtkNotUsed(vol),
861  vtkImageData* maskInput,
862  vtkVolumeMask* mask, int maskType,
863  int noOfComponents,
864  int independentComponents = 0)
865  {
866  std::string shaderStr = std::string("\
867  \n if (!l_skip)\
868  \n {"
869  );
870 
872  {
873  if (noOfComponents == 4)
874  {
875  shaderStr += std::string("\
876  \n vec4 scalar = texture3D(in_volume, g_dataPos);\
877  \n if (l_maxValue.w < scalar.w || l_firstValue)\
878  \n {\
879  \n l_maxValue = scalar;\
880  \n }\
881  \n\
882  \n if (l_firstValue)\
883  \n {\
884  \n l_firstValue = false;\
885  \n }"
886  );
887  }
888  else
889  {
890  shaderStr += std::string("\
891  \n vec4 scalar = texture3D(in_volume, g_dataPos);\
892  \n if (l_maxValue.w < scalar.x || l_firstValue)\
893  \n {\
894  \n l_maxValue.w = scalar.x;\
895  \n }\
896  \n\
897  \n if (l_firstValue)\
898  \n {\
899  \n l_firstValue = false;\
900  \n }"
901  );
902  }
903  }
905  {
906  if (noOfComponents == 4)
907  {
908  shaderStr += std::string("\
909  \n vec4 scalar = texture3D(in_volume, g_dataPos);\
910  \n if (l_minValue.w > scalar.w || l_firstValue)\
911  \n {\
912  \n l_minValue = scalar;\
913  \n }\
914  \n\
915  \n if (l_firstValue)\
916  \n {\
917  \n l_firstValue = false;\
918  \n }"
919  );
920  }
921  else
922  {
923  shaderStr += std::string("\
924  \n vec4 scalar = texture3D(in_volume, g_dataPos);\
925  \n if (l_minValue.w > scalar.x || l_firstValue)\
926  \n {\
927  \n l_minValue.w = scalar.x;\
928  \n }\
929  \n\
930  \n if (l_firstValue)\
931  \n {\
932  \n l_firstValue = false;\
933  \n }"
934  );
935  }
936  }
937  else if (mapper->GetBlendMode() == vtkVolumeMapper::ADDITIVE_BLEND)
938  {
939  shaderStr += std::string("\
940  \n vec4 scalar = texture3D(in_volume, g_dataPos);\
941  \n float opacity = computeOpacity(scalar);\
942  \n l_sumValue = l_sumValue + opacity * scalar.x;"
943  );
944  }
945  else if (mapper->GetBlendMode() == vtkVolumeMapper::COMPOSITE_BLEND)
946  {
947  if (noOfComponents > 1 && independentComponents)
948  {
949  shaderStr += std::string("\
950  \n vec4 color[4]; vec4 tmp = vec4(0.0);\
951  \n float totalAlpha = 0.0;\
952  \n vec4 scalar = texture3D(in_volume, g_dataPos);\
953  \n for (int i = 0; i < in_noOfComponents; ++i)\
954  \n {\
955  ");
956  if (!mask || !maskInput ||
958  {
959  shaderStr += std::string("\
960  \n // Data fetching from the red channel of volume texture\
961  \n color[i] = vec4(computeColor(scalar, i));\
962  \n totalAlpha += color[i][3] * in_componentWeight[i];\
963  \n }\
964  \n if (totalAlpha > 0.0)\
965  \n {\
966  \n for (int i = 0; i < in_noOfComponents; ++i)\
967  \n {\
968  \n tmp.x += color[i].x * color[i].w * in_componentWeight[i] ;\
969  \n tmp.y += color[i].y * color[i].w * in_componentWeight[i];\
970  \n tmp.z += color[i].z * color[i].w * in_componentWeight[i];\
971  \n tmp.w += ((color[i].w * color[i].w)/totalAlpha);\
972  \n }\
973  \n }\
974  \n g_fragColor = (1.0f - g_fragColor.a) * tmp + g_fragColor;"
975  );
976  }
977  }
978  else
979  {
980  if (!mask || !maskInput ||
982  {
983  shaderStr += std::string("\
984  \n // Data fetching from the red channel of volume texture\
985  \n vec4 scalar = texture3D(in_volume, g_dataPos);\
986  \n vec4 g_srcColor = computeColor(scalar);"
987  );
988  }
989 
990  shaderStr += std::string("\
991  \n // Opacity calculation using compositing:\
992  \n // here we use front to back compositing scheme whereby the current\
993  \n // sample value is multiplied to the currently accumulated alpha\
994  \n // and then this product is subtracted from the sample value to\
995  \n // get the alpha from the previous steps.\
996  \n // Next, this alpha is multiplied with the current sample colour\
997  \n // and accumulated to the composited colour. The alpha value from\
998  \n // the previous steps is then accumulated to the composited colour\
999  \n // alpha.\
1000  \n g_srcColor.rgb *= g_srcColor.a;\
1001  \n g_fragColor = (1.0f - g_fragColor.a) * g_srcColor + g_fragColor;"
1002  );
1003  }
1004  }
1005  else
1006  {
1007  shaderStr += std::string();
1008  }
1009 
1010  shaderStr += std::string("\
1011  \n }"
1012  );
1013  return shaderStr;
1014  }
1015 
1016  //--------------------------------------------------------------------------
1018  vtkVolumeMapper* mapper,
1019  vtkVolume* vtkNotUsed(vol),
1020  int noOfComponents,
1021  int independentComponents = 0)
1022  {
1024  {
1025  if (noOfComponents > 1 && independentComponents)
1026  {
1027  return std::string("\
1028  \n vec4 g_srcColor = vec4(0);\
1029  \n for (int i = 0; i < in_noOfComponents; ++i)\
1030  \n {\
1031  \n vec4 tmp = computeColor(l_maxValue, i);\
1032  \n g_srcColor[0] += tmp[0] * tmp[3] * in_componentWeight[i];\
1033  \n g_srcColor[1] += tmp[1] * tmp[3] * in_componentWeight[i];\
1034  \n g_srcColor[2] += tmp[2] * tmp[3] * in_componentWeight[i];\
1035  \n g_srcColor[3] += tmp[3] * in_componentWeight[i];\
1036  \n }\
1037  \n g_fragColor = g_srcColor;"
1038  );
1039  }
1040  else
1041  {
1042  return std::string("\
1043  \n vec4 g_srcColor = vec4(computeColor(l_maxValue).xyz,\
1044  \n computeOpacity(l_maxValue));\
1045  \n g_fragColor.rgb = g_srcColor.rgb * g_srcColor.a;\
1046  \n g_fragColor.a = g_srcColor.a;"
1047  );
1048  }
1049  }
1051  {
1052  if (noOfComponents > 1 && independentComponents)
1053  {
1054  return std::string("\
1055  \n vec4 g_srcColor = vec4(0);\
1056  \n for (int i = 0; i < in_noOfComponents; ++i)\
1057  \n {\
1058  \n vec4 tmp = computeColor(l_minValue, i);\
1059  \n g_srcColor[0] += tmp[0] * tmp[3] * in_componentWeight[i];\
1060  \n g_srcColor[1] += tmp[1] * tmp[3] * in_componentWeight[i];\
1061  \n g_srcColor[2] += tmp[2] * tmp[3] * in_componentWeight[i];\
1062  \n g_srcColor[2] += tmp[3] * tmp[3] * in_componentWeight[i];\
1063  \n }\
1064  \n g_fragColor = g_srcColor;"
1065  );
1066  }
1067  else
1068  {
1069  return std::string("\
1070  \n vec4 g_srcColor = vec4(computeColor(l_minValue).xyz,\
1071  \n computeOpacity(l_minValue));\
1072  \n g_fragColor.rgb = g_srcColor.rgb * g_srcColor.a;\
1073  \n g_fragColor.a = g_srcColor.a;"
1074  );
1075  }
1076  }
1077  else if (mapper->GetBlendMode() == vtkVolumeMapper::ADDITIVE_BLEND)
1078  {
1079  return std::string("\
1080  \n l_sumValue = clamp(l_sumValue, 0.0, 1.0);\
1081  \n g_fragColor = vec4(vec3(l_sumValue), 1.0);"
1082  );
1083  }
1084  else
1085  {
1086  return std::string();
1087  }
1088  }
1089 
1090  //--------------------------------------------------------------------------
1092  vtkVolumeMapper* vtkNotUsed(mapper),
1093  vtkVolume* vtkNotUsed(vol))
1094  {
1095  return std::string();
1096  }
1097 
1098  //--------------------------------------------------------------------------
1100  vtkVolumeMapper* vtkNotUsed(mapper),
1101  vtkVolume* vtkNotUsed(vol))
1102  {
1103  return std::string();
1104  }
1105 
1106  //--------------------------------------------------------------------------
1108  vtkVolumeMapper* vtkNotUsed(mapper),
1109  vtkVolume* vtkNotUsed(vol))
1110  {
1111  return std::string("\
1112  \n // Minimum texture access coordinate\
1113  \n const vec3 l_tex_min = vec3(0);\
1114  \n\
1115  \n // Maximum texture access coordinate\
1116  \n const vec3 l_tex_max = vec3(1);\
1117  \n\
1118  \n // Flag to indicate if the raymarch loop should terminate \
1119  \n bool stop = false;\
1120  \n\
1121  \n // 2D Texture fragment coordinates [0,1] from fragment coordinates \
1122  \n // the frame buffer texture has the size of the plain buffer but \
1123  \n // we use a fraction of it. The texture coordinates is less than 1 if \
1124  \n // the reduction factor is less than 1. \
1125  \n // Device coordinates are between -1 and 1. We need texture \
1126  \n // coordinates between 0 and 1 the in_depthSampler buffer has the \
1127  \n // original size buffer. \
1128  \n vec2 fragTexCoord = (gl_FragCoord.xy - in_windowLowerLeftCorner) *\
1129  \n in_inverseWindowSize;\
1130  \n vec4 l_depthValue = texture2D(in_depthSampler, fragTexCoord);\
1131  \n float l_terminatePointMax = 0.0;\
1132  \n\
1133  \n // Depth test\
1134  \n if(gl_FragCoord.z >= l_depthValue.x)\
1135  \n {\
1136  \n discard;\
1137  \n }\
1138  \n\
1139  \n // color buffer or max scalar buffer have a reduced size.\
1140  \n fragTexCoord = (gl_FragCoord.xy - in_windowLowerLeftCorner) *\
1141  \n in_inverseOriginalWindowSize;\
1142  \n\
1143  \n // Compute max number of iterations it will take before we hit\
1144  \n // the termination point\
1145  \n\
1146  \n // Abscissa of the point on the depth buffer along the ray.\
1147  \n // point in texture coordinates\
1148  \n vec4 terminatePoint;\
1149  \n terminatePoint.x = (gl_FragCoord.x - in_windowLowerLeftCorner.x) * 2.0 *\
1150  \n in_inverseWindowSize.x - 1.0;\
1151  \n terminatePoint.y = (gl_FragCoord.y - in_windowLowerLeftCorner.y) * 2.0 *\
1152  \n in_inverseWindowSize.y - 1.0;\
1153  \n terminatePoint.z = (2.0 * l_depthValue.x - (gl_DepthRange.near +\
1154  \n gl_DepthRange.far)) / gl_DepthRange.diff;\
1155  \n terminatePoint.w = 1.0;\
1156  \n\
1157  \n // From normalized device coordinates to eye coordinates.\
1158  \n // in_projectionMatrix is inversed because of way VT\
1159  \n // From eye coordinates to texture coordinates\
1160  \n terminatePoint = in_inverseTextureDatasetMatrix *\
1161  \n in_inverseVolumeMatrix *\
1162  \n in_inverseModelViewMatrix *\
1163  \n in_inverseProjectionMatrix *\
1164  \n terminatePoint;\
1165  \n terminatePoint /= terminatePoint.w;\
1166  \n\
1167  \n l_terminatePointMax = length(terminatePoint.xyz - g_dataPos.xyz) /\
1168  \n length(g_dirStep);\
1169  \n float l_currentT = 0.0;");
1170  }
1171 
1172  //--------------------------------------------------------------------------
1174  vtkVolumeMapper* vtkNotUsed(mapper),
1175  vtkVolume* vtkNotUsed(vol))
1176  {
1177  return std::string("\
1178  \n // The two constants l_tex_min and l_tex_max have a value of\
1179  \n // vec3(-1,-1,-1) and vec3(1,1,1) respectively. To determine if the\
1180  \n // data value is outside the in_volume data, we use the sign function.\
1181  \n // The sign function return -1 if the value is less than 0, 0 if the\
1182  \n // value is equal to 0 and 1 if value is greater than 0. Hence, the\
1183  \n // sign function for the calculation (sign(g_dataPos-l_tex_min) and\
1184  \n // sign (l_tex_max-g_dataPos)) will give us vec3(1,1,1) at the\
1185  \n // possible minimum and maximum position.\
1186  \n // When we do a dot product between two vec3(1,1,1) we get answer 3.\
1187  \n // So to be within the dataset limits, the dot product will return a\
1188  \n // value less than 3. If it is greater than 3, we are already out of\
1189  \n // the in_volume dataset\
1190  \n stop = dot(sign(g_dataPos - l_tex_min), sign(l_tex_max - g_dataPos))\
1191  \n < 3.0;\
1192  \n\
1193  \n // If the stopping condition is true we brek out of the ray marching\
1194  \n // loop\
1195  \n if (stop)\
1196  \n {\
1197  \n break;\
1198  \n }\
1199  \n // Early ray termination\
1200  \n // if the currently composited colour alpha is already fully saturated\
1201  \n // we terminated the loop or if we have hit an obstacle in the\
1202  \n // direction of they ray (using depth buffer) we terminate as well.\
1203  \n if((g_fragColor.a > (1 - 1/255.0)) || \
1204  \n l_currentT >= l_terminatePointMax)\
1205  \n {\
1206  \n break;\
1207  \n }\
1208  \n ++l_currentT;"
1209  );
1210  }
1211 
1212  //--------------------------------------------------------------------------
1214  vtkVolumeMapper* vtkNotUsed(mapper),
1215  vtkVolume* vtkNotUsed(vol))
1216  {
1217  return std::string();
1218  }
1219 
1220  //--------------------------------------------------------------------------
1222  vtkVolumeMapper* vtkNotUsed(mapper),
1223  vtkVolume* vtkNotUsed(vol))
1224  {
1225  return std::string();
1226  }
1227 
1228  //--------------------------------------------------------------------------
1230  vtkVolumeMapper* mapper,
1231  vtkVolume* vtkNotUsed(vol))
1232  {
1233  if (!mapper->GetCropping()) {
1234  return std::string();
1235  }
1236 
1237  return std::string("\
1238  \nuniform float cropping_planes[6];\
1239  \nuniform int cropping_flags [32];\
1240  \n// X: axis = 0, Y: axis = 1, Z: axis = 2\
1241  \n// cp Cropping plane bounds (minX, maxX, minY, maxY, minZ, maxZ)\
1242  \nint computeRegionCoord(float cp[6], vec3 pos, int axis)\
1243  \n {\
1244  \n int cpmin = axis * 2;\
1245  \n int cpmax = cpmin + 1;\
1246  \n\
1247  \n if (pos[axis] < cp[cpmin])\
1248  \n {\
1249  \n return 1;\
1250  \n }\
1251  \n else if (pos[axis] >= cp[cpmin] &&\
1252  \n pos[axis] < cp[cpmax])\
1253  \n {\
1254  \n return 2;\
1255  \n }\
1256  \n else if (pos[axis] >= cp[cpmax])\
1257  \n {\
1258  \n return 3;\
1259  \n }\
1260  \n return 0;\
1261  \n }\
1262  \n\
1263  \nint computeRegion(float cp[6], vec3 pos)\
1264  \n {\
1265  \n return (computeRegionCoord(cp, pos, 0) +\
1266  \n (computeRegionCoord(cp, pos, 1) - 1) * 3 +\
1267  \n (computeRegionCoord(cp, pos, 2) - 1) * 9);\
1268  \n }"
1269  );
1270  }
1271 
1272  //--------------------------------------------------------------------------
1274  vtkVolumeMapper* mapper,
1275  vtkVolume* vtkNotUsed(vol))
1276  {
1277  if (!mapper->GetCropping()) {
1278  return std::string();
1279  }
1280 
1281  return std::string("\
1282  \n // Convert cropping region to texture space\
1283  \n float cropping_planes_ts[6];\
1284  \n mat4 datasetToTextureMat = in_inverseTextureDatasetMatrix;\
1285  \n vec4 temp = vec4(cropping_planes[0], cropping_planes[1], 0.0, 1.0);\
1286  \n temp = datasetToTextureMat * temp;\
1287  \n if (temp[3] != 0.0)\
1288  \n {\
1289  \n temp[0] /= temp[3]; temp[1] /= temp[3];\
1290  \n }\
1291  \n cropping_planes_ts[0] = temp[0];\
1292  \n cropping_planes_ts[1] = temp[1];\
1293  \n\
1294  \n temp = vec4(cropping_planes[2], cropping_planes[3], 0.0, 1.0);\
1295  \n temp = datasetToTextureMat * temp;\
1296  \n if (temp[3] != 0.0)\
1297  \n {\
1298  \n temp[0] /= temp[3]; temp[1] /= temp[3];\
1299  \n }\
1300  \n cropping_planes_ts[2] = temp[0];\
1301  \n cropping_planes_ts[3] = temp[1];\
1302  \n\
1303  \n temp = vec4(cropping_planes[4], cropping_planes[5], 0.0, 1.0);\
1304  \n temp = datasetToTextureMat * temp;\
1305  \n if (temp[3] != 0.0)\
1306  \n {\
1307  \n temp[0] /= temp[3]; temp[1] /= temp[3];\
1308  \n }\
1309  \n cropping_planes_ts[4] = temp[0];\
1310  \n cropping_planes_ts[5] = temp[1];"
1311  );
1312  }
1313 
1314  //--------------------------------------------------------------------------
1316  vtkVolumeMapper* mapper,
1317  vtkVolume* vtkNotUsed(vol))
1318  {
1319  if (!mapper->GetCropping()) {
1320  return std::string();
1321  }
1322 
1323  return std::string("\
1324  \n // Determine region\
1325  \n int regionNo = computeRegion(cropping_planes_ts, g_dataPos);\
1326  \n\
1327  \n // Do & operation with cropping flags\
1328  \n // Pass the flag that its Ok to sample or not to sample\
1329  \n if (cropping_flags[regionNo] == 0)\
1330  \n {\
1331  \n // Skip this voxel\
1332  \n l_skip = true;\
1333  \n }"
1334  );
1335  }
1336 
1337  //--------------------------------------------------------------------------
1339  vtkVolumeMapper* vtkNotUsed(mapper),
1340  vtkVolume* vtkNotUsed(vol))
1341  {
1342  return std::string();
1343  }
1344 
1345  //--------------------------------------------------------------------------
1347  vtkVolumeMapper* vtkNotUsed(mapper),
1348  vtkVolume* vtkNotUsed(vol))
1349  {
1350  return std::string();
1351  }
1352 
1353  //--------------------------------------------------------------------------
1355  vtkVolumeMapper* vtkNotUsed(mapper),
1356  vtkVolume* vtkNotUsed(vol))
1357  {
1358  return std::string();
1359  }
1360 
1361  //--------------------------------------------------------------------------
1363  vtkVolumeMapper* mapper,
1364  vtkVolume* vtkNotUsed(vol))
1365  {
1366  if (!mapper->GetClippingPlanes())
1367  {
1368  return std::string();
1369  }
1370  else
1371  {
1372  return std::string("\
1373  \nfloat clippingPlanesTexture[48];\
1374  \nint clippingPlanesSize = int(in_clippingPlanes[0]);\
1375  \n\
1376  \nmat4 world_to_texture_mat = in_inverseTextureDatasetMatrix *\
1377  \n in_inverseVolumeMatrix;\
1378  \nfor (int i = 0; i < clippingPlanesSize; i = i + 6)\
1379  \n {\
1380  \n vec4 origin = vec4(in_clippingPlanes[i + 1],\
1381  \n in_clippingPlanes[i + 2],\
1382  \n in_clippingPlanes[i + 3], 1.0);\
1383  \n vec4 normal = vec4(in_clippingPlanes[i + 4],\
1384  \n in_clippingPlanes[i + 5],\
1385  \n in_clippingPlanes[i + 6], 0.0);\
1386  \n\
1387  \n origin = world_to_texture_mat * origin;\
1388  \n normal = world_to_texture_mat * normal;\
1389  \n\
1390  \n if (origin[3] != 0.0)\
1391  \n {\
1392  \n origin[0] = origin[0] / origin[3];\
1393  \n origin[1] = origin[1] / origin[3];\
1394  \n origin[2] = origin[2] / origin[3];\
1395  \n }\
1396  \n if (normal[3] != 0.0)\
1397  \n {\
1398  \n normal[0] = normal[0] / normal[3];\
1399  \n normal[1] = normal[1] / normal[3];\
1400  \n normal[2] = normal[2] / normal[3];\
1401  \n }\
1402  \n\
1403  \n clippingPlanesTexture[i] = origin[0];\
1404  \n clippingPlanesTexture[i + 1] = origin[1];\
1405  \n clippingPlanesTexture[i + 2] = origin[2];\
1406  \n\
1407  \n clippingPlanesTexture[i + 3] = normal[0];\
1408  \n clippingPlanesTexture[i + 4] = normal[1];\
1409  \n clippingPlanesTexture[i + 5] = normal[2];\
1410  \n }"
1411  );
1412  }
1413  }
1414 
1415  //--------------------------------------------------------------------------
1417  vtkVolumeMapper* mapper,
1418  vtkVolume* vtkNotUsed(vol))
1419  {
1420  if (!mapper->GetClippingPlanes())
1421  {
1422  return std::string();
1423  }
1424  else
1425  {
1426  return std::string("\
1427  \n for (int i = 0; i < (clippingPlanesSize) && !l_skip; i = i + 6)\
1428  \n {\
1429  \n if (dot(vec3(g_dataPos - vec3(clippingPlanesTexture[i],\
1430  \n clippingPlanesTexture[i + 1],\
1431  \n clippingPlanesTexture[i + 2])),\
1432  \n vec3(clippingPlanesTexture[i + 3],\
1433  \n clippingPlanesTexture[i + 4],\
1434  \n clippingPlanesTexture[i + 5])) < 0)\
1435  \n {\
1436  \n l_skip = true;\
1437  \n break;\
1438  \n }\
1439  \n }"
1440  );
1441  }
1442  }
1443 
1444  //--------------------------------------------------------------------------
1446  vtkVolumeMapper* vtkNotUsed(mapper),
1447  vtkVolume* vtkNotUsed(vol))
1448  {
1449  return std::string();
1450  }
1451 
1452  //--------------------------------------------------------------------------
1454  vtkVolumeMapper* vtkNotUsed(mapper),
1455  vtkVolume* vtkNotUsed(vol),
1456  vtkImageData* maskInput,
1458  int vtkNotUsed(maskType))
1459  {
1460  if (!mask || !maskInput)
1461  {
1462  return std::string();
1463  }
1464  else
1465  {
1466  return std::string("uniform sampler3D in_mask;");
1467  }
1468  }
1469 
1470  //--------------------------------------------------------------------------
1472  vtkVolumeMapper* vtkNotUsed(mapper),
1473  vtkVolume* vtkNotUsed(vol),
1474  vtkImageData* maskInput,
1475  vtkVolumeMask* mask,
1476  int maskType)
1477  {
1478  if (!mask || !maskInput ||
1480  {
1481  return std::string();
1482  }
1483  else
1484  {
1485  return std::string("\
1486  \nvec4 maskValue = texture3D(in_mask, g_dataPos);\
1487  \nif(maskValue.a <= 0.0)\
1488  \n {\
1489  \n l_skip = true;\
1490  \n }"
1491  );
1492  }
1493  }
1494 
1495  //--------------------------------------------------------------------------
1497  vtkVolumeMapper* vtkNotUsed(mapper),
1498  vtkVolume* vtkNotUsed(vol),
1499  vtkImageData* maskInput,
1500  vtkVolumeMask* mask,
1501  int maskType)
1502  {
1503  if (!mask || !maskInput ||
1505  {
1506  return std::string();
1507  }
1508  else
1509  {
1510  return std::string("\
1511  \nuniform float in_maskBlendFactor;\
1512  \nuniform sampler1D in_mask1;\
1513  \nuniform sampler1D in_mask2;"
1514  );
1515  }
1516  }
1517 
1518  //--------------------------------------------------------------------------
1520  vtkVolumeMapper* vtkNotUsed(mapper),
1521  vtkVolume* vtkNotUsed(vol),
1522  vtkImageData* maskInput,
1523  vtkVolumeMask* mask,
1524  int maskType)
1525  {
1526  if (!mask || !maskInput ||
1528  {
1529  return std::string();
1530  }
1531  else
1532  {
1533  return std::string("\
1534  \nvec4 scalar = texture3D(in_volume, g_dataPos);\
1535  \nif (in_maskBlendFactor == 0.0)\
1536  \n {\
1537  \n g_srcColor = computeColor(scalar);\
1538  \n }\
1539  \nelse\
1540  \n {\
1541  \n // Get the mask value at this same location\
1542  \n vec4 maskValue = texture3D(in_mask, g_dataPos);\
1543  \n if(maskValue.a == 0.0)\
1544  \n {\
1545  \n g_srcColor = computeColor(scalar);\
1546  \n }\
1547  \n else\
1548  \n {\
1549  \n if (maskValue.a == 1.0/255.0)\
1550  \n {\
1551  \n g_srcColor = texture1D(in_mask1, scalar.w);\
1552  \n }\
1553  \n else\
1554  \n {\
1555  \n // maskValue.a == 2.0/255.0\
1556  \n g_srcColor = texture1D(in_mask2, scalar.w);\
1557  \n }\
1558  \n g_srcColor.a = 1.0;\
1559  \n if(in_maskBlendFactor < 1.0)\
1560  \n {\
1561  \n g_srcColor = (1.0 - in_maskBlendFactor) * computeColor(scalar)\
1562  \n + in_maskBlendFactor * g_srcColor;\
1563  \n }\
1564  \n }\
1565  \n g_srcColor.a = computeOpacity(scalar);\
1566  \n }"
1567  );
1568  }
1569  }
1570 }
1571 
1572 #endif // _vtkVolumeShaderComposer_h
1573 // VTK-HeaderTest-Exclude: vtkVolumeShaderComposer.h
std::string ShadingExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol), int noOfComponents, int independentComponents=0)
#define vtkNotUsed(x)
Definition: vtkSetGet.h:547
const GLint * first
Definition: vtkgl.h:11686
represents a volume (data & properties) in a rendered scene
Definition: vtkVolume.h:49
Abstract class for a volume mapper.
std::string ClippingIncrement(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol))
virtual int GetBlendMode()
GLenum GLint GLuint mask
Definition: vtkgl.h:11980
std::string ComputeTextureCoords(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string CompositeMaskGlobalsFrag(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), vtkImageData *maskInput, vtkVolumeMask *mask, int maskType)
std::string CompositeMaskIncrement(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), vtkImageData *maskInput, vtkVolumeMask *mask, int maskType)
abstract specification for renderers
Definition: vtkRenderer.h:63
std::string TerminationExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string GradientsComputeFunc(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vol, int noOfComponents, int independentComponents, std::map< int, std::string > gradientTableMap)
std::string BaseInit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string TerminationIncrement(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
virtual vtkPlaneCollection * GetClippingPlanes()
vtkCamera * GetActiveCamera()
std::string CroppingGlobalsFrag(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol))
std::string BaseGlobalsVert(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
int GetShade(int index)
std::string CroppingGlobalsVert(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string BinaryMaskIncrement(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), vtkImageData *maskInput, vtkVolumeMask *mask, int maskType)
std::string TerminationInit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ClippingExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string RayDirectionFunc(vtkRenderer *ren, vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), int vtkNotUsed(noOfComponents))
topologically and geometrically regular array of data
Definition: vtkImageData.h:44
std::string ClippingGlobalsVert(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
bool HasGradientOpacity(int index=0)
std::string ColorTransferFunc(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), int noOfComponents, int independentComponents, std::map< int, std::string > colorTableMap)
std::string ShadingGlobalsFrag(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ShadingGlobalsVert(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string OpacityTransferFunc(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), int noOfComponents, int independentComponents, std::map< int, std::string > opacityTableMap)
std::string CroppingIncrement(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol))
virtual int GetParallelProjection()
std::string BaseIncrement(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
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 ClippingGlobalsFrag(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string TerminationGlobalsVert(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string ClippingInit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol))
boost::graph_traits< vtkGraph * >::vertex_descriptor source(boost::graph_traits< vtkGraph * >::edge_descriptor e, vtkGraph *)
std::string ShadingIncrement(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol), vtkImageData *maskInput, vtkVolumeMask *mask, int maskType, int noOfComponents, int independentComponents=0)
std::string CroppingInit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *mapper, vtkVolume *vtkNotUsed(vol))
vtkVolumeProperty * GetProperty()
virtual int GetCropping()
std::string replace(std::string source, const std::string &search, const std::string replace, bool all)
std::string TerminationGlobalsFrag(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string BaseGlobalsFrag(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), int vtkNotUsed(numberOfLights), int lightingComplexity, int noOfComponents, int independentComponents)
std::string BaseExit(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
GLsizei const GLchar ** string
Definition: vtkgl.h:12011
std::string LightComputeFunc(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vol, int noOfComponents, int independentComponents, int vtkNotUsed(numberOfLights), int lightingComplexity)
std::string ComputeClip(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol))
std::string BinaryMaskGlobalsFrag(vtkRenderer *vtkNotUsed(ren), vtkVolumeMapper *vtkNotUsed(mapper), vtkVolume *vtkNotUsed(vol), vtkImageData *maskInput, vtkVolumeMask *mask, int vtkNotUsed(maskType))