UNPKG

molstar

Version:

A comprehensive macromolecular library.

141 lines (117 loc) 4.39 kB
/** * Copyright (c) 2019-2025 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ export const spheres_vert = ` precision highp float; precision highp int; #include common #include read_from_texture #include common_vert_params #include color_vert_params #include size_vert_params #include common_clip uniform mat4 uModelView; uniform mat4 uInvProjection; uniform float uIsOrtho; uniform vec2 uTexDim; uniform sampler2D tPositionGroup; attribute mat4 aTransform; attribute float aInstance; varying float vRadius; varying vec3 vPoint; varying vec3 vPointViewPosition; #include matrix_scale /** * Bounding rectangle of a clipped, perspective-projected 3D Sphere. * Michael Mara, Morgan McGuire. 2013 * * Specialization by Arseny Kapoulkine, MIT License Copyright (c) 2018 * https://github.com/zeux/niagara */ void sphereProjection(const in vec3 p, const in float r, const in vec2 mapping) { vec3 pr = p * r; float pzr2 = p.z * p.z - r * r; float vx = sqrt(p.x * p.x + pzr2); float minx = ((vx * p.x - pr.z) / (vx * p.z + pr.x)) * uProjection[0][0]; float maxx = ((vx * p.x + pr.z) / (vx * p.z - pr.x)) * uProjection[0][0]; float vy = sqrt(p.y * p.y + pzr2); float miny = ((vy * p.y - pr.z) / (vy * p.z + pr.y)) * uProjection[1][1]; float maxy = ((vy * p.y + pr.z) / (vy * p.z - pr.y)) * uProjection[1][1]; gl_Position.xy = vec2(maxx + minx, maxy + miny) * -0.5; gl_Position.xy -= mapping * vec2(maxx - minx, maxy - miny) * 0.5; gl_Position.xy *= gl_Position.w; } void main(void){ vec2 mapping = vec2(1.0, 1.0); // vertices 2 and 5 #if __VERSION__ == 100 int m = imod(VertexID, 6); #else int m = VertexID % 6; #endif if (m == 0) { mapping = vec2(-1.0, 1.0); } else if (m == 1 || m == 3) { mapping = vec2(-1.0, -1.0); } else if (m == 4) { mapping = vec2(1.0, -1.0); } int vertexId = VertexID / 6; vec4 positionGroup = readFromTexture(tPositionGroup, vertexId, uTexDim); vec3 position = positionGroup.rgb; float group = positionGroup.a; #include assign_color_varying #include assign_marker_varying #include assign_clipping_varying #include assign_size vRadius = size * matrixScale(uModelView); vec4 position4 = vec4(position, 1.0); vModelPosition = (uModel * aTransform * position4).xyz; // for clipping in frag shader float d; if (uLod.w != 0.0 && (uLod.x != 0.0 || uLod.y != 0.0)) { d = dot(uCameraPlane.xyz, vModelPosition) + uCameraPlane.w; float f = min( smoothstep(uLod.x, uLod.x + uLod.z, d), 1.0 - smoothstep(uLod.y - uLod.z, uLod.y, d) ) * uLod.w; vRadius *= f; } vec4 mvPosition = uModelView * aTransform * position4; #ifdef dApproximate vec4 mvCorner = vec4(mvPosition.xyz, 1.0); mvCorner.xy += mapping * vRadius; gl_Position = uProjection * mvCorner; #else if (uIsOrtho == 1.0) { vec4 mvCorner = vec4(mvPosition.xyz, 1.0); mvCorner.xy += mapping * vRadius; gl_Position = uProjection * mvCorner; } else { gl_Position = uProjection * vec4(mvPosition.xyz, 1.0); sphereProjection(mvPosition.xyz, vRadius, mapping); } #endif vec4 vPoint4 = uInvProjection * gl_Position; vPoint = vPoint4.xyz / vPoint4.w; vPointViewPosition = -mvPosition.xyz / mvPosition.w; if (gl_Position.z < -gl_Position.w) { mvPosition.z -= 2.0 * vRadius; // avoid clipping gl_Position.z = (uProjection * vec4(mvPosition.xyz, 1.0)).z; } if (uLod.w != 0.0 && (uLod.x != 0.0 || uLod.y != 0.0)) { if (d < uLod.x || d > uLod.y) { // move out of [ -w, +w ] to 'discard' in vert shader gl_Position.z = 2.0 * gl_Position.w; } } #if defined(dClipPrimitive) && !defined(dClipVariant_instance) && dClipObjectCount != 0 if (clipTest(vModelPosition)) { // move out of [ -w, +w ] to 'discard' in vert shader gl_Position.z = 2.0 * gl_Position.w; } #else #include clip_instance #endif } `;