@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
3 lines (2 loc) • 8.07 kB
JavaScript
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */
import{__decorate as t}from"tslib";import"../../../../core/has.js";import{disposeMaybe as e,destroyMaybe as i}from"../../../../core/maybe.js";import{property as r,subclass as o}from"../../../../core/accessorSupport/decorators.js";import{multiply as s,fromTranslation as n}from"../../../../core/libs/gl-matrix-2/math/mat4.js";import{create as h}from"../../../../core/libs/gl-matrix-2/factories/mat4f64.js";import{set as u,sub as a}from"../../../../core/libs/gl-matrix-2/math/vec3.js";import{create as p}from"../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{RenderNodeOutput as c}from"../../webgl.js";import{debugFlags as f}from"../../support/debugFlags.js";import{glLayout as d}from"../../support/buffer/glUtil.js";import{newLayout as _}from"../../support/buffer/InterleavedLayout.js";import l from"../../webgl/RenderNode.js";import{Pos2Locations as m}from"./DefaultVertexBufferLayouts.js";import{VertexArrayObject as g}from"./VertexArrayObject.js";import{TaskPriority as x}from"../../../support/Scheduler.js";import{Yield as v}from"../../../support/Yield.js";import{BufferObject as b}from"../../../webgl/BufferObject.js";import{DataType as w,PixelType as y}from"../../../webgl/enums.js";import{makePipelineState as T,defaultColorWrite as j}from"../../../webgl/renderState.js";import{Sync as P}from"../../../webgl/Sync.js";import C from"../../../webgl/Texture.js";import{TextureDescriptor as B}from"../../../webgl/TextureDescriptor.js";import{fromLayout as O}from"../../../webgl/VertexAttributeLocations.js";import{VertexBuffer as D}from"../../../webgl/VertexBuffer.js";let M=class extends l{constructor(t){super(t),this.category=c.COMPOSITE,this._debugVao=null,this._debugVaoLength=0,this.readyToRun=!1,this.done=!0,this._start=!1,this._origin=p(),this._textureWidth=256,this._uploadBuffer=new Float32Array(3*this._textureWidth),this._counter=0,this._width=0,this._height=0,this._pipeline=T({colorWrite:j}),this._format=0}initialize(){const t=this.view.resourceController.scheduler.registerTask(x.GRAPHICS_CORE,this);this.addHandles(t),this.produces="disabled",this.consumes.required=[this.category],this.formatOverride&&(this._format=this.formatOverride)}destroy(){this._program=e(this._program),this._debugProgram=e(this._debugProgram),this._debugVao=e(this._debugVao),this._sync=i(this._sync),this._pixelBuffer=e(this._pixelBuffer),this._texture=e(this._texture)}precompile(){this._ensureProgram(this.renderingContext)}render(t){const e=t.find(({name:t})=>t===this.category),i=this.renderingContext,r=this.gl,o=e.getTexture(r.DEPTH_STENCIL_ATTACHMENT),s=this.view.stage?.renderer.fboCache;if(!o||!s||this._sync||!this._start)return e;this._start=!1,this.produces=f.OCCLUSION_QUERY_DEBUG_PIXEL?this.category:"disabled";const n=s.acquire(this._width,this._height,"hud visibility",10);i.bindFramebuffer(n.fbo),i.setPipelineState(this._pipeline);const h=this._ensureProgram(i);return i.useProgram(h),F(h,this.camera,this._origin),i.bindTexture(o,0),h.setUniform1i("depthTex",0),i.bindTexture(this._texture,1),h.setUniform1i("positionTex",1),h.setUniform1i("count",this._counter),i.screen.draw(),0===this._format&&(this._format=6403===r.getParameter(r.IMPLEMENTATION_COLOR_READ_FORMAT)&&r.getParameter(r.IMPLEMENTATION_COLOR_READ_TYPE)===w.FLOAT?6403:6408),this._pixelBuffer??=b.createPixelPack(i,r.STREAM_READ),this._pixelBuffer.setSize(this._width*this._height*(6403===this._format?4:16)),i.bindBuffer(this._pixelBuffer),r.readPixels(0,0,this._width,this._height,this._format,w.FLOAT,0),i.unbindBuffer(35051),i.bindFramebuffer(null),n.release(),this._sync=new P(r),setTimeout(()=>this.readyToRun=!0,0),e}runTask(){if(this._sync&&this._pixelBuffer){try{if(!this._sync.poll())return v}catch(t){return this.readyToRun=!1,void(this._sync=i(this._sync))}this.readyToRun=!1,this._sync=i(this._sync),this._cpuBuffer=new Float32Array(this._width*this._height*(6403===this._format?1:4)),this._pixelBuffer.getSubData(this._cpuBuffer),this.done=!0}else this.readyToRun=!1}cancel(){this._start=!1,this._sync=i(this._sync)}init(t,e){this.cancel();const i=this._textureWidth;if(this._width=i,this._height=Math.ceil(t/i),this._counter=0,this._texture?.dispose(),0===this._height)return;const r=new B(this._width,this._height);r.pixelFormat=6407,r.dataType=y.FLOAT,r.samplingMode=9728,this._texture=new C(this.renderingContext,r),this.done=!1,u(this._origin,Math.fround(e[0]),Math.fround(e[1]),Math.fround(e[2]))}addPosition(t){const e=this._width;if(this._counter>=e*this._height)return-1;const i=this._counter%e;return a(L,t,this._origin),this._uploadBuffer[3*i+0]=L[0],this._uploadBuffer[3*i+1]=L[1],this._uploadBuffer[3*i+2]=L[2],i===e-1&&this._flush(),this._counter++}start(){if(0===this._width||0===this._height)return void(this.done=!0);const t=this._width;this._counter%t>0&&this._flush(),this.produces=this.category,this._start=!0,this.requestRender(1)}getOcclusion(t){return this._cpuBuffer?.[6403===this._format?t:4*t]??-1}get usedMemory(){return(this._texture?.usedMemory??0)+(this._pixelBuffer?.usedMemory??0)+4*(this._uploadBuffer?.length??0)+4*(this._cpuBuffer?.length??0)}_flush(){const t=this._width,e=Math.floor(this._counter/t);this._texture?.updateData(0,0,e,t,1,this._uploadBuffer)}_ensureProgram(t){return this._program??=t.programCache.acquire(R,E,m),this._program}_ensureDebugProgram(t){return this._debugProgram??=t.programCache.acquire(V,A,z),this._debugProgram}_ensureDebugVao(t,i){if(!this._debugVao||this._debugVaoLength<i){const r=new Float32Array(i);for(let t=0;t<i;t++)r[t]=t;this._debugVao=e(this._debugVao),this._debugVao=new g(t,new D(t,I,r))}return this._debugVao}};t([r()],M.prototype,"category",void 0),t([r()],M.prototype,"formatOverride",void 0),t([r()],M.prototype,"readyToRun",void 0),t([r()],M.prototype,"done",void 0),M=t([o("esri.views.3d.webgl-engine.lib.GPUPointOcclusionQuery")],M);const V="#version 300 es\nprecision highp float;\nprecision highp int;\n\nin highp float componentIndex;\n\nuniform highp mat4 proj;\nuniform highp mat4 view;\n\nuniform highp sampler2D positionTex;\n\nvoid main() {\n int width = textureSize(positionTex, 0).x;\n int u = int(componentIndex) % width;\n int v = int(componentIndex) / width;\n\n vec4 posWorld = vec4(texelFetch(positionTex, ivec2(u, v), 0).rgb, 1.0);\n vec4 posView = view * posWorld;\n vec4 projected = proj * posView;\n\n gl_Position = projected;\n gl_PointSize = 1.0;\n}",A="#version 300 es\nout highp vec4 fragColor;\nuniform lowp vec4 color;\nvoid main() {\n fragColor = color;\n}\n",R="#version 300 es\nprecision highp float;\nin vec2 position;\n\nvoid main() {\n gl_Position = vec4(position, 0.0, 1.0);\n}",E="#version 300 es\nprecision highp float;\nout highp vec4 fragColor;\n\nuniform highp mat4 proj;\nuniform highp mat4 view;\n\nuniform highp int count;\n\nuniform highp sampler2D depthTex;\nuniform highp sampler2D positionTex;\n\nfloat linearizeDepth(float depth) {\n float depthNdc = depth * 2.0 - 1.0;\n float c1 = proj[3][2];\n float c2 = proj[2][2];\n return -c1 / (depthNdc + c2 + 1e-7);\n}\n\nvoid main() {\n int u = int(floor(gl_FragCoord.x));\n int v = int(floor(gl_FragCoord.y));\n if (u + v * textureSize(positionTex, 0).x >= count) {\n fragColor = vec4(-1);\n return;\n }\n vec4 posWorld = vec4(texelFetch(positionTex, ivec2(u, v), 0).rgb, 1.0);\n vec4 posView = view * posWorld;\n vec4 projected = proj * posView;\n\n vec3 clipPos = projected.xyz / projected.w;\n\n if (clipPos.x < -1.0 || clipPos.x > 1.0 || clipPos.y < -1.0 || clipPos.y > 1.0) {\n fragColor = vec4(-1);\n return;\n }\n\n vec3 uvDepth = 0.5 * clipPos + vec3(0.5);\n\n float depth = texture(depthTex, uvDepth.xy).r;\n\n if (uvDepth.z <= depth) {\n fragColor = vec4(0);\n return;\n }\n\n fragColor = vec4(linearizeDepth(depth) - linearizeDepth(uvDepth.z));\n}\n";function F(t,e,i){s(S,e.viewMatrix,n(S,i)),t.setUniformMatrix4fv("view",S),t.setUniformMatrix4fv("proj",e.projectionMatrix)}const L=p(),S=h(),I=d(_().f32("componentIndex")),z=O(I);export{M as GPUPointOcclusionQuery};