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.

167 lines (162 loc) 5.5 kB
import { d as createMappedBuffer, B as BU, I as I32, i as TU, j as U8, k as getOrCreateSampler, F as F32, e as createUniformBuffer, U as U16 } from './index-By0tcgYN.esm.js'; import { W as WGSL_DITHER, a as WGSL_NO_DITHER } from './wgsl-helpers-D-Db86WE.esm.js'; import { S as SCENE_UBO_WGSL } from './scene-uniforms-ucwQkfF-.esm.js'; import { c as createCubemapSkyboxMaterial } from './cubemap-skybox-material-Bitfa3r2.esm.js'; const ddsSkyboxVertSrc = "struct e{world:mat4x4<f32>}@group(1) @binding(0) var<uniform> mesh:e;struct d{@builtin(position) clipPos:vec4<f32>,@location(0) positionUVW:vec3<f32>,@location(1) positionW:vec3<f32>}@vertex fn main(@location(0) b:vec3<f32>)->d{var a:d;a.positionUVW=b;let c=(mesh.world*vec4<f32>(b,1.0)).xyz;a.positionW=c;a.clipPos=scene.viewProjection*vec4<f32>(c,1.0);return a;}"; const ddsSkyboxFragSrc = "struct g{world:mat4x4<f32>,primaryColor:vec3<f32>,exposureLinear:f32,contrast:f32,_pad1:f32,_pad2:f32,_pad3:f32}@group(1) @binding(0) var<uniform> mesh:g;@group(1) @binding(1) var c:texture_cube<f32>;@group(1) @binding(2) var d:sampler;struct h{@location(0) positionUVW:vec3<f32>,@location(1) positionW:vec3<f32>}@fragment fn main(b:h)->@location(0) vec4<f32>{let e=normalize(b.positionUVW);var a=textureSampleLevel(c,d,e,0.0).rgb;a*=mesh.primaryColor;if (scene.vImageInfos.w>=0.0){a*=mesh.exposureLinear;a=1.0-exp2(-1.590579*a);a=pow(a,vec3<f32>(1.0/2.2));a=saturate(a);let f=a*a*(3.0-2.0*a);a=mix(a,f,mesh.contrast-1.0);a=a+vec3<f32>(dither(b.positionW.xy,0.5));a=max(a,vec3<f32>(0.0));}return vec4<f32>(a,1.0);}"; const SKY_DDS_UNIFORM_SIZE = 96; const DEFAULT_SKY_URL = "https://assets.babylonjs.com/core/environments/backgroundSkybox.dds"; function createSkyboxBuffers(engine, S) { const positions = new F32([ -S, -S, -S, S, -S, -S, -S, S, -S, S, S, -S, -S, -S, S, S, -S, S, -S, S, S, S, S, S ]); const indices = new U16([ 6, 4, 5, 7, 6, 5, 0, 2, 3, 1, 0, 3, 5, 1, 3, 7, 5, 3, 0, 4, 6, 2, 0, 6, 3, 2, 6, 7, 3, 6, 0, 1, 5, 4, 0, 5 ]); return { posBuffer: createMappedBuffer(engine, positions, BU.VERTEX), idxBuffer: createMappedBuffer(engine, indices, BU.INDEX) }; } async function buildDdsSkyboxRenderable(scene, skyHalfSize, rootPosition, primaryColor, skyboxTextureUrl, enableNoise = true) { const engine = scene.surface.engine; const skyBufs = createSkyboxBuffers(engine, skyHalfSize); const { cubeView, sampler } = await loadDdsCube(engine, skyboxTextureUrl ?? DEFAULT_SKY_URL); const fragCode = SCENE_UBO_WGSL + (enableNoise ? WGSL_DITHER : WGSL_NO_DITHER) + ddsSkyboxFragSrc; const mat = createCubemapSkyboxMaterial(enableNoise ? "skybox-dds" : "skybox-dds0", SCENE_UBO_WGSL + ddsSkyboxVertSrc, fragCode); const ubo = createDdsMeshUBO(engine, rootPosition, primaryColor, scene.imageProcessing.exposure, scene.imageProcessing.contrast); const bindGroup = mat.createBindGroup(engine, ubo, cubeView, sampler); const r = { order: 0, isTransparent: false, bind(eng, sig) { return { renderable: r, pipeline: mat.getPipeline(eng, sig), draw(pass) { pass.setBindGroup(1, bindGroup); pass.setVertexBuffer(0, skyBufs.posBuffer); pass.setIndexBuffer(skyBufs.idxBuffer, "uint16"); pass.drawIndexed(36); return 1; } }; } }; return r; } function createDdsMeshUBO(engine, rootPosition, primaryColor, exposureLinear, contrast) { const data = new F32(SKY_DDS_UNIFORM_SIZE / 4); data[0] = data[5] = data[10] = data[15] = 1; data[12] = rootPosition[0]; data[13] = rootPosition[1]; data[14] = rootPosition[2]; data[16] = primaryColor[0]; data[17] = primaryColor[1]; data[18] = primaryColor[2]; data[19] = exposureLinear; data[20] = contrast; return createUniformBuffer(engine, data); } async function loadDdsCube(engine, url) { const device = engine._device; const buf = await (await fetch(url)).arrayBuffer(); const header = new I32(buf, 0, 32); const width = header[3]; const height = header[4]; const mipCount = Math.max(header[7], 1); const dataOffset = header[21] === 808540228 ? 128 + 20 : 128; const raw = new U8(buf, dataOffset); const fmt = "rgba16float"; const tex = device.createTexture({ size: [width, height, 6], format: fmt, mipLevelCount: mipCount, usage: TU.TEXTURE_BINDING | TU.COPY_DST | TU.RENDER_ATTACHMENT, dimension: "2d" }); let offset = 0; for (let face = 0; face < 6; face++) { for (let m = 0; m < mipCount; m++) { const s = Math.max(width >> m, 1); device.queue.writeTexture( { texture: tex, origin: { x: 0, y: 0, z: face }, mipLevel: m }, raw.buffer, { offset: raw.byteOffset + offset, bytesPerRow: s * 8 }, { width: s, height: s } ); offset += s * s * 8; } } const cubeView = tex.createView({ dimension: "cube" }); const sampler = getOrCreateSampler(engine, { magFilter: "linear", minFilter: "linear", mipmapFilter: "linear", addressModeU: "clamp-to-edge", addressModeV: "clamp-to-edge", addressModeW: "clamp-to-edge", maxAnisotropy: 4 }); return { cubeView, sampler }; } export { buildDdsSkyboxRenderable }; //# sourceMappingURL=background-dds-skybox-DpASANYm.esm.js.map