molstar
Version:
A comprehensive macromolecular library.
2 lines (1 loc) • 2.81 kB
TypeScript
export declare const activeVoxels_frag = "\nprecision highp float;\nprecision highp int;\nprecision highp sampler2D;\n\nuniform sampler2D tTriCount;\nuniform sampler2D tVolumeData;\n\nuniform float uIsoValue;\nuniform vec3 uGridDim;\nuniform vec3 uGridTexDim;\nuniform vec2 uScale;\n\n#include common\n\n// cube corners (excluding origin)\nconst vec3 c1 = vec3(1., 0., 0.);\nconst vec3 c2 = vec3(1., 1., 0.);\nconst vec3 c3 = vec3(0., 1., 0.);\nconst vec3 c4 = vec3(0., 0., 1.);\nconst vec3 c5 = vec3(1., 0., 1.);\nconst vec3 c6 = vec3(1., 1., 1.);\nconst vec3 c7 = vec3(0., 1., 1.);\n\nvec3 index3dFrom2d(vec2 coord) {\n vec2 gridTexPos = coord * uGridTexDim.xy;\n vec2 columnRow = ivec2Div(gridTexPos, uGridDim.xy);\n vec2 posXY = gridTexPos - columnRow * uGridDim.xy;\n float posZ = columnRow.y * intDiv(uGridTexDim.x, uGridDim.x) + columnRow.x;\n return vec3(posXY, posZ);\n}\n\nvec4 texture3dFrom2dNearest(sampler2D tex, vec3 pos, vec3 gridDim, vec2 texDim) {\n float zSlice = floor(pos.z * gridDim.z + 0.5); // round to nearest z-slice\n float column = intDiv(intMod(zSlice * gridDim.x, texDim.x), gridDim.x);\n float row = intDiv(zSlice * gridDim.x, texDim.x);\n vec2 coord = (vec2(column * gridDim.x, row * gridDim.y) + (pos.xy * gridDim.xy)) / (texDim / uScale);\n return texture2D(tex, coord);\n}\n\nfloat voxelValue(vec3 pos) {\n pos = min(max(vec3(0.0), pos), uGridDim - vec3(1.0));\n vec4 v = texture3dFrom2dNearest(tVolumeData, pos / uGridDim, uGridDim, uGridTexDim.xy);\n #ifdef dValueChannel_red\n return v.r;\n #else\n return v.a;\n #endif\n}\n\nvoid main(void) {\n vec2 uv = gl_FragCoord.xy / uGridTexDim.xy;\n vec3 posXYZ = index3dFrom2d(uv);\n\n // get MC case as the sum of corners that are below the given iso level\n float c = step(voxelValue(posXYZ), uIsoValue)\n + 2. * step(voxelValue(posXYZ + c1), uIsoValue)\n + 4. * step(voxelValue(posXYZ + c2), uIsoValue)\n + 8. * step(voxelValue(posXYZ + c3), uIsoValue)\n + 16. * step(voxelValue(posXYZ + c4), uIsoValue)\n + 32. * step(voxelValue(posXYZ + c5), uIsoValue)\n + 64. * step(voxelValue(posXYZ + c6), uIsoValue)\n + 128. * step(voxelValue(posXYZ + c7), uIsoValue);\n c *= step(c, 254.);\n\n // handle out of bounds positions\n posXYZ += 1.0;\n posXYZ.xy += 1.0; // pixel padding (usually ok even if the texture has no padding)\n if (posXYZ.x >= uGridDim.x || posXYZ.y >= uGridDim.y || posXYZ.z >= uGridDim.z)\n c = 0.0;\n\n // get total triangles to generate for calculated MC case from triCount texture\n float totalTrianglesToGenerate = texture2D(tTriCount, vec2(intMod(c, 16.), floor(c / 16.)) / 16.).a;\n gl_FragColor = vec4(vec3(totalTrianglesToGenerate * 3.0), c / 255.0);\n}\n";