molstar
Version:
A comprehensive macromolecular library.
9 lines • 3.86 kB
JavaScript
/**
* Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*
* heavily based on code by WestLangley from https://github.com/WestLangley/three.js/blob/af28b2fb706ac109771ecad0a7447fad90ab3210/examples/js/lines/LineMaterial.js
*/
export var lines_vert = "\nprecision highp float;\nprecision highp int;\n\n#include common\n#include read_from_texture\n#include common_vert_params\n#include color_vert_params\n#include size_vert_params\n#include common_clip\n\nuniform float uPixelRatio;\nuniform vec4 uViewport;\n\nattribute mat4 aTransform;\nattribute float aInstance;\nattribute float aGroup;\n\nattribute vec2 aMapping;\nattribute vec3 aStart;\nattribute vec3 aEnd;\n\nvoid trimSegment(const in vec4 start, inout vec4 end) {\n // trim end segment so it terminates between the camera plane and the near plane\n // conservative estimate of the near plane\n float a = uProjection[2][2]; // 3rd entry in 3rd column\n float b = uProjection[3][2]; // 3rd entry in 4th column\n float nearEstimate = -0.5 * b / a;\n float alpha = (nearEstimate - start.z) / (end.z - start.z);\n end.xyz = mix(start.xyz, end.xyz, alpha);\n}\n\nvoid main(){\n float aspect = uViewport.z / uViewport.w;\n\n #include assign_group\n #include assign_color_varying\n #include assign_marker_varying\n #include assign_clipping_varying\n #include assign_size\n\n mat4 modelView = uView * uModel * aTransform;\n\n // camera space\n vec4 start = modelView * vec4(aStart, 1.0);\n vec4 end = modelView * vec4(aEnd, 1.0);\n\n // assign position\n vec4 position4 = vec4((aMapping.y < 0.5) ? aStart : aEnd, 1.0);\n vec4 mvPosition = modelView * position4;\n vViewPosition = mvPosition.xyz;\n\n vModelPosition = (uModel * aTransform * position4).xyz; // for clipping in frag shader\n\n // special case for perspective projection, and segments that terminate either in, or behind, the camera plane\n // clearly the gpu firmware has a way of addressing this issue when projecting into ndc space\n // but we need to perform ndc-space calculations in the shader, so we must address this issue directly\n // perhaps there is a more elegant solution -- WestLangley\n bool perspective = (uProjection[2][3] == -1.0); // 4th entry in the 3rd column\n if (perspective) {\n if (start.z < 0.0 && end.z >= 0.0) {\n trimSegment(start, end);\n } else if (end.z < 0.0 && start.z >= 0.0) {\n trimSegment(end, start);\n }\n }\n\n // clip space\n vec4 clipStart = uProjection * start;\n vec4 clipEnd = uProjection * end;\n\n // ndc space\n vec2 ndcStart = clipStart.xy / clipStart.w;\n vec2 ndcEnd = clipEnd.xy / clipEnd.w;\n\n // direction\n vec2 dir = ndcEnd - ndcStart;\n\n // account for clip-space aspect ratio\n dir.x *= aspect;\n dir = normalize(dir);\n\n // perpendicular to dir\n vec2 offset = vec2(dir.y, - dir.x);\n\n // undo aspect ratio adjustment\n dir.x /= aspect;\n offset.x /= aspect;\n\n // sign flip\n if (aMapping.x < 0.0) offset *= -1.0;\n\n // calculate linewidth\n float linewidth;\n #ifdef dLineSizeAttenuation\n linewidth = size * uPixelRatio * ((uViewport.w / 2.0) / -start.z) * 5.0;\n #else\n linewidth = size * uPixelRatio;\n #endif\n linewidth = max(1.0, linewidth);\n\n // adjust for linewidth\n offset *= linewidth;\n\n // adjust for clip-space to screen-space conversion\n offset /= uViewport.w;\n\n // select end\n vec4 clip = (aMapping.y < 0.5) ? clipStart : clipEnd;\n\n // back to clip space\n offset *= clip.w;\n clip.xy += offset;\n gl_Position = clip;\n\n #include clip_instance\n}\n";
//# sourceMappingURL=lines.vert.js.map