UNPKG

@arcgis/core

Version:

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

114 lines (98 loc) 7.69 kB
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */ import{SliceDraw as e}from"../views/3d/webgl-engine/core/shaderLibrary/Slice.glsl.js";import{Transform as o}from"../views/3d/webgl-engine/core/shaderLibrary/Transform.glsl.js";import{ObjectAndLayerIdColor as r}from"../views/3d/webgl-engine/core/shaderLibrary/attributes/ObjectAndLayerIdColor.glsl.js";import{VertexColor as t}from"../views/3d/webgl-engine/core/shaderLibrary/attributes/VertexColor.glsl.js";import{terrainDepthTest as a}from"../views/3d/webgl-engine/core/shaderLibrary/shading/TerrainDepthTest.glsl.js";import{VisualVariables as i}from"../views/3d/webgl-engine/core/shaderLibrary/shading/VisualVariables.glsl.js";import{ColorConversion as l}from"../views/3d/webgl-engine/core/shaderLibrary/util/ColorConversion.glsl.js";import{addProjViewLocalOrigin as n,addCameraPosition as c}from"../views/3d/webgl-engine/core/shaderLibrary/util/View.glsl.js";import{Float4PassUniform as d}from"../views/3d/webgl-engine/core/shaderModules/Float4PassUniform.js";import{FloatBindUniform as s}from"../views/3d/webgl-engine/core/shaderModules/FloatBindUniform.js";import{glsl as v,If as p}from"../views/3d/webgl-engine/core/shaderModules/glsl.js";import{outputColorHighlightOLID as u}from"../views/3d/webgl-engine/shaders/OutputColorHighlightOLID.glsl.js";import{getTextureBackedBufferModule as m}from"../views/3d/webgl-engine/shaders/PatternTextureBuffer.glsl.js";import{ShaderBuilder as f}from"../views/webgl/ShaderBuilder.js";const g=.70710678118,w=g,h=.08715574274,b=10,x=1;function y(y){const j=m(y),C=null!=j,T=new f;C&&T.include(j.TextureBackedBufferModule,y);const{vertex:V,fragment:P,attributes:$,varyings:R}=T,A=8===y.output;n(V,y),T.include(o);let L="";C?(y.hasVVColor&&(L=j.getTextureAttribute("colorFeatureAttribute")),y.hasVertexColors?(T.varyings.add("vColor","vec4"),T.vertex.code.add(v`void forwardVertexColor() { vColor = ${j.getTextureAttribute("color")}; }`)):T.vertex.code.add(v`void forwardVertexColor() {}`),$.add("textureElementIndex","uint")):(T.include(t,y),y.hasVVColor&&($.add("colorFeatureAttribute","float"),L="colorFeatureAttribute")),T.include(i,y),T.include(r,y),T.fragment.include(e,y),T.include(u,y),T.include(a,y),y.draped&&V.uniforms.add(new s("worldToScreenRatio",e=>1/e.screenToPCSRatio)),$.add("position","vec3"),$.add("uvMapSpace","vec4"),y.hasVertexColors||R.add("vColor","vec4"),R.add("vpos","vec3",{invariant:!0}),R.add("vuv","vec2"),V.uniforms.add(new d("uColor",e=>e.color));const D=3===y.style||4===y.style||5===y.style;return D&&V.code.add(v` const mat2 rotate45 = mat2(${v.float(g)}, ${v.float(-w)}, ${v.float(w)}, ${v.float(g)}); `),!y.draped&&C&&(c(V,y),V.uniforms.add(new s("worldToScreenPerDistanceRatio",e=>1/e.camera.perScreenPixelRatio)),V.code.add(v`vec3 projectPointToLineSegment(vec3 center, vec3 halfVector, vec3 point) { float projectedLength = dot(halfVector, point - center) / dot(halfVector, halfVector); return center + halfVector * clamp(projectedLength, -1.0, 1.0); }`),V.code.add(v`vec3 intersectRayPlane(vec3 rayDir, vec3 rayOrigin, vec3 planeNormal, vec3 planePoint) { float d = dot(planeNormal, planePoint); float t = (d - dot(planeNormal, rayOrigin)) / dot(planeNormal, rayDir); return rayOrigin + t * rayDir; }`),V.code.add(v` float boundingRectDistanceToCamera() { vec3 center = ${j.getTextureAttribute("boundingRect")}[0]; vec3 halfU = ${j.getTextureAttribute("boundingRect")}[1]; vec3 halfV = ${j.getTextureAttribute("boundingRect")}[2]; vec3 n = normalize(cross(halfU, halfV)); vec3 viewDir = - vec3(view[0][2], view[1][2], view[2][2]); float viewAngle = dot(viewDir, n); float minViewAngle = ${v.float(h)}; if (abs(viewAngle) < minViewAngle) { // view direction is (almost) parallel to plane -> clamp it to min angle float normalComponent = sign(viewAngle) * minViewAngle - viewAngle; viewDir = normalize(viewDir + normalComponent * n); } // intersect view direction with infinite plane that contains bounding rect vec3 planeProjected = intersectRayPlane(viewDir, cameraPosition, n, center); // clip to bounds by projecting to u and v line segments individually vec3 uProjected = projectPointToLineSegment(center, halfU, planeProjected); vec3 vProjected = projectPointToLineSegment(center, halfV, planeProjected); // use to calculate the closest point to camera on bounding rect vec3 closestPoint = uProjected + vProjected - center; return length(closestPoint - cameraPosition); } `)),V.code.add(v` vec2 scaledUV() { vec2 uv = uvMapSpace.xy ${p(D," * rotate45")}; vec2 uvCellOrigin = uvMapSpace.zw ${p(D," * rotate45")}; ${p(!y.draped,v`float distanceToCamera = boundingRectDistanceToCamera(); float worldToScreenRatio = worldToScreenPerDistanceRatio / distanceToCamera;`)} // Logarithmically discretize ratio to avoid jittering float step = 0.1; float discreteWorldToScreenRatio = log(worldToScreenRatio); discreteWorldToScreenRatio = ceil(discreteWorldToScreenRatio / step) * step; discreteWorldToScreenRatio = exp(discreteWorldToScreenRatio); vec2 uvOffset = mod(uvCellOrigin * discreteWorldToScreenRatio, ${v.float(b)}); return uvOffset + (uv * discreteWorldToScreenRatio); } `),V.main.add(v` vuv = scaledUV(); vpos = position; forwardViewPosDepth((view * vec4(vpos, 1.0)).xyz); forwardVertexColor(); forwardObjectAndLayerIdColor(); ${y.hasVertexColors?"vColor *= uColor;":y.hasVVColor?v`vColor = uColor * interpolateVVColor(${L});`:"vColor = uColor;"} gl_Position = transformPosition(proj, view, vpos); `),P.include(l),y.draped&&P.uniforms.add(new s("texelSize",e=>1/e.camera.pixelRatio)),A||(P.code.add(v` const float lineWidth = ${v.float(x)}; const float spacing = ${v.float(b)}; const float spacingINV = ${v.float(1/b)}; float coverage(float p, float txlSize) { p = mod(p, spacing); float halfTxlSize = txlSize / 2.0; float start = p - halfTxlSize; float end = p + halfTxlSize; float coverage = (ceil(end * spacingINV) - floor(start * spacingINV)) * lineWidth; coverage -= min(lineWidth, mod(start, spacing)); coverage -= max(lineWidth - mod(end, spacing), 0.0); return coverage / txlSize; } `),y.draped||P.code.add(v`const int maxSamples = 5; float sampleAA(float p) { vec2 dxdy = abs(vec2(dFdx(p), dFdy(p))); float fwidth = dxdy.x + dxdy.y; ivec2 samples = 1 + ivec2(clamp(dxdy, 0.0, float(maxSamples - 1))); vec2 invSamples = 1.0 / vec2(samples); float accumulator = 0.0; for (int j = 0; j < maxSamples; j++) { if(j >= samples.y) { break; } for (int i = 0; i < maxSamples; i++) { if(i >= samples.x) { break; } vec2 step = vec2(i,j) * invSamples - 0.5; accumulator += coverage(p + step.x * dxdy.x + step.y * dxdy.y, fwidth); } } accumulator /= float(samples.x * samples.y); return accumulator; }`)),P.main.add(v` discardBySlice(vpos); discardByTerrainDepth(); vec4 color = vColor; ${p(!A,v`color.a *= ${S(y)};`)} outputColorHighlightOLID(applySlice(color, vpos), color.rgb); `),T}function S(e){function o(o){return e.draped?v`coverage(vuv.${o}, texelSize)`:v`sampleAA(vuv.${o})`}switch(e.style){case 3:case 0:return o("y");case 4:case 1:return o("x");case 5:case 2:return v`1.0 - (1.0 - ${o("x")}) * (1.0 - ${o("y")})`;default:return"0.0"}}const j=Object.freeze(Object.defineProperty({__proto__:null,build:y},Symbol.toStringTag,{value:"Module"}));export{j as P,y as b};