molstar
Version:
A comprehensive macromolecular library.
167 lines (139 loc) • 5.18 kB
JavaScript
"use strict";
/**
* Copyright (c) 2019-2025 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.spheres_frag = void 0;
exports.spheres_frag = `
precision highp float;
precision highp int;
uniform mat4 uInvView;
uniform float uAlphaThickness;
varying float vRadius;
varying vec3 vPoint;
varying vec3 vPointViewPosition;
const bool solidInterior = true;
const bool solidInterior = false;
bool SphereImpostor(out vec3 modelPos, out vec3 cameraPos, out vec3 cameraNormal, out bool interior, out float fragmentDepth){
vec3 cameraSpherePos = -vPointViewPosition;
vec3 rayOrigin = mix(vec3(0.0, 0.0, 0.0), vPoint, uIsOrtho);
vec3 rayDirection = mix(normalize(vPoint), vec3(0.0, 0.0, 1.0), uIsOrtho);
vec3 cameraSphereDir = mix(cameraSpherePos, rayOrigin - cameraSpherePos, uIsOrtho);
float B = dot(rayDirection, cameraSphereDir);
float det = B * B + vRadius * vRadius - dot(cameraSphereDir, cameraSphereDir);
if (det < 0.0) return false;
float sqrtDet = sqrt(det);
float posT = mix(B + sqrtDet, B - sqrtDet, uIsOrtho);
float negT = mix(B - sqrtDet, B + sqrtDet, uIsOrtho);
cameraPos = rayDirection * negT + rayOrigin;
modelPos = (uInvView * vec4(cameraPos, 1.0)).xyz;
fragmentDepth = calcDepth(cameraPos);
bool objectClipped = false;
if (clipTest(modelPos)) {
objectClipped = true;
fragmentDepth = -1.0;
}
if (fragmentDepth > 0.0) {
cameraNormal = normalize(cameraPos - cameraSpherePos);
interior = false;
return true;
} else if (uDoubleSided || solidInterior) {
cameraPos = rayDirection * posT + rayOrigin;
modelPos = (uInvView * vec4(cameraPos, 1.0)).xyz;
fragmentDepth = calcDepth(cameraPos);
cameraNormal = -normalize(cameraPos - cameraSpherePos);
interior = true;
if (fragmentDepth > 0.0) {
if (!objectClipped) {
fragmentDepth = 0.0 + (0.0000001 / vRadius);
cameraNormal = -mix(normalize(vPoint), vec3(0.0, 0.0, -1.0), uIsOrtho);
}
return true;
}
}
return false;
}
void main(void){
vec3 cameraNormal;
float fragmentDepth;
vec3 pointDir = -vPointViewPosition - vPoint;
if (dot(pointDir, pointDir) > vRadius * vRadius) discard;
vec3 vViewPosition = -vPointViewPosition;
fragmentDepth = gl_FragCoord.z;
pointDir.z -= cos(length(pointDir));
cameraNormal = -normalize(pointDir);
interior = false;
vec3 modelPos;
vec3 cameraPos;
bool hit = SphereImpostor(modelPos, cameraPos, cameraNormal, interior, fragmentDepth);
if (!hit) discard;
if (fragmentDepth < 0.0) discard;
if (fragmentDepth > 1.0) discard;
gl_FragDepthEXT = fragmentDepth;
vec3 vModelPosition = modelPos;
vec3 vViewPosition = cameraPos;
vec3 normal = -cameraNormal;
if (uRenderMask == MaskTransparent && uAlphaThickness > 0.0) {
material.a *= min(1.0, vRadius / uAlphaThickness);
}
gl_FragColor = vObject;
gl_FragData[1] = vInstance;
gl_FragData[2] = vGroup;
gl_FragData[3] = packDepthToRGBA(fragmentDepth);
gl_FragColor = vColor;
gl_FragColor = material;
gl_FragColor = material;
gl_FragColor = material;
gl_FragData[1] = vec4(normal, emissive);
gl_FragData[2] = vec4(material.rgb, uDensity);
}
`;