direct-volume.frag.ts 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. /**
  2. * Copyright (c) 2017-2020 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. precision highp int;
  10. #include common
  11. #include light_frag_params
  12. #if dClipObjectCount != 0
  13. uniform int uClipObjectType[dClipObjectCount];
  14. uniform vec3 uClipObjectPosition[dClipObjectCount];
  15. uniform vec4 uClipObjectRotation[dClipObjectCount];
  16. uniform vec3 uClipObjectScale[dClipObjectCount];
  17. #endif
  18. #include common_clip
  19. #include read_from_texture
  20. #include texture3d_from_1d_trilinear
  21. #include texture3d_from_2d_nearest
  22. #include texture3d_from_2d_linear
  23. uniform mat4 uProjection, uTransform, uModelView, uModel, uView;
  24. uniform vec3 uCameraDir;
  25. uniform sampler2D tDepth;
  26. uniform vec2 uDrawingBufferSize;
  27. uniform float uNear;
  28. uniform float uFar;
  29. varying vec3 vOrigPos;
  30. varying float vInstance;
  31. varying vec4 vBoundingSphere;
  32. varying mat4 vTransform;
  33. uniform mat4 uInvView;
  34. uniform vec2 uIsoValue;
  35. uniform vec3 uGridDim;
  36. uniform vec3 uBboxSize;
  37. uniform sampler2D tTransferTex;
  38. uniform float uTransferScale;
  39. uniform float uStepScale;
  40. uniform float uJumpLength;
  41. uniform int uObjectId;
  42. uniform int uVertexCount;
  43. uniform int uInstanceCount;
  44. uniform int uGroupCount;
  45. uniform vec3 uHighlightColor;
  46. uniform vec3 uSelectColor;
  47. uniform vec2 uMarkerTexDim;
  48. uniform sampler2D tMarker;
  49. uniform float uFogNear;
  50. uniform float uFogFar;
  51. uniform vec3 uFogColor;
  52. uniform float uAlpha;
  53. uniform float uPickingAlphaThreshold;
  54. uniform bool uTransparentBackground;
  55. uniform float uInteriorDarkening;
  56. uniform bool uInteriorColorFlag;
  57. uniform vec3 uInteriorColor;
  58. bool interior;
  59. uniform float uIsOrtho;
  60. uniform vec3 uCellDim;
  61. uniform vec3 uCameraPosition;
  62. uniform mat4 uCartnToUnit;
  63. #if __VERSION__ == 300
  64. // for webgl1 this is given as a 'define'
  65. uniform int uMaxSteps;
  66. #endif
  67. #if defined(dGridTexType_2d)
  68. precision highp sampler2D;
  69. uniform sampler2D tGridTex;
  70. uniform vec3 uGridTexDim;
  71. #elif defined(dGridTexType_3d)
  72. precision highp sampler3D;
  73. uniform sampler3D tGridTex;
  74. #endif
  75. #if defined(dRenderVariant_color)
  76. #if defined(dColorType_uniform)
  77. uniform vec3 uColor;
  78. #elif defined(dColorType_texture)
  79. uniform vec2 uColorTexDim;
  80. uniform sampler2D tColor;
  81. #endif
  82. #ifdef dOverpaint
  83. varying vec4 vOverpaint;
  84. uniform vec2 uOverpaintTexDim;
  85. uniform sampler2D tOverpaint;
  86. #endif
  87. #endif
  88. #if defined(dGridTexType_2d)
  89. vec4 textureVal(vec3 pos) {
  90. return texture3dFrom2dLinear(tGridTex, pos + (vec3(0.5, 0.5, 0.0) / uGridDim), uGridDim, uGridTexDim.xy);
  91. }
  92. vec4 textureGroup(vec3 pos) {
  93. return texture3dFrom2dNearest(tGridTex, pos + (vec3(0.5, 0.5, 0.0) / uGridDim), uGridDim, uGridTexDim.xy);
  94. }
  95. #elif defined(dGridTexType_3d)
  96. vec4 textureVal(vec3 pos) {
  97. return texture(tGridTex, pos + (vec3(0.5) / uGridDim));
  98. }
  99. vec4 textureGroup(vec3 pos) {
  100. return texelFetch(tGridTex, ivec3(pos * uGridDim), 0);
  101. }
  102. #endif
  103. #include wboit_params
  104. vec4 transferFunction(float value) {
  105. return texture2D(tTransferTex, vec2(value, 0.0));
  106. }
  107. float getDepth(const in vec2 coords) {
  108. #ifdef dPackedDepth
  109. return unpackRGBAToDepth(texture2D(tDepth, coords));
  110. #else
  111. return texture2D(tDepth, coords).r;
  112. #endif
  113. }
  114. const float gradOffset = 0.5;
  115. vec3 v3m4(vec3 p, mat4 m) {
  116. return (m * vec4(p, 1.0)).xyz;
  117. }
  118. vec4 raymarch(vec3 startLoc, vec3 step, vec3 rayDir) {
  119. #if defined(dRenderVariant_color) && !defined(dIgnoreLight)
  120. mat3 normalMatrix = transpose3(inverse3(mat3(uModelView * vTransform)));
  121. #endif
  122. mat4 cartnToUnit = uCartnToUnit * inverse4(vTransform);
  123. #if defined(dClipVariant_pixel) && dClipObjectCount != 0
  124. mat4 modelTransform = uModel * vTransform * uTransform;
  125. #endif
  126. mat4 modelViewTransform = uModelView * vTransform * uTransform;
  127. vec3 scaleVol = vec3(1.0) / uGridDim;
  128. vec3 pos = startLoc;
  129. vec4 cell;
  130. float prevValue = -1.0;
  131. float value = 0.0;
  132. vec4 src = vec4(0.0);
  133. vec4 dst = vec4(0.0);
  134. bool hit = false;
  135. vec3 posMin = vec3(0.0);
  136. vec3 posMax = vec3(1.0) - vec3(1.0) / uGridDim;
  137. vec3 unitPos;
  138. vec3 isoPos;
  139. vec3 nextPos;
  140. float nextValue;
  141. vec3 color = vec3(0.45, 0.55, 0.8);
  142. vec3 gradient = vec3(1.0);
  143. vec3 dx = vec3(gradOffset * scaleVol.x, 0.0, 0.0);
  144. vec3 dy = vec3(0.0, gradOffset * scaleVol.y, 0.0);
  145. vec3 dz = vec3(0.0, 0.0, gradOffset * scaleVol.z);
  146. float maxDist = min(vBoundingSphere.w * 2.0, uFar - uNear);
  147. float maxDistSq = maxDist * maxDist;
  148. for (int i = 0; i < uMaxSteps; ++i) {
  149. // break when beyond bounding-sphere or far-plane
  150. vec3 distVec = startLoc - pos;
  151. if (dot(distVec, distVec) > maxDistSq) break;
  152. unitPos = v3m4(pos, cartnToUnit);
  153. // continue when outside of grid
  154. if (unitPos.x > posMax.x || unitPos.y > posMax.y || unitPos.z > posMax.z ||
  155. unitPos.x < posMin.x || unitPos.y < posMin.y || unitPos.z < posMin.z
  156. ) {
  157. if (hit) break;
  158. prevValue = value;
  159. pos += step;
  160. continue;
  161. }
  162. cell = textureVal(unitPos);
  163. value = cell.a; // current voxel value
  164. if (uJumpLength > 0.0 && value < 0.01) {
  165. nextPos = pos + rayDir * uJumpLength;
  166. nextValue = textureVal(v3m4(nextPos, cartnToUnit)).a;
  167. if (nextValue < 0.01) {
  168. prevValue = nextValue;
  169. pos = nextPos;
  170. continue;
  171. }
  172. }
  173. #if defined(dRenderMode_isosurface)
  174. if (prevValue > 0.0 && ( // there was a prev Value
  175. (prevValue < uIsoValue.x && value > uIsoValue.x) || // entering isosurface
  176. (prevValue > uIsoValue.x && value < uIsoValue.x) // leaving isosurface
  177. )) {
  178. isoPos = v3m4(mix(pos - step, pos, ((prevValue - uIsoValue.x) / ((prevValue - uIsoValue.x) - (value - uIsoValue.x)))), cartnToUnit);
  179. vec4 mvPosition = modelViewTransform * vec4(isoPos * uGridDim, 1.0);
  180. #if defined(dClipVariant_pixel) && dClipObjectCount != 0
  181. vec3 vModelPosition = v3m4(isoPos * uGridDim, modelTransform);
  182. if (clipTest(vec4(vModelPosition, 0.0), 0)) {
  183. prevValue = value;
  184. pos += step;
  185. continue;
  186. }
  187. #endif
  188. float depth = calcDepth(mvPosition.xyz);
  189. if (depth > getDepth(gl_FragCoord.xy / uDrawingBufferSize))
  190. break;
  191. #ifdef enabledFragDepth
  192. if (!hit) {
  193. gl_FragDepthEXT = depth;
  194. hit = true;
  195. }
  196. #endif
  197. #if defined(dRenderVariant_pickObject)
  198. return vec4(encodeFloatRGB(float(uObjectId)), 1.0);
  199. #elif defined(dRenderVariant_pickInstance)
  200. return vec4(encodeFloatRGB(vInstance), 1.0);
  201. #elif defined(dRenderVariant_pickGroup)
  202. #ifdef dPackedGroup
  203. return vec4(textureGroup(floor(isoPos * uGridDim + 0.5) / uGridDim).rgb, 1.0);
  204. #else
  205. vec3 g = floor(isoPos * uGridDim + 0.5);
  206. return vec4(encodeFloatRGB(g.z + g.y * uGridDim.z + g.x * uGridDim.z * uGridDim.y), 1.0);
  207. #endif
  208. #elif defined(dRenderVariant_depth)
  209. #ifdef enabledFragDepth
  210. return packDepthToRGBA(gl_FragDepthEXT);
  211. #else
  212. return packDepthToRGBA(gl_FragCoord.z);
  213. #endif
  214. #elif defined(dRenderVariant_color)
  215. #ifdef dPackedGroup
  216. float group = decodeFloatRGB(textureGroup(floor(isoPos * uGridDim + 0.5) / uGridDim).rgb);
  217. #else
  218. vec3 g = floor(isoPos * uGridDim + 0.5);
  219. float group = g.z + g.y * uGridDim.z + g.x * uGridDim.z * uGridDim.y;
  220. #endif
  221. #if defined(dColorType_uniform)
  222. color = uColor;
  223. #elif defined(dColorType_instance)
  224. color = readFromTexture(tColor, vInstance, uColorTexDim).rgb;
  225. #elif defined(dColorType_group)
  226. color = readFromTexture(tColor, group, uColorTexDim).rgb;
  227. #elif defined(dColorType_groupInstance)
  228. color = readFromTexture(tColor, vInstance * float(uGroupCount) + group, uColorTexDim).rgb;
  229. #elif defined(dColorType_vertex)
  230. color = texture3dFrom1dTrilinear(tColor, isoPos, uGridDim, uColorTexDim, 0.0).rgb;
  231. #elif defined(dColorType_vertexInstance)
  232. color = texture3dFrom1dTrilinear(tColor, isoPos, uGridDim, uColorTexDim, vInstance * float(uVertexCount)).rgb;
  233. #endif
  234. // handle flipping and negative isosurfaces
  235. #ifdef dFlipSided
  236. bool flipped = value < uIsoValue.y; // flipped
  237. #else
  238. bool flipped = value > uIsoValue.y;
  239. #endif
  240. interior = value < uIsoValue.x && flipped;
  241. #ifndef dDoubleSided
  242. if (interior) {
  243. prevValue = value;
  244. pos += step;
  245. continue;
  246. }
  247. #endif
  248. vec3 vViewPosition = mvPosition.xyz;
  249. vec4 material = vec4(color, uAlpha);
  250. #ifdef dIgnoreLight
  251. gl_FragColor = material;
  252. #else
  253. #if defined(dFlatShaded)
  254. // nearest grid point
  255. isoPos = floor(isoPos * uGridDim + 0.5) / uGridDim;
  256. #endif
  257. #ifdef dPackedGroup
  258. // compute gradient by central differences
  259. gradient.x = textureVal(isoPos - dx).a - textureVal(isoPos + dx).a;
  260. gradient.y = textureVal(isoPos - dy).a - textureVal(isoPos + dy).a;
  261. gradient.z = textureVal(isoPos - dz).a - textureVal(isoPos + dz).a;
  262. #else
  263. gradient = textureVal(isoPos).xyz * 2.0 - 1.0;
  264. #endif
  265. vec3 normal = -normalize(normalMatrix * normalize(gradient));
  266. normal = normal * (float(flipped) * 2.0 - 1.0);
  267. normal = normal * -(float(interior) * 2.0 - 1.0);
  268. #include apply_light_color
  269. #endif
  270. float vMarker = readFromTexture(tMarker, vInstance * float(uGroupCount) + group, uMarkerTexDim).a;
  271. #include apply_interior_color
  272. #include apply_marker_color
  273. #include apply_fog
  274. src = gl_FragColor;
  275. src.rgb *= src.a;
  276. dst = (1.0 - dst.a) * src + dst; // standard blending
  277. #endif
  278. #ifdef dSingleLayer
  279. break;
  280. #endif
  281. }
  282. prevValue = value;
  283. #elif defined(dRenderMode_volume)
  284. vec4 mvPosition = modelViewTransform * vec4(unitPos * uGridDim, 1.0);
  285. if (calcDepth(mvPosition.xyz) > getDepth(gl_FragCoord.xy / uDrawingBufferSize))
  286. break;
  287. #if defined(dClipVariant_pixel) && dClipObjectCount != 0
  288. vec3 vModelPosition = v3m4(unitPos * uGridDim, modelTransform);
  289. if (clipTest(vec4(vModelPosition, 0.0), 0)) {
  290. prevValue = value;
  291. pos += step;
  292. continue;
  293. }
  294. #endif
  295. #if defined(dRenderVariant_color)
  296. vec3 vViewPosition = mvPosition.xyz;
  297. vec4 material = transferFunction(value);
  298. #ifdef dIgnoreLight
  299. gl_FragColor.rgb = material.rgb;
  300. #else
  301. if (material.a >= 0.01) {
  302. #ifdef dPackedGroup
  303. // compute gradient by central differences
  304. gradient.x = textureVal(unitPos - dx).a - textureVal(unitPos + dx).a;
  305. gradient.y = textureVal(unitPos - dy).a - textureVal(unitPos + dy).a;
  306. gradient.z = textureVal(unitPos - dz).a - textureVal(unitPos + dz).a;
  307. #else
  308. gradient = cell.xyz * 2.0 - 1.0;
  309. #endif
  310. vec3 normal = -normalize(normalMatrix * normalize(gradient));
  311. #include apply_light_color
  312. } else {
  313. gl_FragColor.rgb = material.rgb;
  314. }
  315. #endif
  316. gl_FragColor.a = material.a * uAlpha * uTransferScale;
  317. #ifdef dPackedGroup
  318. float group = decodeFloatRGB(textureGroup(floor(unitPos * uGridDim + 0.5) / uGridDim).rgb);
  319. #else
  320. vec3 g = floor(unitPos * uGridDim + 0.5);
  321. float group = g.z + g.y * uGridDim.z + g.x * uGridDim.z * uGridDim.y;
  322. #endif
  323. float vMarker = readFromTexture(tMarker, vInstance * float(uGroupCount) + group, uMarkerTexDim).a;
  324. #include apply_marker_color
  325. #include apply_fog
  326. src = gl_FragColor;
  327. src.rgb *= src.a;
  328. dst = (1.0 - dst.a) * src + dst; // standard blending
  329. #endif
  330. #endif
  331. // break if the color is opaque enough
  332. if (dst.a > 0.95)
  333. break;
  334. pos += step;
  335. }
  336. #if defined(dRenderMode_isosurface) && defined(enabledFragDepth)
  337. // ensure depth is written everywhere
  338. if (!hit)
  339. gl_FragDepthEXT = 1.0;
  340. #endif
  341. return dst;
  342. }
  343. // TODO: support float texture for higher precision values???
  344. // TODO: support clipping exclusion texture support
  345. void main () {
  346. #if defined(dRenderVariant_pick) || defined(dRenderVariant_depth)
  347. #if defined(dRenderMode_volume)
  348. // always ignore pick & depth for volume
  349. discard;
  350. #elif defined(dRenderMode_isosurface)
  351. if (uAlpha < uPickingAlphaThreshold)
  352. discard; // ignore so the element below can be picked
  353. #endif
  354. #endif
  355. vec3 rayDir = mix(normalize(vOrigPos - uCameraPosition), uCameraDir, uIsOrtho);
  356. vec3 step = rayDir * uStepScale;
  357. float boundingSphereNear = distance(vBoundingSphere.xyz, uCameraPosition) - vBoundingSphere.w;
  358. float d = max(uNear, boundingSphereNear);
  359. gl_FragColor = raymarch(uCameraPosition + (d * rayDir), step, rayDir);
  360. #if defined(dRenderVariant_pick) || defined(dRenderVariant_depth)
  361. // discard when nothing was hit
  362. if (gl_FragColor == vec4(0.0))
  363. discard;
  364. #endif
  365. #if defined(dRenderVariant_color)
  366. float absFragDepth = abs(calcDepth((uView * vec4(uCameraPosition + (d * rayDir), 1.0)).xyz));
  367. #include wboit_write
  368. #endif
  369. }
  370. `;