@luma.gl/engine 9.3.0-alpha.2 → 9.3.0-alpha.4
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/dist/dist.dev.js +752 -271
- package/dist/dist.min.js +182 -23
- package/dist/dynamic-texture/dynamic-texture.d.ts.map +1 -1
- package/dist/dynamic-texture/dynamic-texture.js +37 -4
- package/dist/dynamic-texture/dynamic-texture.js.map +1 -1
- package/dist/dynamic-texture/mipmaps.d.ts +6 -0
- package/dist/dynamic-texture/mipmaps.d.ts.map +1 -0
- package/dist/dynamic-texture/mipmaps.js +441 -0
- package/dist/dynamic-texture/mipmaps.js.map +1 -0
- package/dist/dynamic-texture/texture-data.js +1 -1
- package/dist/dynamic-texture/texture-data.js.map +1 -1
- package/dist/index.cjs +759 -295
- package/dist/index.cjs.map +4 -4
- package/dist/utils/buffer-layout-order.d.ts.map +1 -1
- package/dist/utils/buffer-layout-order.js +12 -2
- package/dist/utils/buffer-layout-order.js.map +1 -1
- package/package.json +4 -4
- package/src/dynamic-texture/dynamic-texture.ts +54 -6
- package/src/dynamic-texture/mipmaps.ts +517 -0
- package/src/dynamic-texture/texture-data.ts +1 -1
- package/src/utils/buffer-layout-order.ts +18 -2
package/dist/index.cjs
CHANGED
|
@@ -677,8 +677,8 @@ function clearError(device) {
|
|
|
677
677
|
}
|
|
678
678
|
|
|
679
679
|
// dist/model/model.js
|
|
680
|
-
var
|
|
681
|
-
var
|
|
680
|
+
var import_core12 = require("@luma.gl/core");
|
|
681
|
+
var import_shadertools3 = require("@luma.gl/shadertools");
|
|
682
682
|
|
|
683
683
|
// dist/geometry/gpu-geometry.js
|
|
684
684
|
var import_core3 = require("@luma.gl/core");
|
|
@@ -1175,14 +1175,24 @@ var BufferLayoutHelper = class {
|
|
|
1175
1175
|
};
|
|
1176
1176
|
|
|
1177
1177
|
// dist/utils/buffer-layout-order.js
|
|
1178
|
+
function getMinLocation(attributeNames, shaderLayoutMap) {
|
|
1179
|
+
let minLocation = Infinity;
|
|
1180
|
+
for (const name of attributeNames) {
|
|
1181
|
+
const location = shaderLayoutMap[name];
|
|
1182
|
+
if (location !== void 0) {
|
|
1183
|
+
minLocation = Math.min(minLocation, location);
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
return minLocation;
|
|
1187
|
+
}
|
|
1178
1188
|
function sortedBufferLayoutByShaderSourceLocations(shaderLayout, bufferLayout) {
|
|
1179
1189
|
const shaderLayoutMap = Object.fromEntries(shaderLayout.attributes.map((attr) => [attr.name, attr.location]));
|
|
1180
1190
|
const sortedLayout = bufferLayout.slice();
|
|
1181
1191
|
sortedLayout.sort((a, b) => {
|
|
1182
1192
|
const attributeNamesA = a.attributes ? a.attributes.map((attr) => attr.attribute) : [a.name];
|
|
1183
1193
|
const attributeNamesB = b.attributes ? b.attributes.map((attr) => attr.attribute) : [b.name];
|
|
1184
|
-
const minLocationA =
|
|
1185
|
-
const minLocationB =
|
|
1194
|
+
const minLocationA = getMinLocation(attributeNamesA, shaderLayoutMap);
|
|
1195
|
+
const minLocationB = getMinLocation(attributeNamesB, shaderLayoutMap);
|
|
1186
1196
|
return minLocationA - minLocationB;
|
|
1187
1197
|
});
|
|
1188
1198
|
return sortedLayout;
|
|
@@ -1316,7 +1326,7 @@ var ShaderInputs = class {
|
|
|
1316
1326
|
};
|
|
1317
1327
|
|
|
1318
1328
|
// dist/dynamic-texture/dynamic-texture.js
|
|
1319
|
-
var
|
|
1329
|
+
var import_core11 = require("@luma.gl/core");
|
|
1320
1330
|
|
|
1321
1331
|
// dist/dynamic-texture/texture-data.js
|
|
1322
1332
|
var import_core8 = require("@luma.gl/core");
|
|
@@ -1437,25 +1447,660 @@ function getTextureArraySubresources(data) {
|
|
|
1437
1447
|
for (let layer = 0; layer < data.length; layer++) {
|
|
1438
1448
|
subresources.push(...getTexture2DSubresources(layer, data[layer]));
|
|
1439
1449
|
}
|
|
1440
|
-
return subresources;
|
|
1450
|
+
return subresources;
|
|
1451
|
+
}
|
|
1452
|
+
function getTextureCubeSubresources(data) {
|
|
1453
|
+
const subresources = [];
|
|
1454
|
+
for (const [face, faceData] of Object.entries(data)) {
|
|
1455
|
+
const faceDepth = getCubeFaceIndex(face);
|
|
1456
|
+
subresources.push(...getTexture2DSubresources(faceDepth, faceData));
|
|
1457
|
+
}
|
|
1458
|
+
return subresources;
|
|
1459
|
+
}
|
|
1460
|
+
function getTextureCubeArraySubresources(data) {
|
|
1461
|
+
const subresources = [];
|
|
1462
|
+
data.forEach((cubeData, cubeIndex) => {
|
|
1463
|
+
for (const [face, faceData] of Object.entries(cubeData)) {
|
|
1464
|
+
const faceDepth = getCubeArrayFaceIndex(cubeIndex, face);
|
|
1465
|
+
subresources.push(...getTexture2DSubresources(faceDepth, faceData));
|
|
1466
|
+
}
|
|
1467
|
+
});
|
|
1468
|
+
return subresources;
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
// dist/dynamic-texture/mipmaps.js
|
|
1472
|
+
var import_core10 = require("@luma.gl/core");
|
|
1473
|
+
|
|
1474
|
+
// dist/compute/computation.js
|
|
1475
|
+
var import_core9 = require("@luma.gl/core");
|
|
1476
|
+
var import_shadertools2 = require("@luma.gl/shadertools");
|
|
1477
|
+
var import_types2 = require("@math.gl/types");
|
|
1478
|
+
var LOG_DRAW_PRIORITY = 2;
|
|
1479
|
+
var LOG_DRAW_TIMEOUT = 1e4;
|
|
1480
|
+
var _Computation = class {
|
|
1481
|
+
device;
|
|
1482
|
+
id;
|
|
1483
|
+
pipelineFactory;
|
|
1484
|
+
shaderFactory;
|
|
1485
|
+
userData = {};
|
|
1486
|
+
/** Bindings (textures, samplers, uniform buffers) */
|
|
1487
|
+
bindings = {};
|
|
1488
|
+
/** The underlying GPU pipeline. */
|
|
1489
|
+
pipeline;
|
|
1490
|
+
/** Assembled compute shader source */
|
|
1491
|
+
source;
|
|
1492
|
+
/** the underlying compiled compute shader */
|
|
1493
|
+
// @ts-ignore Set in function called from constructor
|
|
1494
|
+
shader;
|
|
1495
|
+
/** ShaderInputs instance */
|
|
1496
|
+
shaderInputs;
|
|
1497
|
+
// @ts-ignore Set in function called from constructor
|
|
1498
|
+
_uniformStore;
|
|
1499
|
+
_pipelineNeedsUpdate = "newly created";
|
|
1500
|
+
_getModuleUniforms;
|
|
1501
|
+
props;
|
|
1502
|
+
_destroyed = false;
|
|
1503
|
+
constructor(device, props) {
|
|
1504
|
+
var _a, _b, _c;
|
|
1505
|
+
if (device.type !== "webgpu") {
|
|
1506
|
+
throw new Error("Computation is only supported in WebGPU");
|
|
1507
|
+
}
|
|
1508
|
+
this.props = { ..._Computation.defaultProps, ...props };
|
|
1509
|
+
props = this.props;
|
|
1510
|
+
this.id = props.id || uid("model");
|
|
1511
|
+
this.device = device;
|
|
1512
|
+
Object.assign(this.userData, props.userData);
|
|
1513
|
+
const moduleMap = Object.fromEntries(((_a = this.props.modules) == null ? void 0 : _a.map((module2) => [module2.name, module2])) || []);
|
|
1514
|
+
this.shaderInputs = props.shaderInputs || new ShaderInputs(moduleMap);
|
|
1515
|
+
this.setShaderInputs(this.shaderInputs);
|
|
1516
|
+
this.props.shaderLayout ||= device.getShaderLayout(this.props.source);
|
|
1517
|
+
const platformInfo = getPlatformInfo(device);
|
|
1518
|
+
const modules = (((_b = this.props.modules) == null ? void 0 : _b.length) > 0 ? this.props.modules : (_c = this.shaderInputs) == null ? void 0 : _c.getModules()) || [];
|
|
1519
|
+
this.pipelineFactory = props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device);
|
|
1520
|
+
this.shaderFactory = props.shaderFactory || ShaderFactory.getDefaultShaderFactory(this.device);
|
|
1521
|
+
const { source: source3, getUniforms: getUniforms2 } = this.props.shaderAssembler.assembleWGSLShader({
|
|
1522
|
+
platformInfo,
|
|
1523
|
+
...this.props,
|
|
1524
|
+
modules
|
|
1525
|
+
});
|
|
1526
|
+
this.source = source3;
|
|
1527
|
+
this._getModuleUniforms = getUniforms2;
|
|
1528
|
+
this.pipeline = this._updatePipeline();
|
|
1529
|
+
if (props.bindings) {
|
|
1530
|
+
this.setBindings(props.bindings);
|
|
1531
|
+
}
|
|
1532
|
+
Object.seal(this);
|
|
1533
|
+
}
|
|
1534
|
+
destroy() {
|
|
1535
|
+
if (this._destroyed)
|
|
1536
|
+
return;
|
|
1537
|
+
this.pipelineFactory.release(this.pipeline);
|
|
1538
|
+
this.shaderFactory.release(this.shader);
|
|
1539
|
+
this._uniformStore.destroy();
|
|
1540
|
+
this._destroyed = true;
|
|
1541
|
+
}
|
|
1542
|
+
// Draw call
|
|
1543
|
+
predraw() {
|
|
1544
|
+
this.updateShaderInputs();
|
|
1545
|
+
}
|
|
1546
|
+
dispatch(computePass, x, y, z) {
|
|
1547
|
+
try {
|
|
1548
|
+
this._logDrawCallStart();
|
|
1549
|
+
this.pipeline = this._updatePipeline();
|
|
1550
|
+
this.pipeline.setBindings(this.bindings);
|
|
1551
|
+
computePass.setPipeline(this.pipeline);
|
|
1552
|
+
computePass.setBindings([]);
|
|
1553
|
+
computePass.dispatch(x, y, z);
|
|
1554
|
+
} finally {
|
|
1555
|
+
this._logDrawCallEnd();
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
// Update fixed fields (can trigger pipeline rebuild)
|
|
1559
|
+
// Update dynamic fields
|
|
1560
|
+
/**
|
|
1561
|
+
* Updates the vertex count (used in draw calls)
|
|
1562
|
+
* @note Any attributes with stepMode=vertex need to be at least this big
|
|
1563
|
+
*/
|
|
1564
|
+
setVertexCount(vertexCount) {
|
|
1565
|
+
}
|
|
1566
|
+
/**
|
|
1567
|
+
* Updates the instance count (used in draw calls)
|
|
1568
|
+
* @note Any attributes with stepMode=instance need to be at least this big
|
|
1569
|
+
*/
|
|
1570
|
+
setInstanceCount(instanceCount) {
|
|
1571
|
+
}
|
|
1572
|
+
setShaderInputs(shaderInputs) {
|
|
1573
|
+
this.shaderInputs = shaderInputs;
|
|
1574
|
+
this._uniformStore = new import_core9.UniformStore(this.shaderInputs.modules);
|
|
1575
|
+
for (const moduleName of Object.keys(this.shaderInputs.modules)) {
|
|
1576
|
+
const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
|
|
1577
|
+
this.bindings[`${moduleName}Uniforms`] = uniformBuffer;
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
/**
|
|
1581
|
+
* Updates shader module settings (which results in uniforms being set)
|
|
1582
|
+
*/
|
|
1583
|
+
setShaderModuleProps(props) {
|
|
1584
|
+
const uniforms = this._getModuleUniforms(props);
|
|
1585
|
+
const keys = Object.keys(uniforms).filter((k) => {
|
|
1586
|
+
const uniform = uniforms[k];
|
|
1587
|
+
return !(0, import_types2.isNumericArray)(uniform) && typeof uniform !== "number" && typeof uniform !== "boolean";
|
|
1588
|
+
});
|
|
1589
|
+
const bindings = {};
|
|
1590
|
+
for (const k of keys) {
|
|
1591
|
+
bindings[k] = uniforms[k];
|
|
1592
|
+
delete uniforms[k];
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
updateShaderInputs() {
|
|
1596
|
+
this._uniformStore.setUniforms(this.shaderInputs.getUniformValues());
|
|
1597
|
+
}
|
|
1598
|
+
/**
|
|
1599
|
+
* Sets bindings (textures, samplers, uniform buffers)
|
|
1600
|
+
*/
|
|
1601
|
+
setBindings(bindings) {
|
|
1602
|
+
Object.assign(this.bindings, bindings);
|
|
1603
|
+
}
|
|
1604
|
+
_setPipelineNeedsUpdate(reason) {
|
|
1605
|
+
this._pipelineNeedsUpdate = this._pipelineNeedsUpdate || reason;
|
|
1606
|
+
}
|
|
1607
|
+
_updatePipeline() {
|
|
1608
|
+
if (this._pipelineNeedsUpdate) {
|
|
1609
|
+
let prevShader = null;
|
|
1610
|
+
if (this.pipeline) {
|
|
1611
|
+
import_core9.log.log(1, `Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`)();
|
|
1612
|
+
prevShader = this.shader;
|
|
1613
|
+
}
|
|
1614
|
+
this._pipelineNeedsUpdate = false;
|
|
1615
|
+
this.shader = this.shaderFactory.createShader({
|
|
1616
|
+
id: `${this.id}-fragment`,
|
|
1617
|
+
stage: "compute",
|
|
1618
|
+
source: this.source,
|
|
1619
|
+
debugShaders: this.props.debugShaders
|
|
1620
|
+
});
|
|
1621
|
+
this.pipeline = this.pipelineFactory.createComputePipeline({
|
|
1622
|
+
...this.props,
|
|
1623
|
+
shader: this.shader
|
|
1624
|
+
});
|
|
1625
|
+
if (prevShader) {
|
|
1626
|
+
this.shaderFactory.release(prevShader);
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
return this.pipeline;
|
|
1630
|
+
}
|
|
1631
|
+
/** Throttle draw call logging */
|
|
1632
|
+
_lastLogTime = 0;
|
|
1633
|
+
_logOpen = false;
|
|
1634
|
+
_logDrawCallStart() {
|
|
1635
|
+
const logDrawTimeout = import_core9.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT;
|
|
1636
|
+
if (import_core9.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
|
|
1637
|
+
return;
|
|
1638
|
+
}
|
|
1639
|
+
this._lastLogTime = Date.now();
|
|
1640
|
+
this._logOpen = true;
|
|
1641
|
+
import_core9.log.group(LOG_DRAW_PRIORITY, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core9.log.level <= 2 })();
|
|
1642
|
+
}
|
|
1643
|
+
_logDrawCallEnd() {
|
|
1644
|
+
if (this._logOpen) {
|
|
1645
|
+
const uniformTable = this.shaderInputs.getDebugTable();
|
|
1646
|
+
import_core9.log.table(LOG_DRAW_PRIORITY, uniformTable)();
|
|
1647
|
+
import_core9.log.groupEnd(LOG_DRAW_PRIORITY)();
|
|
1648
|
+
this._logOpen = false;
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
_drawCount = 0;
|
|
1652
|
+
// TODO - fix typing of luma data types
|
|
1653
|
+
_getBufferOrConstantValues(attribute, dataType) {
|
|
1654
|
+
const TypedArrayConstructor = (0, import_core9.getTypedArrayConstructor)(dataType);
|
|
1655
|
+
const typedArray = attribute instanceof import_core9.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
|
|
1656
|
+
return typedArray.toString();
|
|
1657
|
+
}
|
|
1658
|
+
};
|
|
1659
|
+
var Computation = _Computation;
|
|
1660
|
+
__publicField(Computation, "defaultProps", {
|
|
1661
|
+
...import_core9.ComputePipeline.defaultProps,
|
|
1662
|
+
id: "unnamed",
|
|
1663
|
+
handle: void 0,
|
|
1664
|
+
userData: {},
|
|
1665
|
+
source: "",
|
|
1666
|
+
modules: [],
|
|
1667
|
+
defines: {},
|
|
1668
|
+
bindings: void 0,
|
|
1669
|
+
shaderInputs: void 0,
|
|
1670
|
+
pipelineFactory: void 0,
|
|
1671
|
+
shaderFactory: void 0,
|
|
1672
|
+
shaderAssembler: import_shadertools2.ShaderAssembler.getDefaultShaderAssembler(),
|
|
1673
|
+
debugShaders: void 0
|
|
1674
|
+
});
|
|
1675
|
+
function getPlatformInfo(device) {
|
|
1676
|
+
return {
|
|
1677
|
+
type: device.type,
|
|
1678
|
+
shaderLanguage: device.info.shadingLanguage,
|
|
1679
|
+
shaderLanguageVersion: device.info.shadingLanguageVersion,
|
|
1680
|
+
gpu: device.info.gpu,
|
|
1681
|
+
// HACK - we pretend that the DeviceFeatures is a Set, it has a similar API
|
|
1682
|
+
features: device.features
|
|
1683
|
+
};
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
// dist/dynamic-texture/mipmaps.js
|
|
1687
|
+
var RENDER_DIMENSIONS = [
|
|
1688
|
+
"2d",
|
|
1689
|
+
"2d-array",
|
|
1690
|
+
"cube",
|
|
1691
|
+
"cube-array"
|
|
1692
|
+
];
|
|
1693
|
+
var WORKGROUP_SIZE = {
|
|
1694
|
+
x: 4,
|
|
1695
|
+
y: 4,
|
|
1696
|
+
z: 4
|
|
1697
|
+
};
|
|
1698
|
+
function generateMipmap(device, texture) {
|
|
1699
|
+
if (texture.mipLevels <= 1) {
|
|
1700
|
+
return;
|
|
1701
|
+
}
|
|
1702
|
+
if (device.type !== "webgpu") {
|
|
1703
|
+
throw new Error(`Cannot generate mipmaps on device type "${device.type}". Use generateMipmapsWebGL for WebGL devices.`);
|
|
1704
|
+
}
|
|
1705
|
+
if (texture.dimension === "3d") {
|
|
1706
|
+
generateMipmaps3D(device, texture);
|
|
1707
|
+
return;
|
|
1708
|
+
}
|
|
1709
|
+
if (RENDER_DIMENSIONS.includes(texture.dimension)) {
|
|
1710
|
+
generateMipmapsRender(device, texture);
|
|
1711
|
+
return;
|
|
1712
|
+
}
|
|
1713
|
+
throw new Error(`Cannot generate mipmaps for texture dimension "${texture.dimension}" with WebGPU.`);
|
|
1714
|
+
}
|
|
1715
|
+
function generateMipmapsRender(device, texture) {
|
|
1716
|
+
validateFormatCapabilities(device, texture, ["render", "filter"], "render");
|
|
1717
|
+
const colorAttachmentFormat = getColorAttachmentFormat(texture.format, "render", texture.dimension);
|
|
1718
|
+
const viewDimension = texture.dimension;
|
|
1719
|
+
const shader = getRenderMipmapWGSL(viewDimension);
|
|
1720
|
+
const sampler = device.createSampler({ minFilter: "linear", magFilter: "linear" });
|
|
1721
|
+
const uniformValues = new Uint32Array(1);
|
|
1722
|
+
const uniformsBuffer = device.createBuffer({
|
|
1723
|
+
byteLength: 16,
|
|
1724
|
+
usage: import_core10.Buffer.UNIFORM | import_core10.Buffer.COPY_DST
|
|
1725
|
+
});
|
|
1726
|
+
const model = new Model(device, {
|
|
1727
|
+
source: shader,
|
|
1728
|
+
colorAttachmentFormats: [colorAttachmentFormat],
|
|
1729
|
+
topology: "triangle-list",
|
|
1730
|
+
vertexCount: 3,
|
|
1731
|
+
shaderLayout: {
|
|
1732
|
+
attributes: [],
|
|
1733
|
+
bindings: [
|
|
1734
|
+
{ type: "sampler", name: "sourceSampler", group: 0, location: 0 },
|
|
1735
|
+
{
|
|
1736
|
+
type: "texture",
|
|
1737
|
+
name: "sourceTexture",
|
|
1738
|
+
group: 0,
|
|
1739
|
+
location: 1,
|
|
1740
|
+
viewDimension,
|
|
1741
|
+
sampleType: "float"
|
|
1742
|
+
},
|
|
1743
|
+
{ type: "uniform", name: "uniforms", group: 0, location: 2 }
|
|
1744
|
+
]
|
|
1745
|
+
},
|
|
1746
|
+
bindings: {
|
|
1747
|
+
sourceSampler: sampler,
|
|
1748
|
+
sourceTexture: texture,
|
|
1749
|
+
uniforms: uniformsBuffer
|
|
1750
|
+
}
|
|
1751
|
+
});
|
|
1752
|
+
let sourceWidth = texture.width;
|
|
1753
|
+
let sourceHeight = texture.height;
|
|
1754
|
+
const layerCount = texture.dimension === "2d" ? 1 : texture.depth;
|
|
1755
|
+
try {
|
|
1756
|
+
for (let baseMipLevel = 1; baseMipLevel < texture.mipLevels; ++baseMipLevel) {
|
|
1757
|
+
validateFormatCapabilities(device, texture, ["render", "filter"], "render");
|
|
1758
|
+
const sourceMipLevel = baseMipLevel - 1;
|
|
1759
|
+
const destinationWidth = Math.max(1, sourceWidth >> 1);
|
|
1760
|
+
const destinationHeight = Math.max(1, sourceHeight >> 1);
|
|
1761
|
+
const sourceView = texture.createView({
|
|
1762
|
+
dimension: viewDimension,
|
|
1763
|
+
baseMipLevel: sourceMipLevel,
|
|
1764
|
+
mipLevelCount: 1,
|
|
1765
|
+
baseArrayLayer: 0,
|
|
1766
|
+
arrayLayerCount: texture.depth
|
|
1767
|
+
});
|
|
1768
|
+
model.setBindings({ sourceTexture: sourceView });
|
|
1769
|
+
for (let baseArrayLayer = 0; baseArrayLayer < layerCount; ++baseArrayLayer) {
|
|
1770
|
+
uniformValues[0] = baseArrayLayer;
|
|
1771
|
+
uniformsBuffer.write(uniformValues);
|
|
1772
|
+
const destinationView = texture.createView({
|
|
1773
|
+
dimension: "2d",
|
|
1774
|
+
baseMipLevel,
|
|
1775
|
+
mipLevelCount: 1,
|
|
1776
|
+
baseArrayLayer,
|
|
1777
|
+
arrayLayerCount: 1
|
|
1778
|
+
});
|
|
1779
|
+
const framebuffer = device.createFramebuffer({
|
|
1780
|
+
colorAttachments: [destinationView]
|
|
1781
|
+
});
|
|
1782
|
+
const renderPass = device.beginRenderPass({
|
|
1783
|
+
id: `mipmap-generation:${texture.format}:${baseMipLevel}:${baseArrayLayer}`,
|
|
1784
|
+
framebuffer
|
|
1785
|
+
});
|
|
1786
|
+
renderPass.setParameters({
|
|
1787
|
+
viewport: [0, 0, destinationWidth, destinationHeight, 0, 1],
|
|
1788
|
+
scissorRect: [0, 0, destinationWidth, destinationHeight]
|
|
1789
|
+
});
|
|
1790
|
+
model.draw(renderPass);
|
|
1791
|
+
renderPass.end();
|
|
1792
|
+
device.submit();
|
|
1793
|
+
destinationView.destroy();
|
|
1794
|
+
framebuffer.destroy();
|
|
1795
|
+
}
|
|
1796
|
+
sourceView.destroy();
|
|
1797
|
+
sourceWidth = destinationWidth;
|
|
1798
|
+
sourceHeight = destinationHeight;
|
|
1799
|
+
}
|
|
1800
|
+
} finally {
|
|
1801
|
+
model.destroy();
|
|
1802
|
+
sampler.destroy();
|
|
1803
|
+
uniformsBuffer.destroy();
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
function getColorAttachmentFormat(format, path, dimension) {
|
|
1807
|
+
if (import_core10.textureFormatDecoder.isColor(format)) {
|
|
1808
|
+
return format;
|
|
1809
|
+
}
|
|
1810
|
+
throw new Error(`Cannot run ${path} mipmap generation for ${dimension} texture with format "${format}". Only color textures can be used for this operation. Required capabilities: color. Actual capabilities: color=false.`);
|
|
1811
|
+
}
|
|
1812
|
+
function generateMipmaps3D(device, texture) {
|
|
1813
|
+
validateFormatCapabilities(device, texture, ["filter", "store"], "compute");
|
|
1814
|
+
const format = getColorAttachmentFormat(texture.format, "compute", texture.dimension);
|
|
1815
|
+
const shaderSource = get3DComputeMipmapWGSL(format);
|
|
1816
|
+
const uniformsBuffer = device.createBuffer({
|
|
1817
|
+
byteLength: 32,
|
|
1818
|
+
usage: import_core10.Buffer.UNIFORM | import_core10.Buffer.COPY_DST
|
|
1819
|
+
});
|
|
1820
|
+
const uniformValues = new Uint32Array(8);
|
|
1821
|
+
let sourceWidth = texture.width;
|
|
1822
|
+
let sourceHeight = texture.height;
|
|
1823
|
+
let sourceDepth = texture.depth;
|
|
1824
|
+
try {
|
|
1825
|
+
for (let destinationMipLevel = 1; destinationMipLevel < texture.mipLevels; ++destinationMipLevel) {
|
|
1826
|
+
validateFormatCapabilities(device, texture, ["filter", "store"], "compute");
|
|
1827
|
+
const destinationWidth = Math.max(1, sourceWidth >> 1);
|
|
1828
|
+
const destinationHeight = Math.max(1, sourceHeight >> 1);
|
|
1829
|
+
const destinationDepth = Math.max(1, sourceDepth >> 1);
|
|
1830
|
+
uniformValues[0] = sourceWidth;
|
|
1831
|
+
uniformValues[1] = sourceHeight;
|
|
1832
|
+
uniformValues[2] = sourceDepth;
|
|
1833
|
+
uniformValues[3] = destinationWidth;
|
|
1834
|
+
uniformValues[4] = destinationHeight;
|
|
1835
|
+
uniformValues[5] = destinationDepth;
|
|
1836
|
+
uniformValues[6] = 0;
|
|
1837
|
+
uniformsBuffer.write(uniformValues);
|
|
1838
|
+
const sourceView = texture.createView({
|
|
1839
|
+
dimension: "3d",
|
|
1840
|
+
baseMipLevel: destinationMipLevel - 1,
|
|
1841
|
+
mipLevelCount: 1,
|
|
1842
|
+
baseArrayLayer: 0,
|
|
1843
|
+
arrayLayerCount: 1
|
|
1844
|
+
});
|
|
1845
|
+
const destinationView = texture.createView({
|
|
1846
|
+
dimension: "3d",
|
|
1847
|
+
baseMipLevel: destinationMipLevel,
|
|
1848
|
+
mipLevelCount: 1,
|
|
1849
|
+
baseArrayLayer: 0,
|
|
1850
|
+
arrayLayerCount: 1
|
|
1851
|
+
});
|
|
1852
|
+
const computation = new Computation(device, {
|
|
1853
|
+
source: shaderSource,
|
|
1854
|
+
shaderLayout: {
|
|
1855
|
+
bindings: [
|
|
1856
|
+
{
|
|
1857
|
+
type: "texture",
|
|
1858
|
+
name: "sourceTexture",
|
|
1859
|
+
group: 0,
|
|
1860
|
+
location: 0,
|
|
1861
|
+
viewDimension: "3d",
|
|
1862
|
+
sampleType: "float"
|
|
1863
|
+
},
|
|
1864
|
+
{
|
|
1865
|
+
type: "storage",
|
|
1866
|
+
name: "destinationTexture",
|
|
1867
|
+
group: 0,
|
|
1868
|
+
location: 1,
|
|
1869
|
+
format,
|
|
1870
|
+
viewDimension: "3d",
|
|
1871
|
+
access: "write-only"
|
|
1872
|
+
},
|
|
1873
|
+
{ type: "uniform", name: "uniforms", group: 0, location: 2 }
|
|
1874
|
+
]
|
|
1875
|
+
},
|
|
1876
|
+
bindings: {
|
|
1877
|
+
sourceTexture: sourceView,
|
|
1878
|
+
destinationTexture: destinationView,
|
|
1879
|
+
uniforms: uniformsBuffer
|
|
1880
|
+
}
|
|
1881
|
+
});
|
|
1882
|
+
const workgroupsX = Math.ceil(destinationWidth / WORKGROUP_SIZE.x);
|
|
1883
|
+
const workgroupsY = Math.ceil(destinationHeight / WORKGROUP_SIZE.y);
|
|
1884
|
+
const workgroupsZ = Math.ceil(destinationDepth / WORKGROUP_SIZE.z);
|
|
1885
|
+
const computePass = device.beginComputePass({});
|
|
1886
|
+
computation.dispatch(computePass, workgroupsX, workgroupsY, workgroupsZ);
|
|
1887
|
+
computePass.end();
|
|
1888
|
+
device.submit();
|
|
1889
|
+
computation.destroy();
|
|
1890
|
+
sourceView.destroy();
|
|
1891
|
+
destinationView.destroy();
|
|
1892
|
+
sourceWidth = destinationWidth;
|
|
1893
|
+
sourceHeight = destinationHeight;
|
|
1894
|
+
sourceDepth = destinationDepth;
|
|
1895
|
+
}
|
|
1896
|
+
} finally {
|
|
1897
|
+
uniformsBuffer.destroy();
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
function validateFormatCapabilities(device, texture, requiredCapabilities, path) {
|
|
1901
|
+
const { format, dimension } = texture;
|
|
1902
|
+
const capabilities = device.getTextureFormatCapabilities(format);
|
|
1903
|
+
const missingCapabilities = requiredCapabilities.filter((capability) => !capabilities[capability]);
|
|
1904
|
+
if (missingCapabilities.length > 0) {
|
|
1905
|
+
const required = requiredCapabilities.join(" + ");
|
|
1906
|
+
const actual = requiredCapabilities.map((capability) => `${capability}=${capabilities[capability]}`).join(", ");
|
|
1907
|
+
throw new Error(`Cannot run ${path} mipmap generation for ${dimension} texture with format "${format}". Required capabilities: ${required}. Actual capabilities: ${actual}.`);
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
function getSourceTextureType(dimension) {
|
|
1911
|
+
switch (dimension) {
|
|
1912
|
+
case "2d":
|
|
1913
|
+
return "texture_2d<f32>";
|
|
1914
|
+
case "2d-array":
|
|
1915
|
+
return "texture_2d_array<f32>";
|
|
1916
|
+
case "cube":
|
|
1917
|
+
return "texture_cube<f32>";
|
|
1918
|
+
case "cube-array":
|
|
1919
|
+
return "texture_cube_array<f32>";
|
|
1920
|
+
default:
|
|
1921
|
+
throw new Error(`Unsupported render dimension "${dimension}" for mipmap generation.`);
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
function getRenderMipmapWGSL(dimension) {
|
|
1925
|
+
const sourceSnippet = getRenderMipmapSampleSnippet(dimension);
|
|
1926
|
+
return `
|
|
1927
|
+
struct MipmapUniforms {
|
|
1928
|
+
sourceLayer: u32,
|
|
1929
|
+
};
|
|
1930
|
+
|
|
1931
|
+
fn _touchUniform(uniforms: MipmapUniforms) {
|
|
1932
|
+
let unusedSourceLayer = uniforms.sourceLayer;
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1935
|
+
const faceMat = array(
|
|
1936
|
+
mat3x3f(
|
|
1937
|
+
0.0, 0.0, -2.0,
|
|
1938
|
+
0.0, -2.0, 0.0,
|
|
1939
|
+
1.0, 1.0, 1.0
|
|
1940
|
+
), // pos-x
|
|
1941
|
+
mat3x3f(
|
|
1942
|
+
0.0, 0.0, 2.0,
|
|
1943
|
+
0.0, -2.0, 0.0,
|
|
1944
|
+
-1.0, 1.0, -1.0
|
|
1945
|
+
), // neg-x
|
|
1946
|
+
mat3x3f(
|
|
1947
|
+
2.0, 0.0, 0.0,
|
|
1948
|
+
0.0, 0.0, 2.0,
|
|
1949
|
+
-1.0, 1.0, -1.0
|
|
1950
|
+
), // pos-y
|
|
1951
|
+
mat3x3f(
|
|
1952
|
+
2.0, 0.0, 0.0,
|
|
1953
|
+
0.0, 0.0, -2.0,
|
|
1954
|
+
-1.0, -1.0, 1.0
|
|
1955
|
+
), // neg-y
|
|
1956
|
+
mat3x3f(
|
|
1957
|
+
2.0, 0.0, 0.0,
|
|
1958
|
+
0.0, -2.0, 0.0,
|
|
1959
|
+
-1.0, 1.0, 1.0
|
|
1960
|
+
), // pos-z
|
|
1961
|
+
mat3x3f(
|
|
1962
|
+
-2.0, 0.0, 0.0,
|
|
1963
|
+
0.0, -2.0, 0.0,
|
|
1964
|
+
1.0, 1.0, -1.0
|
|
1965
|
+
) // neg-z
|
|
1966
|
+
);
|
|
1967
|
+
|
|
1968
|
+
struct FragmentInputs {
|
|
1969
|
+
@builtin(position) position: vec4f,
|
|
1970
|
+
@location(0) texcoord: vec2f
|
|
1971
|
+
};
|
|
1972
|
+
|
|
1973
|
+
struct VertexOutput {
|
|
1974
|
+
@builtin(position) position: vec4f,
|
|
1975
|
+
@location(0) texcoord: vec2f
|
|
1976
|
+
};
|
|
1977
|
+
|
|
1978
|
+
@group(0) @binding(0) var sourceSampler: sampler;
|
|
1979
|
+
@group(0) @binding(1) var sourceTexture: ${getSourceTextureType(dimension)};
|
|
1980
|
+
@group(0) @binding(2) var<uniform> uniforms: MipmapUniforms;
|
|
1981
|
+
|
|
1982
|
+
@vertex
|
|
1983
|
+
fn vertexMain(
|
|
1984
|
+
@builtin(vertex_index) vertexIndex: u32
|
|
1985
|
+
) -> VertexOutput {
|
|
1986
|
+
const positions = array(
|
|
1987
|
+
vec2f(-1.0, -1.0),
|
|
1988
|
+
vec2f(-1.0, 3.0),
|
|
1989
|
+
vec2f( 3.0, -1.0)
|
|
1990
|
+
);
|
|
1991
|
+
|
|
1992
|
+
let xy = positions[vertexIndex];
|
|
1993
|
+
return VertexOutput(
|
|
1994
|
+
vec4f(xy, 0.0, 1.0),
|
|
1995
|
+
xy * vec2f(0.5, -0.5) + vec2f(0.5)
|
|
1996
|
+
);
|
|
1997
|
+
}
|
|
1998
|
+
|
|
1999
|
+
@fragment
|
|
2000
|
+
fn fragmentMain(fsInput: VertexOutput) -> @location(0) vec4f {
|
|
2001
|
+
_touchUniform(uniforms);
|
|
2002
|
+
return ${sourceSnippet};
|
|
2003
|
+
}
|
|
2004
|
+
`;
|
|
2005
|
+
}
|
|
2006
|
+
function getRenderMipmapSampleSnippet(dimension) {
|
|
2007
|
+
const layer = "uniforms.sourceLayer";
|
|
2008
|
+
switch (dimension) {
|
|
2009
|
+
case "2d":
|
|
2010
|
+
return "textureSampleLevel(sourceTexture, sourceSampler, fsInput.texcoord, 0.0)";
|
|
2011
|
+
case "2d-array":
|
|
2012
|
+
return `textureSampleLevel(sourceTexture, sourceSampler, fsInput.texcoord, i32(${layer}), 0.0)`;
|
|
2013
|
+
case "cube":
|
|
2014
|
+
return `textureSampleLevel(sourceTexture, sourceSampler, faceMat[i32(${layer})] * vec3f(fract(fsInput.texcoord), 1.0), 0.0)`;
|
|
2015
|
+
case "cube-array":
|
|
2016
|
+
return `textureSampleLevel(sourceTexture, sourceSampler, faceMat[i32(${layer} % 6u)] * vec3f(fract(fsInput.texcoord), 1.0), i32(${layer} / 6u), 0.0)`;
|
|
2017
|
+
default:
|
|
2018
|
+
throw new Error(`Unsupported render dimension "${dimension}" for mipmap generation.`);
|
|
2019
|
+
}
|
|
1441
2020
|
}
|
|
1442
|
-
function
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
2021
|
+
function get3DComputeMipmapWGSL(format) {
|
|
2022
|
+
return `
|
|
2023
|
+
struct MipmapUniforms {
|
|
2024
|
+
sourceWidth: u32,
|
|
2025
|
+
sourceHeight: u32,
|
|
2026
|
+
sourceDepth: u32,
|
|
2027
|
+
destinationWidth: u32,
|
|
2028
|
+
destinationHeight: u32,
|
|
2029
|
+
destinationDepth: u32,
|
|
2030
|
+
padding: u32,
|
|
2031
|
+
};
|
|
2032
|
+
|
|
2033
|
+
@group(0) @binding(0) var sourceTexture: texture_3d<f32>;
|
|
2034
|
+
@group(0) @binding(1) var destinationTexture: texture_storage_3d<${format}, write>;
|
|
2035
|
+
@group(0) @binding(2) var<uniform> uniforms: MipmapUniforms;
|
|
2036
|
+
|
|
2037
|
+
@compute @workgroup_size(${WORKGROUP_SIZE.x}, ${WORKGROUP_SIZE.y}, ${WORKGROUP_SIZE.z})
|
|
2038
|
+
fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
2039
|
+
if (
|
|
2040
|
+
id.x >= uniforms.destinationWidth ||
|
|
2041
|
+
id.y >= uniforms.destinationHeight ||
|
|
2042
|
+
id.z >= uniforms.destinationDepth
|
|
2043
|
+
) {
|
|
2044
|
+
return;
|
|
1447
2045
|
}
|
|
1448
|
-
|
|
2046
|
+
|
|
2047
|
+
let sourceBase = id * 2u;
|
|
2048
|
+
let sourceX0 = min(sourceBase.x, uniforms.sourceWidth - 1u);
|
|
2049
|
+
let sourceY0 = min(sourceBase.y, uniforms.sourceHeight - 1u);
|
|
2050
|
+
let sourceZ0 = min(sourceBase.z, uniforms.sourceDepth - 1u);
|
|
2051
|
+
|
|
2052
|
+
let sourceX1 = min(sourceBase.x + 1u, uniforms.sourceWidth - 1u);
|
|
2053
|
+
let sourceY1 = min(sourceBase.y + 1u, uniforms.sourceHeight - 1u);
|
|
2054
|
+
let sourceZ1 = min(sourceBase.z + 1u, uniforms.sourceDepth - 1u);
|
|
2055
|
+
|
|
2056
|
+
var sum = textureLoad(
|
|
2057
|
+
sourceTexture,
|
|
2058
|
+
vec3<i32>(i32(sourceX0), i32(sourceY0), i32(sourceZ0)),
|
|
2059
|
+
0
|
|
2060
|
+
);
|
|
2061
|
+
sum += textureLoad(
|
|
2062
|
+
sourceTexture,
|
|
2063
|
+
vec3<i32>(i32(sourceX1), i32(sourceY0), i32(sourceZ0)),
|
|
2064
|
+
0
|
|
2065
|
+
);
|
|
2066
|
+
sum += textureLoad(
|
|
2067
|
+
sourceTexture,
|
|
2068
|
+
vec3<i32>(i32(sourceX0), i32(sourceY1), i32(sourceZ0)),
|
|
2069
|
+
0
|
|
2070
|
+
);
|
|
2071
|
+
sum += textureLoad(
|
|
2072
|
+
sourceTexture,
|
|
2073
|
+
vec3<i32>(i32(sourceX1), i32(sourceY1), i32(sourceZ0)),
|
|
2074
|
+
0
|
|
2075
|
+
);
|
|
2076
|
+
sum += textureLoad(
|
|
2077
|
+
sourceTexture,
|
|
2078
|
+
vec3<i32>(i32(sourceX0), i32(sourceY0), i32(sourceZ1)),
|
|
2079
|
+
0
|
|
2080
|
+
);
|
|
2081
|
+
sum += textureLoad(
|
|
2082
|
+
sourceTexture,
|
|
2083
|
+
vec3<i32>(i32(sourceX1), i32(sourceY0), i32(sourceZ1)),
|
|
2084
|
+
0
|
|
2085
|
+
);
|
|
2086
|
+
sum += textureLoad(
|
|
2087
|
+
sourceTexture,
|
|
2088
|
+
vec3<i32>(i32(sourceX0), i32(sourceY1), i32(sourceZ1)),
|
|
2089
|
+
0
|
|
2090
|
+
);
|
|
2091
|
+
sum += textureLoad(
|
|
2092
|
+
sourceTexture,
|
|
2093
|
+
vec3<i32>(i32(sourceX1), i32(sourceY1), i32(sourceZ1)),
|
|
2094
|
+
0
|
|
2095
|
+
);
|
|
2096
|
+
|
|
2097
|
+
textureStore(
|
|
2098
|
+
destinationTexture,
|
|
2099
|
+
vec3<i32>(i32(id.x), i32(id.y), i32(id.z)),
|
|
2100
|
+
vec4<f32>(sum.xyz / 8.0, sum.w / 8.0)
|
|
2101
|
+
);
|
|
1449
2102
|
}
|
|
1450
|
-
|
|
1451
|
-
const subresources = [];
|
|
1452
|
-
data.forEach((cubeData, cubeIndex) => {
|
|
1453
|
-
for (const [face, faceData] of Object.entries(cubeData)) {
|
|
1454
|
-
const faceDepth = getCubeArrayFaceIndex(cubeIndex, face);
|
|
1455
|
-
getTexture2DSubresources(faceDepth, faceData);
|
|
1456
|
-
}
|
|
1457
|
-
});
|
|
1458
|
-
return subresources;
|
|
2103
|
+
`;
|
|
1459
2104
|
}
|
|
1460
2105
|
|
|
1461
2106
|
// dist/dynamic-texture/dynamic-texture.js
|
|
@@ -1535,6 +2180,10 @@ var _DynamicTexture = class {
|
|
|
1535
2180
|
// temporary; updated below
|
|
1536
2181
|
data: void 0
|
|
1537
2182
|
};
|
|
2183
|
+
if (this.device.type === "webgpu" && this.props.mipmaps) {
|
|
2184
|
+
const requiredUsage = this.props.dimension === "3d" ? import_core11.Texture.SAMPLE | import_core11.Texture.STORAGE | import_core11.Texture.COPY_DST | import_core11.Texture.COPY_SRC : import_core11.Texture.SAMPLE | import_core11.Texture.RENDER | import_core11.Texture.COPY_DST | import_core11.Texture.COPY_SRC;
|
|
2185
|
+
baseTextureProps.usage |= requiredUsage;
|
|
2186
|
+
}
|
|
1538
2187
|
const maxMips = this.device.getMipLevelCount(baseTextureProps.width, baseTextureProps.height);
|
|
1539
2188
|
const desired = this.props.mipLevels === "auto" ? maxMips : Math.max(1, Math.min(maxMips, this.props.mipLevels ?? 1));
|
|
1540
2189
|
const finalTextureProps = { ...baseTextureProps, mipLevels: desired };
|
|
@@ -1571,7 +2220,7 @@ var _DynamicTexture = class {
|
|
|
1571
2220
|
}
|
|
1572
2221
|
this.isReady = true;
|
|
1573
2222
|
this.resolveReady(this.texture);
|
|
1574
|
-
|
|
2223
|
+
import_core11.log.info(0, `${this} created`)();
|
|
1575
2224
|
} catch (e) {
|
|
1576
2225
|
const err = e instanceof Error ? e : new Error(String(e));
|
|
1577
2226
|
this.rejectReady(err);
|
|
@@ -1590,14 +2239,16 @@ var _DynamicTexture = class {
|
|
|
1590
2239
|
generateMipmaps() {
|
|
1591
2240
|
if (this.device.type === "webgl") {
|
|
1592
2241
|
this.texture.generateMipmapsWebGL();
|
|
2242
|
+
} else if (this.device.type === "webgpu") {
|
|
2243
|
+
generateMipmap(this.device, this.texture);
|
|
1593
2244
|
} else {
|
|
1594
|
-
|
|
2245
|
+
import_core11.log.warn(`${this} mipmaps not supported on ${this.device.type}`);
|
|
1595
2246
|
}
|
|
1596
2247
|
}
|
|
1597
2248
|
/** Set sampler or create one from props */
|
|
1598
2249
|
setSampler(sampler = {}) {
|
|
1599
2250
|
this._checkReady();
|
|
1600
|
-
const s = sampler instanceof
|
|
2251
|
+
const s = sampler instanceof import_core11.Sampler ? sampler : this.device.createSampler(sampler);
|
|
1601
2252
|
this.texture.setSampler(s);
|
|
1602
2253
|
this._sampler = s;
|
|
1603
2254
|
}
|
|
@@ -1615,7 +2266,7 @@ var _DynamicTexture = class {
|
|
|
1615
2266
|
this._sampler = this.texture.sampler;
|
|
1616
2267
|
this._view = this.texture.view;
|
|
1617
2268
|
prev.destroy();
|
|
1618
|
-
|
|
2269
|
+
import_core11.log.info(`${this} resized`);
|
|
1619
2270
|
return true;
|
|
1620
2271
|
}
|
|
1621
2272
|
/** Convert cube face label to texture slice index. Index can be used with `setTexture2DData()`. */
|
|
@@ -1690,7 +2341,15 @@ var _DynamicTexture = class {
|
|
|
1690
2341
|
break;
|
|
1691
2342
|
case "texture-data":
|
|
1692
2343
|
const { data } = subresource;
|
|
1693
|
-
this.texture.
|
|
2344
|
+
this.texture.writeData(getAlignedUploadData(this.texture, data), {
|
|
2345
|
+
x: 0,
|
|
2346
|
+
y: 0,
|
|
2347
|
+
z,
|
|
2348
|
+
width: data.width,
|
|
2349
|
+
height: data.height,
|
|
2350
|
+
depthOrArrayLayers: 1,
|
|
2351
|
+
mipLevel
|
|
2352
|
+
});
|
|
1694
2353
|
break;
|
|
1695
2354
|
default:
|
|
1696
2355
|
throw new Error("Unsupported 2D mip-level payload");
|
|
@@ -1706,22 +2365,39 @@ var _DynamicTexture = class {
|
|
|
1706
2365
|
}
|
|
1707
2366
|
_checkNotDestroyed() {
|
|
1708
2367
|
if (this.destroyed) {
|
|
1709
|
-
|
|
2368
|
+
import_core11.log.warn(`${this} already destroyed`);
|
|
1710
2369
|
}
|
|
1711
2370
|
}
|
|
1712
2371
|
_checkReady() {
|
|
1713
2372
|
if (!this.isReady) {
|
|
1714
|
-
|
|
2373
|
+
import_core11.log.warn(`${this} Cannot perform this operation before ready`);
|
|
1715
2374
|
}
|
|
1716
2375
|
}
|
|
1717
2376
|
};
|
|
1718
2377
|
var DynamicTexture = _DynamicTexture;
|
|
1719
2378
|
__publicField(DynamicTexture, "defaultProps", {
|
|
1720
|
-
...
|
|
2379
|
+
...import_core11.Texture.defaultProps,
|
|
1721
2380
|
dimension: "2d",
|
|
1722
2381
|
data: null,
|
|
1723
2382
|
mipmaps: false
|
|
1724
2383
|
});
|
|
2384
|
+
function getAlignedUploadData(texture, data) {
|
|
2385
|
+
const { width, height, data: uploadData } = data;
|
|
2386
|
+
const { bytesPerPixel } = texture.device.getTextureFormatInfo(texture.format);
|
|
2387
|
+
const bytesPerRow = width * bytesPerPixel;
|
|
2388
|
+
const alignedBytesPerRow = Math.ceil(bytesPerRow / texture.byteAlignment) * texture.byteAlignment;
|
|
2389
|
+
if (alignedBytesPerRow === bytesPerRow) {
|
|
2390
|
+
return uploadData;
|
|
2391
|
+
}
|
|
2392
|
+
const sourceBytes = new Uint8Array(uploadData.buffer, uploadData.byteOffset, uploadData.byteLength);
|
|
2393
|
+
const paddedBytes = new Uint8Array(alignedBytesPerRow * height);
|
|
2394
|
+
for (let row = 0; row < height; row++) {
|
|
2395
|
+
const sourceOffset = row * bytesPerRow;
|
|
2396
|
+
const destinationOffset = row * alignedBytesPerRow;
|
|
2397
|
+
paddedBytes.set(sourceBytes.subarray(sourceOffset, sourceOffset + bytesPerRow), destinationOffset);
|
|
2398
|
+
}
|
|
2399
|
+
return paddedBytes;
|
|
2400
|
+
}
|
|
1725
2401
|
async function awaitAllPromises(x) {
|
|
1726
2402
|
x = await x;
|
|
1727
2403
|
if (Array.isArray(x)) {
|
|
@@ -1741,8 +2417,8 @@ async function awaitAllPromises(x) {
|
|
|
1741
2417
|
}
|
|
1742
2418
|
|
|
1743
2419
|
// dist/model/model.js
|
|
1744
|
-
var
|
|
1745
|
-
var
|
|
2420
|
+
var LOG_DRAW_PRIORITY2 = 2;
|
|
2421
|
+
var LOG_DRAW_TIMEOUT2 = 1e4;
|
|
1746
2422
|
var _Model = class {
|
|
1747
2423
|
/** Device that created this model */
|
|
1748
2424
|
device;
|
|
@@ -1824,7 +2500,7 @@ var _Model = class {
|
|
|
1824
2500
|
const moduleMap = Object.fromEntries(((_a = this.props.modules) == null ? void 0 : _a.map((module2) => [module2.name, module2])) || []);
|
|
1825
2501
|
const shaderInputs = props.shaderInputs || new ShaderInputs(moduleMap, { disableWarnings: this.props.disableWarnings });
|
|
1826
2502
|
this.setShaderInputs(shaderInputs);
|
|
1827
|
-
const platformInfo =
|
|
2503
|
+
const platformInfo = getPlatformInfo2(device);
|
|
1828
2504
|
const modules = (
|
|
1829
2505
|
// @ts-ignore shaderInputs is assigned in setShaderInputs above.
|
|
1830
2506
|
(((_b = this.props.modules) == null ? void 0 : _b.length) > 0 ? this.props.modules : (_c = this.shaderInputs) == null ? void 0 : _c.getModules()) || []
|
|
@@ -1932,7 +2608,7 @@ var _Model = class {
|
|
|
1932
2608
|
draw(renderPass) {
|
|
1933
2609
|
const loadingBinding = this._areBindingsLoading();
|
|
1934
2610
|
if (loadingBinding) {
|
|
1935
|
-
|
|
2611
|
+
import_core12.log.info(LOG_DRAW_PRIORITY2, `>>> DRAWING ABORTED ${this.id}: ${loadingBinding} not loaded`)();
|
|
1936
2612
|
return false;
|
|
1937
2613
|
}
|
|
1938
2614
|
try {
|
|
@@ -2060,7 +2736,7 @@ var _Model = class {
|
|
|
2060
2736
|
/** Set the shader inputs */
|
|
2061
2737
|
setShaderInputs(shaderInputs) {
|
|
2062
2738
|
this.shaderInputs = shaderInputs;
|
|
2063
|
-
this._uniformStore = new
|
|
2739
|
+
this._uniformStore = new import_core12.UniformStore(this.shaderInputs.modules);
|
|
2064
2740
|
for (const [moduleName, module2] of Object.entries(this.shaderInputs.modules)) {
|
|
2065
2741
|
if (shaderModuleHasUniforms(module2)) {
|
|
2066
2742
|
const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
|
|
@@ -2104,7 +2780,7 @@ var _Model = class {
|
|
|
2104
2780
|
setAttributes(buffers, options) {
|
|
2105
2781
|
const disableWarnings = (options == null ? void 0 : options.disableWarnings) ?? this.props.disableWarnings;
|
|
2106
2782
|
if (buffers["indices"]) {
|
|
2107
|
-
|
|
2783
|
+
import_core12.log.warn(`Model:${this.id} setAttributes() - indexBuffer should be set using setIndexBuffer()`)();
|
|
2108
2784
|
}
|
|
2109
2785
|
this.bufferLayout = sortedBufferLayoutByShaderSourceLocations(this.pipeline.shaderLayout, this.bufferLayout);
|
|
2110
2786
|
const bufferLayoutHelper = new BufferLayoutHelper(this.bufferLayout);
|
|
@@ -2112,7 +2788,7 @@ var _Model = class {
|
|
|
2112
2788
|
const bufferLayout = bufferLayoutHelper.getBufferLayout(bufferName);
|
|
2113
2789
|
if (!bufferLayout) {
|
|
2114
2790
|
if (!disableWarnings) {
|
|
2115
|
-
|
|
2791
|
+
import_core12.log.warn(`Model(${this.id}): Missing layout for buffer "${bufferName}".`)();
|
|
2116
2792
|
}
|
|
2117
2793
|
continue;
|
|
2118
2794
|
}
|
|
@@ -2127,7 +2803,7 @@ var _Model = class {
|
|
|
2127
2803
|
}
|
|
2128
2804
|
}
|
|
2129
2805
|
if (!set && !disableWarnings) {
|
|
2130
|
-
|
|
2806
|
+
import_core12.log.warn(`Model(${this.id}): Ignoring buffer "${buffer.id}" for unknown attribute "${bufferName}"`)();
|
|
2131
2807
|
}
|
|
2132
2808
|
}
|
|
2133
2809
|
this.setNeedsRedraw("attributes");
|
|
@@ -2146,7 +2822,7 @@ var _Model = class {
|
|
|
2146
2822
|
if (attributeInfo) {
|
|
2147
2823
|
this.vertexArray.setConstantWebGL(attributeInfo.location, value);
|
|
2148
2824
|
} else if (!((options == null ? void 0 : options.disableWarnings) ?? this.props.disableWarnings)) {
|
|
2149
|
-
|
|
2825
|
+
import_core12.log.warn(`Model "${this.id}: Ignoring constant supplied for unknown attribute "${attributeName}"`)();
|
|
2150
2826
|
}
|
|
2151
2827
|
}
|
|
2152
2828
|
this.setNeedsRedraw("constants");
|
|
@@ -2179,16 +2855,16 @@ var _Model = class {
|
|
|
2179
2855
|
_getBindingsUpdateTimestamp() {
|
|
2180
2856
|
let timestamp = 0;
|
|
2181
2857
|
for (const binding of Object.values(this.bindings)) {
|
|
2182
|
-
if (binding instanceof
|
|
2858
|
+
if (binding instanceof import_core12.TextureView) {
|
|
2183
2859
|
timestamp = Math.max(timestamp, binding.texture.updateTimestamp);
|
|
2184
|
-
} else if (binding instanceof
|
|
2860
|
+
} else if (binding instanceof import_core12.Buffer || binding instanceof import_core12.Texture) {
|
|
2185
2861
|
timestamp = Math.max(timestamp, binding.updateTimestamp);
|
|
2186
2862
|
} else if (binding instanceof DynamicTexture) {
|
|
2187
2863
|
timestamp = binding.texture ? Math.max(timestamp, binding.texture.updateTimestamp) : (
|
|
2188
2864
|
// The texture will become available in the future
|
|
2189
2865
|
Infinity
|
|
2190
2866
|
);
|
|
2191
|
-
} else if (!(binding instanceof
|
|
2867
|
+
} else if (!(binding instanceof import_core12.Sampler)) {
|
|
2192
2868
|
timestamp = Math.max(timestamp, binding.buffer.updateTimestamp);
|
|
2193
2869
|
}
|
|
2194
2870
|
}
|
|
@@ -2223,7 +2899,7 @@ var _Model = class {
|
|
|
2223
2899
|
let prevShaderVs = null;
|
|
2224
2900
|
let prevShaderFs = null;
|
|
2225
2901
|
if (this.pipeline) {
|
|
2226
|
-
|
|
2902
|
+
import_core12.log.log(1, `Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`)();
|
|
2227
2903
|
prevShaderVs = this.pipeline.vs;
|
|
2228
2904
|
prevShaderFs = this.pipeline.fs;
|
|
2229
2905
|
}
|
|
@@ -2256,7 +2932,7 @@ var _Model = class {
|
|
|
2256
2932
|
vs: vs3,
|
|
2257
2933
|
fs: fs3
|
|
2258
2934
|
});
|
|
2259
|
-
this._attributeInfos = (0,
|
|
2935
|
+
this._attributeInfos = (0, import_core12.getAttributeInfosFromLayouts)(this.pipeline.shaderLayout, this.bufferLayout);
|
|
2260
2936
|
if (prevShaderVs)
|
|
2261
2937
|
this.shaderFactory.release(prevShaderVs);
|
|
2262
2938
|
if (prevShaderFs)
|
|
@@ -2268,24 +2944,24 @@ var _Model = class {
|
|
|
2268
2944
|
_lastLogTime = 0;
|
|
2269
2945
|
_logOpen = false;
|
|
2270
2946
|
_logDrawCallStart() {
|
|
2271
|
-
const logDrawTimeout =
|
|
2272
|
-
if (
|
|
2947
|
+
const logDrawTimeout = import_core12.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT2;
|
|
2948
|
+
if (import_core12.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
|
|
2273
2949
|
return;
|
|
2274
2950
|
}
|
|
2275
2951
|
this._lastLogTime = Date.now();
|
|
2276
2952
|
this._logOpen = true;
|
|
2277
|
-
|
|
2953
|
+
import_core12.log.group(LOG_DRAW_PRIORITY2, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core12.log.level <= 2 })();
|
|
2278
2954
|
}
|
|
2279
2955
|
_logDrawCallEnd() {
|
|
2280
2956
|
if (this._logOpen) {
|
|
2281
2957
|
const shaderLayoutTable = getDebugTableForShaderLayout(this.pipeline.shaderLayout, this.id);
|
|
2282
|
-
|
|
2958
|
+
import_core12.log.table(LOG_DRAW_PRIORITY2, shaderLayoutTable)();
|
|
2283
2959
|
const uniformTable = this.shaderInputs.getDebugTable();
|
|
2284
|
-
|
|
2960
|
+
import_core12.log.table(LOG_DRAW_PRIORITY2, uniformTable)();
|
|
2285
2961
|
const attributeTable = this._getAttributeDebugTable();
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2962
|
+
import_core12.log.table(LOG_DRAW_PRIORITY2, this._attributeInfos)();
|
|
2963
|
+
import_core12.log.table(LOG_DRAW_PRIORITY2, attributeTable)();
|
|
2964
|
+
import_core12.log.groupEnd(LOG_DRAW_PRIORITY2)();
|
|
2289
2965
|
this._logOpen = false;
|
|
2290
2966
|
}
|
|
2291
2967
|
}
|
|
@@ -2324,14 +3000,14 @@ var _Model = class {
|
|
|
2324
3000
|
}
|
|
2325
3001
|
// TODO - fix typing of luma data types
|
|
2326
3002
|
_getBufferOrConstantValues(attribute, dataType) {
|
|
2327
|
-
const TypedArrayConstructor = (0,
|
|
2328
|
-
const typedArray = attribute instanceof
|
|
3003
|
+
const TypedArrayConstructor = (0, import_core12.getTypedArrayConstructor)(dataType);
|
|
3004
|
+
const typedArray = attribute instanceof import_core12.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
|
|
2329
3005
|
return typedArray.toString();
|
|
2330
3006
|
}
|
|
2331
3007
|
};
|
|
2332
3008
|
var Model = _Model;
|
|
2333
3009
|
__publicField(Model, "defaultProps", {
|
|
2334
|
-
...
|
|
3010
|
+
...import_core12.RenderPipeline.defaultProps,
|
|
2335
3011
|
source: void 0,
|
|
2336
3012
|
vs: null,
|
|
2337
3013
|
fs: null,
|
|
@@ -2352,14 +3028,14 @@ __publicField(Model, "defaultProps", {
|
|
|
2352
3028
|
pipelineFactory: void 0,
|
|
2353
3029
|
shaderFactory: void 0,
|
|
2354
3030
|
transformFeedback: void 0,
|
|
2355
|
-
shaderAssembler:
|
|
3031
|
+
shaderAssembler: import_shadertools3.ShaderAssembler.getDefaultShaderAssembler(),
|
|
2356
3032
|
debugShaders: void 0,
|
|
2357
3033
|
disableWarnings: void 0
|
|
2358
3034
|
});
|
|
2359
3035
|
function shaderModuleHasUniforms(module2) {
|
|
2360
3036
|
return Boolean(module2.uniformTypes && !isObjectEmpty(module2.uniformTypes));
|
|
2361
3037
|
}
|
|
2362
|
-
function
|
|
3038
|
+
function getPlatformInfo2(device) {
|
|
2363
3039
|
return {
|
|
2364
3040
|
type: device.type,
|
|
2365
3041
|
shaderLanguage: device.info.shadingLanguage,
|
|
@@ -2377,8 +3053,8 @@ function isObjectEmpty(obj) {
|
|
|
2377
3053
|
}
|
|
2378
3054
|
|
|
2379
3055
|
// dist/compute/buffer-transform.js
|
|
2380
|
-
var
|
|
2381
|
-
var
|
|
3056
|
+
var import_core13 = require("@luma.gl/core");
|
|
3057
|
+
var import_shadertools4 = require("@luma.gl/shadertools");
|
|
2382
3058
|
var _BufferTransform = class {
|
|
2383
3059
|
device;
|
|
2384
3060
|
model;
|
|
@@ -2394,7 +3070,7 @@ var _BufferTransform = class {
|
|
|
2394
3070
|
this.device = device;
|
|
2395
3071
|
this.model = new Model(this.device, {
|
|
2396
3072
|
id: props.id || "buffer-transform-model",
|
|
2397
|
-
fs: props.fs || (0,
|
|
3073
|
+
fs: props.fs || (0, import_shadertools4.getPassthroughFS)(),
|
|
2398
3074
|
topology: props.topology || "point-list",
|
|
2399
3075
|
varyings: props.outputs || props.varyings,
|
|
2400
3076
|
...props
|
|
@@ -2440,7 +3116,7 @@ var _BufferTransform = class {
|
|
|
2440
3116
|
if (!result) {
|
|
2441
3117
|
throw new Error("BufferTransform#getBuffer");
|
|
2442
3118
|
}
|
|
2443
|
-
if (result instanceof
|
|
3119
|
+
if (result instanceof import_core13.Buffer) {
|
|
2444
3120
|
return result.readAsync();
|
|
2445
3121
|
}
|
|
2446
3122
|
const { buffer, byteOffset = 0, byteLength = buffer.byteLength } = result;
|
|
@@ -2455,7 +3131,7 @@ __publicField(BufferTransform, "defaultProps", {
|
|
|
2455
3131
|
});
|
|
2456
3132
|
|
|
2457
3133
|
// dist/compute/texture-transform.js
|
|
2458
|
-
var
|
|
3134
|
+
var import_shadertools5 = require("@luma.gl/shadertools");
|
|
2459
3135
|
var FS_OUTPUT_VARIABLE = "transform_output";
|
|
2460
3136
|
var TextureTransform = class {
|
|
2461
3137
|
device;
|
|
@@ -2478,7 +3154,7 @@ var TextureTransform = class {
|
|
|
2478
3154
|
});
|
|
2479
3155
|
this.model = new Model(this.device, {
|
|
2480
3156
|
id: props.id || uid("texture-transform-model"),
|
|
2481
|
-
fs: props.fs || (0,
|
|
3157
|
+
fs: props.fs || (0, import_shadertools5.getPassthroughFS)({
|
|
2482
3158
|
input: props.targetTextureVarying,
|
|
2483
3159
|
inputChannels: props.targetTextureChannels,
|
|
2484
3160
|
output: FS_OUTPUT_VARIABLE
|
|
@@ -2838,14 +3514,14 @@ var BackgroundTextureModel = class extends ClipSpace {
|
|
|
2838
3514
|
};
|
|
2839
3515
|
|
|
2840
3516
|
// dist/scenegraph/scenegraph-node.js
|
|
2841
|
-
var
|
|
3517
|
+
var import_core14 = require("@math.gl/core");
|
|
2842
3518
|
var ScenegraphNode = class {
|
|
2843
3519
|
id;
|
|
2844
|
-
matrix = new
|
|
3520
|
+
matrix = new import_core14.Matrix4();
|
|
2845
3521
|
display = true;
|
|
2846
|
-
position = new
|
|
2847
|
-
rotation = new
|
|
2848
|
-
scale = new
|
|
3522
|
+
position = new import_core14.Vector3();
|
|
3523
|
+
rotation = new import_core14.Vector3();
|
|
3524
|
+
scale = new import_core14.Vector3(1, 1, 1);
|
|
2849
3525
|
userData = {};
|
|
2850
3526
|
props = {};
|
|
2851
3527
|
constructor(props = {}) {
|
|
@@ -2930,7 +3606,7 @@ var ScenegraphNode = class {
|
|
|
2930
3606
|
}
|
|
2931
3607
|
getCoordinateUniforms(viewMatrix, modelMatrix) {
|
|
2932
3608
|
modelMatrix = modelMatrix || this.matrix;
|
|
2933
|
-
const worldMatrix = new
|
|
3609
|
+
const worldMatrix = new import_core14.Matrix4(viewMatrix).multiplyRight(modelMatrix);
|
|
2934
3610
|
const worldInverse = worldMatrix.invert();
|
|
2935
3611
|
const worldInverseTranspose = worldInverse.transpose();
|
|
2936
3612
|
return {
|
|
@@ -2982,14 +3658,14 @@ var ScenegraphNode = class {
|
|
|
2982
3658
|
};
|
|
2983
3659
|
|
|
2984
3660
|
// dist/scenegraph/group-node.js
|
|
2985
|
-
var
|
|
2986
|
-
var
|
|
3661
|
+
var import_core15 = require("@math.gl/core");
|
|
3662
|
+
var import_core16 = require("@luma.gl/core");
|
|
2987
3663
|
var GroupNode = class extends ScenegraphNode {
|
|
2988
3664
|
children;
|
|
2989
3665
|
constructor(props = {}) {
|
|
2990
3666
|
props = Array.isArray(props) ? { children: props } : props;
|
|
2991
3667
|
const { children = [] } = props;
|
|
2992
|
-
|
|
3668
|
+
import_core16.log.assert(children.every((child) => child instanceof ScenegraphNode), "every child must an instance of ScenegraphNode");
|
|
2993
3669
|
super(props);
|
|
2994
3670
|
this.children = children;
|
|
2995
3671
|
}
|
|
@@ -3004,12 +3680,12 @@ var GroupNode = class extends ScenegraphNode {
|
|
|
3004
3680
|
return;
|
|
3005
3681
|
}
|
|
3006
3682
|
const [min, max] = bounds;
|
|
3007
|
-
const center = new
|
|
3683
|
+
const center = new import_core15.Vector3(min).add(max).divide([2, 2, 2]);
|
|
3008
3684
|
worldMatrix.transformAsPoint(center, center);
|
|
3009
|
-
const halfSize = new
|
|
3685
|
+
const halfSize = new import_core15.Vector3(max).subtract(min).divide([2, 2, 2]);
|
|
3010
3686
|
worldMatrix.transformAsVector(halfSize, halfSize);
|
|
3011
3687
|
for (let v = 0; v < 8; v++) {
|
|
3012
|
-
const position = new
|
|
3688
|
+
const position = new import_core15.Vector3(v & 1 ? -1 : 1, v & 2 ? -1 : 1, v & 4 ? -1 : 1).multiply(halfSize).add(center);
|
|
3013
3689
|
for (let i = 0; i < 3; i++) {
|
|
3014
3690
|
result[0][i] = Math.min(result[0][i], position[i]);
|
|
3015
3691
|
result[1][i] = Math.max(result[1][i], position[i]);
|
|
@@ -3049,8 +3725,8 @@ var GroupNode = class extends ScenegraphNode {
|
|
|
3049
3725
|
this.children = [];
|
|
3050
3726
|
return this;
|
|
3051
3727
|
}
|
|
3052
|
-
traverse(visitor, { worldMatrix = new
|
|
3053
|
-
const modelMatrix = new
|
|
3728
|
+
traverse(visitor, { worldMatrix = new import_core15.Matrix4() } = {}) {
|
|
3729
|
+
const modelMatrix = new import_core15.Matrix4(worldMatrix).multiplyRight(this.matrix);
|
|
3054
3730
|
for (const child of this.children) {
|
|
3055
3731
|
if (child instanceof GroupNode) {
|
|
3056
3732
|
child.traverse(visitor, { worldMatrix: modelMatrix });
|
|
@@ -3832,7 +4508,7 @@ var CylinderGeometry = class extends TruncatedConeGeometry {
|
|
|
3832
4508
|
};
|
|
3833
4509
|
|
|
3834
4510
|
// dist/geometries/ico-sphere-geometry.js
|
|
3835
|
-
var
|
|
4511
|
+
var import_core17 = require("@math.gl/core");
|
|
3836
4512
|
var ICO_POSITIONS = [-1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 1, 0, -1, 0, 1, 0, 0];
|
|
3837
4513
|
var ICO_INDICES = [3, 4, 5, 3, 5, 1, 3, 1, 0, 3, 0, 4, 4, 0, 2, 4, 2, 5, 2, 0, 1, 5, 2, 1];
|
|
3838
4514
|
var IcoSphereGeometry = class extends Geometry {
|
|
@@ -3930,7 +4606,7 @@ function tesselateIcosaHedron(props) {
|
|
|
3930
4606
|
const u3 = 1 - phi3 / PI2;
|
|
3931
4607
|
const vec1 = [x3 - x2, y3 - y2, z3 - z2];
|
|
3932
4608
|
const vec2 = [x1 - x2, y1 - y2, z1 - z2];
|
|
3933
|
-
const normal = new
|
|
4609
|
+
const normal = new import_core17.Vector3(vec1).cross(vec2).normalize();
|
|
3934
4610
|
let newIndex;
|
|
3935
4611
|
if ((u1 === 0 || u2 === 0 || u3 === 0) && (u1 === 0 || u1 > 0.5) && (u2 === 0 || u2 > 0.5) && (u3 === 0 || u3 > 0.5)) {
|
|
3936
4612
|
positions.push(positions[in1 + 0], positions[in1 + 1], positions[in1 + 2]);
|
|
@@ -4217,10 +4893,10 @@ async function loadImage(url, opts) {
|
|
|
4217
4893
|
}
|
|
4218
4894
|
|
|
4219
4895
|
// dist/passes/shader-pass-renderer.js
|
|
4220
|
-
var
|
|
4896
|
+
var import_shadertools6 = require("@luma.gl/shadertools");
|
|
4221
4897
|
|
|
4222
4898
|
// dist/compute/swap.js
|
|
4223
|
-
var
|
|
4899
|
+
var import_core18 = require("@luma.gl/core");
|
|
4224
4900
|
var Swap = class {
|
|
4225
4901
|
id;
|
|
4226
4902
|
/** The current resource - usually the source for renders or computations */
|
|
@@ -4253,7 +4929,7 @@ var SwapFramebuffers = class extends Swap {
|
|
|
4253
4929
|
let colorAttachments = (_a = props.colorAttachments) == null ? void 0 : _a.map((colorAttachment) => typeof colorAttachment !== "string" ? colorAttachment : device.createTexture({
|
|
4254
4930
|
id: `${props.id}-texture-0`,
|
|
4255
4931
|
format: colorAttachment,
|
|
4256
|
-
usage:
|
|
4932
|
+
usage: import_core18.Texture.SAMPLE | import_core18.Texture.RENDER | import_core18.Texture.COPY_SRC | import_core18.Texture.COPY_DST,
|
|
4257
4933
|
width,
|
|
4258
4934
|
height
|
|
4259
4935
|
}));
|
|
@@ -4261,7 +4937,7 @@ var SwapFramebuffers = class extends Swap {
|
|
|
4261
4937
|
colorAttachments = (_b = props.colorAttachments) == null ? void 0 : _b.map((colorAttachment) => typeof colorAttachment !== "string" ? colorAttachment : device.createTexture({
|
|
4262
4938
|
id: `${props.id}-texture-1`,
|
|
4263
4939
|
format: colorAttachment,
|
|
4264
|
-
usage:
|
|
4940
|
+
usage: import_core18.Texture.SAMPLE | import_core18.Texture.RENDER | import_core18.Texture.COPY_SRC | import_core18.Texture.COPY_DST,
|
|
4265
4941
|
width,
|
|
4266
4942
|
height
|
|
4267
4943
|
}));
|
|
@@ -4432,7 +5108,7 @@ var ShaderPassRenderer = class {
|
|
|
4432
5108
|
textureModel;
|
|
4433
5109
|
constructor(device, props) {
|
|
4434
5110
|
this.device = device;
|
|
4435
|
-
props.shaderPasses.map((shaderPass) => (0,
|
|
5111
|
+
props.shaderPasses.map((shaderPass) => (0, import_shadertools6.initializeShaderModule)(shaderPass));
|
|
4436
5112
|
const modules = props.shaderPasses.reduce((object, shaderPass) => ({ ...object, [shaderPass.name]: shaderPass }), {});
|
|
4437
5113
|
this.shaderInputs = props.shaderInputs || new ShaderInputs(modules);
|
|
4438
5114
|
const size = device.getCanvasContext().getDrawingBufferSize();
|
|
@@ -4604,218 +5280,6 @@ var SubPassRenderer = class {
|
|
|
4604
5280
|
}
|
|
4605
5281
|
};
|
|
4606
5282
|
|
|
4607
|
-
// dist/compute/computation.js
|
|
4608
|
-
var import_core17 = require("@luma.gl/core");
|
|
4609
|
-
var import_shadertools6 = require("@luma.gl/shadertools");
|
|
4610
|
-
var import_types2 = require("@math.gl/types");
|
|
4611
|
-
var LOG_DRAW_PRIORITY2 = 2;
|
|
4612
|
-
var LOG_DRAW_TIMEOUT2 = 1e4;
|
|
4613
|
-
var _Computation = class {
|
|
4614
|
-
device;
|
|
4615
|
-
id;
|
|
4616
|
-
pipelineFactory;
|
|
4617
|
-
shaderFactory;
|
|
4618
|
-
userData = {};
|
|
4619
|
-
/** Bindings (textures, samplers, uniform buffers) */
|
|
4620
|
-
bindings = {};
|
|
4621
|
-
/** The underlying GPU pipeline. */
|
|
4622
|
-
pipeline;
|
|
4623
|
-
/** Assembled compute shader source */
|
|
4624
|
-
source;
|
|
4625
|
-
/** the underlying compiled compute shader */
|
|
4626
|
-
// @ts-ignore Set in function called from constructor
|
|
4627
|
-
shader;
|
|
4628
|
-
/** ShaderInputs instance */
|
|
4629
|
-
shaderInputs;
|
|
4630
|
-
// @ts-ignore Set in function called from constructor
|
|
4631
|
-
_uniformStore;
|
|
4632
|
-
_pipelineNeedsUpdate = "newly created";
|
|
4633
|
-
_getModuleUniforms;
|
|
4634
|
-
props;
|
|
4635
|
-
_destroyed = false;
|
|
4636
|
-
constructor(device, props) {
|
|
4637
|
-
var _a, _b, _c;
|
|
4638
|
-
if (device.type !== "webgpu") {
|
|
4639
|
-
throw new Error("Computation is only supported in WebGPU");
|
|
4640
|
-
}
|
|
4641
|
-
this.props = { ..._Computation.defaultProps, ...props };
|
|
4642
|
-
props = this.props;
|
|
4643
|
-
this.id = props.id || uid("model");
|
|
4644
|
-
this.device = device;
|
|
4645
|
-
Object.assign(this.userData, props.userData);
|
|
4646
|
-
const moduleMap = Object.fromEntries(((_a = this.props.modules) == null ? void 0 : _a.map((module2) => [module2.name, module2])) || []);
|
|
4647
|
-
this.shaderInputs = props.shaderInputs || new ShaderInputs(moduleMap);
|
|
4648
|
-
this.setShaderInputs(this.shaderInputs);
|
|
4649
|
-
this.props.shaderLayout ||= device.getShaderLayout(this.props.source);
|
|
4650
|
-
const platformInfo = getPlatformInfo2(device);
|
|
4651
|
-
const modules = (((_b = this.props.modules) == null ? void 0 : _b.length) > 0 ? this.props.modules : (_c = this.shaderInputs) == null ? void 0 : _c.getModules()) || [];
|
|
4652
|
-
this.pipelineFactory = props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device);
|
|
4653
|
-
this.shaderFactory = props.shaderFactory || ShaderFactory.getDefaultShaderFactory(this.device);
|
|
4654
|
-
const { source: source3, getUniforms: getUniforms2 } = this.props.shaderAssembler.assembleWGSLShader({
|
|
4655
|
-
platformInfo,
|
|
4656
|
-
...this.props,
|
|
4657
|
-
modules
|
|
4658
|
-
});
|
|
4659
|
-
this.source = source3;
|
|
4660
|
-
this._getModuleUniforms = getUniforms2;
|
|
4661
|
-
this.pipeline = this._updatePipeline();
|
|
4662
|
-
if (props.bindings) {
|
|
4663
|
-
this.setBindings(props.bindings);
|
|
4664
|
-
}
|
|
4665
|
-
Object.seal(this);
|
|
4666
|
-
}
|
|
4667
|
-
destroy() {
|
|
4668
|
-
if (this._destroyed)
|
|
4669
|
-
return;
|
|
4670
|
-
this.pipelineFactory.release(this.pipeline);
|
|
4671
|
-
this.shaderFactory.release(this.shader);
|
|
4672
|
-
this._uniformStore.destroy();
|
|
4673
|
-
this._destroyed = true;
|
|
4674
|
-
}
|
|
4675
|
-
// Draw call
|
|
4676
|
-
predraw() {
|
|
4677
|
-
this.updateShaderInputs();
|
|
4678
|
-
}
|
|
4679
|
-
dispatch(computePass, x, y, z) {
|
|
4680
|
-
try {
|
|
4681
|
-
this._logDrawCallStart();
|
|
4682
|
-
this.pipeline = this._updatePipeline();
|
|
4683
|
-
this.pipeline.setBindings(this.bindings);
|
|
4684
|
-
computePass.setPipeline(this.pipeline);
|
|
4685
|
-
computePass.setBindings([]);
|
|
4686
|
-
computePass.dispatch(x, y, z);
|
|
4687
|
-
} finally {
|
|
4688
|
-
this._logDrawCallEnd();
|
|
4689
|
-
}
|
|
4690
|
-
}
|
|
4691
|
-
// Update fixed fields (can trigger pipeline rebuild)
|
|
4692
|
-
// Update dynamic fields
|
|
4693
|
-
/**
|
|
4694
|
-
* Updates the vertex count (used in draw calls)
|
|
4695
|
-
* @note Any attributes with stepMode=vertex need to be at least this big
|
|
4696
|
-
*/
|
|
4697
|
-
setVertexCount(vertexCount) {
|
|
4698
|
-
}
|
|
4699
|
-
/**
|
|
4700
|
-
* Updates the instance count (used in draw calls)
|
|
4701
|
-
* @note Any attributes with stepMode=instance need to be at least this big
|
|
4702
|
-
*/
|
|
4703
|
-
setInstanceCount(instanceCount) {
|
|
4704
|
-
}
|
|
4705
|
-
setShaderInputs(shaderInputs) {
|
|
4706
|
-
this.shaderInputs = shaderInputs;
|
|
4707
|
-
this._uniformStore = new import_core17.UniformStore(this.shaderInputs.modules);
|
|
4708
|
-
for (const moduleName of Object.keys(this.shaderInputs.modules)) {
|
|
4709
|
-
const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
|
|
4710
|
-
this.bindings[`${moduleName}Uniforms`] = uniformBuffer;
|
|
4711
|
-
}
|
|
4712
|
-
}
|
|
4713
|
-
/**
|
|
4714
|
-
* Updates shader module settings (which results in uniforms being set)
|
|
4715
|
-
*/
|
|
4716
|
-
setShaderModuleProps(props) {
|
|
4717
|
-
const uniforms = this._getModuleUniforms(props);
|
|
4718
|
-
const keys = Object.keys(uniforms).filter((k) => {
|
|
4719
|
-
const uniform = uniforms[k];
|
|
4720
|
-
return !(0, import_types2.isNumericArray)(uniform) && typeof uniform !== "number" && typeof uniform !== "boolean";
|
|
4721
|
-
});
|
|
4722
|
-
const bindings = {};
|
|
4723
|
-
for (const k of keys) {
|
|
4724
|
-
bindings[k] = uniforms[k];
|
|
4725
|
-
delete uniforms[k];
|
|
4726
|
-
}
|
|
4727
|
-
}
|
|
4728
|
-
updateShaderInputs() {
|
|
4729
|
-
this._uniformStore.setUniforms(this.shaderInputs.getUniformValues());
|
|
4730
|
-
}
|
|
4731
|
-
/**
|
|
4732
|
-
* Sets bindings (textures, samplers, uniform buffers)
|
|
4733
|
-
*/
|
|
4734
|
-
setBindings(bindings) {
|
|
4735
|
-
Object.assign(this.bindings, bindings);
|
|
4736
|
-
}
|
|
4737
|
-
_setPipelineNeedsUpdate(reason) {
|
|
4738
|
-
this._pipelineNeedsUpdate = this._pipelineNeedsUpdate || reason;
|
|
4739
|
-
}
|
|
4740
|
-
_updatePipeline() {
|
|
4741
|
-
if (this._pipelineNeedsUpdate) {
|
|
4742
|
-
let prevShader = null;
|
|
4743
|
-
if (this.pipeline) {
|
|
4744
|
-
import_core17.log.log(1, `Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`)();
|
|
4745
|
-
prevShader = this.shader;
|
|
4746
|
-
}
|
|
4747
|
-
this._pipelineNeedsUpdate = false;
|
|
4748
|
-
this.shader = this.shaderFactory.createShader({
|
|
4749
|
-
id: `${this.id}-fragment`,
|
|
4750
|
-
stage: "compute",
|
|
4751
|
-
source: this.source,
|
|
4752
|
-
debugShaders: this.props.debugShaders
|
|
4753
|
-
});
|
|
4754
|
-
this.pipeline = this.pipelineFactory.createComputePipeline({
|
|
4755
|
-
...this.props,
|
|
4756
|
-
shader: this.shader
|
|
4757
|
-
});
|
|
4758
|
-
if (prevShader) {
|
|
4759
|
-
this.shaderFactory.release(prevShader);
|
|
4760
|
-
}
|
|
4761
|
-
}
|
|
4762
|
-
return this.pipeline;
|
|
4763
|
-
}
|
|
4764
|
-
/** Throttle draw call logging */
|
|
4765
|
-
_lastLogTime = 0;
|
|
4766
|
-
_logOpen = false;
|
|
4767
|
-
_logDrawCallStart() {
|
|
4768
|
-
const logDrawTimeout = import_core17.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT2;
|
|
4769
|
-
if (import_core17.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
|
|
4770
|
-
return;
|
|
4771
|
-
}
|
|
4772
|
-
this._lastLogTime = Date.now();
|
|
4773
|
-
this._logOpen = true;
|
|
4774
|
-
import_core17.log.group(LOG_DRAW_PRIORITY2, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core17.log.level <= 2 })();
|
|
4775
|
-
}
|
|
4776
|
-
_logDrawCallEnd() {
|
|
4777
|
-
if (this._logOpen) {
|
|
4778
|
-
const uniformTable = this.shaderInputs.getDebugTable();
|
|
4779
|
-
import_core17.log.table(LOG_DRAW_PRIORITY2, uniformTable)();
|
|
4780
|
-
import_core17.log.groupEnd(LOG_DRAW_PRIORITY2)();
|
|
4781
|
-
this._logOpen = false;
|
|
4782
|
-
}
|
|
4783
|
-
}
|
|
4784
|
-
_drawCount = 0;
|
|
4785
|
-
// TODO - fix typing of luma data types
|
|
4786
|
-
_getBufferOrConstantValues(attribute, dataType) {
|
|
4787
|
-
const TypedArrayConstructor = (0, import_core17.getTypedArrayConstructor)(dataType);
|
|
4788
|
-
const typedArray = attribute instanceof import_core17.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
|
|
4789
|
-
return typedArray.toString();
|
|
4790
|
-
}
|
|
4791
|
-
};
|
|
4792
|
-
var Computation = _Computation;
|
|
4793
|
-
__publicField(Computation, "defaultProps", {
|
|
4794
|
-
...import_core17.ComputePipeline.defaultProps,
|
|
4795
|
-
id: "unnamed",
|
|
4796
|
-
handle: void 0,
|
|
4797
|
-
userData: {},
|
|
4798
|
-
source: "",
|
|
4799
|
-
modules: [],
|
|
4800
|
-
defines: {},
|
|
4801
|
-
bindings: void 0,
|
|
4802
|
-
shaderInputs: void 0,
|
|
4803
|
-
pipelineFactory: void 0,
|
|
4804
|
-
shaderFactory: void 0,
|
|
4805
|
-
shaderAssembler: import_shadertools6.ShaderAssembler.getDefaultShaderAssembler(),
|
|
4806
|
-
debugShaders: void 0
|
|
4807
|
-
});
|
|
4808
|
-
function getPlatformInfo2(device) {
|
|
4809
|
-
return {
|
|
4810
|
-
type: device.type,
|
|
4811
|
-
shaderLanguage: device.info.shadingLanguage,
|
|
4812
|
-
shaderLanguageVersion: device.info.shadingLanguageVersion,
|
|
4813
|
-
gpu: device.info.gpu,
|
|
4814
|
-
// HACK - we pretend that the DeviceFeatures is a Set, it has a similar API
|
|
4815
|
-
features: device.features
|
|
4816
|
-
};
|
|
4817
|
-
}
|
|
4818
|
-
|
|
4819
5283
|
// dist/modules/picking/picking-uniforms.js
|
|
4820
5284
|
var DEFAULT_HIGHLIGHT_COLOR = [0, 1, 1, 1];
|
|
4821
5285
|
var INVALID_INDEX = -1;
|