molstar
Version:
A comprehensive macromolecular library.
316 lines (280 loc) • 11.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.image_frag = void 0;
/**
* Copyright (c) 2020-2025 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
exports.image_frag = `
precision highp float;
precision highp int;
uniform float uEmissive;
// Density value to estimate object thickness
uniform float uDensity;
varying vec4 vOverpaint;
uniform vec2 uOverpaintTexDim;
uniform sampler2D tOverpaint;
uniform float uOverpaintStrength;
varying float vEmissive;
uniform vec2 uEmissiveTexDim;
uniform sampler2D tEmissive;
uniform float uEmissiveStrength;
varying float vTransparency;
uniform vec2 uTransparencyTexDim;
uniform sampler2D tTransparency;
uniform float uTransparencyStrength;
uniform vec2 uImageTexDim;
uniform sampler2D tImageTex;
uniform sampler2D tGroupTex;
uniform sampler2D tValueTex;
uniform vec2 uMarkerTexDim;
uniform sampler2D tMarker;
varying vec2 vUv;
varying float vInstance;
uniform sampler2D tPalette;
uniform vec3 uPaletteDefault;
uniform int uTrimType;
uniform vec3 uTrimCenter;
uniform vec4 uTrimRotation;
uniform vec3 uTrimScale;
uniform mat4 uTrimTransform;
uniform float uIsoLevel;
const float B = 0.0;
const float C = 0.5;
const float B = 0.333;
const float C = 0.333;
float cubicFilter(float x){
float f = x;
if (f < 0.0) {
f = -f;
}
if (f < 1.0) {
return ((12.0 - 9.0 * B - 6.0 * C) * (f * f * f) +
(-18.0 + 12.0 * B + 6.0 * C) * (f * f) +
(6.0 - 2.0 * B)) / 6.0;
}else if (f >= 1.0 && f < 2.0){
return ((-B - 6.0 * C) * ( f * f * f)
+ (6.0 * B + 30.0 * C) * (f * f) +
(-(12.0 * B) - 48.0 * C) * f +
8.0 * B + 24.0 * C) / 6.0;
}else{
return 0.0;
}
}
float cubicFilter(float x) {
float f = x;
if (f < 0.0) {
f = -f;
}
if (f >= 0.0 && f <= 1.0){
return (2.0 / 3.0) + (0.5) * (f * f * f) - (f * f);
} else if (f > 1.0 && f <= 2.0) {
return 1.0 / 6.0 * pow((2.0 - f), 3.0);
}
return 1.0;
}
vec4 biCubic(sampler2D tex, vec2 texCoord) {
vec2 texelSize = 1.0 / uImageTexDim;
texCoord -= texelSize / 2.0;
vec4 nSum = vec4(0.0);
float nDenom = 0.0;
vec2 cell = fract(texCoord * uImageTexDim);
for (float m = -1.0; m <= 2.0; ++m) {
for (float n = -1.0; n <= 2.0; ++n) {
vec4 vecData = texture2D(tex, texCoord + texelSize * vec2(m, n));
float c = abs(cubicFilter(m - cell.x) * cubicFilter(-n + cell.y));
nSum += vecData * c;
nDenom += c;
}
}
return nSum / nDenom;
}
void main() {
if (uTrimType != 0 && getSignedDistance(vModelPosition, uTrimType, uTrimCenter, uTrimRotation, uTrimScale, uTrimTransform) > 0.0) discard;
vec4 material = texture2D(tImageTex, vUv);
if (material.rgb != vec3(1.0)) {
material = biCubic(tImageTex, vUv);
}
vec4 material = biCubic(tImageTex, vUv);
vec4 material = texture2D(tImageTex, vUv);
if (uIsoLevel >= 0.0) {
if (texture2D(tValueTex, vUv).r < uIsoLevel) discard;
material.a = uAlpha;
} else {
if (material.a == 0.0) discard;
material.a *= uAlpha;
}
float fragmentDepth = gl_FragCoord.z;
vec3 packedGroup = texture2D(tGroupTex, vUv).rgb;
float group = packedGroup == vec3(0.0) ? -1.0 : unpackRGBToInt(packedGroup);
// apply per-group transparency
float transparency = 0.0;
transparency = readFromTexture(tTransparency, vInstance, uTransparencyTexDim).a;
transparency = readFromTexture(tTransparency, vInstance * float(uGroupCount) + group, uTransparencyTexDim).a;
transparency *= uTransparencyStrength;
float ta = 1.0 - transparency;
if (transparency < 0.09) ta = 1.0; // hard cutoff looks better
if (ta * uAlpha < uPickingAlphaThreshold)
discard; // ignore so the element below can be picked
if (ta < 1.0)
discard; // emissive not supported with transparency
material.a *= ta;
if ((uRenderMask == MaskOpaque && material.a < 1.0) ||
(uRenderMask == MaskTransparent && material.a == 1.0)
) {
discard;
}
float marker = uMarker;
if (group == -1.0) {
marker = 0.0;
} else 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
}
float emissive = uEmissive;
if (group == -1.0) {
emissive = 0.0;
} else {
emissive += readFromTexture(tEmissive, vInstance, uEmissiveTexDim).a * uEmissiveStrength;
emissive += readFromTexture(tEmissive, vInstance * float(uGroupCount) + group, uEmissiveTexDim).a * uEmissiveStrength;
}
if (group == -1.0) discard;
gl_FragColor = vec4(packIntToRGB(float(uObjectId)), 1.0);
gl_FragData[1] = vec4(packIntToRGB(vInstance), 1.0);
gl_FragData[2] = vec4(packIntToRGB(group), 1.0);
gl_FragData[3] = packDepthToRGBA(fragmentDepth);
gl_FragColor = vColor;
if (uPickType == 1) {
gl_FragColor = vec4(packIntToRGB(float(uObjectId)), 1.0);
} else if (uPickType == 2) {
gl_FragColor = vec4(packIntToRGB(vInstance), 1.0);
} else {
gl_FragColor = vec4(packIntToRGB(group), 1.0);
}
if (uRenderMask == MaskOpaque) {
gl_FragColor = packDepthToRGBA(fragmentDepth);
} else if (uRenderMask == MaskTransparent) {
gl_FragColor = packDepthWithAlphaToRGBA(fragmentDepth, material.a);
}
if (uMarkingType == 1) {
if (marker > 0.0)
discard;
gl_FragColor = packDepthToRGBA(fragmentDepth);
} else {
if (marker == 0.0)
discard;
float depthTest = 1.0;
if (uMarkingDepthTest) {
depthTest = (fragmentDepth >= getDepthPacked(gl_FragCoord.xy / uDrawingBufferSize)) ? 1.0 : 0.0;
}
bool isHighlight = intMod(marker, 2.0) > 0.1;
float viewZ = depthToViewZ(uIsOrtho, fragmentDepth, uNear, uFar);
float fogFactor = smoothstep(uFogNear, uFogFar, abs(viewZ));
if (fogFactor == 1.0)
discard;
gl_FragColor = vec4(0.0, depthTest, isHighlight ? 1.0 : 0.0, 1.0 - fogFactor);
}
gl_FragColor = vec4(emissive);
if (material.rgb == vec3(1.0)) {
material.rgb = uPaletteDefault;
} else {
float v = ((material.r * 256.0 * 256.0 * 255.0 + material.g * 256.0 * 255.0 + material.b * 255.0) - 1.0) / PALETTE_SCALE;
material.rgb = texture2D(tPalette, vec2(v, 0.0)).rgb;
}
// mix material with overpaint
vec4 overpaint = vec4(0.0);
if (group != -1.0) {
overpaint = readFromTexture(tOverpaint, vInstance, uOverpaintTexDim);
overpaint = readFromTexture(tOverpaint, vInstance * float(uGroupCount) + group, uOverpaintTexDim);
overpaint *= uOverpaintStrength;
}
material.rgb = mix(material.rgb, overpaint.rgb, overpaint.a);
gl_FragColor = material;
gl_FragData[1] = vec4(normalize(vViewPosition), emissive);
gl_FragData[2] = vec4(material.rgb, uDensity);
}
`;