UNPKG

@babylonjs/viewer

Version:

The Babylon Viewer aims to simplify a specific but common Babylon.js use case: loading, viewing, and interacting with a 3D model.

3 lines (2 loc) 8.78 kB
import{B as e,F as n,b8 as i,b9 as t,ba as o,n as r,aD as s}from"./index-B8IgtevW.esm.min.js";import{a}from"./gltf-feature-gaussian-splatting-Ce1heiDe.esm.min.js";const c={id:"gsGpuPicking",helperFunctions:"\nstruct GsPickingU { pickingColor: vec3<f32> };\n@group(2) @binding(0) var<uniform> picking: GsPickingU;\n",fragmentSlots:{GS_FRAGMENT_BEFORE_FRAGCOLOR:"\n if (finalColor.a < 0.001) { discard; }\n finalColor = vec4<f32>(picking.pickingColor, 1.0);\n "}};let l=null;const u=new n(16);function f(e){return a(`\nstruct GsPickScene { pickMatrix: mat4x4<f32> };\n@group(0) @binding(0) var<uniform> gsPickScene: GsPickScene;\n\nstruct U {\n world: mat4x4<f32>,\n view: mat4x4<f32>,\n projection: mat4x4<f32>,\n viewport: vec2<f32>,\n focal: vec2<f32>,\n dataSize: vec2<f32>,\n alpha: f32,\n _pad: f32,\n};\n@group(1) @binding(0) var<uniform> u: U;\n@group(1) @binding(1) var samp: sampler;\n@group(1) @binding(2) var centersTex: texture_2d<f32>;\n@group(1) @binding(3) var covATex: texture_2d<f32>;\n@group(1) @binding(4) var covBTex: texture_2d<f32>;\n@group(1) @binding(5) var colorsTex: texture_2d<f32>;\n\nstruct VOut {\n @builtin(position) pos: vec4<f32>,\n @location(0) vColor: vec4<f32>,\n @location(1) vPos: vec2<f32>,\n};\n\nfn dataUv(idx: f32) -> vec2<f32> {\n let y = floor(idx / u.dataSize.x);\n let x = idx - y * u.dataSize.x;\n return vec2<f32>((x + 0.5) / u.dataSize.x, (y + 0.5) / u.dataSize.y);\n}\n\n@vertex\nfn vs(@location(0) corner: vec2<f32>, @location(1) splatIndex: f32) -> VOut {\n var out: VOut;\n let uv = dataUv(splatIndex);\n let center = textureSampleLevel(centersTex, samp, uv, 0.0).xyz;\n let color = textureSampleLevel(colorsTex, samp, uv, 0.0);\n let covA = textureSampleLevel(covATex, samp, uv, 0.0).xyz;\n let covB = textureSampleLevel(covBTex, samp, uv, 0.0).xyz;\n\n let worldPos = u.world * vec4<f32>(center, 1.0);\n let modelView = u.view * u.world;\n let camspace = u.view * worldPos;\n let pos2d = u.projection * camspace;\n\n let bounds = 1.2 * pos2d.w;\n if (pos2d.z < 0.0\n || pos2d.x < -bounds || pos2d.x > bounds\n || pos2d.y < -bounds || pos2d.y > bounds) {\n out.pos = vec4<f32>(0.0, 0.0, 2.0, 1.0);\n out.vColor = vec4<f32>(0.0);\n out.vPos = vec2<f32>(0.0);\n return out;\n }\n\n let Vrk = mat3x3<f32>(\n vec3<f32>(covA.x, covA.y, covA.z),\n vec3<f32>(covA.y, covB.x, covB.y),\n vec3<f32>(covA.z, covB.y, covB.z));\n\n let invZ = 1.0 / camspace.z;\n let invZ2 = invZ * invZ;\n let J = mat3x3<f32>(\n vec3<f32>(u.focal.x * invZ, 0.0, -u.focal.x * camspace.x * invZ2),\n vec3<f32>(0.0, u.focal.y * invZ, -u.focal.y * camspace.y * invZ2),\n vec3<f32>(0.0, 0.0, 0.0));\n\n let mv3 = mat3x3<f32>(modelView[0].xyz, modelView[1].xyz, modelView[2].xyz);\n let T = transpose(mv3) * J;\n var cov2d = transpose(T) * Vrk * T;\n\n let kernelSize: f32 = 0.3;\n cov2d[0][0] += kernelSize;\n cov2d[1][1] += kernelSize;\n\n let mid = (cov2d[0][0] + cov2d[1][1]) * 0.5;\n let dxy = (cov2d[0][0] - cov2d[1][1]) * 0.5;\n let radius = length(vec2<f32>(dxy, cov2d[0][1]));\n let epsilon: f32 = 0.0001;\n let lambda1 = mid + radius + epsilon;\n let lambda2 = mid - radius + epsilon;\n if (lambda2 < 0.0) {\n out.pos = vec4<f32>(0.0, 0.0, 2.0, 1.0);\n out.vColor = vec4<f32>(0.0);\n out.vPos = vec2<f32>(0.0);\n return out;\n }\n\n let diag = normalize(vec2<f32>(cov2d[0][1], lambda1 - cov2d[0][0]));\n let majorAxis = min(sqrt(2.0 * lambda1), 1024.0) * diag;\n let minorAxis = min(sqrt(2.0 * lambda2), 1024.0) * vec2<f32>(diag.y, -diag.x);\n\n let vCenter = pos2d.xy;\n out.pos = gsPickScene.pickMatrix * vec4<f32>(\n vCenter + (corner.x * majorAxis + corner.y * minorAxis) * pos2d.w / u.viewport,\n pos2d.z, pos2d.w);\n out.vColor = vec4<f32>(color.rgb, color.a * u.alpha);\n out.vPos = corner;\n return out;\n}\n\n/*GS_FRAGMENT_DEFINITIONS*/\nstruct FsOut { @location(0) color: vec4<f32>, @location(1) depth: f32${e?", @location(2) detail: vec4u":""} };\n@fragment\nfn fs(in: VOut) -> FsOut {\n /*GS_FRAGMENT_MAIN_BEGIN*/\n let A = -dot(in.vPos, in.vPos);\n var finalColor: vec4<f32>;\n if (A > -4.0) {\n let B = exp(A) * in.vColor.a;\n finalColor = vec4<f32>(in.vColor.rgb, B);\n } else {\n finalColor = vec4<f32>(0.0);\n }\n /*GS_FRAGMENT_BEFORE_FRAGCOLOR*/\n /*GS_FRAGMENT_MAIN_END*/\n return FsOut(finalColor, in.pos.z${e?", vec4u(0xffffffffu, 0u, 0u, 0u)":""});\n}\n`,[c])}function d(n){const i=n._device;if(l&&l.device===i)return l;const t=i.createBindGroupLayout({label:"gs-picking-mesh-bgl",entries:[{binding:0,visibility:r.VERTEX|r.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:r.VERTEX,sampler:{type:"non-filtering"}},{binding:2,visibility:r.VERTEX,texture:{sampleType:"unfilterable-float"}},{binding:3,visibility:r.VERTEX,texture:{sampleType:"unfilterable-float"}},{binding:4,visibility:r.VERTEX,texture:{sampleType:"unfilterable-float"}},{binding:5,visibility:r.VERTEX,texture:{sampleType:"unfilterable-float"}}]}),o=i.createBindGroupLayout({label:"gs-picking-pick-bgl",entries:[{binding:0,visibility:r.FRAGMENT,buffer:{type:"uniform"}}]}),a=i.createBuffer({size:64,usage:e.UNIFORM|e.COPY_DST,label:"gs-picking-scene-ubo"}),c=i.createBindGroup({label:"gs-picking-scene-bg",layout:s(n),entries:[{binding:0,resource:{buffer:a}}]});return l={device:i,pipelines:new Map,meshBGL:t,pickingBGL:o,pickMatrixUbo:a,sceneBG:c},l}function p(e,n,i){const t=d(n);n._device.queue.writeBuffer(t.pickMatrixUbo,0,i.buffer,i.byteOffset,i.byteLength),e.setBindGroup(0,t.sceneBG)}function v(i,t){const o=i._device,r=d(i),s=o.createBuffer({size:224,usage:e.UNIFORM|e.COPY_DST,label:"gs-picking-mesh-ubo"}),a=new n(56);a[52]=t.textureWidth,a[53]=t.textureHeight,a[54]=1;const c=o.createBindGroup({label:"gs-picking-mesh-bg",layout:r.meshBGL,entries:[{binding:0,resource:{buffer:s}},{binding:1,resource:t._gs._sampler},{binding:2,resource:t._gs._centersView},{binding:3,resource:t._gs._covAView},{binding:4,resource:t._gs._covBView},{binding:5,resource:t._gs._colorsView}]}),l=o.createBuffer({size:16,usage:e.UNIFORM|e.COPY_DST,label:"gs-picking-color-ubo"}),u=new n(4);return{meshUbo:s,meshBG:c,pickingUbo:l,pickingBG:o.createBindGroup({label:"gs-picking-color-bg",layout:r.pickingBGL,entries:[{binding:0,resource:{buffer:l}}]}),meshCpu:a,pickingCpu:u}}function g(e){e.meshUbo.destroy(),e.pickingUbo.destroy()}function b(e,n,r,a,c,l,u,p,v=!1){const g=r.camera;if(!g)return;const b=i(n),m=(u||b.width)/(p||b.height),x=t(g),y=o(g,m),k=a.worldMatrix,B=c.meshCpu;B.set(k,0),B.set(x,16),B.set(y,32),B[48]=b.width,B[49]=b.height,B[50]=.5*b.width*y[0],B[51]=.5*b.height*y[5],n._device.queue.writeBuffer(c.meshUbo,0,B.buffer,0,B.byteLength);const[_,h,G]=[((w=l)>>16&255)/255,(w>>8&255)/255,(255&w)/255];var w;c.pickingCpu[0]=_,c.pickingCpu[1]=h,c.pickingCpu[2]=G,c.pickingCpu[3]=0,n._device.queue.writeBuffer(c.pickingUbo,0,c.pickingCpu.buffer,0,16),e.setPipeline(function(e,n){const i=d(e),t=n?"detailed":"basic",o=i.pipelines.get(t);if(o)return o;const r=e._device,a=r.createShaderModule({label:`gs-picking-${t}-shader`,code:f(n)}),c=r.createRenderPipeline({label:`gs-picking-${t}-pipeline`,layout:r.createPipelineLayout({bindGroupLayouts:[s(e),i.meshBGL,i.pickingBGL]}),vertex:{module:a,entryPoint:"vs",buffers:[{arrayStride:8,stepMode:"vertex",attributes:[{shaderLocation:0,offset:0,format:"float32x2"}]},{arrayStride:4,stepMode:"instance",attributes:[{shaderLocation:1,offset:0,format:"float32"}]}]},fragment:{module:a,entryPoint:"fs",targets:n?[{format:"rgba8unorm"},{format:"r32float"},{format:"rgba32uint"}]:[{format:"rgba8unorm"},{format:"r32float"}]},primitive:{topology:"triangle-list",cullMode:"none"},depthStencil:{format:"depth24plus",depthCompare:"less",depthWriteEnabled:!0},multisample:{count:1}});return i.pipelines.set(t,c),c}(n,v)),e.setBindGroup(1,c.meshBG),e.setBindGroup(2,c.pickingBG),e.setVertexBuffer(0,a._gs._quadBuffer),e.setVertexBuffer(1,a._gs._splatIndexBuffer),e.setIndexBuffer(a._gs._indexBuffer,"uint16"),e.drawIndexed(6,a.vertexCount)}function m(e,n,i,t){x(u,e.px,e.py,e.w,e.h),p(e.pass,e.engine,u),b(e.pass,e.engine,e.scene,n,i,t,e.w,e.h,e.detailed)}function x(e,n,i,t,o){const r=2*n/t-1,s=1-2*i/o;e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=o,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=-r*t,e[13]=-s*o,e[14]=0,e[15]=1}function y(e){let n=null;return{draw:(i,t)=>(!1===e.visible||(n??=v(i.engine,e),m(i,e,n,t)),t+1),resolve(n){n.pickedMesh=e},dispose(){n&&(g(n),n=null)}}}export{x as computeGsPickMatrix,v as createGsPickMeshResources,y as createPickContributor,g as disposeGsPickMeshResources,b as drawGsForPicking,m as drawGsMeshForPicking,p as gsPickWritePickMatrixAndBind}; //# sourceMappingURL=gs-picking-pipeline-DUMOqxO3.esm.min.js.map