@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
JavaScript
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