molstar
Version:
A comprehensive macromolecular library.
9 lines (8 loc) • 5.24 kB
TypeScript
/**
* Copyright (c) 2019-2025 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Áron Samuel Kovács <aron.kovacs@mail.muni.cz>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
* @author Gianluca Tomasello <giagitom@gmail.com>
*/
export declare const outlines_frag = "\nprecision highp float;\nprecision highp int;\nprecision highp sampler2D;\n\nuniform sampler2D tDepthOpaque;\nuniform sampler2D tDepthTransparent;\nuniform vec2 uTexSize;\n\nuniform float uNear;\nuniform float uFar;\nuniform mat4 uInvProjection;\n\nuniform float uOutlineThreshold;\n\n#include common\n\nfloat getViewZ(const in float depth) {\n #if dOrthographic == 1\n return orthographicDepthToViewZ(depth, uNear, uFar);\n #else\n return perspectiveDepthToViewZ(depth, uNear, uFar);\n #endif\n}\n\nfloat getDepthOpaque(const in vec2 coords) {\n #ifdef depthTextureSupport\n return texture2D(tDepthOpaque, coords).r;\n #else\n return unpackRGBAToDepth(texture2D(tDepthOpaque, coords));\n #endif\n}\n\nvec2 getDepthTransparentWithAlpha(const in vec2 coords) {\n #ifdef dTransparentOutline\n return unpackRGBAToDepthWithAlpha(texture2D(tDepthTransparent, coords));\n #else\n return vec2(1.0, 0.0);\n #endif\n}\n\nbool isBackground(const in float depth) {\n return depth == 1.0;\n}\n\nfloat getPixelSize(const in vec2 coords, const in float depth) {\n vec3 viewPos0 = screenSpaceToViewSpace(vec3(coords, depth), uInvProjection);\n vec3 viewPos1 = screenSpaceToViewSpace(vec3(coords + vec2(1.0, 0.0) / uTexSize, depth), uInvProjection);\n return distance(viewPos0, viewPos1);\n}\n\nvoid main(void) {\n float backgroundViewZ = 2.0 * uFar;\n\n vec2 coords = gl_FragCoord.xy / uTexSize;\n vec2 invTexSize = 1.0 / uTexSize;\n\n float selfDepthOpaque = getDepthOpaque(coords);\n float selfViewZOpaque = isBackground(selfDepthOpaque) ? backgroundViewZ : getViewZ(selfDepthOpaque);\n float pixelSizeOpaque = getPixelSize(coords, selfDepthOpaque) * uOutlineThreshold;\n\n vec2 selfDepthTransparentWithAlpha = getDepthTransparentWithAlpha(coords);\n float selfDepthTransparent = selfDepthTransparentWithAlpha.x;\n float selfViewZTransparent = isBackground(selfDepthTransparent) ? backgroundViewZ : getViewZ(selfDepthTransparent);\n float pixelSizeTransparent = getPixelSize(coords, selfDepthTransparent) * uOutlineThreshold;\n\n float bestOpaqueDepth = 1.0;\n float bestTransparentDepth = 1.0;\n float bestTransparentAlpha = 0.0;\n\n float opaqueOutlineFlag = 0.0;\n float transparentOutlineFlag = 0.0;\n\n for (int y = -1; y <= 1; y++) {\n for (int x = -1; x <= 1; x++) {\n vec2 sampleCoords = coords + vec2(float(x), float(y)) * invTexSize;\n\n // Opaque\n float sampleDepthOpaque = getDepthOpaque(sampleCoords);\n float sampleViewZOpaque = isBackground(sampleDepthOpaque) ? backgroundViewZ : getViewZ(sampleDepthOpaque);\n if (abs(selfViewZOpaque - sampleViewZOpaque) > pixelSizeOpaque && selfDepthOpaque > sampleDepthOpaque && sampleDepthOpaque <= bestOpaqueDepth) {\n bestOpaqueDepth = sampleDepthOpaque;\n opaqueOutlineFlag = 1.0;\n }\n\n // Transparent\n vec2 sampleDepthTransparentWithAlpha = getDepthTransparentWithAlpha(sampleCoords);\n float sampleDepthTransparent = sampleDepthTransparentWithAlpha.x;\n float sampleAlphaTransparent = sampleDepthTransparentWithAlpha.y;\n float sampleViewZTransparent = isBackground(sampleDepthTransparent) ? backgroundViewZ : getViewZ(sampleDepthTransparent);\n if (abs(selfViewZTransparent - sampleViewZTransparent) > pixelSizeTransparent && selfDepthTransparent > sampleDepthTransparent && sampleDepthTransparent <= bestTransparentDepth) {\n bestTransparentDepth = sampleDepthTransparent;\n bestTransparentAlpha = sampleAlphaTransparent;\n transparentOutlineFlag = 1.0;\n }\n }\n }\n\n if (transparentOutlineFlag > 0.0 && bestOpaqueDepth < 1.0 && bestTransparentDepth > bestOpaqueDepth) {\n transparentOutlineFlag = 0.0;\n bestTransparentAlpha = 0.0;\n }\n\n vec2 depthPacked; // Pack depth in G/B channels\n float outlineTypeFlag = 0.0;\n if (opaqueOutlineFlag > 0.0 && transparentOutlineFlag > 0.0) {\n outlineTypeFlag = 0.75; // Both\n depthPacked = packUnitIntervalToRG(bestOpaqueDepth);\n } else if (transparentOutlineFlag > 0.0) {\n outlineTypeFlag = 0.5; // Transparent only\n depthPacked = packUnitIntervalToRG(bestTransparentDepth);\n } else if (opaqueOutlineFlag > 0.0) {\n outlineTypeFlag = 0.25; // Opaque only\n depthPacked = packUnitIntervalToRG(bestOpaqueDepth);\n }\n\n float alpha = clamp(bestTransparentAlpha, 0.0, 0.5) * 2.0; // limiting to range [0.0, 0.5] to improve alpha precision since we don't need a wider range\n float packedFlagWithAlpha = pack2x4(vec2(outlineTypeFlag, alpha)); // pack outlineType with alpha\n gl_FragColor = vec4(packedFlagWithAlpha, depthPacked.x, depthPacked.y, bestTransparentDepth);\n}\n";