UNPKG

@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
/* 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};