@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 3.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{WGLDrawPhase as e}from"../../../enums.js";import{FeatureTechnique as t}from"../FeatureTechnique.js";import{isHittest as r,getSelectionDefines as s,getFeatureUniforms as i}from"../featureTechniqueUtils.js";import{TechniqueType as n}from"../TechniqueType.js";import{HeatmapResources as o}from"./HeatmapResources.js";import{HeatmapAccumulateShader as u}from"../shaders/HeatmapAccumulateShader.js";import{HeatmapResolveShader as a}from"../shaders/HeatmapResolveShader.js";import{StencilOperation as l,CompareFunction as d,FramebufferBit as c}from"../../../../../../webgl/enums.js";class h extends t{constructor(){super(...arguments),this.type=n.Heatmap,this.drawPhase=e.MAP|e.HITTEST|e.DEBUG,this.shaders={accumulate:new u,resolve:new a},this._isBound=!1,this._resources=new Map}shutdown(e){super.shutdown(e),this._resources.get(e)?.destroy(),this._resources.delete(e),this._prevFBO=null,this._unbind()}render(e,t){const{context:n,painter:o,state:u}=e,a=t.instance.getInput(),{isFieldActive:l}=a.uniforms,d=this._getOrCreateResourcesRecord(n),c=d.loadQualityProfile(n);r(e)||this._bind(e,d,a),o.setShader({shader:this.shaders.accumulate,uniforms:{...i(e,t.target),kernelControls:{radius:b(a,u),isFieldActive:l?1:0}},defines:{...s(e),...c.defines},optionalAttributes:{},useComputeBuffer:r(e)});const h=r(e)?_:f;o.setPipelineState(h),o.submitDraw(e,t)}getStencilReference(e){return m(e)}renderResolvePass(e,t){if(r(e))return;const{context:s,painter:i}=e,n=this._resources.get(s);if(null==this._prevFBO||null==this._prevViewport||!n?.initialized)return;const{defines:o}=n.loadQualityProfile(s),{minDensity:u,maxDensity:a,radius:l}=t.getInput().uniforms,d=8,c=9,h=n.accumulateFramebuffer,p=n.resolveGradientTexture,m={shader:this.shaders.resolve,uniforms:{accumulatedDensity:{texture:{unit:d,texture:h.colorTexture},minAndInvRange:[u,1/(a-u)],normalization:3/(l*l*Math.PI)},gradient:{texture:{unit:c,texture:p}}},defines:o,optionalAttributes:{},useComputeBuffer:!1};s.bindFramebuffer(this._prevFBO),s.setViewport(0,0,this._prevViewport.width,this._prevViewport.height),s.bindTexture(h.colorTexture,d),s.bindTexture(p,c),i.setPipelineState(w),i.submitDrawMesh(s,m,i.quadMesh),this._unbind()}_getOrCreateResourcesRecord(e){let t=this._resources.get(e);return null==t&&(t=new o,this._resources.set(e,t)),t}_unbind(){this._prevFBO=null,this._prevViewport=null,this._isBound=!1}_bind(e,t,r){if(this._isBound)return;const{context:s,state:i,pixelRatio:n}=e,o=s.getBoundFramebufferObject(),u=s.getViewport();this._prevFBO=o,this._prevViewport=u;const{gradient:a,gradientHash:l}=r.uniforms;t.ensureResolveGradientTexture(s,l,a);const{width:d,height:h}=u,m=p(b(r,i),n),f=d*m,_=h*m,w=t.ensureAccumulateFBO(s,f,_);s.blitFramebuffer(o,w,c.STENCIL),s.bindFramebuffer(w),s.setViewport(0,0,w.width,w.height),s.setColorMask(!0,!0,!0,!0),s.setClearColor(0,0,0,0),s.clear(c.COLOR),this._isBound=!0}}function p(e,t){const r=t>1.5?.25:.5;return e<1/(2*r)?1:r}function m(e){return e.key.level+1}const f={color:{write:[!0,!0,!0,!0],blendMode:"additive"},depth:!1,stencil:{write:!1,test:{ref:m,compare:d.GEQUAL,mask:255,op:{fail:l.KEEP,zFail:l.KEEP,zPass:l.REPLACE}}}},_={...f,stencil:!1},w={color:{write:[!0,!0,!0,!0],blendMode:"composite"},depth:!1,stencil:!1};function b(e,t){const{referenceScale:r,radius:s}=e.uniforms;return s*(0!==r?r/t.scale:1)}export{h as HeatmapTechnique};