molstar
Version:
A comprehensive macromolecular library.
380 lines (316 loc) • 12.6 kB
JavaScript
"use strict";
/**
* Copyright (c) 2017-2025 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
* @author Michael Krone <michael.krone@uni-tuebingen.de>
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.directVolume_frag = void 0;
exports.directVolume_frag = `
precision highp float;
precision highp int;
uniform int uClipObjectType[dClipObjectCount];
uniform bool uClipObjectInvert[dClipObjectCount];
uniform vec3 uClipObjectPosition[dClipObjectCount];
uniform vec4 uClipObjectRotation[dClipObjectCount];
uniform vec3 uClipObjectScale[dClipObjectCount];
uniform mat4 uClipObjectTransform[dClipObjectCount];
uniform mat4 uProjection, uTransform, uModelView, uModel, uView;
uniform vec3 uCameraDir;
uniform sampler2D tDepth;
uniform vec2 uDrawingBufferSize;
varying vec3 vOrigPos;
varying float vInstance;
varying vec4 vBoundingSphere;
varying mat4 vTransform;
uniform mat4 uInvView;
uniform vec3 uGridDim;
uniform vec3 uBboxSize;
uniform sampler2D tTransferTex;
uniform float uTransferScale;
uniform float uStepScale;
uniform float uJumpLength;
uniform int uObjectId;
uniform int uVertexCount;
uniform int uInstanceCount;
uniform int uGroupCount;
uniform vec3 uHighlightColor;
uniform vec3 uSelectColor;
uniform vec3 uDimColor;
uniform float uHighlightStrength;
uniform float uSelectStrength;
uniform float uDimStrength;
uniform int uMarkerPriority;
uniform float uMarkerAverage;
uniform float uMarker;
uniform vec2 uMarkerTexDim;
uniform sampler2D tMarker;
uniform float uMetalness;
uniform float uRoughness;
uniform float uEmissive;
// Density value to estimate object thickness
uniform float uDensity;
uniform bool uFog;
uniform float uFogNear;
uniform float uFogFar;
uniform vec3 uFogColor;
uniform float uAlpha;
uniform bool uTransparentBackground;
uniform float uXrayEdgeFalloff;
uniform float uCelSteps;
uniform float uExposure;
uniform int uRenderMask;
uniform float uNear;
uniform float uFar;
uniform float uIsOrtho;
uniform vec3 uCellDim;
uniform vec3 uCameraPosition;
uniform mat4 uCartnToUnit;
// for webgl1 this is given as a 'define'
uniform int uMaxSteps;
precision highp sampler2D;
uniform sampler2D tGridTex;
uniform vec3 uGridTexDim;
precision highp sampler3D;
uniform sampler3D tGridTex;
uniform vec3 uColor;
uniform vec2 uColorTexDim;
uniform sampler2D tColor;
uniform vec2 uOverpaintTexDim;
uniform sampler2D tOverpaint;
uniform vec2 uPaletteDomain;
uniform sampler2D tPalette;
vec4 textureVal(vec3 pos) {
return texture3dFrom2dLinear(tGridTex, pos + (vec3(0.5, 0.5, 0.0) / uGridDim), uGridDim, uGridTexDim.xy);
}
vec4 textureGroup(vec3 pos) {
return texture3dFrom2dNearest(tGridTex, pos + (vec3(0.5, 0.5, 0.0) / uGridDim), uGridDim, uGridTexDim.xy);
}
vec4 textureVal(vec3 pos) {
return texture(tGridTex, pos + (vec3(0.5) / uGridDim));
}
vec4 textureGroup(vec3 pos) {
return texelFetch(tGridTex, ivec3(pos * uGridDim), 0);
}
float calcDepth(const in vec3 pos) {
vec2 clipZW = pos.z * uProjection[2].zw + uProjection[3].zw;
return 0.5 + 0.5 * clipZW.x / clipZW.y;
}
float transferFunction(float value) {
return texture2D(tTransferTex, vec2(value, 0.0)).a;
}
float getDepth(const in vec2 coords) {
return texture2D(tDepth, coords).r;
return unpackRGBAToDepth(texture2D(tDepth, coords));
}
const float gradOffset = 0.5;
vec3 v3m4(vec3 p, mat4 m) {
return (m * vec4(p, 1.0)).xyz;
}
float preFogAlphaBlended = 0.0;
vec4 raymarch(vec3 startLoc, vec3 step, vec3 rayDir) {
mat3 normalMatrix = adjoint(uModelView * vTransform);
mat4 cartnToUnit = uCartnToUnit * inverse4(vTransform);
mat4 modelTransform = uModel * vTransform * uTransform;
mat4 modelViewTransform = uModelView * vTransform * uTransform;
vec3 scaleVol = vec3(1.0) / uGridDim;
vec3 pos = startLoc;
vec4 cell;
float prevValue = -1.0;
float value = 0.0;
vec4 src = vec4(0.0);
vec4 dst = vec4(0.0);
float fragmentDepth;
vec3 posMin = vec3(0.0);
vec3 posMax = vec3(1.0) - vec3(1.0) / uGridDim;
vec3 unitPos;
vec3 nextPos;
float nextValue;
vec4 material;
vec4 overpaint;
float metalness = uMetalness;
float roughness = uRoughness;
float emissive = uEmissive;
vec3 gradient = vec3(1.0);
vec3 dx = vec3(gradOffset * scaleVol.x, 0.0, 0.0);
vec3 dy = vec3(0.0, gradOffset * scaleVol.y, 0.0);
vec3 dz = vec3(0.0, 0.0, gradOffset * scaleVol.z);
float maxDist = min(vBoundingSphere.w * 2.0, uFar - uNear);
float maxDistSq = maxDist * maxDist;
for (int i = 0; i < uMaxSteps; ++i) {
// break when beyond bounding-sphere or far-plane
vec3 distVec = startLoc - pos;
if (dot(distVec, distVec) > maxDistSq) break;
unitPos = v3m4(pos, cartnToUnit);
// continue when outside of grid
if (unitPos.x > posMax.x || unitPos.y > posMax.y || unitPos.z > posMax.z ||
unitPos.x < posMin.x || unitPos.y < posMin.y || unitPos.z < posMin.z
) {
prevValue = value;
pos += step;
continue;
}
cell = textureVal(unitPos);
value = cell.a; // current voxel value
if (uJumpLength > 0.0 && value < 0.01) {
nextPos = pos + rayDir * uJumpLength;
nextValue = textureVal(v3m4(nextPos, cartnToUnit)).a;
if (nextValue < 0.01) {
prevValue = nextValue;
pos = nextPos;
continue;
}
}
vec4 mvPosition = modelViewTransform * vec4(unitPos * uGridDim, 1.0);
if (calcDepth(mvPosition.xyz) > getDepth(gl_FragCoord.xy / uDrawingBufferSize))
break;
vec3 vModelPosition = v3m4(unitPos * uGridDim, modelTransform);
if (clipTest(modelPosition)) {
prevValue = value;
pos += step;
continue;
}
vec3 vViewPosition = mvPosition.xyz;
material.a = transferFunction(value);
float group = unpackRGBToInt(textureGroup(floor(unitPos * uGridDim + 0.5) / uGridDim).rgb);
vec3 g = floor(unitPos * uGridDim + 0.5);
// note that we swap x and z because the texture is flipped around y
float group = g.z + g.y * uGridDim.z + g.x * uGridDim.z * uGridDim.y; // 210
float group = g.y + g.z * uGridDim.y + g.x * uGridDim.y * uGridDim.z; // 120
float group = g.z + g.x * uGridDim.z + g.y * uGridDim.z * uGridDim.x; // 201
float group = g.x + g.z * uGridDim.x + g.y * uGridDim.x * uGridDim.z; // 021
float group = g.y + g.x * uGridDim.y + g.z * uGridDim.y * uGridDim.x; // 102
float group = g.x + g.y * uGridDim.x + g.z * uGridDim.x * uGridDim.y; // 012
float paletteValue = (value - uPaletteDomain[0]) / (uPaletteDomain[1] - uPaletteDomain[0]);
material.rgb = texture2D(tPalette, vec2(clamp(paletteValue, 0.0, 1.0), 0.0)).rgb;
material.rgb = uColor;
material.rgb = readFromTexture(tColor, vInstance, uColorTexDim).rgb;
material.rgb = readFromTexture(tColor, group, uColorTexDim).rgb;
material.rgb = readFromTexture(tColor, vInstance * float(uGroupCount) + group, uColorTexDim).rgb;
material.rgb = texture3dFrom1dTrilinear(tColor, unitPos, uGridDim, uColorTexDim, 0.0).rgb;
material.rgb = texture3dFrom1dTrilinear(tColor, unitPos, uGridDim, uColorTexDim, vInstance * float(uVertexCount)).rgb;
overpaint = readFromTexture(tOverpaint, vInstance * float(uGroupCount) + group, uOverpaintTexDim);
overpaint = texture3dFrom1dTrilinear(tOverpaint, unitPos, uGridDim, uOverpaintTexDim, vInstance * float(uVertexCount));
material.rgb = mix(material.rgb, overpaint.rgb, overpaint.a);
gl_FragColor.rgb = material.rgb;
if (material.a >= 0.01) {
// compute gradient by central differences
gradient.x = textureVal(unitPos - dx).a - textureVal(unitPos + dx).a;
gradient.y = textureVal(unitPos - dy).a - textureVal(unitPos + dy).a;
gradient.z = textureVal(unitPos - dz).a - textureVal(unitPos + dz).a;
gradient = cell.xyz * 2.0 - 1.0;
vec3 normal = -normalize(normalMatrix * normalize(gradient));
} else {
gl_FragColor.rgb = material.rgb;
}
gl_FragColor.a = material.a * uAlpha * uTransferScale;
float marker = uMarker;
if (uMarker == -1.0) {
marker = readFromTexture(tMarker, vInstance * float(uGroupCount) + group, uMarkerTexDim).a;
marker = floor(marker * 255.0 + 0.5); // rounding required to work on some cards on win
}
preFogAlphaBlended = (1.0 - preFogAlphaBlended) * gl_FragColor.a + preFogAlphaBlended;
fragmentDepth = calcDepth(mvPosition.xyz);
src = gl_FragColor;
if (!uTransparentBackground || !uFog) {
// done in 'apply_fog' otherwise
src.rgb *= src.a;
}
dst = (1.0 - dst.a) * src + dst; // standard blending
// break if the color is opaque enough
if (dst.a > 0.95)
break;
pos += step;
}
return dst;
}
// TODO: support float texture for higher precision values???
// TODO: support clipping exclusion texture support
void main() {
discard;
if (gl_FrontFacing)
discard;
vec3 rayDir = mix(normalize(vOrigPos - uCameraPosition), uCameraDir, uIsOrtho);
vec3 step = rayDir * uStepScale;
float boundingSphereNear = distance(vBoundingSphere.xyz, uCameraPosition) - vBoundingSphere.w;
float d = max(uNear, boundingSphereNear) - mix(0.0, distance(vOrigPos, uCameraPosition), uIsOrtho);
vec3 start = mix(uCameraPosition, vOrigPos, uIsOrtho) + (d * rayDir);
gl_FragColor = raymarch(start, step, rayDir);
float fragmentDepth = calcDepth((uModelView * vec4(start, 1.0)).xyz);
float preFogAlpha = clamp(preFogAlphaBlended, 0.0, 1.0);
}
`;