direct-volume.frag.ts 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /**
  2. * Copyright (c) 2017-2019 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. export default `
  8. precision highp float;
  9. varying vec3 unitCoord;
  10. varying vec3 origPos;
  11. varying float instance;
  12. uniform mat4 uInvView;
  13. uniform float uIsoValue;
  14. uniform vec3 uGridDim;
  15. uniform sampler2D tTransferTex;
  16. uniform int uObjectId;
  17. uniform int uInstanceCount;
  18. uniform int uGroupCount;
  19. uniform vec3 uHighlightColor;
  20. uniform vec3 uSelectColor;
  21. uniform vec2 uMarkerTexDim;
  22. uniform sampler2D tMarker;
  23. uniform float uAlpha;
  24. uniform float uPickingAlphaThreshold;
  25. uniform int uPickable;
  26. #if defined(dGridTexType_2d)
  27. precision highp sampler2D;
  28. uniform sampler2D tGridTex;
  29. uniform vec3 uGridTexDim;
  30. #elif defined(dGridTexType_3d)
  31. precision highp sampler3D;
  32. uniform sampler3D tGridTex;
  33. #endif
  34. #if defined(dColorType_uniform)
  35. uniform vec3 uColor;
  36. #elif defined(dColorType_instance) || defined(dColorType_group) || defined(dColorType_groupInstance)
  37. uniform vec2 uColorTexDim;
  38. uniform sampler2D tColor;
  39. #endif
  40. #include common
  41. #include light_frag_params
  42. #include read_from_texture
  43. #include texture3d_from_2d_nearest
  44. #include texture3d_from_2d_linear
  45. #if defined(dGridTexType_2d)
  46. vec4 textureVal(vec3 pos) {
  47. return texture3dFrom2dLinear(tGridTex, pos, uGridDim, uGridTexDim.xy);
  48. }
  49. vec4 textureGroup(vec3 pos) {
  50. vec3 nearestPos = floor(pos * uGridDim + 0.5) / uGridDim + 0.5 / uGridDim;
  51. return texture3dFrom2dNearest(tGridTex, nearestPos, uGridDim, uGridTexDim.xy);
  52. }
  53. #elif defined(dGridTexType_3d)
  54. vec4 textureVal(vec3 pos) {
  55. return texture(tGridTex, pos);
  56. }
  57. vec4 textureGroup(vec3 pos) {
  58. return texelFetch(tGridTex, ivec3(pos * uGridDim), 0);
  59. }
  60. #endif
  61. vec4 transferFunction(float value) {
  62. return texture2D(tTransferTex, vec2(value, 0.0));
  63. }
  64. const float gradOffset = 0.5;
  65. vec4 raymarch(vec3 startLoc, vec3 step, vec3 viewDir) {
  66. vec3 scaleVol = vec3(1.0) / uGridDim;
  67. vec3 pos = startLoc;
  68. float prevValue = -1.0;
  69. float value = 0.0;
  70. vec4 src = vec4(0.0);
  71. vec4 dst = vec4(0.0);
  72. #if defined(dRenderMode_isosurface)
  73. vec3 isoPos;
  74. float tmp;
  75. vec3 color = vec3(0.45, 0.55, 0.8);
  76. vec3 gradient = vec3(1.0);
  77. vec3 dx = vec3(gradOffset * scaleVol.x, 0.0, 0.0);
  78. vec3 dy = vec3(0.0, gradOffset * scaleVol.y, 0.0);
  79. vec3 dz = vec3(0.0, 0.0, gradOffset * scaleVol.z);
  80. #endif
  81. for(int i = 0; i < dMaxSteps; ++i){
  82. value = textureVal(pos).a; // current voxel value
  83. 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)
  84. break;
  85. #if defined(dRenderMode_volume)
  86. src = transferFunction(value);
  87. src.rgb *= src.a;
  88. dst = (1.0 - dst.a) * src + dst; // standard blending
  89. #endif
  90. #if defined(dRenderMode_isosurface)
  91. if(prevValue > 0.0 && ( // there was a prev Value
  92. (prevValue < uIsoValue && value > uIsoValue) || // entering isosurface
  93. (prevValue > uIsoValue && value < uIsoValue) // leaving isosurface
  94. )) {
  95. tmp = ((prevValue - uIsoValue) / ((prevValue - uIsoValue) - (value - uIsoValue)));
  96. isoPos = mix(pos - step, pos, tmp);
  97. #if defined(dColorType_objectPicking) || defined(dColorType_instancePicking) || defined(dColorType_groupPicking)
  98. if (uAlpha < uPickingAlphaThreshold)
  99. discard; // ignore so the element below can be picked
  100. if (uPickable == 0)
  101. return vec4(0.0, 0.0, 0.0, 1.0); // set to empty picking id
  102. #endif
  103. #if defined(dColorType_objectPicking)
  104. return vec4(encodeFloatRGB(float(uObjectId)), 1.0);
  105. #elif defined(dColorType_instancePicking)
  106. return vec4(encodeFloatRGB(instance), 1.0);
  107. #elif defined(dColorType_groupPicking)
  108. float group = floor(decodeFloatRGB(textureGroup(isoPos).rgb) + 0.5);
  109. return vec4(encodeFloatRGB(group), 1.0);
  110. #else
  111. // compute gradient by central differences
  112. gradient.x = textureVal(isoPos - dx).a - textureVal(isoPos + dx).a;
  113. gradient.y = textureVal(isoPos - dy).a - textureVal(isoPos + dy).a;
  114. gradient.z = textureVal(isoPos - dz).a - textureVal(isoPos + dz).a;
  115. gradient = normalize(gradient);
  116. float d = float(dot(gradient, viewDir) > 0.0);
  117. gradient = (2.0 * d - 1.0) * gradient;
  118. float group = floor(decodeFloatRGB(textureGroup(isoPos).rgb) + 0.5);
  119. #if defined(dColorType_instance)
  120. color = readFromTexture(tColor, instance, uColorTexDim).rgb;
  121. #elif defined(dColorType_group)
  122. color = readFromTexture(tColor, group, uColorTexDim).rgb;
  123. #elif defined(dColorType_groupInstance)
  124. color = readFromTexture(tColor, instance * float(uGroupCount) + group, uColorTexDim).rgb;
  125. #endif
  126. vec3 normal = normalize(gradient);
  127. vec3 vViewPosition = normalize(viewDir);
  128. vec4 material = vec4(color, uAlpha);
  129. #include apply_light_color
  130. float vMarker = readFromTexture(tMarker, instance * float(uGroupCount) + group, uMarkerTexDim).a;
  131. #include apply_marker_color
  132. src.rgb = gl_FragColor.rgb;
  133. src.a = gl_FragColor.a;
  134. // draw interior darker
  135. if( (prevValue - uIsoValue) > 0.0 ) {
  136. src.rgb *= 0.5;
  137. }
  138. src.rgb *= src.a;
  139. dst = (1.0 - dst.a) * src + dst; // standard blending
  140. if(dst.a >= 1.0) {
  141. break;
  142. }
  143. #endif
  144. }
  145. prevValue = value;
  146. #endif
  147. pos += step;
  148. }
  149. return dst;
  150. }
  151. void main () {
  152. vec3 cameraPos = uInvView[3].xyz / uInvView[3].w;
  153. vec3 rayDir = normalize(origPos - cameraPos);
  154. vec3 startLoc = unitCoord;
  155. vec3 step = rayDir * (1.0 / uGridDim) * 0.1;
  156. gl_FragColor = raymarch(startLoc, step, normalize(cameraPos));
  157. if (length(gl_FragColor.rgb) < 0.00001) discard;
  158. #if defined(dRenderMode_volume)
  159. gl_FragColor.a *= uAlpha;
  160. #endif
  161. }
  162. `