@footgun/cobalt 0.7.3 → 0.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/bundle.js +1 -1
- package/package.json +1 -1
- package/src/spritesheet/spritesheet.js +1 -2
package/CHANGELOG.md
CHANGED
package/bundle.js
CHANGED
|
@@ -281,4 +281,4 @@ fn main_fragment(in: VertexOut) -> FragmentOut {
|
|
|
281
281
|
out.color = vec4<f32>(color, 1.0);
|
|
282
282
|
return out;
|
|
283
283
|
}
|
|
284
|
-
`});this.renderPipeline=t.device.createRenderPipeline({label:"LightsRenderer renderpipeline",layout:"auto",vertex:{module:n,entryPoint:"main_vertex"},fragment:{module:n,entryPoint:"main_fragment",targets:[{format:this.targetTexture.format}]},primitive:{cullMode:"none",topology:"triangle-strip"}});let r=this.renderPipeline.getBindGroupLayout(0);this.bindgroup0=t.device.createBindGroup({label:"LightsRenderer bindgroup 0",layout:r,entries:[{binding:0,resource:{buffer:this.uniformsBufferGpu}},{binding:1,resource:{buffer:this.lightsBuffer.gpuBuffer}},{binding:2,resource:this.lightsTexture.texture.createView({label:"LightsRenderer lightsTexture view"})},{binding:3,resource:t.device.createSampler({label:"LightsRenderer sampler",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge",magFilter:t.lightsTextureProperties.filtering,minFilter:t.lightsTextureProperties.filtering})}]}),this.bindgroup1=this.buildBindgroup1(t.albedo),this.renderBundle=this.buildRenderBundle()}computeLightsTexture(t){this.lightsTexture.update(t)}render(t,n){let r=new ArrayBuffer(80);new Float32Array(r,0,16).set(n),new Float32Array(r,64,3).set(this.ambientLight),this.device.queue.writeBuffer(this.uniformsBufferGpu,0,r),t.executeBundles([this.renderBundle])}setAlbedo(t){this.bindgroup1=this.buildBindgroup1(t),this.renderBundle=this.buildRenderBundle()}setAmbientLight(t){this.ambientLight=[...t]}setObstacles(t){this.lightsTexture.setObstacles(t)}destroy(){this.uniformsBufferGpu.destroy(),this.lightsTexture.destroy()}buildBindgroup1(t){return this.device.createBindGroup({label:"LightsRenderer bindgroup 1",layout:this.renderPipeline.getBindGroupLayout(1),entries:[{binding:0,resource:t.view},{binding:1,resource:t.sampler}]})}buildRenderBundle(){let t=this.device.createRenderBundleEncoder({label:"LightsRenderer renderbundle encoder",colorFormats:[this.targetTexture.format]});return t.setPipeline(this.renderPipeline),t.setBindGroup(0,this.bindgroup0),t.setBindGroup(1,this.bindgroup1),t.draw(4),t.finish({label:"LightsRenderer renderbundle"})}};var dn={};hn(dn,{setAmbientLight:()=>du,setLights:()=>vu,setOccluders:()=>gu});function vu(e,t,n){t.data.lights=n,t.data.lightsBufferNeedsUpdate=!0}function du(e,t,n){t.data.lightsRenderer.setAmbientLight(n)}function gu(e,t,n){t.data.lightsRenderer.setObstacles(n),t.data.lightsTextureNeedsUpdate=!0}var br=class{invViewProjectionMatrix=Lt.identity();viewportSize={width:1,height:1};topLeft=[0,0];zoom=1;constructor(t){this.setViewportSize(t.viewportSize.width,t.viewportSize.height);let n=t.center??this.topLeft;this.setTopLeft(...n);let r=t.zoom??1;this.setZoom(r)}get invertViewProjectionMatrix(){return this.invViewProjectionMatrix}setViewportSize(t,n){this.viewportSize.width=t,this.viewportSize.height=n,this.updateMatrices()}setTopLeft(t,n){this.topLeft[0]=t,this.topLeft[1]=n,this.updateMatrices()}setZoom(t){this.zoom=t,this.updateMatrices()}updateMatrices(){Lt.identity(this.invViewProjectionMatrix),Lt.multiply(Lt.scaling([1,-1,0]),this.invViewProjectionMatrix,this.invViewProjectionMatrix),Lt.multiply(Lt.translation([1,1,0]),this.invViewProjectionMatrix,this.invViewProjectionMatrix),Lt.multiply(Lt.scaling([.5*this.viewportSize.width/this.zoom,.5*this.viewportSize.height/this.zoom,0]),this.invViewProjectionMatrix,this.invViewProjectionMatrix),Lt.multiply(Lt.translation([this.topLeft[0],this.topLeft[1],0]),this.invViewProjectionMatrix,this.invViewProjectionMatrix)}};var Ei={type:"cobalt:light",refs:[{name:"in",type:"textureView",format:"rgba16float",access:"read"},{name:"out",type:"textureView",format:"rgba16float",access:"write"}],onInit:async function(e,t={}){return wu(e,t)},onRun:function(e,t,n){xu(e,t,n)},onDestroy:function(e,t){yu(t)},onResize:function(e,t){Mu(e,t)},onViewportPosition:function(e,t){t.data.viewport.setTopLeft(...e.viewport.position)},customFunctions:{...dn}};async function wu(e,t){let{device:n}=e,r=256,i=256,o=new ae(n,r),s=new br({viewportSize:{width:e.viewport.width,height:e.viewport.height},center:e.viewport.position,zoom:e.viewport.zoom}),f=new Mr({device:n,albedo:{view:t.refs.in.data.view,sampler:t.refs.in.data.sampler},targetTexture:t.refs.out.data.texture,lightsBuffer:o,lightsTextureProperties:{resolutionPerLight:i,maxLightSize:i,antialiased:!1,filtering:"nearest",textureFormat:qt(e)}});return{lightsBuffer:o,lightsBufferNeedsUpdate:!0,lightsTextureNeedsUpdate:!0,lightsRenderer:f,viewport:s,lights:[]}}function xu(e,t,n){t.data.lightsBufferNeedsUpdate&&(t.data.lightsBuffer.setLights(t.data.lights),t.data.lightsBufferNeedsUpdate=!1,t.data.lightsTextureNeedsUpdate=!0);let r=t.data.lightsRenderer;t.data.lightsTextureNeedsUpdate&&(r.computeLightsTexture(n),t.data.lightsTextureNeedsUpdate=!1);let i=n.beginRenderPass({label:"light",colorAttachments:[{view:t.refs.out.data.view,clearValue:e.clearValue,loadOp:"load",storeOp:"store"}]});t.data.viewport.setZoom(e.viewport.zoom);let o=t.data.viewport.invertViewProjectionMatrix;r.render(i,o),i.end()}function yu(e){e.data.lightsBuffer.destroy(),e.data.lightsRenderer.destroy()}function Mu(e,t){t.data.lightsRenderer.setAlbedo({view:t.refs.in.data.view,sampler:t.refs.in.data.sampler}),t.data.viewport.setViewportSize(e.viewport.width,e.viewport.height)}function de(e){return e>=0?Math.round(e):e%.5===0?Math.floor(e):Math.round(e)}var Ri="struct TransformData{view:mat4x4<f32>,projection:mat4x4<f32>};@binding(0)@group(0)var<uniform> transformUBO:TransformData;struct Fragment{@builtin(position)Position:vec4<f32>,@location(0)Color:vec4<f32>,};@vertex fn vs_main(@location(0)vertexPosition:vec2<f32>,@location(1)vertexColor:vec4<f32>)->Fragment{var sx:f32=1.0;var sy:f32=1.0;var sz:f32=1.0;var rot:f32=0.0;var tx:f32=1.0;var ty:f32=1.0;var tz:f32=0;var s=sin(rot);var c=cos(rot);var scaleM:mat4x4<f32>=mat4x4<f32>(sx,0.0,0.0,0.0,0.0,sy,0.0,0.0,0.0,0.0,sz,0.0,0,0,0,1.0);var modelM:mat4x4<f32>=mat4x4<f32>(c,s,0.0,0.0,-s,c,0.0,0.0,0.0,0.0,1.0,0.0,tx,ty,tz,1.0)*scaleM;var output:Fragment;output.Position=transformUBO.projection*transformUBO.view*modelM*vec4<f32>(vertexPosition,0.0,1.0);output.Color=vertexColor;return output;}@fragment fn fs_main(@location(0)Color:vec4<f32>)->@location(0)vec4<f32>{return Color;}";var ps=pi(co(),1);var hs=pi(ls(),1);function ti(e,t){if(!Array.isArray(e))throw new Error("poly-to-pslg: Error, invalid polygon");if(e.length===0)return{points:[],edges:[]};t=t||{};var n=!0;"nested"in t?n=!!t.nested:e[0].length===2&&typeof e[0][0]=="number"&&(n=!1),n||(e=[e]);for(var r=[],i=[],o=0;o<e.length;++o)for(var s=e[o],f=r.length,h=0;h<s.length;++h)r.push(s[h]),i.push([f+h,f+(h+1)%s.length]);var p="clean"in t?!0:!!t.clean;return p&&(0,hs.default)(r,i),{points:r,edges:i}}var vs={line:Re,save:function(e,t){t.data.transforms.push(Me.clone(t.data.transforms.at(-1)))},restore:function(e,t){t.data.transforms.length>1&&t.data.transforms.pop()},translate:function(e,t,n){let r=t.data.transforms.at(-1);Me.translate(r,n,r)},rotate:function(e,t,n){let r=t.data.transforms.at(-1);Me.rotate(r,n,r)},scale:function(e,t,n){let r=t.data.transforms.at(-1);Me.scale(r,n,r)},strokePath:function(e,t,n,r,i=1){for(let o of n)Re(e,t,o[0],o[1],r,i)},filledPath:function(e,t,n,r){let i=ti(n),o=(0,ps.default)(i.points,i.edges,{exterior:!1}),s=t.data.transforms.at(-1),f=t.data.vertexCount*6,h=t.data.vertexCount*6,p=o.length*3*6;t.data.vertices=Zr(Float32Array,t.data.vertices,h,p);let g=Et.create();for(let D of o)Et.transformMat3(n[D[0]],s,g),t.data.vertices[f+0]=g[0],t.data.vertices[f+1]=g[1],t.data.vertices[f+2]=r[0],t.data.vertices[f+3]=r[1],t.data.vertices[f+4]=r[2],t.data.vertices[f+5]=r[3],Et.transformMat3(n[D[1]],s,g),t.data.vertices[f+6]=g[0],t.data.vertices[f+7]=g[1],t.data.vertices[f+8]=r[0],t.data.vertices[f+9]=r[1],t.data.vertices[f+10]=r[2],t.data.vertices[f+11]=r[3],Et.transformMat3(n[D[2]],s,g),t.data.vertices[f+12]=g[0],t.data.vertices[f+13]=g[1],t.data.vertices[f+14]=r[0],t.data.vertices[f+15]=r[1],t.data.vertices[f+16]=r[2],t.data.vertices[f+17]=r[3],f+=18;t.data.vertexCount+=3*o.length,t.data.dirty=!0},ellipse:function(e,t,n,r,i,o,s,f=1){let[h,p]=n,g=2*Math.PI/o;for(let D=0;D<o;D++){let X=D*g,N=(D+1)*g,I=h+r*Math.cos(X),V=p+i*Math.sin(X),q=h+r*Math.cos(N),Y=p+i*Math.sin(N);Re(e,t,[I,V],[q,Y],s,f)}},filledEllipse:function(e,t,n,r,i,o,s){let[f,h]=n,p=2*Math.PI/o,g=t.data.vertexCount*6,D=o*3*6;t.data.vertices=Zr(Float32Array,t.data.vertices,g,D);let X=t.data.transforms.at(-1);for(let N=0;N<o;N++){let I=N*p,V=(N+1)*p,q=f+r*Math.cos(I),Y=h+i*Math.sin(I),K=f+r*Math.cos(V),Q=h+i*Math.sin(V),H=t.data.vertexCount*6+N*18,W=Et.transformMat3([f,h],X);t.data.vertices[H+0]=W[0],t.data.vertices[H+1]=W[1],t.data.vertices[H+2]=s[0],t.data.vertices[H+3]=s[1],t.data.vertices[H+4]=s[2],t.data.vertices[H+5]=s[3],Et.transformMat3([q,Y],X,W),t.data.vertices[H+6]=W[0],t.data.vertices[H+7]=W[1],t.data.vertices[H+8]=s[0],t.data.vertices[H+9]=s[1],t.data.vertices[H+10]=s[2],t.data.vertices[H+11]=s[3],Et.transformMat3([K,Q],X,W),t.data.vertices[H+12]=W[0],t.data.vertices[H+13]=W[1],t.data.vertices[H+14]=s[0],t.data.vertices[H+15]=s[1],t.data.vertices[H+16]=s[2],t.data.vertices[H+17]=s[3]}t.data.vertexCount+=3*o,t.data.dirty=!0},box:function(e,t,n,r,i,o,s=1){let[f,h]=n,p=r/2,g=i/2,D=[f-p,h-g],X=[f+p,h-g],N=[f-p,h+g],I=[f+p,h+g];Re(e,t,D,X,o,s),Re(e,t,N,I,o,s),Re(e,t,D,N,o,s),Re(e,t,X,I,o,s)},filledBox:function(e,t,n,r,i,o){let[s,f]=n,h=r/2,p=i/2,g=t.data.transforms.at(-1),D=Et.transformMat3([s-h,f-p],g),X=Et.transformMat3([s+h,f-p],g),N=Et.transformMat3([s-h,f+p],g),I=Et.transformMat3([s+h,f+p],g),V=t.data.vertexCount*6,q=36;t.data.vertices=Zr(Float32Array,t.data.vertices,V,q);let Y=t.data.vertexCount*6;t.data.vertices[Y+0]=D[0],t.data.vertices[Y+1]=D[1],t.data.vertices[Y+2]=o[0],t.data.vertices[Y+3]=o[1],t.data.vertices[Y+4]=o[2],t.data.vertices[Y+5]=o[3],t.data.vertices[Y+6]=N[0],t.data.vertices[Y+7]=N[1],t.data.vertices[Y+8]=o[0],t.data.vertices[Y+9]=o[1],t.data.vertices[Y+10]=o[2],t.data.vertices[Y+11]=o[3],t.data.vertices[Y+12]=X[0],t.data.vertices[Y+13]=X[1],t.data.vertices[Y+14]=o[0],t.data.vertices[Y+15]=o[1],t.data.vertices[Y+16]=o[2],t.data.vertices[Y+17]=o[3],t.data.vertices[Y+18]=N[0],t.data.vertices[Y+19]=N[1],t.data.vertices[Y+20]=o[0],t.data.vertices[Y+21]=o[1],t.data.vertices[Y+22]=o[2],t.data.vertices[Y+23]=o[3],t.data.vertices[Y+24]=I[0],t.data.vertices[Y+25]=I[1],t.data.vertices[Y+26]=o[0],t.data.vertices[Y+27]=o[1],t.data.vertices[Y+28]=o[2],t.data.vertices[Y+29]=o[3],t.data.vertices[Y+30]=X[0],t.data.vertices[Y+31]=X[1],t.data.vertices[Y+32]=o[0],t.data.vertices[Y+33]=o[1],t.data.vertices[Y+34]=o[2],t.data.vertices[Y+35]=o[3],t.data.vertexCount+=6,t.data.dirty=!0},clear:function(e,t){t.data.vertexCount=0,t.data.transforms.length=1,Me.identity(t.data.transforms[0]),t.data.dirty=!0}};function Re(e,t,n,r,i,o=1){let s=t.data.transforms.at(-1);n=Et.transformMat3(n,s),r=Et.transformMat3(r,s);let f=Et.sub(r,n),h=Et.normalize(f),p=Sc(h),g=o/2,D=t.data.vertexCount*6,X=t.data.vertexCount*6,N=36;t.data.vertices=Zr(Float32Array,t.data.vertices,X,N),t.data.vertices[D+0]=n[0]+p[0]*g,t.data.vertices[D+1]=n[1]+p[1]*g,t.data.vertices[D+2]=i[0],t.data.vertices[D+3]=i[1],t.data.vertices[D+4]=i[2],t.data.vertices[D+5]=i[3],t.data.vertices[D+6]=n[0]-p[0]*g,t.data.vertices[D+7]=n[1]-p[1]*g,t.data.vertices[D+8]=i[0],t.data.vertices[D+9]=i[1],t.data.vertices[D+10]=i[2],t.data.vertices[D+11]=i[3],t.data.vertices[D+12]=r[0]+p[0]*g,t.data.vertices[D+13]=r[1]+p[1]*g,t.data.vertices[D+14]=i[0],t.data.vertices[D+15]=i[1],t.data.vertices[D+16]=i[2],t.data.vertices[D+17]=i[3],t.data.vertices[D+18]=n[0]-p[0]*g,t.data.vertices[D+19]=n[1]-p[1]*g,t.data.vertices[D+20]=i[0],t.data.vertices[D+21]=i[1],t.data.vertices[D+22]=i[2],t.data.vertices[D+23]=i[3],t.data.vertices[D+24]=r[0]+p[0]*g,t.data.vertices[D+25]=r[1]+p[1]*g,t.data.vertices[D+26]=i[0],t.data.vertices[D+27]=i[1],t.data.vertices[D+28]=i[2],t.data.vertices[D+29]=i[3],t.data.vertices[D+30]=r[0]-p[0]*g,t.data.vertices[D+31]=r[1]-p[1]*g,t.data.vertices[D+32]=i[0],t.data.vertices[D+33]=i[1],t.data.vertices[D+34]=i[2],t.data.vertices[D+35]=i[3],t.data.vertexCount+=6,t.data.dirty=!0}function Zr(e,t,n,r){if(n+r<=t.length)return t;let i=t.length*2,o=16*1024*1024/t.BYTES_PER_ELEMENT;if(i>o)throw new Error("vertices exceed max array size");let s=new e(i);return s.set(t),s}function Sc(e){return[-e[1],e[0]]}var ds=fe.create(0,0,0),ws={type:"cobalt:primitives",refs:[{name:"color",type:"textView",format:"PREFERRED_TEXTURE_VIEW",access:"write"}],onInit:async function(e,t={}){return _c(e,t)},onRun:function(e,t,n){Bc(e,t,n)},onDestroy:function(e,t){Dc(t)},onResize:function(e,t){gs(e,t)},onViewportPosition:function(e,t){gs(e,t)},customFunctions:vs};async function _c(e,t){let{device:n}=e,r=new Float32Array(1024),i=n.createBuffer({size:r.byteLength,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),o=n.createBuffer({size:128,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),s=n.createShaderModule({code:Ri}),f=n.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{}}]}),h=n.createPipelineLayout({bindGroupLayouts:[f]}),p=n.createBindGroup({layout:f,entries:[{binding:0,resource:{buffer:o}}]}),g=n.createRenderPipeline({label:"primitives",layout:h,vertex:{module:s,entryPoint:"vs_main",buffers:[{arrayStride:6*Float32Array.BYTES_PER_ELEMENT,attributes:[{shaderLocation:0,offset:0,format:"float32x2"},{shaderLocation:1,format:"float32x4",offset:8}]}]},fragment:{module:s,entryPoint:"fs_main",targets:[{format:qt(e),blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{srcFactor:"zero",dstFactor:"one"}}}]},primitive:{topology:"triangle-list"}});return{uniformBuffer:o,vertexBuffer:i,pipeline:g,bindGroup:p,vertexCount:0,dirty:!1,vertices:r,transforms:[Me.identity()]}}function Bc(e,t,n){if(t.data.vertexCount===0)return;let{device:r}=e;if(t.data.dirty){t.data.dirty=!1;let s=6*Float32Array.BYTES_PER_ELEMENT;t.data.vertices.buffer.byteLength>t.data.vertexBuffer.size&&(t.data.vertexBuffer.destroy(),t.data.vertexBuffer=r.createBuffer({size:t.data.vertices.byteLength,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}));let f=t.data.vertexCount*s;if(f>t.data.vertexBuffer.size){console.error("too many primitives, bailing");return}e.device.queue.writeBuffer(t.data.vertexBuffer,0,t.data.vertices.buffer,0,f)}let i=t.options.loadOp||"load",o=n.beginRenderPass({label:"primitives",colorAttachments:[{view:t.refs.color,clearValue:e.clearValue,loadOp:i,storeOp:"store"}]});o.setPipeline(t.data.pipeline),o.setBindGroup(0,t.data.bindGroup),o.setVertexBuffer(0,t.data.vertexBuffer),o.draw(t.data.vertexCount),o.end()}function Dc(e){e.data.vertexBuffer.destroy(),e.data.vertexBuffer=null,e.data.uniformBuffer.destroy(),e.data.uniformBuffer=null,e.data.transforms.length=0}function gs(e,t){let{device:n}=e,r=e.viewport.width/e.viewport.zoom,i=e.viewport.height/e.viewport.zoom,o=Lt.ortho(0,r,i,0,-10,10);fe.set(-e.viewport.position[0]-1,-e.viewport.position[1]-1,0,ds);let s=Lt.translation(ds);n.queue.writeBuffer(t.data.uniformBuffer,0,s.buffer),n.queue.writeBuffer(t.data.uniformBuffer,64,o.buffer)}var ei="struct BloomComposite{bloom_intensity:f32,bloom_combine_constant:f32,}@group(0)@binding(0)var mySampler:sampler;@group(0)@binding(1)var colorTexture:texture_2d<f32>;@group(0)@binding(2)var emissiveTexture:texture_2d<f32>;@group(0)@binding(3)var<uniform> composite_parameter:BloomComposite;struct VertexOutput{@builtin(position)Position:vec4<f32>,@location(0)fragUV:vec2<f32>,}const positions=array<vec2<f32>,3>(vec2<f32>(-1.0,-3.0),vec2<f32>(3.0,1.0),vec2<f32>(-1.0,1.0));const uvs=array<vec2<f32>,3>(vec2<f32>(0.0,2.0),vec2<f32>(2.0,0.0),vec2<f32>(0.0,0.0));@vertex fn vert_main(@builtin(vertex_index)VertexIndex:u32)->VertexOutput{var output:VertexOutput;output.Position=vec4<f32>(positions[VertexIndex],0.0,1.0);output.fragUV=vec2<f32>(uvs[VertexIndex]);return output;}fn GTTonemap_point(x:f32)->f32{let m:f32=0.22;let a:f32=1.0;let c:f32=1.33;let P:f32=1.0;let l:f32=0.4;let l0:f32=((P-m)*l)/a;let S0:f32=m+l0;let S1:f32=m+a*l0;let C2:f32=(a*P)/(P-S1);let L:f32=m+a*(x-m);let T:f32=m*pow(x/m,c);let S:f32=P-(P-S1)*exp(-C2*(x-S0)/P);let w0:f32=1.0-smoothstep(0.0,m,x);var w2:f32=1.0;if(x<m+l){w2=0.0;}let w1:f32=1.0-w0-w2;return f32(T*w0+L*w1+S*w2);}fn GTTonemap(x:vec3<f32>)->vec3<f32>{return vec3<f32>(GTTonemap_point(x.r),GTTonemap_point(x.g),GTTonemap_point(x.b));}fn aces(x:vec3<f32>)->vec3<f32>{let a:f32=2.51;let b:f32=0.03;let c:f32=2.43;let d:f32=0.59;let e:f32=0.14;return clamp((x*(a*x+b))/(x*(c*x+d)+e),vec3<f32>(0.0),vec3<f32>(1.0));}@fragment fn frag_main(@location(0)fragUV:vec2<f32>)->@location(0)vec4<f32>{let hdr_color=textureSample(colorTexture,mySampler,fragUV);let bloom_color=textureSample(emissiveTexture,mySampler,fragUV);let combined_color=((bloom_color*composite_parameter.bloom_intensity)*composite_parameter.bloom_combine_constant);let mapped_color=GTTonemap(combined_color.rgb);let gamma_corrected_color=pow(mapped_color,vec3<f32>(1.0/2.2));return vec4<f32>(gamma_corrected_color+hdr_color.rgb,1.0);}";var xs={type:"cobalt:bloom",refs:[{name:"hdr",type:"textureView",format:"rgba16",access:"read"},{name:"bloom",type:"textureView",format:"rgba16",access:"read"},{name:"combined",type:"textureView",format:"PREFERRED_TEXTURE_FORMAT",access:"write"}],onInit:async function(e,t={}){return Uc(e,t)},onRun:function(e,t,n){Fc(e,t,n)},onDestroy:function(e,t){},onResize:function(e,t){Gc(e,t)},onViewportPosition:function(e,t){}};function Uc(e,t){let{options:n,refs:r}=t,{device:i}=e,o=qt(e),s=n.bloom_intensity??40,f=n.bloom_combine_constant??.68,h=new Float32Array([s,f]),p=i.createBuffer({label:"scene composite params buffer",size:h.byteLength,mappedAtCreation:!0,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});new Float32Array(p.getMappedRange()).set(h),p.unmap();let g=i.createRenderPipeline({label:"scenecomposite",layout:"auto",vertex:{module:i.createShaderModule({code:ei}),entryPoint:"vert_main"},fragment:{module:i.createShaderModule({code:ei}),entryPoint:"frag_main",targets:[{format:o}]},primitive:{topology:"triangle-list"}});return{bindGroup:i.createBindGroup({layout:g.getBindGroupLayout(0),entries:[{binding:0,resource:r.hdr.data.sampler},{binding:1,resource:r.hdr.data.view},{binding:2,resource:r.bloom.data.mip_view[0]},{binding:3,resource:{buffer:p}}]}),pipeline:g,params_buf:p}}function Fc(e,t,n){let r=n.beginRenderPass({label:"scene-composite",colorAttachments:[{view:t.refs.combined.data.view,clearValue:{r:0,g:0,b:0,a:1},loadOp:"clear",storeOp:"store"}]}),{pipeline:i,bindGroup:o}=t.data;r.setPipeline(i),r.setBindGroup(0,o),r.draw(3),r.end()}function Gc(e,t){let{pipeline:n,params_buf:r}=t.data,{device:i}=e;t.data.bindGroup=i.createBindGroup({layout:n.getBindGroupLayout(0),entries:[{binding:0,resource:t.refs.hdr.data.sampler},{binding:1,resource:t.refs.hdr.data.view},{binding:2,resource:t.refs.bloom.data.mip_view[0]},{binding:3,resource:{buffer:r}}]})}var ri={};hn(ri,{addSprite:()=>Ac,clear:()=>Lc,removeSprite:()=>zc,setSpriteName:()=>Ec,setSpriteOpacity:()=>Oc,setSpritePosition:()=>Rc,setSpriteRotation:()=>mc,setSpriteScale:()=>Vc,setSpriteTint:()=>Ic});function Ac(e,t,n,r,i,o,s,f){let{idByName:h}=t.refs.spritesheet.data;return t.data.sprites.push({position:Et.clone(r),sizeX:1,sizeY:1,scale:Et.clone(i),rotation:f,opacity:s,tint:Ce.clone(o),spriteID:h.get(n),id:Be()}),t.data.sprites.at(-1).id}function zc(e,t,n){for(let r=0;r<t.data.sprites.length;r++)if(t.data.sprites[r].id===n){t.data.sprites.splice(r,1);return}}function Lc(e,t){t.data.sprites.length=0}function Ec(e,t,n,r){let i=t.data.sprites.find(s=>s.id===n);if(!i)return;let{idByName:o}=t.refs.spritesheet.data;i.spriteID=o.get(r)}function Rc(e,t,n,r){let i=t.data.sprites.find(o=>o.id===n);i&&Et.copy(r,i.position)}function Ic(e,t,n,r){let i=t.data.sprites.find(o=>o.id===n);i&&Ce.copy(r,i.tint)}function Oc(e,t,n,r){let i=t.data.sprites.find(o=>o.id===n);i&&(i.opacity=r)}function mc(e,t,n,r){let i=t.data.sprites.find(o=>o.id===n);i&&(i.rotation=r)}function Vc(e,t,n,r){let i=t.data.sprites.find(o=>o.id===n);i&&Et.copy(r,i.scale)}var ys="struct ViewParams{view:mat4x4<f32>,proj:mat4x4<f32>};@group(0)@binding(0)var<uniform> uView:ViewParams;@group(0)@binding(1)var uSampler:sampler;@group(0)@binding(2)var uTex:texture_2d<f32>;struct SpriteDesc{uvOrigin:vec2<f32>,uvSpan:vec2<f32>,frameSize:vec2<f32>,centerOffset:vec2<f32>,};@group(0)@binding(3)var<storage,read>Sprites:array<SpriteDesc>;struct VSOut{@builtin(position)pos:vec4<f32>,@location(0)uv:vec2<f32>,@location(1)tint:vec4<f32>,@location(2)opacity:f32,};const corners=array<vec2<f32>,4>(vec2<f32>(-0.5,-0.5),vec2<f32>(0.5,-0.5),vec2<f32>(-0.5,0.5),vec2<f32>(0.5,0.5),);const uvBase=array<vec2<f32>,4>(vec2<f32>(0.0,0.0),vec2<f32>(1.0,0.0),vec2<f32>(0.0,1.0),vec2<f32>(1.0,1.0),);@vertex fn vs_main(@builtin(vertex_index)vid:u32,@location(0)i_pos:vec2<f32>,@location(1)i_size:vec2<f32>,@location(2)i_scale:vec2<f32>,@location(3)i_tint:vec4<f32>,@location(4)i_spriteId:u32,@location(5)i_opacity:f32,@location(6)i_rotation:f32)->VSOut{let rot=i_rotation;let c=cos(rot);let s=sin(rot);let d=Sprites[i_spriteId];let corner=corners[vid];let sizePx=d.frameSize*i_size*i_scale;var local=corner*sizePx;local+=d.centerOffset*i_scale;let rotated=vec2<f32>(local.x*c-local.y*s,local.x*s+local.y*c);let world=vec4<f32>(rotated+i_pos,0.0,1.0);var out:VSOut;out.pos=uView.proj*uView.view*world;out.uv=d.uvOrigin+d.uvSpan*uvBase[vid];out.tint=i_tint;out.opacity=i_opacity;return out;}@fragment fn fs_main(in:VSOut)->@location(0)vec4<f32>{let texel=textureSample(uTex,uSampler,in.uv);return vec4<f32>(texel.rgb*(1.0-in.tint.a)+(in.tint.rgb*in.tint.a),texel.a*in.opacity);}";var ni=fe.create(0,0,0),Ie=64,ii=0,oi=8,ai=16,fr=24,bs=40,Ts=44,Ps=48,Ss={type:"cobalt:sprite",refs:[{name:"spritesheet",type:"customResource",access:"read"},{name:"color",type:"textureView",format:"rgba8unorm",access:"write"}],onInit:async function(e,t={}){return qc(e,t)},onRun:function(e,t,n){Cc(e,t,n)},onDestroy:function(e,t){try{t.data.instanceBuf?.destroy()}catch{}try{t.data.spriteBuf?.destroy()}catch{}try{t.data.uniformBuffer?.destroy()}catch{}t.data.pipeline=null,t.data.bindGroup=null,t.data.bindGroupLayout=null,t.data.instanceStaging=null,t.data.instanceView=null,t.data.sprites.length=0,t.data.visible.length=0},onResize:function(e,t){Ms(e,t)},onViewportPosition:function(e,t){Ms(e,t)},customFunctions:{...ri}};async function qc(e,t){let{device:n}=e,{descs:r,names:i}=t.refs.spritesheet.data.spritesheet,o=n.createBuffer({size:128,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),s=32,f=new ArrayBuffer(s*r.length),h=new Float32Array(f);for(let tt=0;tt<r.length;tt++){let H=r[tt],W=tt*8;h[W+0]=H.UvOrigin[0],h[W+1]=H.UvOrigin[1],h[W+2]=H.UvSpan[0],h[W+3]=H.UvSpan[1],h[W+4]=H.FrameSize[0],h[W+5]=H.FrameSize[1],h[W+6]=H.CenterOffset[0],h[W+7]=H.CenterOffset[1]}let p=n.createBuffer({label:"sprite desc table",size:Math.max(16,f.byteLength),usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST});n.queue.writeBuffer(p,0,f);let g=1024,D=n.createBuffer({label:"sprite instances",size:Ie*g,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),X=new ArrayBuffer(Ie*g),N=new DataView(X),I=n.createShaderModule({code:ys}),V=n.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}},{binding:3,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}}]}),q=n.createPipelineLayout({bindGroupLayouts:[V]}),Y={arrayStride:Ie,stepMode:"instance",attributes:[{shaderLocation:0,offset:ii,format:"float32x2"},{shaderLocation:1,offset:oi,format:"float32x2"},{shaderLocation:2,offset:ai,format:"float32x2"},{shaderLocation:3,offset:fr,format:"float32x4"},{shaderLocation:4,offset:bs,format:"uint32"},{shaderLocation:5,offset:Ts,format:"float32"},{shaderLocation:6,offset:Ps,format:"float32"}]},K=n.createRenderPipeline({layout:q,vertex:{module:I,entryPoint:"vs_main",buffers:[Y]},fragment:{module:I,entryPoint:"fs_main",targets:[{format:qt(e),blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{srcFactor:"zero",dstFactor:"one"}}}]},primitive:{topology:"triangle-strip",cullMode:"none"},multisample:{count:1}}),Q=n.createBindGroup({layout:V,entries:[{binding:0,resource:{buffer:o}},{binding:1,resource:t.refs.spritesheet.data.colorTexture.sampler},{binding:2,resource:t.refs.spritesheet.data.colorTexture.view},{binding:3,resource:{buffer:p}}]});return{sprites:[],visible:[],visibleCount:0,viewRect:{x:0,y:0,w:0,h:0},spriteBuf:p,uniformBuffer:o,instanceCap:g,instanceView:N,instanceBuf:D,instanceStaging:X,pipeline:K,bindGroup:Q}}function Nc(e,t,n){let{instanceCap:r}=t.data;if(n<=r)return;let i=r;for(i===0&&(i=1024);i<n;)i*=2;t.data.instanceBuf.destroy(),t.data.instanceBuf=e.device.createBuffer({size:Ie*i,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),t.data.instanceStaging=new ArrayBuffer(Ie*i),t.data.instanceView=new DataView(t.data.instanceStaging),t.data.instanceCap=i}function Cc(e,t,n){let{device:r,context:i}=e,{instanceView:o,instanceBuf:s,instanceStaging:f,pipeline:h,bindGroup:p}=t.data,{descs:g}=t.refs.spritesheet.data.spritesheet,D=t.data.viewRect;D.x=e.viewport.position[0],D.y=e.viewport.position[1],D.w=e.viewport.width,D.h=e.viewport.height,t.data.visibleCount=0;for(let I of t.data.sprites){let V=g[I.spriteID];if(V){if(!t.options.isScreenSpace){let q=V.FrameSize[0]*I.sizeX*I.scale[0]*.5,Y=V.FrameSize[1]*I.sizeY*I.scale[1]*.5,K=Math.hypot(q,Y),Q=I.position[0],tt=I.position[1];if(Q+K<D.x||Q-K>D.x+D.w||tt+K<D.y||tt-K>D.y+D.h)continue}t.data.visible[t.data.visibleCount]=I,t.data.visibleCount++}}Nc(e,t,t.data.visibleCount);for(let I=0;I<t.data.visibleCount;I++){let V=I*Ie,q=t.data.visible[I],Y=q.tint;o.setFloat32(V+ii+0,q.position[0],!0),o.setFloat32(V+ii+4,q.position[1],!0),o.setFloat32(V+oi+0,q.sizeX,!0),o.setFloat32(V+oi+4,q.sizeY,!0),o.setFloat32(V+ai+0,q.scale[0],!0),o.setFloat32(V+ai+4,q.scale[1],!0),o.setFloat32(V+fr+0,Y[0],!0),o.setFloat32(V+fr+4,Y[1],!0),o.setFloat32(V+fr+8,Y[2],!0),o.setFloat32(V+fr+12,Y[3],!0),o.setUint32(V+bs,q.spriteID>>>0,!0),o.setFloat32(V+Ts,q.opacity,!0),o.setFloat32(V+Ps,q.rotation,!0)}r.queue.writeBuffer(s,0,f,0,t.data.visibleCount*Ie);let X=t.options.loadOp||"load",N=n.beginRenderPass({label:"sprite renderpass",colorAttachments:[{view:t.refs.color,clearValue:e.clearValue,loadOp:X,storeOp:"store"}]});N.setPipeline(h),N.setBindGroup(0,p),N.setVertexBuffer(0,s),t.data.visibleCount&&N.draw(4,t.data.visibleCount,0,0),N.end()}function Ms(e,t){let{device:n,viewport:r}=e,i=r.width/r.zoom,o=r.height/r.zoom,s=Lt.ortho(0,i,o,0,-10,10);t.options.isScreenSpace?fe.set(0,0,0,ni):fe.set(-de(r.position[0]),-de(r.position[1]),0,ni);let f=Lt.translation(ni);n.queue.writeBuffer(t.data.uniformBuffer,0,f.buffer),n.queue.writeBuffer(t.data.uniformBuffer,64,s.buffer)}var si={};hn(si,{addSprite:()=>Xc,clear:()=>Yc,removeSprite:()=>kc,setSpriteName:()=>Hc,setSpriteOpacity:()=>Wc,setSpritePosition:()=>Zc,setSpriteRotation:()=>Kc,setSpriteScale:()=>Qc,setSpriteTint:()=>$c});function Xc(e,t,n,r,i,o,s,f){let{idByName:h}=t.refs.spritesheet.data;return t.data.sprites.push({position:Et.clone(r),sizeX:1,sizeY:1,scale:Et.clone(i),rotation:f,opacity:s,tint:Ce.clone(o),spriteID:h.get(n),id:Be()}),t.data.sprites.at(-1).id}function kc(e,t,n){for(let r=0;r<t.data.sprites.length;r++)if(t.data.sprites[r].id===n){t.data.sprites.splice(r,1);return}}function Yc(e,t){t.data.sprites.length=0}function Hc(e,t,n,r){let i=t.data.sprites.find(s=>s.id===n);if(!i)return;let{idByName:o}=t.refs.spritesheet.data;i.spriteID=o.get(r)}function Zc(e,t,n,r){let i=t.data.sprites.find(o=>o.id===n);i&&Et.copy(r,i.position)}function $c(e,t,n,r){let i=t.data.sprites.find(o=>o.id===n);i&&Ce.copy(r,i.tint)}function Wc(e,t,n,r){let i=t.data.sprites.find(o=>o.id===n);i&&(i.opacity=r)}function Kc(e,t,n,r){let i=t.data.sprites.find(o=>o.id===n);i&&(i.rotation=r)}function Qc(e,t,n,r){let i=t.data.sprites.find(o=>o.id===n);i&&Et.copy(r,i.scale)}var _s="struct ViewParams{view:mat4x4<f32>,proj:mat4x4<f32>};@group(0)@binding(0)var<uniform> uView:ViewParams;@group(0)@binding(1)var uSampler:sampler;@group(0)@binding(2)var uTex:texture_2d<f32>;struct SpriteDesc{uvOrigin:vec2<f32>,uvSpan:vec2<f32>,frameSize:vec2<f32>,centerOffset:vec2<f32>,};@group(0)@binding(3)var<storage,read>Sprites:array<SpriteDesc>;@group(0)@binding(4)var emissiveTexture:texture_2d<f32>;struct VSOut{@builtin(position)pos:vec4<f32>,@location(0)uv:vec2<f32>,@location(1)tint:vec4<f32>,@location(2)opacity:f32,};const corners=array<vec2<f32>,4>(vec2<f32>(-0.5,-0.5),vec2<f32>(0.5,-0.5),vec2<f32>(-0.5,0.5),vec2<f32>(0.5,0.5),);const uvBase=array<vec2<f32>,4>(vec2<f32>(0.0,0.0),vec2<f32>(1.0,0.0),vec2<f32>(0.0,1.0),vec2<f32>(1.0,1.0),);struct GBufferOutput{@location(0)color:vec4<f32>,@location(1)emissive:vec4<f32>,}@vertex fn vs_main(@builtin(vertex_index)vid:u32,@location(0)i_pos:vec2<f32>,@location(1)i_size:vec2<f32>,@location(2)i_scale:vec2<f32>,@location(3)i_tint:vec4<f32>,@location(4)i_spriteId:u32,@location(5)i_opacity:f32,@location(6)i_rotation:f32)->VSOut{let rot=i_rotation;let c=cos(rot);let s=sin(rot);let d=Sprites[i_spriteId];let corner=corners[vid];let sizePx=d.frameSize*i_size*i_scale;var local=corner*sizePx;local+=d.centerOffset*i_scale;let rotated=vec2<f32>(local.x*c-local.y*s,local.x*s+local.y*c);let world=vec4<f32>(rotated+i_pos,0.0,1.0);var out:VSOut;out.pos=uView.proj*uView.view*world;out.uv=d.uvOrigin+d.uvSpan*uvBase[vid];out.tint=i_tint;out.opacity=i_opacity;return out;}@fragment fn fs_main(in:VSOut)->GBufferOutput{var output:GBufferOutput;let texel=textureSample(uTex,uSampler,in.uv);output.color=vec4<f32>(texel.rgb*(1.0-in.tint.a)+(in.tint.rgb*in.tint.a),texel.a*in.opacity);let emissive=textureSample(emissiveTexture,uSampler,in.uv);output.emissive=vec4(emissive.rgb,1.0)*emissive.a;return output;}";var ui=fe.create(0,0,0),Oe=64,fi=0,ci=8,li=16,cr=24,Ds=40,Us=44,Fs=48,Gs={type:"cobalt:spriteHDR",refs:[{name:"spritesheet",type:"customResource",access:"read"},{name:"color",type:"textureView",format:"rgba16float",access:"write"},{name:"emissive",type:"textureView",format:"rgba16float",access:"write"}],onInit:async function(e,t={}){return Jc(e,t)},onRun:function(e,t,n){tl(e,t,n)},onDestroy:function(e,t){try{t.data.instanceBuf?.destroy()}catch{}try{t.data.spriteBuf?.destroy()}catch{}try{t.data.uniformBuffer?.destroy()}catch{}t.data.pipeline=null,t.data.bindGroup=null,t.data.bindGroupLayout=null,t.data.instanceStaging=null,t.data.instanceView=null,t.data.sprites.length=0,t.data.visible.length=0},onResize:function(e,t){Bs(e,t)},onViewportPosition:function(e,t){Bs(e,t)},customFunctions:{...si}};async function Jc(e,t){let{device:n}=e,{descs:r,names:i}=t.refs.spritesheet.data.spritesheet,o=n.createBuffer({size:128,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),s=32,f=new ArrayBuffer(s*r.length),h=new Float32Array(f);for(let H=0;H<r.length;H++){let W=r[H],st=H*8;h[st+0]=W.UvOrigin[0],h[st+1]=W.UvOrigin[1],h[st+2]=W.UvSpan[0],h[st+3]=W.UvSpan[1],h[st+4]=W.FrameSize[0],h[st+5]=W.FrameSize[1],h[st+6]=W.CenterOffset[0],h[st+7]=W.CenterOffset[1]}let p=n.createBuffer({label:"spriteHDR desc table",size:Math.max(16,f.byteLength),usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST});n.queue.writeBuffer(p,0,f);let g=1024,D=n.createBuffer({label:"spriteHDR instances",size:Oe*g,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),X=new ArrayBuffer(Oe*g),N=new DataView(X),I=n.createShaderModule({code:_s}),V=n.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}},{binding:3,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}},{binding:4,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}}]}),q=n.createPipelineLayout({bindGroupLayouts:[V]}),Y={arrayStride:Oe,stepMode:"instance",attributes:[{shaderLocation:0,offset:fi,format:"float32x2"},{shaderLocation:1,offset:ci,format:"float32x2"},{shaderLocation:2,offset:li,format:"float32x2"},{shaderLocation:3,offset:cr,format:"float32x4"},{shaderLocation:4,offset:Ds,format:"uint32"},{shaderLocation:5,offset:Us,format:"float32"},{shaderLocation:6,offset:Fs,format:"float32"}]},K=n.createRenderPipeline({layout:q,vertex:{module:I,entryPoint:"vs_main",buffers:[Y]},fragment:{module:I,entryPoint:"fs_main",targets:[{format:"rgba16float",blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{srcFactor:"zero",dstFactor:"one"}}},{format:"rgba16float"}]},primitive:{topology:"triangle-strip",cullMode:"none"},multisample:{count:1}}),Q=V,tt=n.createBindGroup({layout:V,entries:[{binding:0,resource:{buffer:o}},{binding:1,resource:t.refs.spritesheet.data.colorTexture.sampler},{binding:2,resource:t.refs.spritesheet.data.colorTexture.view},{binding:3,resource:{buffer:p}},{binding:4,resource:t.refs.spritesheet.data.emissiveTexture.view}]});return{sprites:[],visible:[],visibleCount:0,viewRect:{x:0,y:0,w:0,h:0},spriteBuf:p,uniformBuffer:o,instanceCap:g,instanceView:N,instanceBuf:D,instanceStaging:X,pipeline:K,bindGroup:tt}}function jc(e,t,n){let{instanceCap:r}=t.data;if(n<=r)return;let i=r;for(i===0&&(i=1024);i<n;)i*=2;t.data.instanceBuf.destroy(),t.data.instanceBuf=e.device.createBuffer({size:Oe*i,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),t.data.instanceStaging=new ArrayBuffer(Oe*i),t.data.instanceView=new DataView(t.data.instanceStaging),t.data.instanceCap=i}function tl(e,t,n){let{device:r,context:i}=e,{instanceView:o,instanceBuf:s,instanceStaging:f,pipeline:h,bindGroup:p}=t.data,{descs:g}=t.refs.spritesheet.data.spritesheet,D=t.data.viewRect;D.x=e.viewport.position[0],D.y=e.viewport.position[1],D.w=e.viewport.width,D.h=e.viewport.height,t.data.visibleCount=0;for(let I of t.data.sprites){let V=g[I.spriteID];if(V){if(!t.options.isScreenSpace){let q=V.FrameSize[0]*I.sizeX*I.scale[0]*.5,Y=V.FrameSize[1]*I.sizeY*I.scale[1]*.5,K=Math.hypot(q,Y),Q=I.position[0],tt=I.position[1];if(Q+K<D.x||Q-K>D.x+D.w||tt+K<D.y||tt-K>D.y+D.h)continue}t.data.visible[t.data.visibleCount]=I,t.data.visibleCount++}}jc(e,t,t.data.visibleCount);for(let I=0;I<t.data.visibleCount;I++){let V=I*Oe,q=t.data.visible[I],Y=q.tint;o.setFloat32(V+fi+0,q.position[0],!0),o.setFloat32(V+fi+4,q.position[1],!0),o.setFloat32(V+ci+0,q.sizeX,!0),o.setFloat32(V+ci+4,q.sizeY,!0),o.setFloat32(V+li+0,q.scale[0],!0),o.setFloat32(V+li+4,q.scale[1],!0),o.setFloat32(V+cr+0,Y[0],!0),o.setFloat32(V+cr+4,Y[1],!0),o.setFloat32(V+cr+8,Y[2],!0),o.setFloat32(V+cr+12,Y[3],!0),o.setUint32(V+Ds,q.spriteID>>>0,!0),o.setFloat32(V+Us,q.opacity,!0),o.setFloat32(V+Fs,q.rotation,!0)}r.queue.writeBuffer(s,0,f,0,t.data.visibleCount*Oe);let X=t.options.loadOp||"load",N=n.beginRenderPass({label:"spriteHDR renderpass",colorAttachments:[{view:t.refs.color.data.view,clearValue:e.clearValue,loadOp:X,storeOp:"store"},{view:t.refs.emissive.data.view,clearValue:e.clearValue,loadOp:"clear",storeOp:"store"}]});N.setPipeline(h),N.setBindGroup(0,p),N.setVertexBuffer(0,s),t.data.visibleCount&&N.draw(4,t.data.visibleCount,0,0),N.end()}function Bs(e,t){let{device:n,viewport:r}=e,i=r.width/r.zoom,o=r.height/r.zoom,s=Lt.ortho(0,i,o,0,-10,10);t.options.isScreenSpace?fe.set(0,0,0,ui):fe.set(-de(r.position[0]),-de(r.position[1]),0,ui);let f=Lt.translation(ui);n.queue.writeBuffer(t.data.uniformBuffer,0,f.buffer),n.queue.writeBuffer(t.data.uniformBuffer,64,s.buffer)}function $r(e){let t=e.meta.size.w,n=e.meta.size.h,r=Object.keys(e.frames).sort(),i=new Array(r.length);for(let o=0;o<r.length;o++){let s=e.frames[r[o]],f=s.frame.x,h=s.frame.y,p=s.frame.w,g=s.frame.h,D=f/t,X=h/n,N=p/t,I=g/n,V=s.sourceSize.w,q=s.sourceSize.h,Y=s.spriteSourceSize.x,K=s.spriteSourceSize.y,Q=Y+p*.5-V*.5,tt=K+g*.5-q*.5;i[o]={UvOrigin:[D,X],UvSpan:[N,I],FrameSize:[p,g],CenterOffset:[Q,tt]}}return{descs:i,names:r}}var As={type:"cobalt:spritesheet",refs:[],onInit:async function(e,t={}){return el(e,t)},onRun:function(e,t,n){},onDestroy:function(e,t){rl(t)},onResize:function(e,t){},onViewportPosition:function(e,t){}};async function el(e,t){let{canvas:n,device:r}=e,i,o,s,f=t.options.format||"rgba8unorm";n?(i=await fetch(t.options.spriteSheetJsonUrl),i=await i.json(),i=$r(i),o=await ve(e,"sprite",t.options.colorTextureUrl,f),s=await ve(e,"emissive sprite",t.options.emissiveTextureUrl,f),n.style.imageRendering="pixelated"):(i=$r(t.options.spriteSheetJson),o=await pe(e,"sprite",t.options.colorTexture,f),s=await pe(e,"emissive sprite",t.options.emissiveTexture,f));let h=new Map(i.names.map((p,g)=>[p,g]));return{colorTexture:o,emissiveTexture:s,spritesheet:i,idByName:h}}function rl(e){e.data.quads.buffer.destroy(),e.data.colorTexture.buffer.destroy(),e.data.emissiveTexture.texture.destroy()}var hi="struct TransformData{viewOffset:vec2<f32>,viewportSize:vec2<f32>,inverseAtlasTextureSize:vec2<f32>,tileSize:f32,inverseTileSize:f32,};struct TileScroll{scrollScale:vec2<f32>};const positions=array<vec2<f32>,3>(vec2<f32>(-1.0,-3.0),vec2<f32>(3.0,1.0),vec2<f32>(-1.0,1.0));const uvs=array<vec2<f32>,3>(vec2<f32>(0.0,2.0),vec2<f32>(2.0,0.0),vec2<f32>(0.0,0.0));@binding(0)@group(0)var<uniform> myScroll:TileScroll;@binding(1)@group(0)var tileTexture:texture_2d<f32>;@binding(2)@group(0)var tileSampler:sampler;@binding(0)@group(1)var<uniform> transformUBO:TransformData;@binding(1)@group(1)var atlasTexture:texture_2d<f32>;@binding(2)@group(1)var atlasSampler:sampler;struct Fragment{@builtin(position)Position:vec4<f32>,@location(0)TexCoord:vec2<f32>};@vertex fn vs_main(@builtin(instance_index)i_id:u32,@builtin(vertex_index)VertexIndex:u32)->Fragment{var vertexPosition=vec2<f32>(positions[VertexIndex]);var vertexTexCoord=vec2<f32>(uvs[VertexIndex]);var output:Fragment;let inverseTileTextureSize=1/vec2<f32>(textureDimensions(tileTexture,0));var scrollScale=myScroll.scrollScale;var viewOffset:vec2<f32>=transformUBO.viewOffset*scrollScale;let PixelCoord=(vertexTexCoord*transformUBO.viewportSize)+viewOffset;output.TexCoord=PixelCoord/transformUBO.tileSize;output.Position=vec4<f32>(vertexPosition,0.0,1.0);return output;}@fragment fn fs_main(@location(0)TexCoord:vec2<f32>)->@location(0)vec4<f32>{var tilemapCoord=floor(TexCoord);var u_tilemapSize=vec2<f32>(textureDimensions(tileTexture,0));var tileFoo=fract((tilemapCoord+vec2<f32>(0.5,0.5))/u_tilemapSize);var tile=floor(textureSample(tileTexture,tileSampler,tileFoo)*255.0);if(tile.x==255&&tile.y==255){discard;}var u_tilesetSize=vec2<f32>(textureDimensions(atlasTexture,0))/transformUBO.tileSize;let u_tileUVMinBounds=vec2<f32>(0.5/transformUBO.tileSize,0.5/transformUBO.tileSize);let u_tileUVMaxBounds=vec2<f32>((transformUBO.tileSize-0.5)/transformUBO.tileSize,(transformUBO.tileSize-0.5)/transformUBO.tileSize);var texcoord=clamp(fract(TexCoord),u_tileUVMinBounds,u_tileUVMaxBounds);var tileCoord=(tile.xy+texcoord)/u_tilesetSize;var color=textureSample(atlasTexture,atlasSampler,tileCoord);if(color.a<=0.1){discard;}return color;}";var ye=new Float32Array(8),Ls={type:"cobalt:tileAtlas",refs:[],onInit:async function(e,t={}){return nl(e,t)},onRun:function(e,t,n){},onDestroy:function(e,t){il(t)},onResize:function(e,t){zs(e,t)},onViewportPosition:function(e,t){zs(e,t)}};async function nl(e,t){let{canvas:n,device:r}=e,i=t.options.format||"rgba8unorm",o;n?o=await ve(e,"tile atlas",t.options.textureUrl,i):o=await pe(e,"tile atlas",t.options.texture,i);let s=r.createBuffer({size:32,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),f=r.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:2,visibility:GPUShaderStage.FRAGMENT,sampler:{}}]}),h=r.createBindGroup({layout:f,entries:[{binding:0,resource:{buffer:s}},{binding:1,resource:o.view},{binding:2,resource:o.sampler}]}),p=r.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,texture:{}},{binding:2,visibility:GPUShaderStage.FRAGMENT,sampler:{}}]}),g=r.createPipelineLayout({bindGroupLayouts:[p,f]});return{pipeline:r.createRenderPipeline({label:"tileatlas",vertex:{module:r.createShaderModule({code:hi}),entryPoint:"vs_main",buffers:[]},fragment:{module:r.createShaderModule({code:hi}),entryPoint:"fs_main",targets:[{format:t.options.outputFormat||qt(e),blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{srcFactor:"zero",dstFactor:"one"}}}]},primitive:{topology:"triangle-list"},layout:g}),uniformBuffer:s,atlasBindGroup:h,atlasMaterial:o,tileBindGroupLayout:p,tileSize:t.options.tileSize,tileScale:t.options.tileScale}}function il(e){e.data.atlasMaterial.texture.destroy(),e.data.atlasMaterial.texture=void 0}function zs(e,t){ye[0]=de(e.viewport.position[0]),ye[1]=de(e.viewport.position[1]);let n=t.data,{tileScale:r,tileSize:i}=n,o=e.viewport.width/e.viewport.zoom,s=e.viewport.height/e.viewport.zoom;ye[2]=o/r,ye[3]=s/r,ye[4]=1/n.atlasMaterial.texture.width,ye[5]=1/n.atlasMaterial.texture.height,ye[6]=i,ye[7]=1/i,e.device.queue.writeBuffer(n.uniformBuffer,0,ye,0,8)}var Rs={type:"cobalt:tileHDR",refs:[{name:"tileAtlas",type:"textureView",format:"rgba8unorm",access:"read"},{name:"hdr",type:"textureView",format:"rgba16float",access:"write"}],onInit:async function(e,t={}){return ol(e,t)},onRun:function(e,t,n){al(e,t,n)},onDestroy:function(e,t){Es(t)},onResize:function(e,t){},onViewportPosition:function(e,t){},customFunctions:{setTexture:async function(e,t,n){let{canvas:r,device:i}=e;Es(t);let o=t.options.format||qt(e),s;r?(t.options.textureUrl=n,s=await ve(e,"tile map",n,o)):s=await pe(e,"tile map",n,o);let f=i.createBindGroup({layout:t.refs.tileAtlas.data.tileBindGroupLayout,entries:[{binding:0,resource:{buffer:t.data.uniformBuffer}},{binding:1,resource:s.view},{binding:2,resource:s.sampler}]});t.data.bindGroup=f,t.data.material=s}}};async function ol(e,t){let{canvas:n,device:r}=e,i,o=t.options.format||qt(e);n?i=await ve(e,"tile map",t.options.textureUrl,o):i=await pe(e,"tile map",t.options.texture,o);let s=new Float32Array([t.options.scrollScale,t.options.scrollScale]),f=GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,h={size:s.byteLength,usage:f,mappedAtCreation:!0},p=r.createBuffer(h);return new Float32Array(p.getMappedRange()).set(s),p.unmap(),{bindGroup:r.createBindGroup({layout:t.refs.tileAtlas.data.tileBindGroupLayout,entries:[{binding:0,resource:{buffer:p}},{binding:1,resource:i.view},{binding:2,resource:i.sampler}]}),material:i,uniformBuffer:p,scrollScale:t.options.scrollScale}}function al(e,t,n){if(!t.data.material.texture)return;let{device:r}=e,i=t.options.loadOp||"load",o=n.beginRenderPass({label:"tile",colorAttachments:[{view:t.refs.hdr.data?.view||t.refs.hdr,clearValue:e.clearValue,loadOp:i,storeOp:"store"}]}),s=t.refs.tileAtlas.data;o.setPipeline(s.pipeline),o.setBindGroup(0,t.data.bindGroup),o.setBindGroup(1,s.atlasBindGroup),o.draw(3),o.end()}function Es(e){e.data.material.texture.destroy(),e.data.material.texture=void 0}async function Ap(e,t,n){let r,i,o,s;return e.sdlWindow&&e.gpu?(i=e.gpu,r=await(await i.create(["verbose=1","enable-dawn-features=allow_unsafe_apis"]).requestAdapter()).requestDevice({requiredFeatures:["texture-component-swizzle"]}),o=i.renderGPUDeviceToWindow({device:r,window:e.sdlWindow}),global.GPUBufferUsage=i.GPUBufferUsage,global.GPUShaderStage=i.GPUShaderStage,global.GPUTextureUsage=i.GPUTextureUsage):(s=e,r=await(await navigator.gpu?.requestAdapter({powerPreference:"high-performance"}))?.requestDevice(),i=navigator.gpu,o=s.getContext("webgpu"),o.configure({device:r,format:navigator.gpu?.getPreferredCanvasFormat(),alphaMode:"opaque"})),{nodeDefs:{"cobalt:tileAtlas":Ls,"cobalt:spritesheet":As,"cobalt:fbTexture":zi,"cobalt:sprite":Ss,"cobalt:bloom":wi,"cobalt:composite":xs,"cobalt:spriteHDR":Gs,"cobalt:tileHDR":Rs,"cobalt:displacement":Gi,"cobalt:fbBlit":Ai,"cobalt:primitives":ws,"cobalt:light":Ei},nodes:[],defaultTextureViewRefs:[],canvas:s,device:r,context:o,gpu:i,clearValue:{r:0,g:0,b:0,a:1},viewport:{width:t,height:n,zoom:1,position:[0,0]}}}function zp(e,t){if(!t?.type)throw new Error("Can't define a new node missing a type.");e.nodeDefs[t.type]=t}async function Lp(e,t){let n=e.nodeDefs[t?.type];if(!n)throw new Error("Can't initialize a new node missing a type.");let r={type:t.type,refs:t.refs||{},options:t.options||{},data:{},enabled:!0};for(let o in r.refs)r.refs[o]==="FRAME_TEXTURE_VIEW"&&(e.defaultTextureViewRefs.push({node:r,refName:o}),r.refs[o]=Is(e));r.data=await n.onInit(e,r);let i=n.customFunctions||{};for(let o in i)r[o]=function(...s){return i[o](e,r,...s)};return e.nodes.push(r),r}function Ep(e){let{device:t,context:n}=e,r=t.createCommandEncoder(),i=Is(e);for(let o of e.defaultTextureViewRefs)o.node.refs[o.refName]=i;for(let o of e.nodes){if(!o.enabled)continue;e.nodeDefs[o.type].onRun(e,o,r)}t.queue.submit([r.finish()]),e.canvas||e.context.swap()}function Rp(e){for(let t of e.nodes)e.nodeDefs[t.type].onDestroy(e,t);e.nodes.length=0,e.defaultTextureViewRefs.length=0}function Ip(e,t,n){e.viewport.width=t,e.viewport.height=n;for(let r of e.nodes)e.nodeDefs[r.type].onResize(e,r)}function Op(e,t){e.viewport.position[0]=t[0]-e.viewport.width/2/e.viewport.zoom,e.viewport.position[1]=t[1]-e.viewport.height/2/e.viewport.zoom;for(let n of e.nodes)e.nodeDefs[n.type].onViewportPosition(e,n)}function Is(e){return e.canvas?e.context.getCurrentTexture().createView():e.context.getCurrentTextureView()}export{ne as createTexture,pe as createTextureFromBuffer,ve as createTextureFromUrl,zp as defineNode,Ep as draw,Is as getCurrentTextureView,Ap as init,Lp as initNode,Rp as reset,Ip as setViewportDimensions,Op as setViewportPosition};
|
|
284
|
+
`});this.renderPipeline=t.device.createRenderPipeline({label:"LightsRenderer renderpipeline",layout:"auto",vertex:{module:n,entryPoint:"main_vertex"},fragment:{module:n,entryPoint:"main_fragment",targets:[{format:this.targetTexture.format}]},primitive:{cullMode:"none",topology:"triangle-strip"}});let r=this.renderPipeline.getBindGroupLayout(0);this.bindgroup0=t.device.createBindGroup({label:"LightsRenderer bindgroup 0",layout:r,entries:[{binding:0,resource:{buffer:this.uniformsBufferGpu}},{binding:1,resource:{buffer:this.lightsBuffer.gpuBuffer}},{binding:2,resource:this.lightsTexture.texture.createView({label:"LightsRenderer lightsTexture view"})},{binding:3,resource:t.device.createSampler({label:"LightsRenderer sampler",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge",magFilter:t.lightsTextureProperties.filtering,minFilter:t.lightsTextureProperties.filtering})}]}),this.bindgroup1=this.buildBindgroup1(t.albedo),this.renderBundle=this.buildRenderBundle()}computeLightsTexture(t){this.lightsTexture.update(t)}render(t,n){let r=new ArrayBuffer(80);new Float32Array(r,0,16).set(n),new Float32Array(r,64,3).set(this.ambientLight),this.device.queue.writeBuffer(this.uniformsBufferGpu,0,r),t.executeBundles([this.renderBundle])}setAlbedo(t){this.bindgroup1=this.buildBindgroup1(t),this.renderBundle=this.buildRenderBundle()}setAmbientLight(t){this.ambientLight=[...t]}setObstacles(t){this.lightsTexture.setObstacles(t)}destroy(){this.uniformsBufferGpu.destroy(),this.lightsTexture.destroy()}buildBindgroup1(t){return this.device.createBindGroup({label:"LightsRenderer bindgroup 1",layout:this.renderPipeline.getBindGroupLayout(1),entries:[{binding:0,resource:t.view},{binding:1,resource:t.sampler}]})}buildRenderBundle(){let t=this.device.createRenderBundleEncoder({label:"LightsRenderer renderbundle encoder",colorFormats:[this.targetTexture.format]});return t.setPipeline(this.renderPipeline),t.setBindGroup(0,this.bindgroup0),t.setBindGroup(1,this.bindgroup1),t.draw(4),t.finish({label:"LightsRenderer renderbundle"})}};var dn={};hn(dn,{setAmbientLight:()=>du,setLights:()=>vu,setOccluders:()=>gu});function vu(e,t,n){t.data.lights=n,t.data.lightsBufferNeedsUpdate=!0}function du(e,t,n){t.data.lightsRenderer.setAmbientLight(n)}function gu(e,t,n){t.data.lightsRenderer.setObstacles(n),t.data.lightsTextureNeedsUpdate=!0}var br=class{invViewProjectionMatrix=Lt.identity();viewportSize={width:1,height:1};topLeft=[0,0];zoom=1;constructor(t){this.setViewportSize(t.viewportSize.width,t.viewportSize.height);let n=t.center??this.topLeft;this.setTopLeft(...n);let r=t.zoom??1;this.setZoom(r)}get invertViewProjectionMatrix(){return this.invViewProjectionMatrix}setViewportSize(t,n){this.viewportSize.width=t,this.viewportSize.height=n,this.updateMatrices()}setTopLeft(t,n){this.topLeft[0]=t,this.topLeft[1]=n,this.updateMatrices()}setZoom(t){this.zoom=t,this.updateMatrices()}updateMatrices(){Lt.identity(this.invViewProjectionMatrix),Lt.multiply(Lt.scaling([1,-1,0]),this.invViewProjectionMatrix,this.invViewProjectionMatrix),Lt.multiply(Lt.translation([1,1,0]),this.invViewProjectionMatrix,this.invViewProjectionMatrix),Lt.multiply(Lt.scaling([.5*this.viewportSize.width/this.zoom,.5*this.viewportSize.height/this.zoom,0]),this.invViewProjectionMatrix,this.invViewProjectionMatrix),Lt.multiply(Lt.translation([this.topLeft[0],this.topLeft[1],0]),this.invViewProjectionMatrix,this.invViewProjectionMatrix)}};var Ei={type:"cobalt:light",refs:[{name:"in",type:"textureView",format:"rgba16float",access:"read"},{name:"out",type:"textureView",format:"rgba16float",access:"write"}],onInit:async function(e,t={}){return wu(e,t)},onRun:function(e,t,n){xu(e,t,n)},onDestroy:function(e,t){yu(t)},onResize:function(e,t){Mu(e,t)},onViewportPosition:function(e,t){t.data.viewport.setTopLeft(...e.viewport.position)},customFunctions:{...dn}};async function wu(e,t){let{device:n}=e,r=256,i=256,o=new ae(n,r),s=new br({viewportSize:{width:e.viewport.width,height:e.viewport.height},center:e.viewport.position,zoom:e.viewport.zoom}),f=new Mr({device:n,albedo:{view:t.refs.in.data.view,sampler:t.refs.in.data.sampler},targetTexture:t.refs.out.data.texture,lightsBuffer:o,lightsTextureProperties:{resolutionPerLight:i,maxLightSize:i,antialiased:!1,filtering:"nearest",textureFormat:qt(e)}});return{lightsBuffer:o,lightsBufferNeedsUpdate:!0,lightsTextureNeedsUpdate:!0,lightsRenderer:f,viewport:s,lights:[]}}function xu(e,t,n){t.data.lightsBufferNeedsUpdate&&(t.data.lightsBuffer.setLights(t.data.lights),t.data.lightsBufferNeedsUpdate=!1,t.data.lightsTextureNeedsUpdate=!0);let r=t.data.lightsRenderer;t.data.lightsTextureNeedsUpdate&&(r.computeLightsTexture(n),t.data.lightsTextureNeedsUpdate=!1);let i=n.beginRenderPass({label:"light",colorAttachments:[{view:t.refs.out.data.view,clearValue:e.clearValue,loadOp:"load",storeOp:"store"}]});t.data.viewport.setZoom(e.viewport.zoom);let o=t.data.viewport.invertViewProjectionMatrix;r.render(i,o),i.end()}function yu(e){e.data.lightsBuffer.destroy(),e.data.lightsRenderer.destroy()}function Mu(e,t){t.data.lightsRenderer.setAlbedo({view:t.refs.in.data.view,sampler:t.refs.in.data.sampler}),t.data.viewport.setViewportSize(e.viewport.width,e.viewport.height)}function de(e){return e>=0?Math.round(e):e%.5===0?Math.floor(e):Math.round(e)}var Ri="struct TransformData{view:mat4x4<f32>,projection:mat4x4<f32>};@binding(0)@group(0)var<uniform> transformUBO:TransformData;struct Fragment{@builtin(position)Position:vec4<f32>,@location(0)Color:vec4<f32>,};@vertex fn vs_main(@location(0)vertexPosition:vec2<f32>,@location(1)vertexColor:vec4<f32>)->Fragment{var sx:f32=1.0;var sy:f32=1.0;var sz:f32=1.0;var rot:f32=0.0;var tx:f32=1.0;var ty:f32=1.0;var tz:f32=0;var s=sin(rot);var c=cos(rot);var scaleM:mat4x4<f32>=mat4x4<f32>(sx,0.0,0.0,0.0,0.0,sy,0.0,0.0,0.0,0.0,sz,0.0,0,0,0,1.0);var modelM:mat4x4<f32>=mat4x4<f32>(c,s,0.0,0.0,-s,c,0.0,0.0,0.0,0.0,1.0,0.0,tx,ty,tz,1.0)*scaleM;var output:Fragment;output.Position=transformUBO.projection*transformUBO.view*modelM*vec4<f32>(vertexPosition,0.0,1.0);output.Color=vertexColor;return output;}@fragment fn fs_main(@location(0)Color:vec4<f32>)->@location(0)vec4<f32>{return Color;}";var ps=pi(co(),1);var hs=pi(ls(),1);function ti(e,t){if(!Array.isArray(e))throw new Error("poly-to-pslg: Error, invalid polygon");if(e.length===0)return{points:[],edges:[]};t=t||{};var n=!0;"nested"in t?n=!!t.nested:e[0].length===2&&typeof e[0][0]=="number"&&(n=!1),n||(e=[e]);for(var r=[],i=[],o=0;o<e.length;++o)for(var s=e[o],f=r.length,h=0;h<s.length;++h)r.push(s[h]),i.push([f+h,f+(h+1)%s.length]);var p="clean"in t?!0:!!t.clean;return p&&(0,hs.default)(r,i),{points:r,edges:i}}var vs={line:Re,save:function(e,t){t.data.transforms.push(Me.clone(t.data.transforms.at(-1)))},restore:function(e,t){t.data.transforms.length>1&&t.data.transforms.pop()},translate:function(e,t,n){let r=t.data.transforms.at(-1);Me.translate(r,n,r)},rotate:function(e,t,n){let r=t.data.transforms.at(-1);Me.rotate(r,n,r)},scale:function(e,t,n){let r=t.data.transforms.at(-1);Me.scale(r,n,r)},strokePath:function(e,t,n,r,i=1){for(let o of n)Re(e,t,o[0],o[1],r,i)},filledPath:function(e,t,n,r){let i=ti(n),o=(0,ps.default)(i.points,i.edges,{exterior:!1}),s=t.data.transforms.at(-1),f=t.data.vertexCount*6,h=t.data.vertexCount*6,p=o.length*3*6;t.data.vertices=Zr(Float32Array,t.data.vertices,h,p);let g=Et.create();for(let D of o)Et.transformMat3(n[D[0]],s,g),t.data.vertices[f+0]=g[0],t.data.vertices[f+1]=g[1],t.data.vertices[f+2]=r[0],t.data.vertices[f+3]=r[1],t.data.vertices[f+4]=r[2],t.data.vertices[f+5]=r[3],Et.transformMat3(n[D[1]],s,g),t.data.vertices[f+6]=g[0],t.data.vertices[f+7]=g[1],t.data.vertices[f+8]=r[0],t.data.vertices[f+9]=r[1],t.data.vertices[f+10]=r[2],t.data.vertices[f+11]=r[3],Et.transformMat3(n[D[2]],s,g),t.data.vertices[f+12]=g[0],t.data.vertices[f+13]=g[1],t.data.vertices[f+14]=r[0],t.data.vertices[f+15]=r[1],t.data.vertices[f+16]=r[2],t.data.vertices[f+17]=r[3],f+=18;t.data.vertexCount+=3*o.length,t.data.dirty=!0},ellipse:function(e,t,n,r,i,o,s,f=1){let[h,p]=n,g=2*Math.PI/o;for(let D=0;D<o;D++){let X=D*g,N=(D+1)*g,I=h+r*Math.cos(X),V=p+i*Math.sin(X),q=h+r*Math.cos(N),Y=p+i*Math.sin(N);Re(e,t,[I,V],[q,Y],s,f)}},filledEllipse:function(e,t,n,r,i,o,s){let[f,h]=n,p=2*Math.PI/o,g=t.data.vertexCount*6,D=o*3*6;t.data.vertices=Zr(Float32Array,t.data.vertices,g,D);let X=t.data.transforms.at(-1);for(let N=0;N<o;N++){let I=N*p,V=(N+1)*p,q=f+r*Math.cos(I),Y=h+i*Math.sin(I),K=f+r*Math.cos(V),Q=h+i*Math.sin(V),H=t.data.vertexCount*6+N*18,W=Et.transformMat3([f,h],X);t.data.vertices[H+0]=W[0],t.data.vertices[H+1]=W[1],t.data.vertices[H+2]=s[0],t.data.vertices[H+3]=s[1],t.data.vertices[H+4]=s[2],t.data.vertices[H+5]=s[3],Et.transformMat3([q,Y],X,W),t.data.vertices[H+6]=W[0],t.data.vertices[H+7]=W[1],t.data.vertices[H+8]=s[0],t.data.vertices[H+9]=s[1],t.data.vertices[H+10]=s[2],t.data.vertices[H+11]=s[3],Et.transformMat3([K,Q],X,W),t.data.vertices[H+12]=W[0],t.data.vertices[H+13]=W[1],t.data.vertices[H+14]=s[0],t.data.vertices[H+15]=s[1],t.data.vertices[H+16]=s[2],t.data.vertices[H+17]=s[3]}t.data.vertexCount+=3*o,t.data.dirty=!0},box:function(e,t,n,r,i,o,s=1){let[f,h]=n,p=r/2,g=i/2,D=[f-p,h-g],X=[f+p,h-g],N=[f-p,h+g],I=[f+p,h+g];Re(e,t,D,X,o,s),Re(e,t,N,I,o,s),Re(e,t,D,N,o,s),Re(e,t,X,I,o,s)},filledBox:function(e,t,n,r,i,o){let[s,f]=n,h=r/2,p=i/2,g=t.data.transforms.at(-1),D=Et.transformMat3([s-h,f-p],g),X=Et.transformMat3([s+h,f-p],g),N=Et.transformMat3([s-h,f+p],g),I=Et.transformMat3([s+h,f+p],g),V=t.data.vertexCount*6,q=36;t.data.vertices=Zr(Float32Array,t.data.vertices,V,q);let Y=t.data.vertexCount*6;t.data.vertices[Y+0]=D[0],t.data.vertices[Y+1]=D[1],t.data.vertices[Y+2]=o[0],t.data.vertices[Y+3]=o[1],t.data.vertices[Y+4]=o[2],t.data.vertices[Y+5]=o[3],t.data.vertices[Y+6]=N[0],t.data.vertices[Y+7]=N[1],t.data.vertices[Y+8]=o[0],t.data.vertices[Y+9]=o[1],t.data.vertices[Y+10]=o[2],t.data.vertices[Y+11]=o[3],t.data.vertices[Y+12]=X[0],t.data.vertices[Y+13]=X[1],t.data.vertices[Y+14]=o[0],t.data.vertices[Y+15]=o[1],t.data.vertices[Y+16]=o[2],t.data.vertices[Y+17]=o[3],t.data.vertices[Y+18]=N[0],t.data.vertices[Y+19]=N[1],t.data.vertices[Y+20]=o[0],t.data.vertices[Y+21]=o[1],t.data.vertices[Y+22]=o[2],t.data.vertices[Y+23]=o[3],t.data.vertices[Y+24]=I[0],t.data.vertices[Y+25]=I[1],t.data.vertices[Y+26]=o[0],t.data.vertices[Y+27]=o[1],t.data.vertices[Y+28]=o[2],t.data.vertices[Y+29]=o[3],t.data.vertices[Y+30]=X[0],t.data.vertices[Y+31]=X[1],t.data.vertices[Y+32]=o[0],t.data.vertices[Y+33]=o[1],t.data.vertices[Y+34]=o[2],t.data.vertices[Y+35]=o[3],t.data.vertexCount+=6,t.data.dirty=!0},clear:function(e,t){t.data.vertexCount=0,t.data.transforms.length=1,Me.identity(t.data.transforms[0]),t.data.dirty=!0}};function Re(e,t,n,r,i,o=1){let s=t.data.transforms.at(-1);n=Et.transformMat3(n,s),r=Et.transformMat3(r,s);let f=Et.sub(r,n),h=Et.normalize(f),p=Sc(h),g=o/2,D=t.data.vertexCount*6,X=t.data.vertexCount*6,N=36;t.data.vertices=Zr(Float32Array,t.data.vertices,X,N),t.data.vertices[D+0]=n[0]+p[0]*g,t.data.vertices[D+1]=n[1]+p[1]*g,t.data.vertices[D+2]=i[0],t.data.vertices[D+3]=i[1],t.data.vertices[D+4]=i[2],t.data.vertices[D+5]=i[3],t.data.vertices[D+6]=n[0]-p[0]*g,t.data.vertices[D+7]=n[1]-p[1]*g,t.data.vertices[D+8]=i[0],t.data.vertices[D+9]=i[1],t.data.vertices[D+10]=i[2],t.data.vertices[D+11]=i[3],t.data.vertices[D+12]=r[0]+p[0]*g,t.data.vertices[D+13]=r[1]+p[1]*g,t.data.vertices[D+14]=i[0],t.data.vertices[D+15]=i[1],t.data.vertices[D+16]=i[2],t.data.vertices[D+17]=i[3],t.data.vertices[D+18]=n[0]-p[0]*g,t.data.vertices[D+19]=n[1]-p[1]*g,t.data.vertices[D+20]=i[0],t.data.vertices[D+21]=i[1],t.data.vertices[D+22]=i[2],t.data.vertices[D+23]=i[3],t.data.vertices[D+24]=r[0]+p[0]*g,t.data.vertices[D+25]=r[1]+p[1]*g,t.data.vertices[D+26]=i[0],t.data.vertices[D+27]=i[1],t.data.vertices[D+28]=i[2],t.data.vertices[D+29]=i[3],t.data.vertices[D+30]=r[0]-p[0]*g,t.data.vertices[D+31]=r[1]-p[1]*g,t.data.vertices[D+32]=i[0],t.data.vertices[D+33]=i[1],t.data.vertices[D+34]=i[2],t.data.vertices[D+35]=i[3],t.data.vertexCount+=6,t.data.dirty=!0}function Zr(e,t,n,r){if(n+r<=t.length)return t;let i=t.length*2,o=16*1024*1024/t.BYTES_PER_ELEMENT;if(i>o)throw new Error("vertices exceed max array size");let s=new e(i);return s.set(t),s}function Sc(e){return[-e[1],e[0]]}var ds=fe.create(0,0,0),ws={type:"cobalt:primitives",refs:[{name:"color",type:"textView",format:"PREFERRED_TEXTURE_VIEW",access:"write"}],onInit:async function(e,t={}){return _c(e,t)},onRun:function(e,t,n){Bc(e,t,n)},onDestroy:function(e,t){Dc(t)},onResize:function(e,t){gs(e,t)},onViewportPosition:function(e,t){gs(e,t)},customFunctions:vs};async function _c(e,t){let{device:n}=e,r=new Float32Array(1024),i=n.createBuffer({size:r.byteLength,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),o=n.createBuffer({size:128,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),s=n.createShaderModule({code:Ri}),f=n.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{}}]}),h=n.createPipelineLayout({bindGroupLayouts:[f]}),p=n.createBindGroup({layout:f,entries:[{binding:0,resource:{buffer:o}}]}),g=n.createRenderPipeline({label:"primitives",layout:h,vertex:{module:s,entryPoint:"vs_main",buffers:[{arrayStride:6*Float32Array.BYTES_PER_ELEMENT,attributes:[{shaderLocation:0,offset:0,format:"float32x2"},{shaderLocation:1,format:"float32x4",offset:8}]}]},fragment:{module:s,entryPoint:"fs_main",targets:[{format:qt(e),blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{srcFactor:"zero",dstFactor:"one"}}}]},primitive:{topology:"triangle-list"}});return{uniformBuffer:o,vertexBuffer:i,pipeline:g,bindGroup:p,vertexCount:0,dirty:!1,vertices:r,transforms:[Me.identity()]}}function Bc(e,t,n){if(t.data.vertexCount===0)return;let{device:r}=e;if(t.data.dirty){t.data.dirty=!1;let s=6*Float32Array.BYTES_PER_ELEMENT;t.data.vertices.buffer.byteLength>t.data.vertexBuffer.size&&(t.data.vertexBuffer.destroy(),t.data.vertexBuffer=r.createBuffer({size:t.data.vertices.byteLength,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}));let f=t.data.vertexCount*s;if(f>t.data.vertexBuffer.size){console.error("too many primitives, bailing");return}e.device.queue.writeBuffer(t.data.vertexBuffer,0,t.data.vertices.buffer,0,f)}let i=t.options.loadOp||"load",o=n.beginRenderPass({label:"primitives",colorAttachments:[{view:t.refs.color,clearValue:e.clearValue,loadOp:i,storeOp:"store"}]});o.setPipeline(t.data.pipeline),o.setBindGroup(0,t.data.bindGroup),o.setVertexBuffer(0,t.data.vertexBuffer),o.draw(t.data.vertexCount),o.end()}function Dc(e){e.data.vertexBuffer.destroy(),e.data.vertexBuffer=null,e.data.uniformBuffer.destroy(),e.data.uniformBuffer=null,e.data.transforms.length=0}function gs(e,t){let{device:n}=e,r=e.viewport.width/e.viewport.zoom,i=e.viewport.height/e.viewport.zoom,o=Lt.ortho(0,r,i,0,-10,10);fe.set(-e.viewport.position[0]-1,-e.viewport.position[1]-1,0,ds);let s=Lt.translation(ds);n.queue.writeBuffer(t.data.uniformBuffer,0,s.buffer),n.queue.writeBuffer(t.data.uniformBuffer,64,o.buffer)}var ei="struct BloomComposite{bloom_intensity:f32,bloom_combine_constant:f32,}@group(0)@binding(0)var mySampler:sampler;@group(0)@binding(1)var colorTexture:texture_2d<f32>;@group(0)@binding(2)var emissiveTexture:texture_2d<f32>;@group(0)@binding(3)var<uniform> composite_parameter:BloomComposite;struct VertexOutput{@builtin(position)Position:vec4<f32>,@location(0)fragUV:vec2<f32>,}const positions=array<vec2<f32>,3>(vec2<f32>(-1.0,-3.0),vec2<f32>(3.0,1.0),vec2<f32>(-1.0,1.0));const uvs=array<vec2<f32>,3>(vec2<f32>(0.0,2.0),vec2<f32>(2.0,0.0),vec2<f32>(0.0,0.0));@vertex fn vert_main(@builtin(vertex_index)VertexIndex:u32)->VertexOutput{var output:VertexOutput;output.Position=vec4<f32>(positions[VertexIndex],0.0,1.0);output.fragUV=vec2<f32>(uvs[VertexIndex]);return output;}fn GTTonemap_point(x:f32)->f32{let m:f32=0.22;let a:f32=1.0;let c:f32=1.33;let P:f32=1.0;let l:f32=0.4;let l0:f32=((P-m)*l)/a;let S0:f32=m+l0;let S1:f32=m+a*l0;let C2:f32=(a*P)/(P-S1);let L:f32=m+a*(x-m);let T:f32=m*pow(x/m,c);let S:f32=P-(P-S1)*exp(-C2*(x-S0)/P);let w0:f32=1.0-smoothstep(0.0,m,x);var w2:f32=1.0;if(x<m+l){w2=0.0;}let w1:f32=1.0-w0-w2;return f32(T*w0+L*w1+S*w2);}fn GTTonemap(x:vec3<f32>)->vec3<f32>{return vec3<f32>(GTTonemap_point(x.r),GTTonemap_point(x.g),GTTonemap_point(x.b));}fn aces(x:vec3<f32>)->vec3<f32>{let a:f32=2.51;let b:f32=0.03;let c:f32=2.43;let d:f32=0.59;let e:f32=0.14;return clamp((x*(a*x+b))/(x*(c*x+d)+e),vec3<f32>(0.0),vec3<f32>(1.0));}@fragment fn frag_main(@location(0)fragUV:vec2<f32>)->@location(0)vec4<f32>{let hdr_color=textureSample(colorTexture,mySampler,fragUV);let bloom_color=textureSample(emissiveTexture,mySampler,fragUV);let combined_color=((bloom_color*composite_parameter.bloom_intensity)*composite_parameter.bloom_combine_constant);let mapped_color=GTTonemap(combined_color.rgb);let gamma_corrected_color=pow(mapped_color,vec3<f32>(1.0/2.2));return vec4<f32>(gamma_corrected_color+hdr_color.rgb,1.0);}";var xs={type:"cobalt:bloom",refs:[{name:"hdr",type:"textureView",format:"rgba16",access:"read"},{name:"bloom",type:"textureView",format:"rgba16",access:"read"},{name:"combined",type:"textureView",format:"PREFERRED_TEXTURE_FORMAT",access:"write"}],onInit:async function(e,t={}){return Uc(e,t)},onRun:function(e,t,n){Fc(e,t,n)},onDestroy:function(e,t){},onResize:function(e,t){Gc(e,t)},onViewportPosition:function(e,t){}};function Uc(e,t){let{options:n,refs:r}=t,{device:i}=e,o=qt(e),s=n.bloom_intensity??40,f=n.bloom_combine_constant??.68,h=new Float32Array([s,f]),p=i.createBuffer({label:"scene composite params buffer",size:h.byteLength,mappedAtCreation:!0,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});new Float32Array(p.getMappedRange()).set(h),p.unmap();let g=i.createRenderPipeline({label:"scenecomposite",layout:"auto",vertex:{module:i.createShaderModule({code:ei}),entryPoint:"vert_main"},fragment:{module:i.createShaderModule({code:ei}),entryPoint:"frag_main",targets:[{format:o}]},primitive:{topology:"triangle-list"}});return{bindGroup:i.createBindGroup({layout:g.getBindGroupLayout(0),entries:[{binding:0,resource:r.hdr.data.sampler},{binding:1,resource:r.hdr.data.view},{binding:2,resource:r.bloom.data.mip_view[0]},{binding:3,resource:{buffer:p}}]}),pipeline:g,params_buf:p}}function Fc(e,t,n){let r=n.beginRenderPass({label:"scene-composite",colorAttachments:[{view:t.refs.combined.data.view,clearValue:{r:0,g:0,b:0,a:1},loadOp:"clear",storeOp:"store"}]}),{pipeline:i,bindGroup:o}=t.data;r.setPipeline(i),r.setBindGroup(0,o),r.draw(3),r.end()}function Gc(e,t){let{pipeline:n,params_buf:r}=t.data,{device:i}=e;t.data.bindGroup=i.createBindGroup({layout:n.getBindGroupLayout(0),entries:[{binding:0,resource:t.refs.hdr.data.sampler},{binding:1,resource:t.refs.hdr.data.view},{binding:2,resource:t.refs.bloom.data.mip_view[0]},{binding:3,resource:{buffer:r}}]})}var ri={};hn(ri,{addSprite:()=>Ac,clear:()=>Lc,removeSprite:()=>zc,setSpriteName:()=>Ec,setSpriteOpacity:()=>Oc,setSpritePosition:()=>Rc,setSpriteRotation:()=>mc,setSpriteScale:()=>Vc,setSpriteTint:()=>Ic});function Ac(e,t,n,r,i,o,s,f){let{idByName:h}=t.refs.spritesheet.data;return t.data.sprites.push({position:Et.clone(r),sizeX:1,sizeY:1,scale:Et.clone(i),rotation:f,opacity:s,tint:Ce.clone(o),spriteID:h.get(n),id:Be()}),t.data.sprites.at(-1).id}function zc(e,t,n){for(let r=0;r<t.data.sprites.length;r++)if(t.data.sprites[r].id===n){t.data.sprites.splice(r,1);return}}function Lc(e,t){t.data.sprites.length=0}function Ec(e,t,n,r){let i=t.data.sprites.find(s=>s.id===n);if(!i)return;let{idByName:o}=t.refs.spritesheet.data;i.spriteID=o.get(r)}function Rc(e,t,n,r){let i=t.data.sprites.find(o=>o.id===n);i&&Et.copy(r,i.position)}function Ic(e,t,n,r){let i=t.data.sprites.find(o=>o.id===n);i&&Ce.copy(r,i.tint)}function Oc(e,t,n,r){let i=t.data.sprites.find(o=>o.id===n);i&&(i.opacity=r)}function mc(e,t,n,r){let i=t.data.sprites.find(o=>o.id===n);i&&(i.rotation=r)}function Vc(e,t,n,r){let i=t.data.sprites.find(o=>o.id===n);i&&Et.copy(r,i.scale)}var ys="struct ViewParams{view:mat4x4<f32>,proj:mat4x4<f32>};@group(0)@binding(0)var<uniform> uView:ViewParams;@group(0)@binding(1)var uSampler:sampler;@group(0)@binding(2)var uTex:texture_2d<f32>;struct SpriteDesc{uvOrigin:vec2<f32>,uvSpan:vec2<f32>,frameSize:vec2<f32>,centerOffset:vec2<f32>,};@group(0)@binding(3)var<storage,read>Sprites:array<SpriteDesc>;struct VSOut{@builtin(position)pos:vec4<f32>,@location(0)uv:vec2<f32>,@location(1)tint:vec4<f32>,@location(2)opacity:f32,};const corners=array<vec2<f32>,4>(vec2<f32>(-0.5,-0.5),vec2<f32>(0.5,-0.5),vec2<f32>(-0.5,0.5),vec2<f32>(0.5,0.5),);const uvBase=array<vec2<f32>,4>(vec2<f32>(0.0,0.0),vec2<f32>(1.0,0.0),vec2<f32>(0.0,1.0),vec2<f32>(1.0,1.0),);@vertex fn vs_main(@builtin(vertex_index)vid:u32,@location(0)i_pos:vec2<f32>,@location(1)i_size:vec2<f32>,@location(2)i_scale:vec2<f32>,@location(3)i_tint:vec4<f32>,@location(4)i_spriteId:u32,@location(5)i_opacity:f32,@location(6)i_rotation:f32)->VSOut{let rot=i_rotation;let c=cos(rot);let s=sin(rot);let d=Sprites[i_spriteId];let corner=corners[vid];let sizePx=d.frameSize*i_size*i_scale;var local=corner*sizePx;local+=d.centerOffset*i_scale;let rotated=vec2<f32>(local.x*c-local.y*s,local.x*s+local.y*c);let world=vec4<f32>(rotated+i_pos,0.0,1.0);var out:VSOut;out.pos=uView.proj*uView.view*world;out.uv=d.uvOrigin+d.uvSpan*uvBase[vid];out.tint=i_tint;out.opacity=i_opacity;return out;}@fragment fn fs_main(in:VSOut)->@location(0)vec4<f32>{let texel=textureSample(uTex,uSampler,in.uv);return vec4<f32>(texel.rgb*(1.0-in.tint.a)+(in.tint.rgb*in.tint.a),texel.a*in.opacity);}";var ni=fe.create(0,0,0),Ie=64,ii=0,oi=8,ai=16,fr=24,bs=40,Ts=44,Ps=48,Ss={type:"cobalt:sprite",refs:[{name:"spritesheet",type:"customResource",access:"read"},{name:"color",type:"textureView",format:"rgba8unorm",access:"write"}],onInit:async function(e,t={}){return qc(e,t)},onRun:function(e,t,n){Cc(e,t,n)},onDestroy:function(e,t){try{t.data.instanceBuf?.destroy()}catch{}try{t.data.spriteBuf?.destroy()}catch{}try{t.data.uniformBuffer?.destroy()}catch{}t.data.pipeline=null,t.data.bindGroup=null,t.data.bindGroupLayout=null,t.data.instanceStaging=null,t.data.instanceView=null,t.data.sprites.length=0,t.data.visible.length=0},onResize:function(e,t){Ms(e,t)},onViewportPosition:function(e,t){Ms(e,t)},customFunctions:{...ri}};async function qc(e,t){let{device:n}=e,{descs:r,names:i}=t.refs.spritesheet.data.spritesheet,o=n.createBuffer({size:128,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),s=32,f=new ArrayBuffer(s*r.length),h=new Float32Array(f);for(let tt=0;tt<r.length;tt++){let H=r[tt],W=tt*8;h[W+0]=H.UvOrigin[0],h[W+1]=H.UvOrigin[1],h[W+2]=H.UvSpan[0],h[W+3]=H.UvSpan[1],h[W+4]=H.FrameSize[0],h[W+5]=H.FrameSize[1],h[W+6]=H.CenterOffset[0],h[W+7]=H.CenterOffset[1]}let p=n.createBuffer({label:"sprite desc table",size:Math.max(16,f.byteLength),usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST});n.queue.writeBuffer(p,0,f);let g=1024,D=n.createBuffer({label:"sprite instances",size:Ie*g,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),X=new ArrayBuffer(Ie*g),N=new DataView(X),I=n.createShaderModule({code:ys}),V=n.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}},{binding:3,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}}]}),q=n.createPipelineLayout({bindGroupLayouts:[V]}),Y={arrayStride:Ie,stepMode:"instance",attributes:[{shaderLocation:0,offset:ii,format:"float32x2"},{shaderLocation:1,offset:oi,format:"float32x2"},{shaderLocation:2,offset:ai,format:"float32x2"},{shaderLocation:3,offset:fr,format:"float32x4"},{shaderLocation:4,offset:bs,format:"uint32"},{shaderLocation:5,offset:Ts,format:"float32"},{shaderLocation:6,offset:Ps,format:"float32"}]},K=n.createRenderPipeline({layout:q,vertex:{module:I,entryPoint:"vs_main",buffers:[Y]},fragment:{module:I,entryPoint:"fs_main",targets:[{format:qt(e),blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{srcFactor:"zero",dstFactor:"one"}}}]},primitive:{topology:"triangle-strip",cullMode:"none"},multisample:{count:1}}),Q=n.createBindGroup({layout:V,entries:[{binding:0,resource:{buffer:o}},{binding:1,resource:t.refs.spritesheet.data.colorTexture.sampler},{binding:2,resource:t.refs.spritesheet.data.colorTexture.view},{binding:3,resource:{buffer:p}}]});return{sprites:[],visible:[],visibleCount:0,viewRect:{x:0,y:0,w:0,h:0},spriteBuf:p,uniformBuffer:o,instanceCap:g,instanceView:N,instanceBuf:D,instanceStaging:X,pipeline:K,bindGroup:Q}}function Nc(e,t,n){let{instanceCap:r}=t.data;if(n<=r)return;let i=r;for(i===0&&(i=1024);i<n;)i*=2;t.data.instanceBuf.destroy(),t.data.instanceBuf=e.device.createBuffer({size:Ie*i,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),t.data.instanceStaging=new ArrayBuffer(Ie*i),t.data.instanceView=new DataView(t.data.instanceStaging),t.data.instanceCap=i}function Cc(e,t,n){let{device:r,context:i}=e,{instanceView:o,instanceBuf:s,instanceStaging:f,pipeline:h,bindGroup:p}=t.data,{descs:g}=t.refs.spritesheet.data.spritesheet,D=t.data.viewRect;D.x=e.viewport.position[0],D.y=e.viewport.position[1],D.w=e.viewport.width,D.h=e.viewport.height,t.data.visibleCount=0;for(let I of t.data.sprites){let V=g[I.spriteID];if(V){if(!t.options.isScreenSpace){let q=V.FrameSize[0]*I.sizeX*I.scale[0]*.5,Y=V.FrameSize[1]*I.sizeY*I.scale[1]*.5,K=Math.hypot(q,Y),Q=I.position[0],tt=I.position[1];if(Q+K<D.x||Q-K>D.x+D.w||tt+K<D.y||tt-K>D.y+D.h)continue}t.data.visible[t.data.visibleCount]=I,t.data.visibleCount++}}Nc(e,t,t.data.visibleCount);for(let I=0;I<t.data.visibleCount;I++){let V=I*Ie,q=t.data.visible[I],Y=q.tint;o.setFloat32(V+ii+0,q.position[0],!0),o.setFloat32(V+ii+4,q.position[1],!0),o.setFloat32(V+oi+0,q.sizeX,!0),o.setFloat32(V+oi+4,q.sizeY,!0),o.setFloat32(V+ai+0,q.scale[0],!0),o.setFloat32(V+ai+4,q.scale[1],!0),o.setFloat32(V+fr+0,Y[0],!0),o.setFloat32(V+fr+4,Y[1],!0),o.setFloat32(V+fr+8,Y[2],!0),o.setFloat32(V+fr+12,Y[3],!0),o.setUint32(V+bs,q.spriteID>>>0,!0),o.setFloat32(V+Ts,q.opacity,!0),o.setFloat32(V+Ps,q.rotation,!0)}r.queue.writeBuffer(s,0,f,0,t.data.visibleCount*Ie);let X=t.options.loadOp||"load",N=n.beginRenderPass({label:"sprite renderpass",colorAttachments:[{view:t.refs.color,clearValue:e.clearValue,loadOp:X,storeOp:"store"}]});N.setPipeline(h),N.setBindGroup(0,p),N.setVertexBuffer(0,s),t.data.visibleCount&&N.draw(4,t.data.visibleCount,0,0),N.end()}function Ms(e,t){let{device:n,viewport:r}=e,i=r.width/r.zoom,o=r.height/r.zoom,s=Lt.ortho(0,i,o,0,-10,10);t.options.isScreenSpace?fe.set(0,0,0,ni):fe.set(-de(r.position[0]),-de(r.position[1]),0,ni);let f=Lt.translation(ni);n.queue.writeBuffer(t.data.uniformBuffer,0,f.buffer),n.queue.writeBuffer(t.data.uniformBuffer,64,s.buffer)}var si={};hn(si,{addSprite:()=>Xc,clear:()=>Yc,removeSprite:()=>kc,setSpriteName:()=>Hc,setSpriteOpacity:()=>Wc,setSpritePosition:()=>Zc,setSpriteRotation:()=>Kc,setSpriteScale:()=>Qc,setSpriteTint:()=>$c});function Xc(e,t,n,r,i,o,s,f){let{idByName:h}=t.refs.spritesheet.data;return t.data.sprites.push({position:Et.clone(r),sizeX:1,sizeY:1,scale:Et.clone(i),rotation:f,opacity:s,tint:Ce.clone(o),spriteID:h.get(n),id:Be()}),t.data.sprites.at(-1).id}function kc(e,t,n){for(let r=0;r<t.data.sprites.length;r++)if(t.data.sprites[r].id===n){t.data.sprites.splice(r,1);return}}function Yc(e,t){t.data.sprites.length=0}function Hc(e,t,n,r){let i=t.data.sprites.find(s=>s.id===n);if(!i)return;let{idByName:o}=t.refs.spritesheet.data;i.spriteID=o.get(r)}function Zc(e,t,n,r){let i=t.data.sprites.find(o=>o.id===n);i&&Et.copy(r,i.position)}function $c(e,t,n,r){let i=t.data.sprites.find(o=>o.id===n);i&&Ce.copy(r,i.tint)}function Wc(e,t,n,r){let i=t.data.sprites.find(o=>o.id===n);i&&(i.opacity=r)}function Kc(e,t,n,r){let i=t.data.sprites.find(o=>o.id===n);i&&(i.rotation=r)}function Qc(e,t,n,r){let i=t.data.sprites.find(o=>o.id===n);i&&Et.copy(r,i.scale)}var _s="struct ViewParams{view:mat4x4<f32>,proj:mat4x4<f32>};@group(0)@binding(0)var<uniform> uView:ViewParams;@group(0)@binding(1)var uSampler:sampler;@group(0)@binding(2)var uTex:texture_2d<f32>;struct SpriteDesc{uvOrigin:vec2<f32>,uvSpan:vec2<f32>,frameSize:vec2<f32>,centerOffset:vec2<f32>,};@group(0)@binding(3)var<storage,read>Sprites:array<SpriteDesc>;@group(0)@binding(4)var emissiveTexture:texture_2d<f32>;struct VSOut{@builtin(position)pos:vec4<f32>,@location(0)uv:vec2<f32>,@location(1)tint:vec4<f32>,@location(2)opacity:f32,};const corners=array<vec2<f32>,4>(vec2<f32>(-0.5,-0.5),vec2<f32>(0.5,-0.5),vec2<f32>(-0.5,0.5),vec2<f32>(0.5,0.5),);const uvBase=array<vec2<f32>,4>(vec2<f32>(0.0,0.0),vec2<f32>(1.0,0.0),vec2<f32>(0.0,1.0),vec2<f32>(1.0,1.0),);struct GBufferOutput{@location(0)color:vec4<f32>,@location(1)emissive:vec4<f32>,}@vertex fn vs_main(@builtin(vertex_index)vid:u32,@location(0)i_pos:vec2<f32>,@location(1)i_size:vec2<f32>,@location(2)i_scale:vec2<f32>,@location(3)i_tint:vec4<f32>,@location(4)i_spriteId:u32,@location(5)i_opacity:f32,@location(6)i_rotation:f32)->VSOut{let rot=i_rotation;let c=cos(rot);let s=sin(rot);let d=Sprites[i_spriteId];let corner=corners[vid];let sizePx=d.frameSize*i_size*i_scale;var local=corner*sizePx;local+=d.centerOffset*i_scale;let rotated=vec2<f32>(local.x*c-local.y*s,local.x*s+local.y*c);let world=vec4<f32>(rotated+i_pos,0.0,1.0);var out:VSOut;out.pos=uView.proj*uView.view*world;out.uv=d.uvOrigin+d.uvSpan*uvBase[vid];out.tint=i_tint;out.opacity=i_opacity;return out;}@fragment fn fs_main(in:VSOut)->GBufferOutput{var output:GBufferOutput;let texel=textureSample(uTex,uSampler,in.uv);output.color=vec4<f32>(texel.rgb*(1.0-in.tint.a)+(in.tint.rgb*in.tint.a),texel.a*in.opacity);let emissive=textureSample(emissiveTexture,uSampler,in.uv);output.emissive=vec4(emissive.rgb,1.0)*emissive.a;return output;}";var ui=fe.create(0,0,0),Oe=64,fi=0,ci=8,li=16,cr=24,Ds=40,Us=44,Fs=48,Gs={type:"cobalt:spriteHDR",refs:[{name:"spritesheet",type:"customResource",access:"read"},{name:"color",type:"textureView",format:"rgba16float",access:"write"},{name:"emissive",type:"textureView",format:"rgba16float",access:"write"}],onInit:async function(e,t={}){return Jc(e,t)},onRun:function(e,t,n){tl(e,t,n)},onDestroy:function(e,t){try{t.data.instanceBuf?.destroy()}catch{}try{t.data.spriteBuf?.destroy()}catch{}try{t.data.uniformBuffer?.destroy()}catch{}t.data.pipeline=null,t.data.bindGroup=null,t.data.bindGroupLayout=null,t.data.instanceStaging=null,t.data.instanceView=null,t.data.sprites.length=0,t.data.visible.length=0},onResize:function(e,t){Bs(e,t)},onViewportPosition:function(e,t){Bs(e,t)},customFunctions:{...si}};async function Jc(e,t){let{device:n}=e,{descs:r,names:i}=t.refs.spritesheet.data.spritesheet,o=n.createBuffer({size:128,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),s=32,f=new ArrayBuffer(s*r.length),h=new Float32Array(f);for(let H=0;H<r.length;H++){let W=r[H],st=H*8;h[st+0]=W.UvOrigin[0],h[st+1]=W.UvOrigin[1],h[st+2]=W.UvSpan[0],h[st+3]=W.UvSpan[1],h[st+4]=W.FrameSize[0],h[st+5]=W.FrameSize[1],h[st+6]=W.CenterOffset[0],h[st+7]=W.CenterOffset[1]}let p=n.createBuffer({label:"spriteHDR desc table",size:Math.max(16,f.byteLength),usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST});n.queue.writeBuffer(p,0,f);let g=1024,D=n.createBuffer({label:"spriteHDR instances",size:Oe*g,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),X=new ArrayBuffer(Oe*g),N=new DataView(X),I=n.createShaderModule({code:_s}),V=n.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}},{binding:3,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}},{binding:4,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}}]}),q=n.createPipelineLayout({bindGroupLayouts:[V]}),Y={arrayStride:Oe,stepMode:"instance",attributes:[{shaderLocation:0,offset:fi,format:"float32x2"},{shaderLocation:1,offset:ci,format:"float32x2"},{shaderLocation:2,offset:li,format:"float32x2"},{shaderLocation:3,offset:cr,format:"float32x4"},{shaderLocation:4,offset:Ds,format:"uint32"},{shaderLocation:5,offset:Us,format:"float32"},{shaderLocation:6,offset:Fs,format:"float32"}]},K=n.createRenderPipeline({layout:q,vertex:{module:I,entryPoint:"vs_main",buffers:[Y]},fragment:{module:I,entryPoint:"fs_main",targets:[{format:"rgba16float",blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{srcFactor:"zero",dstFactor:"one"}}},{format:"rgba16float"}]},primitive:{topology:"triangle-strip",cullMode:"none"},multisample:{count:1}}),Q=V,tt=n.createBindGroup({layout:V,entries:[{binding:0,resource:{buffer:o}},{binding:1,resource:t.refs.spritesheet.data.colorTexture.sampler},{binding:2,resource:t.refs.spritesheet.data.colorTexture.view},{binding:3,resource:{buffer:p}},{binding:4,resource:t.refs.spritesheet.data.emissiveTexture.view}]});return{sprites:[],visible:[],visibleCount:0,viewRect:{x:0,y:0,w:0,h:0},spriteBuf:p,uniformBuffer:o,instanceCap:g,instanceView:N,instanceBuf:D,instanceStaging:X,pipeline:K,bindGroup:tt}}function jc(e,t,n){let{instanceCap:r}=t.data;if(n<=r)return;let i=r;for(i===0&&(i=1024);i<n;)i*=2;t.data.instanceBuf.destroy(),t.data.instanceBuf=e.device.createBuffer({size:Oe*i,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),t.data.instanceStaging=new ArrayBuffer(Oe*i),t.data.instanceView=new DataView(t.data.instanceStaging),t.data.instanceCap=i}function tl(e,t,n){let{device:r,context:i}=e,{instanceView:o,instanceBuf:s,instanceStaging:f,pipeline:h,bindGroup:p}=t.data,{descs:g}=t.refs.spritesheet.data.spritesheet,D=t.data.viewRect;D.x=e.viewport.position[0],D.y=e.viewport.position[1],D.w=e.viewport.width,D.h=e.viewport.height,t.data.visibleCount=0;for(let I of t.data.sprites){let V=g[I.spriteID];if(V){if(!t.options.isScreenSpace){let q=V.FrameSize[0]*I.sizeX*I.scale[0]*.5,Y=V.FrameSize[1]*I.sizeY*I.scale[1]*.5,K=Math.hypot(q,Y),Q=I.position[0],tt=I.position[1];if(Q+K<D.x||Q-K>D.x+D.w||tt+K<D.y||tt-K>D.y+D.h)continue}t.data.visible[t.data.visibleCount]=I,t.data.visibleCount++}}jc(e,t,t.data.visibleCount);for(let I=0;I<t.data.visibleCount;I++){let V=I*Oe,q=t.data.visible[I],Y=q.tint;o.setFloat32(V+fi+0,q.position[0],!0),o.setFloat32(V+fi+4,q.position[1],!0),o.setFloat32(V+ci+0,q.sizeX,!0),o.setFloat32(V+ci+4,q.sizeY,!0),o.setFloat32(V+li+0,q.scale[0],!0),o.setFloat32(V+li+4,q.scale[1],!0),o.setFloat32(V+cr+0,Y[0],!0),o.setFloat32(V+cr+4,Y[1],!0),o.setFloat32(V+cr+8,Y[2],!0),o.setFloat32(V+cr+12,Y[3],!0),o.setUint32(V+Ds,q.spriteID>>>0,!0),o.setFloat32(V+Us,q.opacity,!0),o.setFloat32(V+Fs,q.rotation,!0)}r.queue.writeBuffer(s,0,f,0,t.data.visibleCount*Oe);let X=t.options.loadOp||"load",N=n.beginRenderPass({label:"spriteHDR renderpass",colorAttachments:[{view:t.refs.color.data.view,clearValue:e.clearValue,loadOp:X,storeOp:"store"},{view:t.refs.emissive.data.view,clearValue:e.clearValue,loadOp:"clear",storeOp:"store"}]});N.setPipeline(h),N.setBindGroup(0,p),N.setVertexBuffer(0,s),t.data.visibleCount&&N.draw(4,t.data.visibleCount,0,0),N.end()}function Bs(e,t){let{device:n,viewport:r}=e,i=r.width/r.zoom,o=r.height/r.zoom,s=Lt.ortho(0,i,o,0,-10,10);t.options.isScreenSpace?fe.set(0,0,0,ui):fe.set(-de(r.position[0]),-de(r.position[1]),0,ui);let f=Lt.translation(ui);n.queue.writeBuffer(t.data.uniformBuffer,0,f.buffer),n.queue.writeBuffer(t.data.uniformBuffer,64,s.buffer)}function $r(e){let t=e.meta.size.w,n=e.meta.size.h,r=Object.keys(e.frames).sort(),i=new Array(r.length);for(let o=0;o<r.length;o++){let s=e.frames[r[o]],f=s.frame.x,h=s.frame.y,p=s.frame.w,g=s.frame.h,D=f/t,X=h/n,N=p/t,I=g/n,V=s.sourceSize.w,q=s.sourceSize.h,Y=s.spriteSourceSize.x,K=s.spriteSourceSize.y,Q=Y+p*.5-V*.5,tt=K+g*.5-q*.5;i[o]={UvOrigin:[D,X],UvSpan:[N,I],FrameSize:[p,g],CenterOffset:[Q,tt]}}return{descs:i,names:r}}var As={type:"cobalt:spritesheet",refs:[],onInit:async function(e,t={}){return el(e,t)},onRun:function(e,t,n){},onDestroy:function(e,t){rl(t)},onResize:function(e,t){},onViewportPosition:function(e,t){}};async function el(e,t){let{canvas:n,device:r}=e,i,o,s,f=t.options.format||"rgba8unorm";n?(i=await fetch(t.options.spriteSheetJsonUrl),i=await i.json(),i=$r(i),o=await ve(e,"sprite",t.options.colorTextureUrl,f),s=await ve(e,"emissive sprite",t.options.emissiveTextureUrl,f),n.style.imageRendering="pixelated"):(i=$r(t.options.spriteSheetJson),o=await pe(e,"sprite",t.options.colorTexture,f),s=await pe(e,"emissive sprite",t.options.emissiveTexture,f));let h=new Map(i.names.map((p,g)=>[p,g]));return{colorTexture:o,emissiveTexture:s,spritesheet:i,idByName:h}}function rl(e){e.data.colorTexture.texture.destroy(),e.data.emissiveTexture.texture.destroy()}var hi="struct TransformData{viewOffset:vec2<f32>,viewportSize:vec2<f32>,inverseAtlasTextureSize:vec2<f32>,tileSize:f32,inverseTileSize:f32,};struct TileScroll{scrollScale:vec2<f32>};const positions=array<vec2<f32>,3>(vec2<f32>(-1.0,-3.0),vec2<f32>(3.0,1.0),vec2<f32>(-1.0,1.0));const uvs=array<vec2<f32>,3>(vec2<f32>(0.0,2.0),vec2<f32>(2.0,0.0),vec2<f32>(0.0,0.0));@binding(0)@group(0)var<uniform> myScroll:TileScroll;@binding(1)@group(0)var tileTexture:texture_2d<f32>;@binding(2)@group(0)var tileSampler:sampler;@binding(0)@group(1)var<uniform> transformUBO:TransformData;@binding(1)@group(1)var atlasTexture:texture_2d<f32>;@binding(2)@group(1)var atlasSampler:sampler;struct Fragment{@builtin(position)Position:vec4<f32>,@location(0)TexCoord:vec2<f32>};@vertex fn vs_main(@builtin(instance_index)i_id:u32,@builtin(vertex_index)VertexIndex:u32)->Fragment{var vertexPosition=vec2<f32>(positions[VertexIndex]);var vertexTexCoord=vec2<f32>(uvs[VertexIndex]);var output:Fragment;let inverseTileTextureSize=1/vec2<f32>(textureDimensions(tileTexture,0));var scrollScale=myScroll.scrollScale;var viewOffset:vec2<f32>=transformUBO.viewOffset*scrollScale;let PixelCoord=(vertexTexCoord*transformUBO.viewportSize)+viewOffset;output.TexCoord=PixelCoord/transformUBO.tileSize;output.Position=vec4<f32>(vertexPosition,0.0,1.0);return output;}@fragment fn fs_main(@location(0)TexCoord:vec2<f32>)->@location(0)vec4<f32>{var tilemapCoord=floor(TexCoord);var u_tilemapSize=vec2<f32>(textureDimensions(tileTexture,0));var tileFoo=fract((tilemapCoord+vec2<f32>(0.5,0.5))/u_tilemapSize);var tile=floor(textureSample(tileTexture,tileSampler,tileFoo)*255.0);if(tile.x==255&&tile.y==255){discard;}var u_tilesetSize=vec2<f32>(textureDimensions(atlasTexture,0))/transformUBO.tileSize;let u_tileUVMinBounds=vec2<f32>(0.5/transformUBO.tileSize,0.5/transformUBO.tileSize);let u_tileUVMaxBounds=vec2<f32>((transformUBO.tileSize-0.5)/transformUBO.tileSize,(transformUBO.tileSize-0.5)/transformUBO.tileSize);var texcoord=clamp(fract(TexCoord),u_tileUVMinBounds,u_tileUVMaxBounds);var tileCoord=(tile.xy+texcoord)/u_tilesetSize;var color=textureSample(atlasTexture,atlasSampler,tileCoord);if(color.a<=0.1){discard;}return color;}";var ye=new Float32Array(8),Ls={type:"cobalt:tileAtlas",refs:[],onInit:async function(e,t={}){return nl(e,t)},onRun:function(e,t,n){},onDestroy:function(e,t){il(t)},onResize:function(e,t){zs(e,t)},onViewportPosition:function(e,t){zs(e,t)}};async function nl(e,t){let{canvas:n,device:r}=e,i=t.options.format||"rgba8unorm",o;n?o=await ve(e,"tile atlas",t.options.textureUrl,i):o=await pe(e,"tile atlas",t.options.texture,i);let s=r.createBuffer({size:32,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),f=r.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:2,visibility:GPUShaderStage.FRAGMENT,sampler:{}}]}),h=r.createBindGroup({layout:f,entries:[{binding:0,resource:{buffer:s}},{binding:1,resource:o.view},{binding:2,resource:o.sampler}]}),p=r.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,texture:{}},{binding:2,visibility:GPUShaderStage.FRAGMENT,sampler:{}}]}),g=r.createPipelineLayout({bindGroupLayouts:[p,f]});return{pipeline:r.createRenderPipeline({label:"tileatlas",vertex:{module:r.createShaderModule({code:hi}),entryPoint:"vs_main",buffers:[]},fragment:{module:r.createShaderModule({code:hi}),entryPoint:"fs_main",targets:[{format:t.options.outputFormat||qt(e),blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{srcFactor:"zero",dstFactor:"one"}}}]},primitive:{topology:"triangle-list"},layout:g}),uniformBuffer:s,atlasBindGroup:h,atlasMaterial:o,tileBindGroupLayout:p,tileSize:t.options.tileSize,tileScale:t.options.tileScale}}function il(e){e.data.atlasMaterial.texture.destroy(),e.data.atlasMaterial.texture=void 0}function zs(e,t){ye[0]=de(e.viewport.position[0]),ye[1]=de(e.viewport.position[1]);let n=t.data,{tileScale:r,tileSize:i}=n,o=e.viewport.width/e.viewport.zoom,s=e.viewport.height/e.viewport.zoom;ye[2]=o/r,ye[3]=s/r,ye[4]=1/n.atlasMaterial.texture.width,ye[5]=1/n.atlasMaterial.texture.height,ye[6]=i,ye[7]=1/i,e.device.queue.writeBuffer(n.uniformBuffer,0,ye,0,8)}var Rs={type:"cobalt:tileHDR",refs:[{name:"tileAtlas",type:"textureView",format:"rgba8unorm",access:"read"},{name:"hdr",type:"textureView",format:"rgba16float",access:"write"}],onInit:async function(e,t={}){return ol(e,t)},onRun:function(e,t,n){al(e,t,n)},onDestroy:function(e,t){Es(t)},onResize:function(e,t){},onViewportPosition:function(e,t){},customFunctions:{setTexture:async function(e,t,n){let{canvas:r,device:i}=e;Es(t);let o=t.options.format||qt(e),s;r?(t.options.textureUrl=n,s=await ve(e,"tile map",n,o)):s=await pe(e,"tile map",n,o);let f=i.createBindGroup({layout:t.refs.tileAtlas.data.tileBindGroupLayout,entries:[{binding:0,resource:{buffer:t.data.uniformBuffer}},{binding:1,resource:s.view},{binding:2,resource:s.sampler}]});t.data.bindGroup=f,t.data.material=s}}};async function ol(e,t){let{canvas:n,device:r}=e,i,o=t.options.format||qt(e);n?i=await ve(e,"tile map",t.options.textureUrl,o):i=await pe(e,"tile map",t.options.texture,o);let s=new Float32Array([t.options.scrollScale,t.options.scrollScale]),f=GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,h={size:s.byteLength,usage:f,mappedAtCreation:!0},p=r.createBuffer(h);return new Float32Array(p.getMappedRange()).set(s),p.unmap(),{bindGroup:r.createBindGroup({layout:t.refs.tileAtlas.data.tileBindGroupLayout,entries:[{binding:0,resource:{buffer:p}},{binding:1,resource:i.view},{binding:2,resource:i.sampler}]}),material:i,uniformBuffer:p,scrollScale:t.options.scrollScale}}function al(e,t,n){if(!t.data.material.texture)return;let{device:r}=e,i=t.options.loadOp||"load",o=n.beginRenderPass({label:"tile",colorAttachments:[{view:t.refs.hdr.data?.view||t.refs.hdr,clearValue:e.clearValue,loadOp:i,storeOp:"store"}]}),s=t.refs.tileAtlas.data;o.setPipeline(s.pipeline),o.setBindGroup(0,t.data.bindGroup),o.setBindGroup(1,s.atlasBindGroup),o.draw(3),o.end()}function Es(e){e.data.material.texture.destroy(),e.data.material.texture=void 0}async function Ap(e,t,n){let r,i,o,s;return e.sdlWindow&&e.gpu?(i=e.gpu,r=await(await i.create(["verbose=1","enable-dawn-features=allow_unsafe_apis"]).requestAdapter()).requestDevice({requiredFeatures:["texture-component-swizzle"]}),o=i.renderGPUDeviceToWindow({device:r,window:e.sdlWindow}),global.GPUBufferUsage=i.GPUBufferUsage,global.GPUShaderStage=i.GPUShaderStage,global.GPUTextureUsage=i.GPUTextureUsage):(s=e,r=await(await navigator.gpu?.requestAdapter({powerPreference:"high-performance"}))?.requestDevice(),i=navigator.gpu,o=s.getContext("webgpu"),o.configure({device:r,format:navigator.gpu?.getPreferredCanvasFormat(),alphaMode:"opaque"})),{nodeDefs:{"cobalt:tileAtlas":Ls,"cobalt:spritesheet":As,"cobalt:fbTexture":zi,"cobalt:sprite":Ss,"cobalt:bloom":wi,"cobalt:composite":xs,"cobalt:spriteHDR":Gs,"cobalt:tileHDR":Rs,"cobalt:displacement":Gi,"cobalt:fbBlit":Ai,"cobalt:primitives":ws,"cobalt:light":Ei},nodes:[],defaultTextureViewRefs:[],canvas:s,device:r,context:o,gpu:i,clearValue:{r:0,g:0,b:0,a:1},viewport:{width:t,height:n,zoom:1,position:[0,0]}}}function zp(e,t){if(!t?.type)throw new Error("Can't define a new node missing a type.");e.nodeDefs[t.type]=t}async function Lp(e,t){let n=e.nodeDefs[t?.type];if(!n)throw new Error("Can't initialize a new node missing a type.");let r={type:t.type,refs:t.refs||{},options:t.options||{},data:{},enabled:!0};for(let o in r.refs)r.refs[o]==="FRAME_TEXTURE_VIEW"&&(e.defaultTextureViewRefs.push({node:r,refName:o}),r.refs[o]=Is(e));r.data=await n.onInit(e,r);let i=n.customFunctions||{};for(let o in i)r[o]=function(...s){return i[o](e,r,...s)};return e.nodes.push(r),r}function Ep(e){let{device:t,context:n}=e,r=t.createCommandEncoder(),i=Is(e);for(let o of e.defaultTextureViewRefs)o.node.refs[o.refName]=i;for(let o of e.nodes){if(!o.enabled)continue;e.nodeDefs[o.type].onRun(e,o,r)}t.queue.submit([r.finish()]),e.canvas||e.context.swap()}function Rp(e){for(let t of e.nodes)e.nodeDefs[t.type].onDestroy(e,t);e.nodes.length=0,e.defaultTextureViewRefs.length=0}function Ip(e,t,n){e.viewport.width=t,e.viewport.height=n;for(let r of e.nodes)e.nodeDefs[r.type].onResize(e,r)}function Op(e,t){e.viewport.position[0]=t[0]-e.viewport.width/2/e.viewport.zoom,e.viewport.position[1]=t[1]-e.viewport.height/2/e.viewport.zoom;for(let n of e.nodes)e.nodeDefs[n.type].onViewportPosition(e,n)}function Is(e){return e.canvas?e.context.getCurrentTexture().createView():e.context.getCurrentTextureView()}export{ne as createTexture,pe as createTextureFromBuffer,ve as createTextureFromUrl,zp as defineNode,Ep as draw,Is as getCurrentTextureView,Ap as init,Lp as initNode,Rp as reset,Ip as setViewportDimensions,Op as setViewportPosition};
|
package/package.json
CHANGED