/**
 * Copyright (c) 2018-2025 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 declare const 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    int vertexId = VertexID;\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";
