direct-volume.frag 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  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. precision highp float;
  8. varying vec3 unitCoord;
  9. varying vec3 origPos;
  10. varying float instance;
  11. uniform mat4 uInvView;
  12. uniform float uIsoValue;
  13. uniform vec3 uGridDim;
  14. uniform sampler2D tTransferTex;
  15. uniform int uObjectId;
  16. uniform int uInstanceCount;
  17. uniform int uGroupCount;
  18. uniform vec3 uHighlightColor;
  19. uniform vec3 uSelectColor;
  20. uniform vec2 uMarkerTexDim;
  21. uniform sampler2D tMarker;
  22. uniform float uAlpha;
  23. uniform float uPickingAlphaThreshold;
  24. uniform int uPickable;
  25. #if defined(dGridTexType_2d)
  26. precision mediump sampler2D;
  27. uniform sampler2D tGridTex;
  28. uniform vec3 uGridTexDim;
  29. #elif defined(dGridTexType_3d)
  30. precision mediump sampler3D;
  31. uniform sampler3D tGridTex;
  32. #endif
  33. #if defined(dColorType_uniform)
  34. uniform vec3 uColor;
  35. #elif defined(dColorType_instance) || defined(dColorType_group) || defined(dColorType_groupInstance)
  36. uniform vec2 uColorTexDim;
  37. uniform sampler2D tColor;
  38. #endif
  39. #pragma glslify: import('./chunks/common.glsl')
  40. #pragma glslify: readFromTexture = require(./utils/read-from-texture.glsl, intMod=intMod, intDiv=intDiv, foo=foo) // foo=foo is a workaround for a bug in glslify
  41. #pragma glslify: encodeFloatRGB = require(./utils/encode-float-rgb.glsl)
  42. #pragma glslify: decodeFloatRGB = require(./utils/decode-float-rgb.glsl)
  43. #pragma glslify: texture3dFrom2dNearest = require(./utils/texture3d-from-2d-nearest.glsl, intMod=intMod, intDiv=intDiv, foo=foo) // foo=foo is a workaround for a bug in glslify
  44. #pragma glslify: texture3dFrom2dLinear = require(./utils/texture3d-from-2d-linear.glsl, intMod=intMod, intDiv=intDiv, foo=foo) // foo=foo is a workaround for a bug in glslify
  45. // uniform vec3 uLightPosition;
  46. uniform vec3 uLightColor;
  47. uniform vec3 uLightAmbient;
  48. uniform mat4 uView;
  49. #pragma glslify: attenuation = require(./utils/attenuation.glsl)
  50. #pragma glslify: calculateSpecular = require(./utils/phong-specular.glsl)
  51. #pragma glslify: calculateDiffuse = require(./utils/oren-nayar-diffuse.glsl)
  52. const float specularScale = 0.15;
  53. const float shininess = 200.0;
  54. const float roughness = 100.0;
  55. const float albedo = 0.95;
  56. #if defined(dGridTexType_2d)
  57. vec4 textureVal(vec3 pos) {
  58. return texture3dFrom2dLinear(tGridTex, pos, uGridDim, uGridTexDim.xy);
  59. }
  60. vec4 textureGroup(vec3 pos) {
  61. vec3 nearestPos = floor(pos * uGridDim + 0.5) / uGridDim + 0.5 / uGridDim;
  62. return texture3dFrom2dNearest(tGridTex, nearestPos, uGridDim, uGridTexDim.xy);
  63. }
  64. #elif defined(dGridTexType_3d)
  65. vec4 textureVal(vec3 pos) {
  66. return texture(tGridTex, pos);
  67. }
  68. vec4 textureGroup(vec3 pos) {
  69. return texelFetch(tGridTex, ivec3(pos * uGridDim), 0);
  70. }
  71. #endif
  72. vec4 transferFunction(float value) {
  73. return texture2D(tTransferTex, vec2(value, 0.0));
  74. }
  75. const float gradOffset = 0.5;
  76. vec4 raymarch(vec3 startLoc, vec3 step, vec3 viewDir) {
  77. vec3 scaleVol = vec3(1.0) / uGridDim;
  78. vec3 pos = startLoc;
  79. float prevValue = -1.0;
  80. float value = 0.0;
  81. vec4 src = vec4(0.0);
  82. vec4 dst = vec4(0.0);
  83. #if defined(dRenderMode_isosurface)
  84. vec3 isoPos;
  85. float tmp;
  86. vec3 color = vec3(0.45, 0.55, 0.8);
  87. vec3 gradient = vec3(1.0);
  88. vec3 dx = vec3(gradOffset * scaleVol.x, 0.0, 0.0);
  89. vec3 dy = vec3(0.0, gradOffset * scaleVol.y, 0.0);
  90. vec3 dz = vec3(0.0, 0.0, gradOffset * scaleVol.z);
  91. #endif
  92. for(int i = 0; i < dMaxSteps; ++i){
  93. value = textureVal(pos).a; // current voxel value
  94. 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)
  95. break;
  96. #if defined(dRenderMode_volume)
  97. src = transferFunction(value);
  98. src.rgb *= src.a;
  99. dst = (1.0 - dst.a) * src + dst; // standard blending
  100. #endif
  101. #if defined(dRenderMode_isosurface)
  102. if(prevValue > 0.0 && ( // there was a prev Value
  103. (prevValue < uIsoValue && value > uIsoValue) || // entering isosurface
  104. (prevValue > uIsoValue && value < uIsoValue) // leaving isosurface
  105. )) {
  106. tmp = ((prevValue - uIsoValue) / ((prevValue - uIsoValue) - (value - uIsoValue)));
  107. isoPos = mix(pos - step, pos, tmp);
  108. #if defined(dColorType_objectPicking) || defined(dColorType_instancePicking) || defined(dColorType_groupPicking)
  109. if (uAlpha < uPickingAlphaThreshold)
  110. discard; // ignore so the element below can be picked
  111. if (uPickable == 0)
  112. return vec4(0.0, 0.0, 0.0, 1.0); // set to empty picking id
  113. #endif
  114. #if defined(dColorType_objectPicking)
  115. return vec4(encodeFloatRGB(float(uObjectId)), 1.0);
  116. #elif defined(dColorType_instancePicking)
  117. return vec4(encodeFloatRGB(instance), 1.0);
  118. #elif defined(dColorType_groupPicking)
  119. float group = floor(decodeFloatRGB(textureGroup(isoPos).rgb) + 0.5);
  120. return vec4(encodeFloatRGB(group), 1.0);
  121. #else
  122. // compute gradient by central differences
  123. gradient.x = textureVal(isoPos - dx).a - textureVal(isoPos + dx).a;
  124. gradient.y = textureVal(isoPos - dy).a - textureVal(isoPos + dy).a;
  125. gradient.z = textureVal(isoPos - dz).a - textureVal(isoPos + dz).a;
  126. gradient = normalize(gradient);
  127. float d = float(dot(gradient, viewDir) > 0.0);
  128. gradient = (2.0 * d - 1.0) * gradient;
  129. float group = floor(decodeFloatRGB(textureGroup(isoPos).rgb) + 0.5);
  130. #if defined(dColorType_instance)
  131. color = readFromTexture(tColor, instance, uColorTexDim).rgb;
  132. #elif defined(dColorType_group)
  133. color = readFromTexture(tColor, group, uColorTexDim).rgb;
  134. #elif defined(dColorType_groupInstance)
  135. color = readFromTexture(tColor, instance * float(uGroupCount) + group, uColorTexDim).rgb;
  136. #endif
  137. vec3 L = normalize(viewDir); // light direction
  138. vec3 V = normalize(viewDir); // eye direction
  139. vec3 N = normalize(gradient); // surface normal
  140. // compute our diffuse & specular terms
  141. float specular = calculateSpecular(L, V, N, shininess) * specularScale;
  142. vec3 diffuse = uLightColor * calculateDiffuse(L, V, N, roughness, albedo);
  143. vec3 ambient = uLightAmbient;
  144. // add the lighting
  145. vec3 finalColor = color.rgb * (diffuse + ambient) + specular;
  146. src.rgb = finalColor;
  147. src.a = uAlpha;
  148. float marker = readFromTexture(tMarker, instance * float(uGroupCount) + group, uMarkerTexDim).a * 255.0;
  149. if (marker > 0.1) {
  150. if (mod(marker, 2.0) > 0.1) {
  151. src.rgb = mix(uHighlightColor, src.rgb, 0.3);
  152. } else {
  153. src.rgb = mix(uSelectColor, src.rgb, 0.3);
  154. }
  155. }
  156. // draw interior darker
  157. if( (prevValue - uIsoValue) > 0.0 ) {
  158. src.rgb *= 0.5;
  159. }
  160. src.rgb *= src.a;
  161. dst = (1.0 - dst.a) * src + dst; // standard blending
  162. if(dst.a >= 1.0) {
  163. break;
  164. }
  165. #endif
  166. }
  167. prevValue = value;
  168. #endif
  169. pos += step;
  170. }
  171. return dst;
  172. }
  173. void main () {
  174. vec3 cameraPos = uInvView[3].xyz / uInvView[3].w;
  175. vec3 rayDir = normalize(origPos - cameraPos);
  176. vec3 startLoc = unitCoord;
  177. vec3 step = rayDir * (1.0 / uGridDim) * 0.1;
  178. gl_FragColor = raymarch(startLoc, step, normalize(cameraPos));
  179. if (length(gl_FragColor.rgb) < 0.00001) discard;
  180. #if defined(dRenderMode_volume)
  181. gl_FragColor.a *= uAlpha;
  182. #endif
  183. }