UNPKG

@arcgis/core

Version:

ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API

120 lines (94 loc) 8.45 kB
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */ import{set as e}from"../core/libs/gl-matrix-2/math/vec2.js";import{create as i}from"../core/libs/gl-matrix-2/factories/vec2f64.js";import{SliceDraw as o}from"../views/3d/webgl-engine/core/shaderLibrary/Slice.glsl.js";import{terrainDepthTest as n}from"../views/3d/webgl-engine/core/shaderLibrary/shading/TerrainDepthTest.glsl.js";import{Float2BindUniform as s}from"../views/3d/webgl-engine/core/shaderModules/Float2BindUniform.js";import{Float4BindUniform as t}from"../views/3d/webgl-engine/core/shaderModules/Float4BindUniform.js";import{FloatBindUniform as d}from"../views/3d/webgl-engine/core/shaderModules/FloatBindUniform.js";import{glsl as l,If as a}from"../views/3d/webgl-engine/core/shaderModules/glsl.js";import{AdjustProjectedPosition as r}from"../views/3d/webgl-engine/shaders/sources/edgeRenderer/AdjustProjectedPosition.glsl.js";import{DiscardNonSilhouetteEdges as c}from"../views/3d/webgl-engine/shaders/sources/edgeRenderer/DiscardNonSilhouetteEdges.glsl.js";import{DistanceFalloff as p}from"../views/3d/webgl-engine/shaders/sources/edgeRenderer/DistanceFalloff.glsl.js";import{EdgeUtil as P}from"../views/3d/webgl-engine/shaders/sources/edgeRenderer/EdgeUtil.glsl.js";import{LineAmplitude as u}from"../views/3d/webgl-engine/shaders/sources/edgeRenderer/LineAmplitude.glsl.js";import{LineOffset as f}from"../views/3d/webgl-engine/shaders/sources/edgeRenderer/LineOffset.glsl.js";import{UnpackAttributes as g}from"../views/3d/webgl-engine/shaders/sources/edgeRenderer/UnpackAttributes.glsl.js";import{ShaderBuilder as v}from"../views/webgl/ShaderBuilder.js";import{Uniform as m}from"../views/webgl/Uniform.js";function x(i){const m=new v,{vertex:x,fragment:L,varyings:A,attributes:b}=m;i.legacy&&x.uniforms.add(new h("model"),new h("localView")),m.include(r,i),m.include(P,i),m.include(u,i),m.include(g,i),m.include(f,i),L.include(o,i),m.include(c,i),m.include(n,i),m.include(p,i),A.add("vColor","vec4"),A.add("vRadius","float"),A.add("vPosition","vec3",{invariant:!0}),A.add("vWorldPosition","vec3",{invariant:!0}),A.add("vLineLengthPixels","float"),A.add("vSizeFalloffFactor","float"),x.uniforms.add(new s("pixelToNDC",({camera:i})=>e(w,2/i.fullViewport[2],2/i.fullViewport[3])),new t("viewport",e=>e.camera.fullViewport),new d("pixelRatio",e=>e.camera.pixelRatio)),b.add("position0","vec3"),b.add("position1","vec3"),b.add("variantOffset","float"),b.add("variantStroke","float"),b.add("variantExtension","float");const j=1===i.type,V=2===i.type,C=1/255,S=1;return x.code.add(l` void calculateGeometricOutputs(vec3 viewPosV0, vec3 viewPosV1, vec3 worldPosV0, vec3 worldPosV1, vec3 worldNormal, UnpackedAttributes unpackedAttributes) { vec2 sideness = unpackedAttributes.sideness; vec2 sidenessNorm = unpackedAttributes.sidenessNorm; vWorldPosition = mix(worldPosV0, worldPosV1, sidenessNorm.y).xyz; vec3 viewPos = mix(viewPosV0, viewPosV1, sidenessNorm.y); forwardViewPosDepth(viewPos); vec4 projPosV0 = projFromViewPosition(viewPosV0); vec4 projPosV1 = projFromViewPosition(viewPosV1); vec4 projPos = projFromViewPosition(viewPos); vec3 screenSpaceLineNDC = (projPosV1.xyz / projPosV1.w - projPosV0.xyz / projPosV0.w); vec2 ndcToPixel = viewport.zw * 0.5; vec2 screenSpaceLinePixels = screenSpaceLineNDC.xy * ndcToPixel; float lineLengthPixels = length(screenSpaceLinePixels); float dzPerPixel = screenSpaceLineNDC.z / lineLengthPixels; vec2 screenSpaceDirection = screenSpaceLinePixels / lineLengthPixels; vec2 perpendicularScreenSpaceDirection = vec2(screenSpaceDirection.y, -screenSpaceDirection.x) * sideness.x; float falloffFactor = distanceBasedPerspectiveFactor(-viewPos.z) * pixelRatio; float lineWidthPixels = unpackedAttributes.lineWidthPixels * falloffFactor; float extensionLengthPixels = calculateExtensionLength(unpackedAttributes.extensionLengthPixels, lineLengthPixels) * falloffFactor; float lineAmplitudePixels = calculateLineAmplitude(unpackedAttributes) * pixelRatio; vSizeFalloffFactor = falloffFactor; float lineWidthAndAmplitudePixels = lineWidthPixels + lineAmplitudePixels + lineAmplitudePixels; float extendedLineLengthPixels = lineLengthPixels + extensionLengthPixels + extensionLengthPixels; // Line size with padding float halfAAPaddedLineWidthAndAmplitudePixels = lineWidthAndAmplitudePixels * 0.5 + ${l.float(S)}; float aaPaddedRoundedCapSizePixels = lineWidthPixels * 0.5 + ${l.float(S)}; // Half line width in NDC including padding for anti aliasing vec2 halfAAPaddedLineWidthAndAmplitudeNDC = halfAAPaddedLineWidthAndAmplitudePixels * pixelToNDC; vec2 aaPaddedRoundedCapSizeNDC = aaPaddedRoundedCapSizePixels * pixelToNDC; vec2 extensionLengthNDC = extensionLengthPixels * pixelToNDC; // Compute screen space position of vertex, offsetting for line size and end caps vec2 ndcOffset = ( screenSpaceDirection * sideness.y * (aaPaddedRoundedCapSizeNDC + extensionLengthNDC) + perpendicularScreenSpaceDirection * halfAAPaddedLineWidthAndAmplitudeNDC ); projPos.xy += ndcOffset * projPos.w; projPos.z += (dzPerPixel * (aaPaddedRoundedCapSizePixels + extensionLengthPixels)) * sideness.y * projPos.w; projPos = adjustProjectedPosition(projPos, worldNormal, 1.0 + max((lineWidthAndAmplitudePixels - 1.0) * 0.5, 0.0)); // Line length with end caps float aaPaddedLineWithCapsLengthPixels = extendedLineLengthPixels + aaPaddedRoundedCapSizePixels + aaPaddedRoundedCapSizePixels; float pixelPositionAlongLine = aaPaddedLineWithCapsLengthPixels * sidenessNorm.y - aaPaddedRoundedCapSizePixels; // Position in pixels with origin at first vertex of line segment vPosition = vec3( halfAAPaddedLineWidthAndAmplitudePixels * sideness.x, pixelPositionAlongLine, pixelPositionAlongLine / extendedLineLengthPixels ); // The line width radius in pixels vRadius = lineWidthPixels * 0.5; vLineLengthPixels = extendedLineLengthPixels; // discard short edges below a certain length threshold ${a(j||V,l`if (lineLengthPixels <= 3.0 ${a(V," && unpackedAttributes.type <= 0.0")}) { gl_Position = vec4(10.0, 10.0, 10.0, 1.0); return; }`)} gl_Position = projPos; }`),x.main.add(l` ComponentData component = readComponentData(); UnpackedAttributes unpackedAttributes = unpackAttributes(component); vec3 worldPosV0, worldPosV1, viewPosV0, viewPosV1; worldAndViewFromModelPosition(position0, component.verticalOffset, worldPosV0, viewPosV0); worldAndViewFromModelPosition(position1, component.verticalOffset, worldPosV1, viewPosV1); // Component color vColor = component.color; // Discard fully transparent edges if (vColor.a < ${l.float(C)}) { gl_Position = vec4(10.0, 10.0, 10.0, 1.0); return; } if (discardNonSilhouetteEdges(viewPosV0, worldPosV0, component)) { return; } // General geometric computation for all types of edges calculateGeometricOutputs(viewPosV0, viewPosV1, worldPosV0, worldPosV1, worldNormal(component), unpackedAttributes); // Specific computation for different edge styles calculateStyleOutputs(unpackedAttributes);`),L.code.add(l`float lineWithCapsDistance(float radius, vec2 position, float lineLength) { float positionX = position.x - calculateLineOffset(); if (radius < 1.0) { float coverageX = clamp(min(radius, positionX + 0.5) - max(-radius, positionX - 0.5), 0.0, 1.0); float coverageY = clamp(min(lineLength, position.y + 0.5) - max(0.0, position.y - 0.5), 0.0, 1.0); return 0.5 - min(coverageX, coverageY); } else { float positionOnCap = position.y - clamp(position.y, 0.0, lineLength); return length(vec2(positionX, positionOnCap)) - radius; } }`),L.main.add(l`discardByTerrainDepth(); float radius = vRadius * calculateLinePressure(); float distance = lineWithCapsDistance(radius, vPosition.xy, vLineLengthPixels); float coverage = clamp(0.5 - distance, 0.0, 1.0); discardBySlice(vWorldPosition); fragColor = vec4(vColor.rgb, vColor.a * coverage);`),m}const w=i();class h extends m{constructor(e){super(e,"mat4")}}const L=Object.freeze(Object.defineProperty({__proto__:null,build:x},Symbol.toStringTag,{value:"Module"}));export{L as E,x as b};