@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
87 lines (72 loc) • 5.5 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.33/esri/copyright.txt for details.
*/
import{translate as e}from"../core/libs/gl-matrix-2/math/mat4.js";import{create as t}from"../core/libs/gl-matrix-2/factories/mat4f64.js";import{set as o}from"../core/libs/gl-matrix-2/math/vec2.js";import{create as r}from"../core/libs/gl-matrix-2/factories/vec2f64.js";import{Laserline as a}from"../views/3d/webgl-engine/core/shaderLibrary/Laserline.glsl.js";import{Float2BindUniform as i}from"../views/3d/webgl-engine/core/shaderModules/Float2BindUniform.js";import{FloatBindUniform as n}from"../views/3d/webgl-engine/core/shaderModules/FloatBindUniform.js";import{FloatPassUniform as s}from"../views/3d/webgl-engine/core/shaderModules/FloatPassUniform.js";import{If as l,glsl as d}from"../views/3d/webgl-engine/core/shaderModules/glsl.js";import{Matrix4BindUniform as c}from"../views/3d/webgl-engine/core/shaderModules/Matrix4BindUniform.js";import{Matrix4PassUniform as m}from"../views/3d/webgl-engine/core/shaderModules/Matrix4PassUniform.js";import{VertexAttribute as v}from"../views/3d/webgl-engine/lib/VertexAttribute.js";import{ShaderBuilder as p}from"../views/webgl/ShaderBuilder.js";function w(t){const r=new p;r.include(a,t);const{vertex:w,fragment:u}=r;w.uniforms.add(new m("modelView",((t,{camera:o})=>e(f,o.viewMatrix,t.origin))),new c("proj",(({camera:e})=>e.projectionMatrix)),new s("glowWidth",((e,{camera:t})=>e.glowWidth*t.pixelRatio)),new i("pixelToNDC",(({camera:e})=>o(g,2/e.fullViewport[2],2/e.fullViewport[3])))),r.attributes.add(v.START,"vec3"),r.attributes.add(v.END,"vec3"),t.spherical&&(r.attributes.add(v.START_UP,"vec3"),r.attributes.add(v.END_UP,"vec3")),r.attributes.add(v.EXTRUDE,"vec2"),r.varyings.add("uv","vec2"),r.varyings.add("vViewStart","vec3"),r.varyings.add("vViewEnd","vec3"),r.varyings.add("vViewSegmentNormal","vec3"),r.varyings.add("vViewStartNormal","vec3"),r.varyings.add("vViewEndNormal","vec3");const h=!t.spherical;return w.main.add(d`
vec3 pos = mix(start, end, extrude.x);
vec4 viewPos = modelView * vec4(pos, 1);
vec4 projPos = proj * viewPos;
vec2 ndcPos = projPos.xy / projPos.w;
// in planar we hardcode the up vectors to be Z-up */
${l(h,d`vec3 startUp = vec3(0, 0, 1);`)}
${l(h,d`vec3 endUp = vec3(0, 0, 1);`)}
// up vector corresponding to the location of the vertex, selecting either startUp or endUp */
vec3 up = extrude.y * mix(startUp, endUp, extrude.x);
vec3 viewUp = (modelView * vec4(up, 0)).xyz;
vec4 projPosUp = proj * vec4(viewPos.xyz + viewUp, 1);
vec2 projUp = normalize(projPosUp.xy / projPosUp.w - ndcPos);
// extrude ndcPos along projUp to the edge of the screen
vec2 lxy = abs(sign(projUp) - ndcPos);
ndcPos += length(lxy) * projUp;
vViewStart = (modelView * vec4(start, 1)).xyz;
vViewEnd = (modelView * vec4(end, 1)).xyz;
vec3 viewStartEndDir = vViewEnd - vViewStart;
vec3 viewStartUp = (modelView * vec4(startUp, 0)).xyz;
// the normal of the plane that aligns with the segment and the up vector
vViewSegmentNormal = normalize(cross(viewStartUp, viewStartEndDir));
// the normal orthogonal to the segment normal and the start up vector
vViewStartNormal = -normalize(cross(vViewSegmentNormal, viewStartUp));
// the normal orthogonal to the segment normal and the end up vector
vec3 viewEndUp = (modelView * vec4(endUp, 0)).xyz;
vViewEndNormal = normalize(cross(vViewSegmentNormal, viewEndUp));
// Add enough padding in the X screen space direction for "glow"
float xPaddingPixels = sign(dot(vViewSegmentNormal, viewPos.xyz)) * (extrude.x * 2.0 - 1.0) * glowWidth;
ndcPos.x += xPaddingPixels * pixelToNDC.x;
// uv is used to read back depth to reconstruct the position at the fragment
uv = ndcPos * 0.5 + 0.5;
gl_Position = vec4(ndcPos, 0, 1);
`),u.uniforms.add(new n("perScreenPixelRatio",(e=>e.camera.perScreenPixelRatio))),u.code.add(d`float planeDistance(vec3 planeNormal, vec3 planeOrigin, vec3 pos) {
return dot(planeNormal, pos - planeOrigin);
}
float segmentDistancePixels(vec3 segmentNormal, vec3 startNormal, vec3 endNormal, vec3 pos, vec3 start, vec3 end) {
float distSegmentPlane = planeDistance(segmentNormal, start, pos);
float distStartPlane = planeDistance(startNormal, start, pos);
float distEndPlane = planeDistance(endNormal, end, pos);
float dist = max(max(distStartPlane, distEndPlane), abs(distSegmentPlane));
float width = fwidth(distSegmentPlane);
float maxPixelDistance = length(pos) * perScreenPixelRatio * 2.0;
float pixelDist = dist / min(width, maxPixelDistance);
return abs(pixelDist);
}`),u.main.add(d`fragColor = vec4(0.0);
vec3 dEndStart = vViewEnd - vViewStart;
if (dot(dEndStart, dEndStart) < 1e-5) {
return;
}
vec3 pos;
vec3 normal;
float angleCutoffAdjust;
float depthDiscontinuityAlpha;
if (!laserlineReconstructFromDepth(pos, normal, angleCutoffAdjust, depthDiscontinuityAlpha)) {
return;
}
float distance = segmentDistancePixels(
vViewSegmentNormal,
vViewStartNormal,
vViewEndNormal,
pos,
vViewStart,
vViewEnd
);
vec4 color = laserlineProfile(distance);
float alpha = (1.0 - smoothstep(0.995 - angleCutoffAdjust, 0.999 - angleCutoffAdjust, abs(dot(normal, vViewSegmentNormal))));
fragColor = laserlineOutput(color * alpha * depthDiscontinuityAlpha);`),r}const g=r(),f=t(),u=Object.freeze(Object.defineProperty({__proto__:null,build:w},Symbol.toStringTag,{value:"Module"}));export{u as L,w as b};