direct-volume.frag 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /**
  2. * Copyright (c) 2017-2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. * @author Michael Krone <michael.krone@uni-tuebingen.de>
  6. */
  7. #if defined(dGridTexType_2d)
  8. precision mediump sampler2D;
  9. #elif defined(dGridTexType_3d)
  10. precision mediump sampler3D;
  11. #endif
  12. precision highp float;
  13. varying vec3 unitCoord;
  14. varying vec3 origPos;
  15. uniform float uAlpha;
  16. uniform mat4 uInvView;
  17. uniform float uIsoValue;
  18. uniform vec3 uGridDim;
  19. uniform sampler2D tTransferTex;
  20. #if defined(dGridTexType_2d)
  21. uniform sampler2D tGridTex;
  22. uniform vec2 uGridTexDim;
  23. #elif defined(dGridTexType_3d)
  24. uniform sampler3D tGridTex;
  25. #endif
  26. #if defined(dGridTexType_2d)
  27. // TODO workaround due to some kind of GPU bug
  28. float myMod(float a, float b) {
  29. return a - b * float(int(a) / int(b));
  30. }
  31. float myDiv(float a, float b) {
  32. return float(int(a) / int(b));
  33. }
  34. vec4 textureVal(vec3 pos) {
  35. float zSlice0 = floor(pos.z * uGridDim.z);
  36. float column0 = myMod(zSlice0 * uGridDim.x, uGridTexDim.x) / uGridDim.x;
  37. float row0 = floor(myDiv(zSlice0 * uGridDim.x, uGridTexDim.x));
  38. vec2 coord0 = (vec2(column0 * uGridDim.x, row0 * uGridDim.y) + (pos.xy * uGridDim.xy)) / uGridTexDim;
  39. vec4 color0 = texture2D(tGridTex, coord0);
  40. float zSlice1 = zSlice0 + 1.0;
  41. float column1 = myMod(zSlice1 * uGridDim.x, uGridTexDim.x) / uGridDim.x;
  42. float row1 = floor(myDiv(zSlice1 * uGridDim.x, uGridTexDim.x));
  43. vec2 coord1 = (vec2(column1 * uGridDim.x, row1 * uGridDim.y) + (pos.xy * uGridDim.xy)) / uGridTexDim;
  44. vec4 color1 = texture2D(tGridTex, coord1);
  45. float delta0 = abs((pos.z * uGridDim.z) - zSlice0);
  46. return mix(color0, color1, delta0);
  47. }
  48. #elif defined(dGridTexType_3d)
  49. vec4 textureVal(vec3 pos) {
  50. return texture(tGridTex, pos);
  51. }
  52. #endif
  53. vec4 transferFunction(float value) {
  54. return texture2D(tTransferTex, vec2(value, 0.0));
  55. }
  56. const float gradOffset = 0.5;
  57. const vec3 color = vec3(0.45, 0.55, 0.8);
  58. vec4 raymarch(vec3 startLoc, vec3 step, vec3 viewDir) {
  59. vec3 scaleVol = vec3(1.0) / uGridDim;
  60. vec3 pos = startLoc + scaleVol * 0.5;
  61. float prevValue = -1.0;
  62. float value = 0.0;
  63. vec4 src = vec4(0.0);
  64. vec4 dst = vec4(0.0);
  65. #if defined(dRenderMode_isosurface)
  66. vec3 isoPos;
  67. float tmp;
  68. vec3 gradient = vec3(1.0);
  69. vec3 dx = vec3(gradOffset * scaleVol.x, 0.0, 0.0);
  70. vec3 dy = vec3(0.0, gradOffset * scaleVol.y, 0.0);
  71. vec3 dz = vec3(0.0, 0.0, gradOffset * scaleVol.z);
  72. #endif
  73. for(int i = 0; i < dMaxSteps; ++i){
  74. value = textureVal(pos).a; // current voxel value
  75. if(pos.x > 1.01 || pos.y > 1.01 || pos.z > 1.01 || pos.x < -0.01 || pos.y < -0.01 || pos.z < -0.01)
  76. break;
  77. #if defined(dRenderMode_volume)
  78. src = transferFunction(value);
  79. src.rgb *= src.a;
  80. dst = (1.0 - dst.a) * src + dst; // standard blending
  81. #endif
  82. #if defined(dRenderMode_isosurface)
  83. if(prevValue > 0.0 && ( // there was a prev Value
  84. (prevValue < uIsoValue && value > uIsoValue) || // entering isosurface
  85. (prevValue > uIsoValue && value < uIsoValue) // leaving isosurface
  86. )) {
  87. tmp = ((prevValue - uIsoValue) / ((prevValue - uIsoValue) - (value - uIsoValue)));
  88. isoPos = mix(pos - step, pos, tmp);
  89. // compute gradient by central differences
  90. gradient.x = textureVal(isoPos - dx).a - textureVal(isoPos + dx).a;
  91. gradient.y = textureVal(isoPos - dy).a - textureVal(isoPos + dy).a;
  92. gradient.z = textureVal(isoPos - dz).a - textureVal(isoPos + dz).a;
  93. gradient = normalize(gradient);
  94. float d = float(dot(gradient, viewDir) > 0.0);
  95. gradient = (2.0 * d - 1.0) * gradient;
  96. src.rgb = color.rgb * abs(dot(gradient, viewDir));
  97. src.a = uAlpha;
  98. // draw interior darker
  99. if( (prevValue - uIsoValue) > 0.0 ) {
  100. src.rgb *= 0.5;
  101. }
  102. src.rgb *= src.a;
  103. dst = (1.0 - dst.a) * src + dst; // standard blending
  104. if(dst.a >= 1.0) {
  105. break;
  106. }
  107. }
  108. prevValue = value;
  109. #endif
  110. pos += step;
  111. }
  112. return dst;
  113. }
  114. void main () {
  115. vec3 cameraPos = uInvView[3].xyz / uInvView[3].w;
  116. vec3 rayDir = normalize(origPos - cameraPos);
  117. vec3 startLoc = unitCoord;
  118. vec3 step = rayDir * (1.0 / uGridDim) * 0.5;
  119. gl_FragColor = raymarch(startLoc, step, normalize(cameraPos));
  120. if (length(gl_FragColor.rgb) < 0.00001) discard;
  121. #if defined(dRenderMode_volume)
  122. gl_FragColor.a *= uAlpha;
  123. #endif
  124. }