VTK
|
00001 /*========================================================================= 00002 00003 Program: Visualization Toolkit 00004 Module: vtkVolumeShaderComposer.h 00005 00006 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 00007 All rights reserved. 00008 See Copyright.txt or http://www.kitware.com/Copyright.htm for details. 00009 00010 This software is distributed WITHOUT ANY WARRANTY; without even 00011 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00012 PURPOSE. See the above copyright notice for more information. 00013 00014 =========================================================================*/ 00015 00016 #ifndef _vtkVolumeShaderComposer_h 00017 #define _vtkVolumeShaderComposer_h 00018 00019 #include "vtkVolumeMask.h" 00020 00021 #include <vtkCamera.h> 00022 #include <vtkRenderer.h> 00023 #include <vtkVolume.h> 00024 #include <vtkVolumeMapper.h> 00025 #include <vtkVolumeProperty.h> 00026 00027 #include <map> 00028 #include <string> 00029 00030 namespace vtkvolume 00031 { 00032 //-------------------------------------------------------------------------- 00033 std::string replace(std::string source, const std::string &search, 00034 const std::string replace, bool all) 00035 { 00036 std::string::size_type pos = 0; 00037 bool first = true; 00038 while ((pos = source.find(search, 0)) != std::string::npos) 00039 { 00040 source.replace(pos, search.length(), replace); 00041 pos += search.length(); 00042 if (first) 00043 { 00044 first = false; 00045 if (!all) 00046 { 00047 return source; 00048 } 00049 } 00050 } 00051 return source; 00052 } 00053 00054 //-------------------------------------------------------------------------- 00055 std::string ComputeClip(vtkRenderer* vtkNotUsed(ren), 00056 vtkVolumeMapper* vtkNotUsed(mapper), 00057 vtkVolume* vtkNotUsed(vol)) 00058 { 00059 return std::string("\ 00060 \n vec4 pos = in_projectionMatrix * in_modelViewMatrix *\ 00061 \n in_volumeMatrix * vec4(in_vertexPos.xyz, 1.0);\ 00062 \n gl_Position = pos;" 00063 ); 00064 } 00065 00066 //-------------------------------------------------------------------------- 00067 std::string ComputeTextureCoords(vtkRenderer* vtkNotUsed(ren), 00068 vtkVolumeMapper* vtkNotUsed(mapper), 00069 vtkVolume* vtkNotUsed(vol)) 00070 { 00071 return std::string( 00072 "\n // Assuming point data only. Also, we offset the texture coordinate\ 00073 \n // to account for OpenGL treating voxel at the center of the cell.\ 00074 \n vec3 uvx = (in_vertexPos - in_volumeExtentsMin) /\ 00075 \n (in_volumeExtentsMax - in_volumeExtentsMin);\ 00076 \n vec3 delta = in_textureExtentsMax - in_textureExtentsMin;\ 00077 \n ip_textureCoords = (uvx * (delta - vec3(1.0)) + vec3(0.5)) / delta;" 00078 ); 00079 } 00080 00081 //-------------------------------------------------------------------------- 00082 std::string BaseGlobalsVert(vtkRenderer* vtkNotUsed(ren), 00083 vtkVolumeMapper* vtkNotUsed(mapper), 00084 vtkVolume* vtkNotUsed(vol)) 00085 { 00086 return std::string("\ 00087 \n uniform mat4 in_modelViewMatrix;\ 00088 \n uniform mat4 in_projectionMatrix;\ 00089 \n uniform mat4 in_volumeMatrix;\ 00090 \n\ 00091 \n uniform vec3 in_volumeExtentsMin;\ 00092 \n uniform vec3 in_volumeExtentsMax;\ 00093 \n\ 00094 \n uniform vec3 in_textureExtentsMax;\ 00095 \n uniform vec3 in_textureExtentsMin;" 00096 ); 00097 } 00098 00099 //-------------------------------------------------------------------------- 00100 std::string BaseGlobalsFrag(vtkRenderer* vtkNotUsed(ren), 00101 vtkVolumeMapper* vtkNotUsed(mapper), 00102 vtkVolume* vtkNotUsed(vol), 00103 int vtkNotUsed(numberOfLights), 00104 int lightingComplexity, 00105 int noOfComponents, 00106 int independentComponents) 00107 { 00108 std::string shaderStr = std::string("\ 00109 \n// Volume dataset\ 00110 \nuniform sampler3D in_volume;\ 00111 \nuniform int in_noOfComponents;\ 00112 \nuniform int in_independentComponents;\ 00113 \n\ 00114 \nuniform sampler2D in_noiseSampler;\ 00115 \nuniform sampler2D in_depthSampler;\ 00116 \n\ 00117 \n// Camera position\ 00118 \nuniform vec3 in_cameraPos;\ 00119 \n\ 00120 \n// view and model matrices\ 00121 \nuniform mat4 in_volumeMatrix;\ 00122 \nuniform mat4 in_inverseVolumeMatrix;\ 00123 \nuniform mat4 in_projectionMatrix;\ 00124 \nuniform mat4 in_inverseProjectionMatrix;\ 00125 \nuniform mat4 in_modelViewMatrix;\ 00126 \nuniform mat4 in_inverseModelViewMatrix;\ 00127 \nuniform mat4 in_textureDatasetMatrix;\ 00128 \nuniform mat4 in_inverseTextureDatasetMatrix;\ 00129 \nuniform mat3 in_texureToEyeIt;\ 00130 \n\ 00131 \n// Ray step size\ 00132 \nuniform vec3 in_cellStep;\ 00133 \nuniform vec2 in_scalarsRange;\ 00134 \nuniform vec3 in_cellSpacing;\ 00135 \n\ 00136 \n// Sample distance\ 00137 \nuniform float in_sampleDistance;\ 00138 \n\ 00139 \n// Scales\ 00140 \nuniform vec3 in_cellScale;\ 00141 \nuniform vec2 in_windowLowerLeftCorner;\ 00142 \nuniform vec2 in_inverseOriginalWindowSize;\ 00143 \nuniform vec2 in_inverseWindowSize;\ 00144 \nuniform vec3 in_textureExtentsMax;\ 00145 \nuniform vec3 in_textureExtentsMin;\ 00146 \nuniform float in_volumeScale;\ 00147 \nuniform float in_volumeBias;\ 00148 \n\ 00149 \n// Material and lighting\ 00150 \nuniform vec3 in_diffuse;\ 00151 \nuniform vec3 in_ambient;\ 00152 \nuniform vec3 in_specular;\ 00153 \nuniform float in_shininess;\ 00154 "); 00155 00156 if (lightingComplexity > 0) 00157 { 00158 shaderStr += std::string("\ 00159 \nuniform bool in_twoSidedLighting;" 00160 ); 00161 } 00162 00163 if (lightingComplexity == 3) 00164 { 00165 shaderStr += std::string("\ 00166 \nuniform int in_numberOfLights;\ 00167 \nuniform vec3 in_lightAmbientColor[6];\ 00168 \nuniform vec3 in_lightDiffuseColor[6];\ 00169 \nuniform vec3 in_lightSpecularColor[6];\ 00170 \nuniform vec3 in_lightDirection[6];\ 00171 \nuniform vec3 in_lightPosition[6];\ 00172 \nuniform vec3 in_lightAttenuation[6];\ 00173 \nuniform float in_lightConeAngle[6];\ 00174 \nuniform float in_lightExponent[6];\ 00175 \nuniform int in_lightPositional[6];\ 00176 "); 00177 } 00178 else if (lightingComplexity == 2) 00179 { 00180 shaderStr += std::string("\ 00181 \nuniform int in_numberOfLights;\ 00182 \nuniform vec3 in_lightAmbientColor[6];\ 00183 \nuniform vec3 in_lightDiffuseColor[6];\ 00184 \nuniform vec3 in_lightSpecularColor[6];\ 00185 \nuniform vec3 in_lightDirection[6];\ 00186 "); 00187 } 00188 else 00189 { 00190 shaderStr += std::string("\ 00191 \nuniform vec3 in_lightAmbientColor[1];\ 00192 \nuniform vec3 in_lightDiffuseColor[1];\ 00193 \nuniform vec3 in_lightSpecularColor[1];\ 00194 "); 00195 } 00196 00197 if (noOfComponents > 1 && independentComponents) 00198 { 00199 shaderStr += std::string("\ 00200 \nuniform vec4 in_componentWeight;"); 00201 } 00202 00203 return shaderStr; 00204 } 00205 00206 //-------------------------------------------------------------------------- 00207 std::string BaseInit(vtkRenderer* vtkNotUsed(ren), 00208 vtkVolumeMapper* vtkNotUsed(mapper), 00209 vtkVolume* vtkNotUsed(vol)) 00210 { 00211 return std::string("\ 00212 \n // Get the 3D texture coordinates for lookup into the in_volume dataset\ 00213 \n g_dataPos = ip_textureCoords.xyz;\ 00214 \n\ 00215 \n // Eye position in object space\ 00216 \n g_eyePosObj = (in_inverseVolumeMatrix * vec4(in_cameraPos, 1.0));\ 00217 \n if (g_eyePosObj.w != 0.0)\ 00218 \n {\ 00219 \n g_eyePosObj.x /= g_eyePosObj.w;\ 00220 \n g_eyePosObj.y /= g_eyePosObj.w;\ 00221 \n g_eyePosObj.z /= g_eyePosObj.w;\ 00222 \n g_eyePosObj.w = 1.0;\ 00223 \n }\ 00224 \n\ 00225 \n // Getting the ray marching direction (in object space);\ 00226 \n vec3 rayDir = computeRayDirection();\ 00227 \n\ 00228 \n // Multiply the raymarching direction with the step size to get the\ 00229 \n // sub-step size we need to take at each raymarching step\ 00230 \n g_dirStep = (in_inverseTextureDatasetMatrix *\ 00231 \n vec4(rayDir, 0.0)).xyz * in_sampleDistance;\ 00232 \n\ 00233 \n g_dataPos += g_dirStep * (texture2D(in_noiseSampler, g_dataPos.xy).x);\ 00234 \n\ 00235 \n // Flag to deternmine if voxel should be considered for the rendering\ 00236 \n bool l_skip = false;"); 00237 } 00238 00239 //-------------------------------------------------------------------------- 00240 std::string BaseIncrement(vtkRenderer* vtkNotUsed(ren), 00241 vtkVolumeMapper* vtkNotUsed(mapper), 00242 vtkVolume* vtkNotUsed(vol)) 00243 { 00244 return std::string("\ 00245 \n l_skip = false;" 00246 ); 00247 } 00248 00249 //-------------------------------------------------------------------------- 00250 std::string BaseExit(vtkRenderer* vtkNotUsed(ren), 00251 vtkVolumeMapper* vtkNotUsed(mapper), 00252 vtkVolume* vtkNotUsed(vol)) 00253 { 00254 return std::string(); 00255 } 00256 00257 //-------------------------------------------------------------------------- 00258 std::string GradientsComputeFunc(vtkRenderer* vtkNotUsed(ren), 00259 vtkVolumeMapper* vtkNotUsed(mapper), 00260 vtkVolume* vol, 00261 int noOfComponents, 00262 int independentComponents, 00263 std::map<int, std::string> gradientTableMap) 00264 { 00265 std::string shaderStr; 00266 if (noOfComponents == 1 && vol->GetProperty()->HasGradientOpacity()) 00267 { 00268 shaderStr += std::string("\ 00269 \nuniform sampler1D in_gradientTransferFunc;\ 00270 \nfloat computeGradientOpacity(vec4 grad)\ 00271 \n {\ 00272 \n return texture1D(in_gradientTransferFunc, grad.w).w;\ 00273 \n }" 00274 ); 00275 } 00276 else if (noOfComponents > 1 && independentComponents && 00277 vol->GetProperty()->HasGradientOpacity()) 00278 { 00279 for (int i = 0; i < noOfComponents; ++i) 00280 { 00281 shaderStr += std::string("\n uniform sampler1D ") + 00282 gradientTableMap[i] + std::string(";"); 00283 } 00284 00285 shaderStr += std::string("\ 00286 \nfloat computeGradientOpacity(vec4 grad, int component)\ 00287 \n {\ 00288 \n if (component == 0)\ 00289 \n {\ 00290 \n return texture1D(in_gradientTransferFunc, grad.w).w;\ 00291 \n }\ 00292 \n if (component == 1)\ 00293 \n {\ 00294 \n return texture1D(in_gradientTransferFunc1, grad.w).w;\ 00295 \n }\ 00296 \n if (component == 2)\ 00297 \n {\ 00298 \n return texture1D(in_gradientTransferFunc2, grad.w).w;\ 00299 \n }\ 00300 \n if (component == 3)\ 00301 \n {\ 00302 \n return texture1D(in_gradientTransferFunc3, grad.w).w;\ 00303 \n }\ 00304 \n }" 00305 ); 00306 } 00307 00308 if (vol->GetProperty()->GetShade() && 00309 !vol->GetProperty()->HasGradientOpacity()) 00310 { 00311 shaderStr += std::string("\ 00312 \nvec4 computeGradient()\ 00313 \n {\ 00314 \n vec3 g1;\ 00315 \n vec3 g2;\ 00316 \n vec3 xvec = vec3(in_cellStep[0], 0.0, 0.0);\ 00317 \n vec3 yvec = vec3(0.0, in_cellStep[1], 0.0);\ 00318 \n vec3 zvec = vec3(0.0, 0.0, in_cellStep[2]);\ 00319 \n g1.x = texture3D(in_volume, vec3(g_dataPos + xvec)).x;\ 00320 \n g1.y = texture3D(in_volume, vec3(g_dataPos + yvec)).x;\ 00321 \n g1.z = texture3D(in_volume, vec3(g_dataPos + zvec)).x;\ 00322 \n g2.x = texture3D(in_volume, vec3(g_dataPos - xvec)).x;\ 00323 \n g2.y = texture3D(in_volume, vec3(g_dataPos - yvec)).x;\ 00324 \n g2.z = texture3D(in_volume, vec3(g_dataPos - zvec)).x;\ 00325 \n return vec4((g1 - g2), -1.0);\ 00326 \n }" 00327 ); 00328 } 00329 else if (vol->GetProperty()->GetShade() && 00330 vol->GetProperty()->HasGradientOpacity()) 00331 { 00332 shaderStr += std::string("\ 00333 \nvec4 computeGradient()\ 00334 \n {\ 00335 \n vec3 g1;\ 00336 \n vec4 g2;\ 00337 \n vec3 xvec = vec3(in_cellStep[0], 0.0, 0.0);\ 00338 \n vec3 yvec = vec3(0.0, in_cellStep[1], 0.0);\ 00339 \n vec3 zvec = vec3(0.0, 0.0, in_cellStep[2]);\ 00340 \n g1.x = texture3D(in_volume, vec3(g_dataPos + xvec)).x;\ 00341 \n g1.y = texture3D(in_volume, vec3(g_dataPos + yvec)).x;\ 00342 \n g1.z = texture3D(in_volume, vec3(g_dataPos + zvec)).x;\ 00343 \n g2.x = texture3D(in_volume, vec3(g_dataPos - xvec)).x;\ 00344 \n g2.y = texture3D(in_volume, vec3(g_dataPos - yvec)).x;\ 00345 \n g2.z = texture3D(in_volume, vec3(g_dataPos - zvec)).x;\ 00346 \n g1.x = in_scalarsRange[0] + (\ 00347 \n in_scalarsRange[1] - in_scalarsRange[0]) * g1.x;\ 00348 \n g1.y = in_scalarsRange[0] + (\ 00349 \n in_scalarsRange[1] - in_scalarsRange[0]) * g1.y;\ 00350 \n g1.z = in_scalarsRange[0] + (\ 00351 \n in_scalarsRange[1] - in_scalarsRange[0]) * g1.z;\ 00352 \n g2.x = in_scalarsRange[0] + (\ 00353 \n in_scalarsRange[1] - in_scalarsRange[0]) * g2.x;\ 00354 \n g2.y = in_scalarsRange[0] + (\ 00355 \n in_scalarsRange[1] - in_scalarsRange[0]) * g2.y;\ 00356 \n g2.z = in_scalarsRange[0] + (\ 00357 \n in_scalarsRange[1] - in_scalarsRange[0]) * g2.z;\ 00358 \n g2.xyz = g1 - g2.xyz;\ 00359 \n vec3 cellSpacing = vec3(in_cellSpacing[0],\ 00360 \n in_cellSpacing[1],\ 00361 \n in_cellSpacing[2]);\ 00362 \n vec3 aspect;\ 00363 \n float avgSpacing = (cellSpacing[0] +\ 00364 \n cellSpacing[1] +\ 00365 \n cellSpacing[2])/3.0;\ 00366 \n // Adjust the aspect\ 00367 \n aspect.x = cellSpacing[0] * 2.0 / avgSpacing;\ 00368 \n aspect.y = cellSpacing[1] * 2.0 / avgSpacing;\ 00369 \n aspect.z = cellSpacing[2] * 2.0 / avgSpacing;\ 00370 \n g2.x /= aspect.x;\ 00371 \n g2.y /= aspect.y;\ 00372 \n g2.z /= aspect.z;\ 00373 \n float grad_mag = sqrt(g2.x * g2.x +\ 00374 \n g2.y * g2.y +\ 00375 \n g2.z * g2.z);\ 00376 \n if (grad_mag > 0.0)\ 00377 \n {\ 00378 \n g2.x /= grad_mag;\ 00379 \n g2.y /= grad_mag;\ 00380 \n g2.z /= grad_mag;\ 00381 \n }\ 00382 \n else\ 00383 \n {\ 00384 \n g2.xyz = vec3(0.0, 0.0, 0.0);\ 00385 \n }\ 00386 \n grad_mag = grad_mag * 1.0 / (0.25 * (in_scalarsRange[1] -\ 00387 \n (in_scalarsRange[0])));\ 00388 \n grad_mag = clamp(grad_mag, 0.0, 1.0);\ 00389 \n g2.w = grad_mag;\ 00390 \n return g2;\ 00391 \n }" 00392 ); 00393 } 00394 else 00395 { 00396 shaderStr += std::string("\ 00397 \nvec4 computeGradient()\ 00398 \n {\ 00399 \n return vec4(0.0);\ 00400 \n }"); 00401 } 00402 00403 return shaderStr; 00404 } 00405 00406 //-------------------------------------------------------------------------- 00407 std::string LightComputeFunc(vtkRenderer* vtkNotUsed(ren), 00408 vtkVolumeMapper* vtkNotUsed(mapper), 00409 vtkVolume* vol, 00410 int noOfComponents, 00411 int independentComponents, 00412 int vtkNotUsed(numberOfLights), 00413 int lightingComplexity) 00414 { 00415 vtkVolumeProperty* volProperty = vol->GetProperty(); 00416 std::string shaderStr = std::string("\ 00417 \nvec4 computeLighting(vec4 color)\ 00418 \n {" 00419 ); 00420 00421 if (volProperty->GetShade() || volProperty->HasGradientOpacity()) 00422 { 00423 shaderStr += std::string("\ 00424 \n // Compute gradient function only once\ 00425 \n vec4 gradient = computeGradient();" 00426 ); 00427 } 00428 00429 if (volProperty->GetShade()) 00430 { 00431 if (lightingComplexity == 1) 00432 { 00433 shaderStr += std::string("\ 00434 \n // Light position in object space\ 00435 \n vec4 lightPosObj = (in_inverseVolumeMatrix *\ 00436 \n vec4(in_cameraPos, 1.0));\ 00437 \n if (lightPosObj.w != 0.0)\ 00438 \n {\ 00439 \n lightPosObj.x /= lightPosObj.w;\ 00440 \n lightPosObj.y /= lightPosObj.w;\ 00441 \n lightPosObj.z /= lightPosObj.w;\ 00442 \n lightPosObj.w = 1.0;\ 00443 \n }\ 00444 \n vec3 diffuse = vec3(0.0);\ 00445 \n vec3 specular = vec3(0.0);\ 00446 \n vec3 ldir = normalize(lightPosObj.xyz - ip_vertexPos);\ 00447 \n vec3 vdir = normalize(g_eyePosObj.xyz - ip_vertexPos);\ 00448 \n vec3 h = normalize(ldir + vdir);\ 00449 \n vec3 g2 = gradient.xyz;\ 00450 \n g2 = (1.0/in_cellSpacing) * g2;\ 00451 \n float normalLength = length(g2);\ 00452 \n if (normalLength > 0.0)\ 00453 \n {\ 00454 \n g2 = normalize(g2);\ 00455 \n }\ 00456 \n else\ 00457 \n {\ 00458 \n g2 = vec3(0.0, 0.0, 0.0);\ 00459 \n }\ 00460 \n float nDotL = dot(g2, ldir);\ 00461 \n float nDotH = dot(g2, h);\ 00462 \n if (nDotL < 0.0 && in_twoSidedLighting)\ 00463 \n {\ 00464 \n nDotL = -nDotL;\ 00465 \n }\ 00466 \n if (nDotH < 0.0 && in_twoSidedLighting)\ 00467 \n {\ 00468 \n nDotH = -nDotH;\ 00469 \n }\ 00470 \n if (nDotL > 0)\ 00471 \n {\ 00472 \n diffuse = nDotL * in_diffuse * in_lightDiffuseColor[0]\ 00473 \n * color.rgb;\ 00474 \n }\ 00475 \n if (nDotH > 0)\ 00476 \n {\ 00477 \n specular = pow(nDotH, in_shininess) * in_specular *\ 00478 \n in_lightSpecularColor[0];\ 00479 \n }\ 00480 \n // For the headlight, ignore the light's ambient color\ 00481 \n // for now as it is causing the old mapper tests to fail\ 00482 \n vec3 finalColor = (in_ambient * color.rgb +\ 00483 \n diffuse + specular);" 00484 ); 00485 } 00486 else if (lightingComplexity == 2) 00487 { 00488 shaderStr += std::string("\ 00489 \n vec4 fragWorldPos = in_modelViewMatrix * in_volumeMatrix *\ 00490 \n in_textureDatasetMatrix * vec4(-g_dataPos, 1.0);\ 00491 \n if (fragWorldPos.w != 0.0)\ 00492 \n {\ 00493 \n fragWorldPos /= fragWorldPos.w;\ 00494 \n }\ 00495 \n vec3 vdir = normalize(fragWorldPos.xyz);\ 00496 \n vec3 normal = gradient.xyz;\ 00497 \n vec3 ambient = vec3(0.0);\ 00498 \n vec3 diffuse = vec3(0.0);\ 00499 \n vec3 specular = vec3(0.0);\ 00500 \n float normalLength = length(normal);\ 00501 \n if (normalLength > 0.0)\ 00502 \n {\ 00503 \n normal = normalize(in_texureToEyeIt * normal);\ 00504 \n }\ 00505 \n else\ 00506 \n {\ 00507 \n normal = vec3(0.0, 0.0, 0.0);\ 00508 \n }\ 00509 \n for (int lightNum = 0; lightNum < in_numberOfLights; lightNum++)\ 00510 \n {\ 00511 \n vec3 ldir = in_lightDirection[lightNum].xyz;\ 00512 \n vec3 h = normalize(ldir + vdir);\ 00513 \n float nDotH = dot(normal, h);\ 00514 \n if (nDotH < 0.0 && in_twoSidedLighting)\ 00515 \n {\ 00516 \n nDotH = -nDotH;\ 00517 \n }\ 00518 \n float nDotL = dot(normal, ldir);\ 00519 \n if (nDotL < 0.0 && in_twoSidedLighting)\ 00520 \n {\ 00521 \n nDotL = -nDotL;\ 00522 \n }\ 00523 \n if (nDotL > 0)\ 00524 \n {\ 00525 \n diffuse += in_lightDiffuseColor[lightNum] * nDotL;\ 00526 \n }\ 00527 \n if (nDotH > 0)\ 00528 \n {\ 00529 \n specular = in_lightSpecularColor[lightNum] * pow(nDotH, in_shininess);\ 00530 \n }\ 00531 \n ambient += in_lightAmbientColor[lightNum];\ 00532 \n }\ 00533 \n vec3 finalColor = in_ambient * ambient +\ 00534 \n in_diffuse * diffuse * color.rgb +\ 00535 \n in_specular * specular;" 00536 ); 00537 } 00538 else if (lightingComplexity == 3) 00539 { 00540 shaderStr += std::string("\ 00541 \n vec4 fragWorldPos = in_modelViewMatrix * in_volumeMatrix *\ 00542 \n in_textureDatasetMatrix * vec4(g_dataPos, 1.0);\ 00543 \n if (fragWorldPos.w != 0.0)\ 00544 \n {\ 00545 \n fragWorldPos /= fragWorldPos.w;\ 00546 \n }\ 00547 \n vec3 viewDirection = normalize(-fragWorldPos.xyz);\ 00548 \n vec3 ambient = vec3(0,0,0);\ 00549 \n vec3 diffuse = vec3(0,0,0);\ 00550 \n vec3 specular = vec3(0,0,0);\ 00551 \n vec3 vertLightDirection;\ 00552 \n vec3 normal = normalize(in_texureToEyeIt * gradient.xyz);\ 00553 \n vec3 lightDir;\ 00554 \n for (int lightNum = 0; lightNum < in_numberOfLights; lightNum++)\ 00555 \n {\ 00556 \n float attenuation = 1.0;\ 00557 \n // directional\ 00558 \n lightDir = in_lightDirection[lightNum];\ 00559 \n if (in_lightPositional[lightNum] == 0)\ 00560 \n {\ 00561 \n vertLightDirection = lightDir;\ 00562 \n }\ 00563 \n else\ 00564 \n {\ 00565 \n vertLightDirection = (fragWorldPos.xyz - in_lightPosition[lightNum]);\ 00566 \n float distance = length(vertLightDirection);\ 00567 \n vertLightDirection = normalize(vertLightDirection);\ 00568 \n attenuation = 1.0 /\ 00569 \n (in_lightAttenuation[lightNum].x\ 00570 \n + in_lightAttenuation[lightNum].y * distance\ 00571 \n + in_lightAttenuation[lightNum].z * distance * distance);\ 00572 \n // per OpenGL standard cone angle is 90 or less for a spot light\ 00573 \n if (in_lightConeAngle[lightNum] <= 90.0)\ 00574 \n {\ 00575 \n float coneDot = dot(vertLightDirection, lightDir);\ 00576 \n // if inside the cone\ 00577 \n if (coneDot >= cos(radians(in_lightConeAngle[lightNum])))\ 00578 \n {\ 00579 \n attenuation = attenuation * pow(coneDot, in_lightExponent[lightNum]);\ 00580 \n }\ 00581 \n else\ 00582 \n {\ 00583 \n attenuation = 0.0;\ 00584 \n }\ 00585 \n }\ 00586 \n }\ 00587 \n // diffuse and specular lighting\ 00588 \n float nDotL = dot(normal, vertLightDirection);\ 00589 \n if (nDotL < 0.0 && in_twoSidedLighting)\ 00590 \n {\ 00591 \n nDotL = -nDotL;\ 00592 \n }\ 00593 \n if (nDotL > 0)\ 00594 \n {\ 00595 \n float df = max(0.0, attenuation * nDotL);\ 00596 \n diffuse += (df * in_lightDiffuseColor[lightNum]);\ 00597 \n }\ 00598 \n vec3 h = normalize(vertLightDirection + viewDirection);\ 00599 \n float nDotH = dot(normal, h);\ 00600 \n if (nDotH < 0.0 && in_twoSidedLighting)\ 00601 \n {\ 00602 \n nDotH = -nDotH;\ 00603 \n }\ 00604 \n if (nDotH > 0)\ 00605 \n {\ 00606 \n float sf = attenuation * pow(nDotH, in_shininess);\ 00607 \n specular += (sf * in_lightSpecularColor[lightNum]);\ 00608 \n }\ 00609 \n ambient += in_lightAmbientColor[lightNum];\ 00610 \n }\ 00611 \n vec3 finalColor = in_ambient * ambient + in_diffuse *\ 00612 \n diffuse * color.rgb + in_specular * specular;\ 00613 "); 00614 } 00615 } 00616 else 00617 { 00618 shaderStr += std::string( 00619 "\n vec3 finalColor = color.rgb;" 00620 ); 00621 } 00622 00623 if (noOfComponents == 1 && volProperty->HasGradientOpacity()) 00624 { 00625 shaderStr += std::string("\ 00626 \n if (gradient.w >= 0.0)\ 00627 \n {\ 00628 \n color.a = color.a *\ 00629 \n computeGradientOpacity(gradient);\ 00630 \n }" 00631 ); 00632 } 00633 else if (noOfComponents > 1 && independentComponents && 00634 volProperty->HasGradientOpacity()) 00635 { 00636 shaderStr += std::string("\ 00637 \n if (gradient.w >= 0.0)\ 00638 \n {\ 00639 \n for (int i = 0; i < in_noOfComponents; ++i)\ 00640 \n {\ 00641 \n color.a = color.a *\ 00642 \n computeGradientOpacity(gradient, i) * in_componentWeight[i];\ 00643 \n }" 00644 ); 00645 } 00646 00647 shaderStr += std::string("\ 00648 \n return vec4(finalColor, color.a);\ 00649 \n }" 00650 ); 00651 00652 return shaderStr; 00653 } 00654 00655 //-------------------------------------------------------------------------- 00656 std::string RayDirectionFunc(vtkRenderer* ren, 00657 vtkVolumeMapper* vtkNotUsed(mapper), 00658 vtkVolume* vtkNotUsed(vol), 00659 int vtkNotUsed(noOfComponents)) 00660 { 00661 if (!ren->GetActiveCamera()->GetParallelProjection()) 00662 { 00663 return std::string("\ 00664 \nvec3 computeRayDirection()\ 00665 \n {\ 00666 \n return normalize(ip_vertexPos.xyz - g_eyePosObj.xyz);\ 00667 \n }"); 00668 } 00669 else 00670 { 00671 return std::string("\ 00672 \nuniform vec3 in_projectionDirection;\ 00673 \nvec3 computeRayDirection()\ 00674 \n {\ 00675 \n return normalize((in_inverseVolumeMatrix *\ 00676 \n vec4(in_projectionDirection, 0.0)).xyz);\ 00677 \n }"); 00678 } 00679 } 00680 00681 //-------------------------------------------------------------------------- 00682 std::string ColorTransferFunc(vtkRenderer* vtkNotUsed(ren), 00683 vtkVolumeMapper* vtkNotUsed(mapper), 00684 vtkVolume* vtkNotUsed(vol), 00685 int noOfComponents, 00686 int independentComponents, 00687 std::map<int, std::string> colorTableMap) 00688 { 00689 if (noOfComponents == 1) 00690 { 00691 return std::string("\ 00692 \nuniform sampler1D in_colorTransferFunc;\ 00693 \nvec4 computeColor(vec4 scalar)\ 00694 \n {\ 00695 \n return computeLighting(vec4(texture1D(in_colorTransferFunc,\ 00696 \n scalar.w).xyz,\ 00697 \n computeOpacity(scalar)));\ 00698 \n }"); 00699 } 00700 else if (noOfComponents > 1 && independentComponents) 00701 { 00702 std::string shaderStr; 00703 for (int i = 0; i < noOfComponents; ++i) 00704 { 00705 shaderStr += std::string("\n uniform sampler1D ") + 00706 colorTableMap[i] + std::string(";"); 00707 } 00708 00709 shaderStr += std::string("\ 00710 \nvec4 computeColor(vec4 scalar, int component)\ 00711 \n {\ 00712 \n if (component == 0)\ 00713 \n {\ 00714 \n return computeLighting(vec4(texture1D(\ 00715 \n in_colorTransferFunc,\ 00716 \n scalar[component]).xyz,\ 00717 \n computeOpacity(scalar, component)));\ 00718 \n }\ 00719 \n if (component == 1)\ 00720 \n {\ 00721 \n return computeLighting(vec4(texture1D(\ 00722 \n in_colorTransferFunc1,\ 00723 \n scalar[component]).xyz,\ 00724 \n computeOpacity(scalar, component)));\ 00725 \n }\ 00726 \n if (component == 2)\ 00727 \n {\ 00728 \n return computeLighting(vec4(texture1D(\ 00729 \n in_colorTransferFunc2,\ 00730 \n scalar[component]).xyz,\ 00731 \n computeOpacity(scalar, component)));\ 00732 \n }\ 00733 \n if (component == 3)\ 00734 \n {\ 00735 \n return computeLighting(vec4(texture1D(\ 00736 \n in_colorTransferFunc3,\ 00737 \n scalar[component]).xyz,\ 00738 \n computeOpacity(scalar, component)));\ 00739 \n }\ 00740 \n }"); 00741 00742 return shaderStr; 00743 } 00744 00745 return std::string("\ 00746 \nvec4 computeColor(vec4 scalar)\ 00747 \n {\ 00748 \n return computeLighting(vec4(scalar.xyz, computeOpacity(scalar)));\ 00749 \n }"); 00750 } 00751 00752 //-------------------------------------------------------------------------- 00753 std::string OpacityTransferFunc(vtkRenderer* vtkNotUsed(ren), 00754 vtkVolumeMapper* vtkNotUsed(mapper), 00755 vtkVolume* vtkNotUsed(vol), 00756 int noOfComponents, 00757 int independentComponents, 00758 std::map<int, std::string> opacityTableMap) 00759 { 00760 if (noOfComponents > 1 && independentComponents) 00761 { 00762 std::string shaderStr; 00763 for (int i = 0; i < noOfComponents; ++i) 00764 { 00765 shaderStr += std::string("\n uniform sampler1D ") + 00766 opacityTableMap[i] + std::string(";"); 00767 } 00768 00769 shaderStr += std::string("\ 00770 \nfloat computeOpacity(vec4 scalar, int component)\ 00771 \n {\ 00772 \n if (component == 0)\ 00773 \n {\ 00774 \n return texture1D(in_opacityTransferFunc,\ 00775 \n scalar[component]).w;\ 00776 \n }\ 00777 \n if (component == 1)\ 00778 \n {\ 00779 \n return texture1D(in_opacityTransferFunc1,\ 00780 \n scalar[component]).w;\ 00781 \n }\ 00782 \n if (component == 2)\ 00783 \n {\ 00784 \n return texture1D(in_opacityTransferFunc2,\ 00785 \n scalar[component]).w;\ 00786 \n }\ 00787 \n if (component == 3)\ 00788 \n {\ 00789 \n return texture1D(in_opacityTransferFunc3,\ 00790 \n scalar[component]).w;\ 00791 \n }\ 00792 \n }"); 00793 00794 return shaderStr; 00795 } 00796 else 00797 { 00798 return std::string("\ 00799 \nuniform sampler1D in_opacityTransferFunc;\ 00800 \nfloat computeOpacity(vec4 scalar)\ 00801 \n {\ 00802 \n return texture1D(in_opacityTransferFunc, scalar.w).w;\ 00803 \n }"); 00804 } 00805 } 00806 00807 //-------------------------------------------------------------------------- 00808 std::string ShadingGlobalsVert(vtkRenderer* vtkNotUsed(ren), 00809 vtkVolumeMapper* vtkNotUsed(mapper), 00810 vtkVolume* vtkNotUsed(vol)) 00811 { 00812 return std::string(); 00813 } 00814 00815 //-------------------------------------------------------------------------- 00816 std::string ShadingGlobalsFrag(vtkRenderer* vtkNotUsed(ren), 00817 vtkVolumeMapper* vtkNotUsed(mapper), 00818 vtkVolume* vtkNotUsed(vol)) 00819 { 00820 return std::string(); 00821 } 00822 00823 //-------------------------------------------------------------------------- 00824 std::string ShadingInit(vtkRenderer* vtkNotUsed(ren), 00825 vtkVolumeMapper* mapper, 00826 vtkVolume* vtkNotUsed(vol)) 00827 { 00828 if (mapper->GetBlendMode() == vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND) 00829 { 00830 return std::string("\ 00831 \n // We get data between 0.0 - 1.0 range\ 00832 \n bool l_firstValue = true;\ 00833 \n vec4 l_maxValue = vec4(0.0);" 00834 ); 00835 } 00836 else if (mapper->GetBlendMode() == vtkVolumeMapper::MINIMUM_INTENSITY_BLEND) 00837 { 00838 return std::string("\ 00839 \n //We get data between 0.0 - 1.0 range\ 00840 \n bool l_firstValue = true;\ 00841 \n vec4 l_minValue = vec4(1.0);" 00842 ); 00843 } 00844 else if (mapper->GetBlendMode() == vtkVolumeMapper::ADDITIVE_BLEND) 00845 { 00846 return std::string("\ 00847 \n //We get data between 0.0 - 1.0 range\ 00848 \n float l_sumValue = 0.0;" 00849 ); 00850 } 00851 else 00852 { 00853 return std::string(); 00854 } 00855 } 00856 00857 //-------------------------------------------------------------------------- 00858 std::string ShadingIncrement(vtkRenderer* vtkNotUsed(ren), 00859 vtkVolumeMapper* mapper, 00860 vtkVolume* vtkNotUsed(vol), 00861 vtkImageData* maskInput, 00862 vtkVolumeMask* mask, int maskType, 00863 int noOfComponents, 00864 int independentComponents = 0) 00865 { 00866 std::string shaderStr = std::string("\ 00867 \n if (!l_skip)\ 00868 \n {" 00869 ); 00870 00871 if (mapper->GetBlendMode() == vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND) 00872 { 00873 if (noOfComponents == 4) 00874 { 00875 shaderStr += std::string("\ 00876 \n vec4 scalar = texture3D(in_volume, g_dataPos);\ 00877 \n if (l_maxValue.w < scalar.w || l_firstValue)\ 00878 \n {\ 00879 \n l_maxValue = scalar;\ 00880 \n }\ 00881 \n\ 00882 \n if (l_firstValue)\ 00883 \n {\ 00884 \n l_firstValue = false;\ 00885 \n }" 00886 ); 00887 } 00888 else 00889 { 00890 shaderStr += std::string("\ 00891 \n vec4 scalar = texture3D(in_volume, g_dataPos);\ 00892 \n if (l_maxValue.w < scalar.x || l_firstValue)\ 00893 \n {\ 00894 \n l_maxValue.w = scalar.x;\ 00895 \n }\ 00896 \n\ 00897 \n if (l_firstValue)\ 00898 \n {\ 00899 \n l_firstValue = false;\ 00900 \n }" 00901 ); 00902 } 00903 } 00904 else if (mapper->GetBlendMode() == vtkVolumeMapper::MINIMUM_INTENSITY_BLEND) 00905 { 00906 if (noOfComponents == 4) 00907 { 00908 shaderStr += std::string("\ 00909 \n vec4 scalar = texture3D(in_volume, g_dataPos);\ 00910 \n if (l_minValue.w > scalar.w || l_firstValue)\ 00911 \n {\ 00912 \n l_minValue = scalar;\ 00913 \n }\ 00914 \n\ 00915 \n if (l_firstValue)\ 00916 \n {\ 00917 \n l_firstValue = false;\ 00918 \n }" 00919 ); 00920 } 00921 else 00922 { 00923 shaderStr += std::string("\ 00924 \n vec4 scalar = texture3D(in_volume, g_dataPos);\ 00925 \n if (l_minValue.w > scalar.x || l_firstValue)\ 00926 \n {\ 00927 \n l_minValue.w = scalar.x;\ 00928 \n }\ 00929 \n\ 00930 \n if (l_firstValue)\ 00931 \n {\ 00932 \n l_firstValue = false;\ 00933 \n }" 00934 ); 00935 } 00936 } 00937 else if (mapper->GetBlendMode() == vtkVolumeMapper::ADDITIVE_BLEND) 00938 { 00939 shaderStr += std::string("\ 00940 \n vec4 scalar = texture3D(in_volume, g_dataPos);\ 00941 \n float opacity = computeOpacity(scalar);\ 00942 \n l_sumValue = l_sumValue + opacity * scalar.x;" 00943 ); 00944 } 00945 else if (mapper->GetBlendMode() == vtkVolumeMapper::COMPOSITE_BLEND) 00946 { 00947 if (noOfComponents > 1 && independentComponents) 00948 { 00949 shaderStr += std::string("\ 00950 \n vec4 color[4]; vec4 tmp = vec4(0.0);\ 00951 \n float totalAlpha = 0.0;\ 00952 \n vec4 scalar = texture3D(in_volume, g_dataPos);\ 00953 \n for (int i = 0; i < in_noOfComponents; ++i)\ 00954 \n {\ 00955 "); 00956 if (!mask || !maskInput || 00957 maskType != vtkGPUVolumeRayCastMapper::LabelMapMaskType) 00958 { 00959 shaderStr += std::string("\ 00960 \n // Data fetching from the red channel of volume texture\ 00961 \n color[i] = vec4(computeColor(scalar, i));\ 00962 \n totalAlpha += color[i][3] * in_componentWeight[i];\ 00963 \n }\ 00964 \n if (totalAlpha > 0.0)\ 00965 \n {\ 00966 \n for (int i = 0; i < in_noOfComponents; ++i)\ 00967 \n {\ 00968 \n tmp.x += color[i].x * color[i].w * in_componentWeight[i] ;\ 00969 \n tmp.y += color[i].y * color[i].w * in_componentWeight[i];\ 00970 \n tmp.z += color[i].z * color[i].w * in_componentWeight[i];\ 00971 \n tmp.w += ((color[i].w * color[i].w)/totalAlpha);\ 00972 \n }\ 00973 \n }\ 00974 \n g_fragColor = (1.0f - g_fragColor.a) * tmp + g_fragColor;" 00975 ); 00976 } 00977 } 00978 else 00979 { 00980 if (!mask || !maskInput || 00981 maskType != vtkGPUVolumeRayCastMapper::LabelMapMaskType) 00982 { 00983 shaderStr += std::string("\ 00984 \n // Data fetching from the red channel of volume texture\ 00985 \n vec4 scalar = texture3D(in_volume, g_dataPos);\ 00986 \n vec4 g_srcColor = computeColor(scalar);" 00987 ); 00988 } 00989 00990 shaderStr += std::string("\ 00991 \n // Opacity calculation using compositing:\ 00992 \n // here we use front to back compositing scheme whereby the current\ 00993 \n // sample value is multiplied to the currently accumulated alpha\ 00994 \n // and then this product is subtracted from the sample value to\ 00995 \n // get the alpha from the previous steps.\ 00996 \n // Next, this alpha is multiplied with the current sample colour\ 00997 \n // and accumulated to the composited colour. The alpha value from\ 00998 \n // the previous steps is then accumulated to the composited colour\ 00999 \n // alpha.\ 01000 \n g_srcColor.rgb *= g_srcColor.a;\ 01001 \n g_fragColor = (1.0f - g_fragColor.a) * g_srcColor + g_fragColor;" 01002 ); 01003 } 01004 } 01005 else 01006 { 01007 shaderStr += std::string(); 01008 } 01009 01010 shaderStr += std::string("\ 01011 \n }" 01012 ); 01013 return shaderStr; 01014 } 01015 01016 //-------------------------------------------------------------------------- 01017 std::string ShadingExit(vtkRenderer* vtkNotUsed(ren), 01018 vtkVolumeMapper* mapper, 01019 vtkVolume* vtkNotUsed(vol), 01020 int noOfComponents, 01021 int independentComponents = 0) 01022 { 01023 if (mapper->GetBlendMode() == vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND) 01024 { 01025 if (noOfComponents > 1 && independentComponents) 01026 { 01027 return std::string("\ 01028 \n vec4 g_srcColor = vec4(0);\ 01029 \n for (int i = 0; i < in_noOfComponents; ++i)\ 01030 \n {\ 01031 \n vec4 tmp = computeColor(l_maxValue, i);\ 01032 \n g_srcColor[0] += tmp[0] * tmp[3] * in_componentWeight[i];\ 01033 \n g_srcColor[1] += tmp[1] * tmp[3] * in_componentWeight[i];\ 01034 \n g_srcColor[2] += tmp[2] * tmp[3] * in_componentWeight[i];\ 01035 \n g_srcColor[3] += tmp[3] * in_componentWeight[i];\ 01036 \n }\ 01037 \n g_fragColor = g_srcColor;" 01038 ); 01039 } 01040 else 01041 { 01042 return std::string("\ 01043 \n vec4 g_srcColor = vec4(computeColor(l_maxValue).xyz,\ 01044 \n computeOpacity(l_maxValue));\ 01045 \n g_fragColor.rgb = g_srcColor.rgb * g_srcColor.a;\ 01046 \n g_fragColor.a = g_srcColor.a;" 01047 ); 01048 } 01049 } 01050 else if (mapper->GetBlendMode() == vtkVolumeMapper::MINIMUM_INTENSITY_BLEND) 01051 { 01052 if (noOfComponents > 1 && independentComponents) 01053 { 01054 return std::string("\ 01055 \n vec4 g_srcColor = vec4(0);\ 01056 \n for (int i = 0; i < in_noOfComponents; ++i)\ 01057 \n {\ 01058 \n vec4 tmp = computeColor(l_minValue, i);\ 01059 \n g_srcColor[0] += tmp[0] * tmp[3] * in_componentWeight[i];\ 01060 \n g_srcColor[1] += tmp[1] * tmp[3] * in_componentWeight[i];\ 01061 \n g_srcColor[2] += tmp[2] * tmp[3] * in_componentWeight[i];\ 01062 \n g_srcColor[2] += tmp[3] * tmp[3] * in_componentWeight[i];\ 01063 \n }\ 01064 \n g_fragColor = g_srcColor;" 01065 ); 01066 } 01067 else 01068 { 01069 return std::string("\ 01070 \n vec4 g_srcColor = vec4(computeColor(l_minValue).xyz,\ 01071 \n computeOpacity(l_minValue));\ 01072 \n g_fragColor.rgb = g_srcColor.rgb * g_srcColor.a;\ 01073 \n g_fragColor.a = g_srcColor.a;" 01074 ); 01075 } 01076 } 01077 else if (mapper->GetBlendMode() == vtkVolumeMapper::ADDITIVE_BLEND) 01078 { 01079 return std::string("\ 01080 \n l_sumValue = clamp(l_sumValue, 0.0, 1.0);\ 01081 \n g_fragColor = vec4(vec3(l_sumValue), 1.0);" 01082 ); 01083 } 01084 else 01085 { 01086 return std::string(); 01087 } 01088 } 01089 01090 //-------------------------------------------------------------------------- 01091 std::string TerminationGlobalsVert(vtkRenderer* vtkNotUsed(ren), 01092 vtkVolumeMapper* vtkNotUsed(mapper), 01093 vtkVolume* vtkNotUsed(vol)) 01094 { 01095 return std::string(); 01096 } 01097 01098 //-------------------------------------------------------------------------- 01099 std::string TerminationGlobalsFrag(vtkRenderer* vtkNotUsed(ren), 01100 vtkVolumeMapper* vtkNotUsed(mapper), 01101 vtkVolume* vtkNotUsed(vol)) 01102 { 01103 return std::string(); 01104 } 01105 01106 //-------------------------------------------------------------------------- 01107 std::string TerminationInit(vtkRenderer* vtkNotUsed(ren), 01108 vtkVolumeMapper* vtkNotUsed(mapper), 01109 vtkVolume* vtkNotUsed(vol)) 01110 { 01111 return std::string("\ 01112 \n // Minimum texture access coordinate\ 01113 \n const vec3 l_tex_min = vec3(0);\ 01114 \n\ 01115 \n // Maximum texture access coordinate\ 01116 \n const vec3 l_tex_max = vec3(1);\ 01117 \n\ 01118 \n // Flag to indicate if the raymarch loop should terminate \ 01119 \n bool stop = false;\ 01120 \n\ 01121 \n // 2D Texture fragment coordinates [0,1] from fragment coordinates \ 01122 \n // the frame buffer texture has the size of the plain buffer but \ 01123 \n // we use a fraction of it. The texture coordinates is less than 1 if \ 01124 \n // the reduction factor is less than 1. \ 01125 \n // Device coordinates are between -1 and 1. We need texture \ 01126 \n // coordinates between 0 and 1 the in_depthSampler buffer has the \ 01127 \n // original size buffer. \ 01128 \n vec2 fragTexCoord = (gl_FragCoord.xy - in_windowLowerLeftCorner) *\ 01129 \n in_inverseWindowSize;\ 01130 \n vec4 l_depthValue = texture2D(in_depthSampler, fragTexCoord);\ 01131 \n float l_terminatePointMax = 0.0;\ 01132 \n\ 01133 \n // Depth test\ 01134 \n if(gl_FragCoord.z >= l_depthValue.x)\ 01135 \n {\ 01136 \n discard;\ 01137 \n }\ 01138 \n\ 01139 \n // color buffer or max scalar buffer have a reduced size.\ 01140 \n fragTexCoord = (gl_FragCoord.xy - in_windowLowerLeftCorner) *\ 01141 \n in_inverseOriginalWindowSize;\ 01142 \n\ 01143 \n // Compute max number of iterations it will take before we hit\ 01144 \n // the termination point\ 01145 \n\ 01146 \n // Abscissa of the point on the depth buffer along the ray.\ 01147 \n // point in texture coordinates\ 01148 \n vec4 terminatePoint;\ 01149 \n terminatePoint.x = (gl_FragCoord.x - in_windowLowerLeftCorner.x) * 2.0 *\ 01150 \n in_inverseWindowSize.x - 1.0;\ 01151 \n terminatePoint.y = (gl_FragCoord.y - in_windowLowerLeftCorner.y) * 2.0 *\ 01152 \n in_inverseWindowSize.y - 1.0;\ 01153 \n terminatePoint.z = (2.0 * l_depthValue.x - (gl_DepthRange.near +\ 01154 \n gl_DepthRange.far)) / gl_DepthRange.diff;\ 01155 \n terminatePoint.w = 1.0;\ 01156 \n\ 01157 \n // From normalized device coordinates to eye coordinates.\ 01158 \n // in_projectionMatrix is inversed because of way VT\ 01159 \n // From eye coordinates to texture coordinates\ 01160 \n terminatePoint = in_inverseTextureDatasetMatrix *\ 01161 \n in_inverseVolumeMatrix *\ 01162 \n in_inverseModelViewMatrix *\ 01163 \n in_inverseProjectionMatrix *\ 01164 \n terminatePoint;\ 01165 \n terminatePoint /= terminatePoint.w;\ 01166 \n\ 01167 \n l_terminatePointMax = length(terminatePoint.xyz - g_dataPos.xyz) /\ 01168 \n length(g_dirStep);\ 01169 \n float l_currentT = 0.0;"); 01170 } 01171 01172 //-------------------------------------------------------------------------- 01173 std::string TerminationIncrement(vtkRenderer* vtkNotUsed(ren), 01174 vtkVolumeMapper* vtkNotUsed(mapper), 01175 vtkVolume* vtkNotUsed(vol)) 01176 { 01177 return std::string("\ 01178 \n // The two constants l_tex_min and l_tex_max have a value of\ 01179 \n // vec3(-1,-1,-1) and vec3(1,1,1) respectively. To determine if the\ 01180 \n // data value is outside the in_volume data, we use the sign function.\ 01181 \n // The sign function return -1 if the value is less than 0, 0 if the\ 01182 \n // value is equal to 0 and 1 if value is greater than 0. Hence, the\ 01183 \n // sign function for the calculation (sign(g_dataPos-l_tex_min) and\ 01184 \n // sign (l_tex_max-g_dataPos)) will give us vec3(1,1,1) at the\ 01185 \n // possible minimum and maximum position.\ 01186 \n // When we do a dot product between two vec3(1,1,1) we get answer 3.\ 01187 \n // So to be within the dataset limits, the dot product will return a\ 01188 \n // value less than 3. If it is greater than 3, we are already out of\ 01189 \n // the in_volume dataset\ 01190 \n stop = dot(sign(g_dataPos - l_tex_min), sign(l_tex_max - g_dataPos))\ 01191 \n < 3.0;\ 01192 \n\ 01193 \n // If the stopping condition is true we brek out of the ray marching\ 01194 \n // loop\ 01195 \n if (stop)\ 01196 \n {\ 01197 \n break;\ 01198 \n }\ 01199 \n // Early ray termination\ 01200 \n // if the currently composited colour alpha is already fully saturated\ 01201 \n // we terminated the loop or if we have hit an obstacle in the\ 01202 \n // direction of they ray (using depth buffer) we terminate as well.\ 01203 \n if((g_fragColor.a > (1 - 1/255.0)) || \ 01204 \n l_currentT >= l_terminatePointMax)\ 01205 \n {\ 01206 \n break;\ 01207 \n }\ 01208 \n ++l_currentT;" 01209 ); 01210 } 01211 01212 //-------------------------------------------------------------------------- 01213 std::string TerminationExit(vtkRenderer* vtkNotUsed(ren), 01214 vtkVolumeMapper* vtkNotUsed(mapper), 01215 vtkVolume* vtkNotUsed(vol)) 01216 { 01217 return std::string(); 01218 } 01219 01220 //-------------------------------------------------------------------------- 01221 std::string CroppingGlobalsVert(vtkRenderer* vtkNotUsed(ren), 01222 vtkVolumeMapper* vtkNotUsed(mapper), 01223 vtkVolume* vtkNotUsed(vol)) 01224 { 01225 return std::string(); 01226 } 01227 01228 //-------------------------------------------------------------------------- 01229 std::string CroppingGlobalsFrag(vtkRenderer* vtkNotUsed(ren), 01230 vtkVolumeMapper* mapper, 01231 vtkVolume* vtkNotUsed(vol)) 01232 { 01233 if (!mapper->GetCropping()) { 01234 return std::string(); 01235 } 01236 01237 return std::string("\ 01238 \nuniform float cropping_planes[6];\ 01239 \nuniform int cropping_flags [32];\ 01240 \n// X: axis = 0, Y: axis = 1, Z: axis = 2\ 01241 \n// cp Cropping plane bounds (minX, maxX, minY, maxY, minZ, maxZ)\ 01242 \nint computeRegionCoord(float cp[6], vec3 pos, int axis)\ 01243 \n {\ 01244 \n int cpmin = axis * 2;\ 01245 \n int cpmax = cpmin + 1;\ 01246 \n\ 01247 \n if (pos[axis] < cp[cpmin])\ 01248 \n {\ 01249 \n return 1;\ 01250 \n }\ 01251 \n else if (pos[axis] >= cp[cpmin] &&\ 01252 \n pos[axis] < cp[cpmax])\ 01253 \n {\ 01254 \n return 2;\ 01255 \n }\ 01256 \n else if (pos[axis] >= cp[cpmax])\ 01257 \n {\ 01258 \n return 3;\ 01259 \n }\ 01260 \n return 0;\ 01261 \n }\ 01262 \n\ 01263 \nint computeRegion(float cp[6], vec3 pos)\ 01264 \n {\ 01265 \n return (computeRegionCoord(cp, pos, 0) +\ 01266 \n (computeRegionCoord(cp, pos, 1) - 1) * 3 +\ 01267 \n (computeRegionCoord(cp, pos, 2) - 1) * 9);\ 01268 \n }" 01269 ); 01270 } 01271 01272 //-------------------------------------------------------------------------- 01273 std::string CroppingInit(vtkRenderer* vtkNotUsed(ren), 01274 vtkVolumeMapper* mapper, 01275 vtkVolume* vtkNotUsed(vol)) 01276 { 01277 if (!mapper->GetCropping()) { 01278 return std::string(); 01279 } 01280 01281 return std::string("\ 01282 \n // Convert cropping region to texture space\ 01283 \n float cropping_planes_ts[6];\ 01284 \n mat4 datasetToTextureMat = in_inverseTextureDatasetMatrix;\ 01285 \n vec4 temp = vec4(cropping_planes[0], cropping_planes[1], 0.0, 1.0);\ 01286 \n temp = datasetToTextureMat * temp;\ 01287 \n if (temp[3] != 0.0)\ 01288 \n {\ 01289 \n temp[0] /= temp[3]; temp[1] /= temp[3];\ 01290 \n }\ 01291 \n cropping_planes_ts[0] = temp[0];\ 01292 \n cropping_planes_ts[1] = temp[1];\ 01293 \n\ 01294 \n temp = vec4(cropping_planes[2], cropping_planes[3], 0.0, 1.0);\ 01295 \n temp = datasetToTextureMat * temp;\ 01296 \n if (temp[3] != 0.0)\ 01297 \n {\ 01298 \n temp[0] /= temp[3]; temp[1] /= temp[3];\ 01299 \n }\ 01300 \n cropping_planes_ts[2] = temp[0];\ 01301 \n cropping_planes_ts[3] = temp[1];\ 01302 \n\ 01303 \n temp = vec4(cropping_planes[4], cropping_planes[5], 0.0, 1.0);\ 01304 \n temp = datasetToTextureMat * temp;\ 01305 \n if (temp[3] != 0.0)\ 01306 \n {\ 01307 \n temp[0] /= temp[3]; temp[1] /= temp[3];\ 01308 \n }\ 01309 \n cropping_planes_ts[4] = temp[0];\ 01310 \n cropping_planes_ts[5] = temp[1];" 01311 ); 01312 } 01313 01314 //-------------------------------------------------------------------------- 01315 std::string CroppingIncrement(vtkRenderer* vtkNotUsed(ren), 01316 vtkVolumeMapper* mapper, 01317 vtkVolume* vtkNotUsed(vol)) 01318 { 01319 if (!mapper->GetCropping()) { 01320 return std::string(); 01321 } 01322 01323 return std::string("\ 01324 \n // Determine region\ 01325 \n int regionNo = computeRegion(cropping_planes_ts, g_dataPos);\ 01326 \n\ 01327 \n // Do & operation with cropping flags\ 01328 \n // Pass the flag that its Ok to sample or not to sample\ 01329 \n if (cropping_flags[regionNo] == 0)\ 01330 \n {\ 01331 \n // Skip this voxel\ 01332 \n l_skip = true;\ 01333 \n }" 01334 ); 01335 } 01336 01337 //-------------------------------------------------------------------------- 01338 std::string CroppingExit(vtkRenderer* vtkNotUsed(ren), 01339 vtkVolumeMapper* vtkNotUsed(mapper), 01340 vtkVolume* vtkNotUsed(vol)) 01341 { 01342 return std::string(); 01343 } 01344 01345 //-------------------------------------------------------------------------- 01346 std::string ClippingGlobalsVert(vtkRenderer* vtkNotUsed(ren), 01347 vtkVolumeMapper* vtkNotUsed(mapper), 01348 vtkVolume* vtkNotUsed(vol)) 01349 { 01350 return std::string(); 01351 } 01352 01353 //-------------------------------------------------------------------------- 01354 std::string ClippingGlobalsFrag(vtkRenderer* vtkNotUsed(ren), 01355 vtkVolumeMapper* vtkNotUsed(mapper), 01356 vtkVolume* vtkNotUsed(vol)) 01357 { 01358 return std::string(); 01359 } 01360 01361 //-------------------------------------------------------------------------- 01362 std::string ClippingInit(vtkRenderer* vtkNotUsed(ren), 01363 vtkVolumeMapper* mapper, 01364 vtkVolume* vtkNotUsed(vol)) 01365 { 01366 if (!mapper->GetClippingPlanes()) 01367 { 01368 return std::string(); 01369 } 01370 else 01371 { 01372 return std::string("\ 01373 \nfloat clippingPlanesTexture[48];\ 01374 \nint clippingPlanesSize = int(in_clippingPlanes[0]);\ 01375 \n\ 01376 \nmat4 world_to_texture_mat = in_inverseTextureDatasetMatrix *\ 01377 \n in_inverseVolumeMatrix;\ 01378 \nfor (int i = 0; i < clippingPlanesSize; i = i + 6)\ 01379 \n {\ 01380 \n vec4 origin = vec4(in_clippingPlanes[i + 1],\ 01381 \n in_clippingPlanes[i + 2],\ 01382 \n in_clippingPlanes[i + 3], 1.0);\ 01383 \n vec4 normal = vec4(in_clippingPlanes[i + 4],\ 01384 \n in_clippingPlanes[i + 5],\ 01385 \n in_clippingPlanes[i + 6], 0.0);\ 01386 \n\ 01387 \n origin = world_to_texture_mat * origin;\ 01388 \n normal = world_to_texture_mat * normal;\ 01389 \n\ 01390 \n if (origin[3] != 0.0)\ 01391 \n {\ 01392 \n origin[0] = origin[0] / origin[3];\ 01393 \n origin[1] = origin[1] / origin[3];\ 01394 \n origin[2] = origin[2] / origin[3];\ 01395 \n }\ 01396 \n if (normal[3] != 0.0)\ 01397 \n {\ 01398 \n normal[0] = normal[0] / normal[3];\ 01399 \n normal[1] = normal[1] / normal[3];\ 01400 \n normal[2] = normal[2] / normal[3];\ 01401 \n }\ 01402 \n\ 01403 \n clippingPlanesTexture[i] = origin[0];\ 01404 \n clippingPlanesTexture[i + 1] = origin[1];\ 01405 \n clippingPlanesTexture[i + 2] = origin[2];\ 01406 \n\ 01407 \n clippingPlanesTexture[i + 3] = normal[0];\ 01408 \n clippingPlanesTexture[i + 4] = normal[1];\ 01409 \n clippingPlanesTexture[i + 5] = normal[2];\ 01410 \n }" 01411 ); 01412 } 01413 } 01414 01415 //-------------------------------------------------------------------------- 01416 std::string ClippingIncrement(vtkRenderer* vtkNotUsed(ren), 01417 vtkVolumeMapper* mapper, 01418 vtkVolume* vtkNotUsed(vol)) 01419 { 01420 if (!mapper->GetClippingPlanes()) 01421 { 01422 return std::string(); 01423 } 01424 else 01425 { 01426 return std::string("\ 01427 \n for (int i = 0; i < (clippingPlanesSize) && !l_skip; i = i + 6)\ 01428 \n {\ 01429 \n if (dot(vec3(g_dataPos - vec3(clippingPlanesTexture[i],\ 01430 \n clippingPlanesTexture[i + 1],\ 01431 \n clippingPlanesTexture[i + 2])),\ 01432 \n vec3(clippingPlanesTexture[i + 3],\ 01433 \n clippingPlanesTexture[i + 4],\ 01434 \n clippingPlanesTexture[i + 5])) < 0)\ 01435 \n {\ 01436 \n l_skip = true;\ 01437 \n break;\ 01438 \n }\ 01439 \n }" 01440 ); 01441 } 01442 } 01443 01444 //-------------------------------------------------------------------------- 01445 std::string ClippingExit(vtkRenderer* vtkNotUsed(ren), 01446 vtkVolumeMapper* vtkNotUsed(mapper), 01447 vtkVolume* vtkNotUsed(vol)) 01448 { 01449 return std::string(); 01450 } 01451 01452 //-------------------------------------------------------------------------- 01453 std::string BinaryMaskGlobalsFrag(vtkRenderer* vtkNotUsed(ren), 01454 vtkVolumeMapper* vtkNotUsed(mapper), 01455 vtkVolume* vtkNotUsed(vol), 01456 vtkImageData* maskInput, 01457 vtkVolumeMask* mask, 01458 int vtkNotUsed(maskType)) 01459 { 01460 if (!mask || !maskInput) 01461 { 01462 return std::string(); 01463 } 01464 else 01465 { 01466 return std::string("uniform sampler3D in_mask;"); 01467 } 01468 } 01469 01470 //-------------------------------------------------------------------------- 01471 std::string BinaryMaskIncrement(vtkRenderer* vtkNotUsed(ren), 01472 vtkVolumeMapper* vtkNotUsed(mapper), 01473 vtkVolume* vtkNotUsed(vol), 01474 vtkImageData* maskInput, 01475 vtkVolumeMask* mask, 01476 int maskType) 01477 { 01478 if (!mask || !maskInput || 01479 maskType == vtkGPUVolumeRayCastMapper::LabelMapMaskType) 01480 { 01481 return std::string(); 01482 } 01483 else 01484 { 01485 return std::string("\ 01486 \nvec4 maskValue = texture3D(in_mask, g_dataPos);\ 01487 \nif(maskValue.a <= 0.0)\ 01488 \n {\ 01489 \n l_skip = true;\ 01490 \n }" 01491 ); 01492 } 01493 } 01494 01495 //-------------------------------------------------------------------------- 01496 std::string CompositeMaskGlobalsFrag(vtkRenderer* vtkNotUsed(ren), 01497 vtkVolumeMapper* vtkNotUsed(mapper), 01498 vtkVolume* vtkNotUsed(vol), 01499 vtkImageData* maskInput, 01500 vtkVolumeMask* mask, 01501 int maskType) 01502 { 01503 if (!mask || !maskInput || 01504 maskType != vtkGPUVolumeRayCastMapper::LabelMapMaskType) 01505 { 01506 return std::string(); 01507 } 01508 else 01509 { 01510 return std::string("\ 01511 \nuniform float in_maskBlendFactor;\ 01512 \nuniform sampler1D in_mask1;\ 01513 \nuniform sampler1D in_mask2;" 01514 ); 01515 } 01516 } 01517 01518 //-------------------------------------------------------------------------- 01519 std::string CompositeMaskIncrement(vtkRenderer* vtkNotUsed(ren), 01520 vtkVolumeMapper* vtkNotUsed(mapper), 01521 vtkVolume* vtkNotUsed(vol), 01522 vtkImageData* maskInput, 01523 vtkVolumeMask* mask, 01524 int maskType) 01525 { 01526 if (!mask || !maskInput || 01527 maskType != vtkGPUVolumeRayCastMapper::LabelMapMaskType) 01528 { 01529 return std::string(); 01530 } 01531 else 01532 { 01533 return std::string("\ 01534 \nvec4 scalar = texture3D(in_volume, g_dataPos);\ 01535 \nif (in_maskBlendFactor == 0.0)\ 01536 \n {\ 01537 \n g_srcColor = computeColor(scalar);\ 01538 \n }\ 01539 \nelse\ 01540 \n {\ 01541 \n // Get the mask value at this same location\ 01542 \n vec4 maskValue = texture3D(in_mask, g_dataPos);\ 01543 \n if(maskValue.a == 0.0)\ 01544 \n {\ 01545 \n g_srcColor = computeColor(scalar);\ 01546 \n }\ 01547 \n else\ 01548 \n {\ 01549 \n if (maskValue.a == 1.0/255.0)\ 01550 \n {\ 01551 \n g_srcColor = texture1D(in_mask1, scalar.w);\ 01552 \n }\ 01553 \n else\ 01554 \n {\ 01555 \n // maskValue.a == 2.0/255.0\ 01556 \n g_srcColor = texture1D(in_mask2, scalar.w);\ 01557 \n }\ 01558 \n g_srcColor.a = 1.0;\ 01559 \n if(in_maskBlendFactor < 1.0)\ 01560 \n {\ 01561 \n g_srcColor = (1.0 - in_maskBlendFactor) * computeColor(scalar)\ 01562 \n + in_maskBlendFactor * g_srcColor;\ 01563 \n }\ 01564 \n }\ 01565 \n g_srcColor.a = computeOpacity(scalar);\ 01566 \n }" 01567 ); 01568 } 01569 } 01570 } 01571 01572 #endif // _vtkVolumeShaderComposer_h 01573 // VTK-HeaderTest-Exclude: vtkVolumeShaderComposer.h