@plasius/gpu-renderer 0.2.41 → 0.2.43
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 +40 -0
- package/README.md +14 -0
- package/dist/index.cjs +232 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +232 -41
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.d.ts +24 -0
- package/src/wavefront-compute.js +27 -46
- package/src/wavefront-config.js +161 -23
- package/src/wavefront-frame-telemetry.js +5 -1
- package/src/wavefront-runtime-support.js +73 -3
package/dist/index.js
CHANGED
|
@@ -4438,6 +4438,13 @@ function dispatchWavefrontGpuAccelerationBuild({
|
|
|
4438
4438
|
}
|
|
4439
4439
|
|
|
4440
4440
|
// src/wavefront-config.js
|
|
4441
|
+
var WEBGPU_DEFAULT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT = 256;
|
|
4442
|
+
function allocatedRecordBytes(count, recordBytes) {
|
|
4443
|
+
return Math.max(1, count) * recordBytes;
|
|
4444
|
+
}
|
|
4445
|
+
function alignByteSize(value, alignment) {
|
|
4446
|
+
return Math.ceil(value / alignment) * alignment;
|
|
4447
|
+
}
|
|
4441
4448
|
function resolveEnvironmentLighting(input, environmentColor, ambientColor) {
|
|
4442
4449
|
const source = input ?? {};
|
|
4443
4450
|
return Object.freeze({
|
|
@@ -4614,6 +4621,18 @@ function resolveCamera(input, width, height) {
|
|
|
4614
4621
|
});
|
|
4615
4622
|
}
|
|
4616
4623
|
function estimateWavefrontPathTracingMemory(options = {}) {
|
|
4624
|
+
const width = readPositiveInteger2("width", options.width, DEFAULT_WIDTH);
|
|
4625
|
+
const height = readPositiveInteger2("height", options.height, DEFAULT_HEIGHT);
|
|
4626
|
+
const tileSize = readPositiveInteger2("tileSize", options.tileSize, DEFAULT_TILE_SIZE);
|
|
4627
|
+
const samplesPerPixel = clamp2(
|
|
4628
|
+
readPositiveInteger2(
|
|
4629
|
+
"samplesPerPixel",
|
|
4630
|
+
options.samplesPerPixel,
|
|
4631
|
+
DEFAULT_SAMPLES_PER_PIXEL
|
|
4632
|
+
),
|
|
4633
|
+
1,
|
|
4634
|
+
MAX_SAMPLES_PER_PIXEL
|
|
4635
|
+
);
|
|
4617
4636
|
const tilePixelCapacity = readPositiveInteger2(
|
|
4618
4637
|
"tilePixelCapacity",
|
|
4619
4638
|
options.tilePixelCapacity,
|
|
@@ -4646,18 +4665,89 @@ function estimateWavefrontPathTracingMemory(options = {}) {
|
|
|
4646
4665
|
options.environmentPortalCapacity,
|
|
4647
4666
|
0
|
|
4648
4667
|
);
|
|
4649
|
-
|
|
4668
|
+
readNonNegativeInteger2("materialCapacity", options.materialCapacity, 0);
|
|
4669
|
+
const meshVertexCount = readNonNegativeInteger2(
|
|
4670
|
+
"meshVertexCount",
|
|
4671
|
+
options.meshVertexCount,
|
|
4672
|
+
0
|
|
4673
|
+
);
|
|
4674
|
+
const meshIndexCount = readNonNegativeInteger2(
|
|
4675
|
+
"meshIndexCount",
|
|
4676
|
+
options.meshIndexCount,
|
|
4677
|
+
0
|
|
4678
|
+
);
|
|
4679
|
+
const meshRangeCount = readNonNegativeInteger2(
|
|
4680
|
+
"meshRangeCount",
|
|
4681
|
+
options.meshRangeCount,
|
|
4682
|
+
0
|
|
4683
|
+
);
|
|
4684
|
+
const bvhSortStageCount = readNonNegativeInteger2(
|
|
4685
|
+
"bvhSortStageCount",
|
|
4686
|
+
options.bvhSortStageCount,
|
|
4687
|
+
0
|
|
4688
|
+
);
|
|
4689
|
+
const bvhBuildLevelCount = readNonNegativeInteger2(
|
|
4690
|
+
"bvhBuildLevelCount",
|
|
4691
|
+
options.bvhBuildLevelCount,
|
|
4692
|
+
0
|
|
4693
|
+
);
|
|
4694
|
+
const minUniformBufferOffsetAlignment = readPositiveInteger2(
|
|
4695
|
+
"minUniformBufferOffsetAlignment",
|
|
4696
|
+
options.minUniformBufferOffsetAlignment,
|
|
4697
|
+
WEBGPU_DEFAULT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT
|
|
4698
|
+
);
|
|
4699
|
+
const denoise = options.denoise !== false;
|
|
4700
|
+
const deferredPathResolve = options.deferredPathResolve !== false;
|
|
4650
4701
|
const queueBytes = tilePixelCapacity * RAY_RECORD_BYTES;
|
|
4651
4702
|
const hitBytes = tilePixelCapacity * HIT_RECORD_BYTES;
|
|
4652
4703
|
const accumulationBytes = tilePixelCapacity * ACCUMULATION_RECORD_BYTES;
|
|
4653
4704
|
const pathVertexBytes = tilePixelCapacity * (maxDepth + 1) * PATH_VERTEX_RECORD_BYTES;
|
|
4654
4705
|
const sceneObjectBytes = sceneObjectCapacity * SCENE_OBJECT_RECORD_BYTES;
|
|
4655
|
-
const triangleBytes = triangleCapacity
|
|
4656
|
-
const materialTableBytes =
|
|
4706
|
+
const triangleBytes = allocatedRecordBytes(triangleCapacity, TRIANGLE_RECORD_BYTES);
|
|
4707
|
+
const materialTableBytes = 0;
|
|
4657
4708
|
const bvhNodeBytes = bvhNodeCapacity * BVH_NODE_RECORD_BYTES;
|
|
4658
|
-
const bvhLeafReferenceBytes =
|
|
4709
|
+
const bvhLeafReferenceBytes = allocatedRecordBytes(
|
|
4710
|
+
bvhLeafSortCapacity,
|
|
4711
|
+
BVH_LEAF_REF_RECORD_BYTES
|
|
4712
|
+
);
|
|
4659
4713
|
const emissiveTriangleMetadataBytes = emissiveTriangleCapacity * BVH_NODE_RECORD_BYTES;
|
|
4660
|
-
const
|
|
4714
|
+
const bvhCombinedBytes = allocatedRecordBytes(
|
|
4715
|
+
bvhNodeCapacity + emissiveTriangleCapacity,
|
|
4716
|
+
BVH_NODE_RECORD_BYTES
|
|
4717
|
+
);
|
|
4718
|
+
const meshVertexBytes = allocatedRecordBytes(meshVertexCount, MESH_VERTEX_RECORD_BYTES);
|
|
4719
|
+
const meshIndexBytes = allocatedRecordBytes(meshIndexCount, 4);
|
|
4720
|
+
const meshRangeBytes = allocatedRecordBytes(meshRangeCount, MESH_RANGE_RECORD_BYTES);
|
|
4721
|
+
const environmentPortalBytes = allocatedRecordBytes(
|
|
4722
|
+
environmentPortalCapacity,
|
|
4723
|
+
ENVIRONMENT_PORTAL_RECORD_BYTES
|
|
4724
|
+
);
|
|
4725
|
+
const tileCount = Math.ceil(width / tileSize) * Math.ceil(height / tileSize);
|
|
4726
|
+
const outputConfigSlotCount = deferredPathResolve ? 0 : tileCount;
|
|
4727
|
+
const frameConfigSlotCount = Math.max(
|
|
4728
|
+
1,
|
|
4729
|
+
tileCount * samplesPerPixel + outputConfigSlotCount + (denoise ? 1 : 0)
|
|
4730
|
+
);
|
|
4731
|
+
const configBufferStride = alignByteSize(
|
|
4732
|
+
CONFIG_BUFFER_BYTES,
|
|
4733
|
+
minUniformBufferOffsetAlignment
|
|
4734
|
+
);
|
|
4735
|
+
const frameConfigBytes = frameConfigSlotCount * configBufferStride;
|
|
4736
|
+
const bvhBuildConfigBytes = Math.max(
|
|
4737
|
+
1,
|
|
4738
|
+
1 + bvhSortStageCount + bvhBuildLevelCount
|
|
4739
|
+
) * configBufferStride;
|
|
4740
|
+
const sceneStorageBufferBindingBytes = Math.max(
|
|
4741
|
+
sceneObjectBytes,
|
|
4742
|
+
triangleBytes,
|
|
4743
|
+
bvhCombinedBytes,
|
|
4744
|
+
meshVertexBytes,
|
|
4745
|
+
meshIndexBytes,
|
|
4746
|
+
meshRangeBytes,
|
|
4747
|
+
environmentPortalBytes,
|
|
4748
|
+
bvhLeafReferenceBytes
|
|
4749
|
+
);
|
|
4750
|
+
const totalHotBufferBytes = queueBytes * 2 + hitBytes + accumulationBytes + pathVertexBytes + sceneObjectBytes + triangleBytes + bvhCombinedBytes + meshVertexBytes + meshIndexBytes + meshRangeBytes + bvhLeafReferenceBytes + environmentPortalBytes + frameConfigBytes + bvhBuildConfigBytes + COUNTER_BUFFER_BYTES + INDIRECT_DISPATCH_ARGS_BYTES;
|
|
4661
4751
|
return Object.freeze({
|
|
4662
4752
|
queueBytes,
|
|
4663
4753
|
queuePairBytes: queueBytes * 2,
|
|
@@ -4668,13 +4758,45 @@ function estimateWavefrontPathTracingMemory(options = {}) {
|
|
|
4668
4758
|
triangleBytes,
|
|
4669
4759
|
materialTableBytes,
|
|
4670
4760
|
bvhNodeBytes,
|
|
4761
|
+
bvhCombinedBytes,
|
|
4671
4762
|
bvhLeafReferenceBytes,
|
|
4672
4763
|
emissiveTriangleMetadataBytes,
|
|
4764
|
+
meshVertexBytes,
|
|
4765
|
+
meshIndexBytes,
|
|
4766
|
+
meshRangeBytes,
|
|
4673
4767
|
environmentPortalBytes,
|
|
4674
4768
|
configBytes: CONFIG_BUFFER_BYTES,
|
|
4769
|
+
configBufferStride,
|
|
4770
|
+
frameConfigBytes,
|
|
4771
|
+
bvhBuildConfigBytes,
|
|
4675
4772
|
counterBytes: COUNTER_BUFFER_BYTES,
|
|
4676
4773
|
indirectDispatchBytes: INDIRECT_DISPATCH_ARGS_BYTES,
|
|
4677
|
-
|
|
4774
|
+
sceneStorageBufferBindingBytes,
|
|
4775
|
+
totalHotBufferBytes
|
|
4776
|
+
});
|
|
4777
|
+
}
|
|
4778
|
+
function estimateWavefrontPathTracingMemoryForConfig(config, limits = {}) {
|
|
4779
|
+
return estimateWavefrontPathTracingMemory({
|
|
4780
|
+
width: config.width,
|
|
4781
|
+
height: config.height,
|
|
4782
|
+
tileSize: config.tileSize,
|
|
4783
|
+
samplesPerPixel: config.samplesPerPixel,
|
|
4784
|
+
tilePixelCapacity: config.tilePixelCapacity,
|
|
4785
|
+
maxDepth: config.maxDepth,
|
|
4786
|
+
sceneObjectCapacity: config.sceneObjectCapacity,
|
|
4787
|
+
triangleCapacity: config.triangleCapacity,
|
|
4788
|
+
bvhNodeCapacity: config.bvhNodeCapacity,
|
|
4789
|
+
bvhLeafSortCapacity: config.bvhLeafSortCapacity,
|
|
4790
|
+
emissiveTriangleCapacity: config.emissiveTriangleCapacity,
|
|
4791
|
+
environmentPortalCapacity: config.environmentPortalCapacity,
|
|
4792
|
+
meshVertexCount: config.gpuMeshSource.vertices.count,
|
|
4793
|
+
meshIndexCount: config.gpuMeshSource.indices.count,
|
|
4794
|
+
meshRangeCount: config.gpuMeshSource.meshes.count,
|
|
4795
|
+
bvhSortStageCount: config.bvhSortStages.length,
|
|
4796
|
+
bvhBuildLevelCount: config.bvhBuildLevels.length,
|
|
4797
|
+
denoise: config.denoise,
|
|
4798
|
+
deferredPathResolve: config.deferredPathResolve,
|
|
4799
|
+
minUniformBufferOffsetAlignment: limits.minUniformBufferOffsetAlignment ?? WEBGPU_DEFAULT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT
|
|
4678
4800
|
});
|
|
4679
4801
|
}
|
|
4680
4802
|
function createWavefrontPathTracingComputeConfig(options = {}) {
|
|
@@ -4819,15 +4941,25 @@ function createWavefrontPathTracingComputeConfig(options = {}) {
|
|
|
4819
4941
|
denoise: options.denoise !== false,
|
|
4820
4942
|
frameIndex: readNonNegativeInteger2("frameIndex", options.frameIndex, 0),
|
|
4821
4943
|
memory: estimateWavefrontPathTracingMemory({
|
|
4944
|
+
width,
|
|
4945
|
+
height,
|
|
4946
|
+
tileSize,
|
|
4947
|
+
samplesPerPixel,
|
|
4822
4948
|
tilePixelCapacity,
|
|
4823
4949
|
maxDepth,
|
|
4824
4950
|
sceneObjectCapacity,
|
|
4825
4951
|
triangleCapacity,
|
|
4826
|
-
materialCapacity: gpuMaterialSource.count,
|
|
4827
4952
|
bvhNodeCapacity,
|
|
4828
4953
|
bvhLeafSortCapacity,
|
|
4829
4954
|
emissiveTriangleCapacity: emissiveTriangleIndices.capacity,
|
|
4830
|
-
environmentPortalCapacity
|
|
4955
|
+
environmentPortalCapacity,
|
|
4956
|
+
meshVertexCount: gpuMeshSource.vertices.count,
|
|
4957
|
+
meshIndexCount: gpuMeshSource.indices.count,
|
|
4958
|
+
meshRangeCount: gpuMeshSource.meshes.count,
|
|
4959
|
+
bvhSortStageCount: bvhSortStages.length,
|
|
4960
|
+
bvhBuildLevelCount: bvhBuildLevels.length,
|
|
4961
|
+
denoise: options.denoise !== false,
|
|
4962
|
+
deferredPathResolve
|
|
4831
4963
|
})
|
|
4832
4964
|
});
|
|
4833
4965
|
}
|
|
@@ -5672,6 +5804,32 @@ function createWavefrontPresentBindGroup({
|
|
|
5672
5804
|
}
|
|
5673
5805
|
|
|
5674
5806
|
// src/wavefront-runtime-support.js
|
|
5807
|
+
var WEBGPU_DEFAULT_MAX_STORAGE_BUFFER_BINDING_SIZE = 128 * 1024 * 1024;
|
|
5808
|
+
var WEBGPU_DEFAULT_MAX_BUFFER_SIZE = 256 * 1024 * 1024;
|
|
5809
|
+
function readRequestedDeviceLimit(source, name) {
|
|
5810
|
+
const rawValue = source?.[name];
|
|
5811
|
+
if (rawValue === void 0 || rawValue === null) {
|
|
5812
|
+
return 0;
|
|
5813
|
+
}
|
|
5814
|
+
const value = Number(rawValue);
|
|
5815
|
+
if (!Number.isSafeInteger(value) || value < 0) {
|
|
5816
|
+
throw new Error(`${name} must be a non-negative safe integer.`);
|
|
5817
|
+
}
|
|
5818
|
+
return value;
|
|
5819
|
+
}
|
|
5820
|
+
function assertAdapterSupportsRequiredLimit(adapter, name, requiredValue) {
|
|
5821
|
+
const availableValue = Number(adapter?.limits?.[name]);
|
|
5822
|
+
if (!Number.isFinite(availableValue)) {
|
|
5823
|
+
throw new Error(
|
|
5824
|
+
`Wavefront scene buffers require ${name}>=${requiredValue} bytes, but this adapter does not expose that limit.`
|
|
5825
|
+
);
|
|
5826
|
+
}
|
|
5827
|
+
if (availableValue < requiredValue) {
|
|
5828
|
+
throw new Error(
|
|
5829
|
+
`Wavefront scene buffers require ${name}>=${requiredValue} bytes, but this adapter exposes ${availableValue} bytes.`
|
|
5830
|
+
);
|
|
5831
|
+
}
|
|
5832
|
+
}
|
|
5675
5833
|
function getGpuUsageConstants() {
|
|
5676
5834
|
if (typeof GPUBufferUsage === "undefined" || typeof GPUTextureUsage === "undefined" || typeof GPUShaderStage === "undefined") {
|
|
5677
5835
|
throw new Error("WebGPU runtime unavailable. Required GPU constants are missing.");
|
|
@@ -5769,8 +5927,13 @@ async function createRenderPipeline(device, descriptor) {
|
|
|
5769
5927
|
}
|
|
5770
5928
|
return device.createRenderPipeline(descriptor);
|
|
5771
5929
|
}
|
|
5772
|
-
function createWavefrontDeviceDescriptor(adapter, options = {}) {
|
|
5773
|
-
const
|
|
5930
|
+
function createWavefrontDeviceDescriptor(adapter, options = {}, memory = null) {
|
|
5931
|
+
const descriptor = { ...options.deviceDescriptor ?? {} };
|
|
5932
|
+
const descriptorRequiredLimits = { ...descriptor.requiredLimits ?? {} };
|
|
5933
|
+
const requiredLimits = {
|
|
5934
|
+
...descriptorRequiredLimits,
|
|
5935
|
+
...options.requiredLimits ?? {}
|
|
5936
|
+
};
|
|
5774
5937
|
const exposedStorageBufferLimit = Number(adapter?.limits?.maxStorageBuffersPerShaderStage);
|
|
5775
5938
|
if (Number.isFinite(exposedStorageBufferLimit)) {
|
|
5776
5939
|
if (exposedStorageBufferLimit < TRACE_STORAGE_BUFFER_BINDINGS) {
|
|
@@ -5795,7 +5958,32 @@ function createWavefrontDeviceDescriptor(adapter, options = {}) {
|
|
|
5795
5958
|
TRACE_SAMPLED_TEXTURE_BINDINGS
|
|
5796
5959
|
);
|
|
5797
5960
|
}
|
|
5798
|
-
const
|
|
5961
|
+
const sceneStorageBufferBindingBytes = Number(
|
|
5962
|
+
memory?.sceneStorageBufferBindingBytes ?? 0
|
|
5963
|
+
);
|
|
5964
|
+
const requestedStorageBufferBindingSize = Math.max(
|
|
5965
|
+
readRequestedDeviceLimit(descriptorRequiredLimits, "maxStorageBufferBindingSize"),
|
|
5966
|
+
readRequestedDeviceLimit(options.requiredLimits, "maxStorageBufferBindingSize"),
|
|
5967
|
+
sceneStorageBufferBindingBytes > WEBGPU_DEFAULT_MAX_STORAGE_BUFFER_BINDING_SIZE ? sceneStorageBufferBindingBytes : 0
|
|
5968
|
+
);
|
|
5969
|
+
if (requestedStorageBufferBindingSize > 0) {
|
|
5970
|
+
assertAdapterSupportsRequiredLimit(
|
|
5971
|
+
adapter,
|
|
5972
|
+
"maxStorageBufferBindingSize",
|
|
5973
|
+
requestedStorageBufferBindingSize
|
|
5974
|
+
);
|
|
5975
|
+
requiredLimits.maxStorageBufferBindingSize = requestedStorageBufferBindingSize;
|
|
5976
|
+
}
|
|
5977
|
+
const requestedMaxBufferSize = Math.max(
|
|
5978
|
+
readRequestedDeviceLimit(descriptorRequiredLimits, "maxBufferSize"),
|
|
5979
|
+
readRequestedDeviceLimit(options.requiredLimits, "maxBufferSize"),
|
|
5980
|
+
sceneStorageBufferBindingBytes > WEBGPU_DEFAULT_MAX_BUFFER_SIZE ? sceneStorageBufferBindingBytes : 0,
|
|
5981
|
+
requestedStorageBufferBindingSize > WEBGPU_DEFAULT_MAX_BUFFER_SIZE ? requestedStorageBufferBindingSize : 0
|
|
5982
|
+
);
|
|
5983
|
+
if (requestedMaxBufferSize > 0) {
|
|
5984
|
+
assertAdapterSupportsRequiredLimit(adapter, "maxBufferSize", requestedMaxBufferSize);
|
|
5985
|
+
requiredLimits.maxBufferSize = requestedMaxBufferSize;
|
|
5986
|
+
}
|
|
5799
5987
|
const requiredFeatures = Array.from(descriptor.requiredFeatures ?? []);
|
|
5800
5988
|
const adapterFeatures = adapter?.features;
|
|
5801
5989
|
const timestampQuerySupported = typeof adapterFeatures?.has === "function" ? adapterFeatures.has("timestamp-query") : adapterFeatures && typeof adapterFeatures[Symbol.iterator] === "function" ? Array.from(adapterFeatures).includes("timestamp-query") : false;
|
|
@@ -5846,7 +6034,8 @@ function createGpuAdapterParallelismDiagnostics(adapter, device) {
|
|
|
5846
6034
|
maxComputeWorkgroupSizeZ: readGpuLimit(adapter, device, "maxComputeWorkgroupSizeZ"),
|
|
5847
6035
|
maxComputeWorkgroupsPerDimension: readGpuLimit(adapter, device, "maxComputeWorkgroupsPerDimension"),
|
|
5848
6036
|
maxStorageBuffersPerShaderStage: readGpuLimit(adapter, device, "maxStorageBuffersPerShaderStage"),
|
|
5849
|
-
maxStorageBufferBindingSize: readGpuLimit(adapter, device, "maxStorageBufferBindingSize")
|
|
6037
|
+
maxStorageBufferBindingSize: readGpuLimit(adapter, device, "maxStorageBufferBindingSize"),
|
|
6038
|
+
maxBufferSize: readGpuLimit(adapter, device, "maxBufferSize")
|
|
5850
6039
|
}),
|
|
5851
6040
|
configuredWorkgroupSize: WORKGROUP_SIZE
|
|
5852
6041
|
});
|
|
@@ -6256,7 +6445,11 @@ function createWavefrontFrameTelemetryResources({
|
|
|
6256
6445
|
const rayCounts = new Uint32Array(rayCopy, 0, recordCount);
|
|
6257
6446
|
rayCountReadbackBuffer.unmap();
|
|
6258
6447
|
rayReadbackMapped = false;
|
|
6259
|
-
|
|
6448
|
+
let maximumBounceIndex = 0;
|
|
6449
|
+
for (const bounceIndex of bounceIndices) {
|
|
6450
|
+
maximumBounceIndex = Math.max(maximumBounceIndex, bounceIndex);
|
|
6451
|
+
}
|
|
6452
|
+
const bounceHistogram = Array.from({ length: maximumBounceIndex + 1 }, () => 0);
|
|
6260
6453
|
let observedPrimaryRays = 0;
|
|
6261
6454
|
let secondaryRays = 0;
|
|
6262
6455
|
let totalPathSegments = 0;
|
|
@@ -11148,7 +11341,9 @@ async function createWavefrontPathTracingComputeRenderer(options = {}) {
|
|
|
11148
11341
|
if (!adapter) {
|
|
11149
11342
|
throw new Error("Unable to acquire a WebGPU adapter for wavefront path tracing.");
|
|
11150
11343
|
}
|
|
11151
|
-
const device = await adapter.requestDevice(
|
|
11344
|
+
const device = await adapter.requestDevice(
|
|
11345
|
+
createWavefrontDeviceDescriptor(adapter, options, initialConfig.memory)
|
|
11346
|
+
);
|
|
11152
11347
|
const gpuAdapterParallelism = createGpuAdapterParallelismDiagnostics(adapter, device);
|
|
11153
11348
|
const context = canvas.getContext("webgpu");
|
|
11154
11349
|
if (!context || typeof context.configure !== "function") {
|
|
@@ -11166,6 +11361,10 @@ async function createWavefrontPathTracingComputeRenderer(options = {}) {
|
|
|
11166
11361
|
tileSize: safeTileSize
|
|
11167
11362
|
});
|
|
11168
11363
|
}
|
|
11364
|
+
config = Object.freeze({
|
|
11365
|
+
...config,
|
|
11366
|
+
memory: estimateWavefrontPathTracingMemoryForConfig(config, device.limits)
|
|
11367
|
+
});
|
|
11169
11368
|
canvas.width = config.width;
|
|
11170
11369
|
canvas.height = config.height;
|
|
11171
11370
|
context.configure({
|
|
@@ -11174,79 +11373,72 @@ async function createWavefrontPathTracingComputeRenderer(options = {}) {
|
|
|
11174
11373
|
alphaMode: options.alpha === true ? "premultiplied" : "opaque"
|
|
11175
11374
|
});
|
|
11176
11375
|
const bufferUsage = constants.buffer.STORAGE | constants.buffer.COPY_DST;
|
|
11177
|
-
const
|
|
11178
|
-
const
|
|
11179
|
-
const
|
|
11180
|
-
const
|
|
11181
|
-
const activeQueue = createBuffer(device, bufferUsage, rayQueueBytes, "plasius.wavefront.activeQueue");
|
|
11182
|
-
const nextQueue = createBuffer(device, bufferUsage, rayQueueBytes, "plasius.wavefront.nextQueue");
|
|
11183
|
-
const hitBuffer = createBuffer(device, bufferUsage, hitBytes, "plasius.wavefront.hitBuffer");
|
|
11376
|
+
const memory = config.memory;
|
|
11377
|
+
const activeQueue = createBuffer(device, bufferUsage, memory.queueBytes, "plasius.wavefront.activeQueue");
|
|
11378
|
+
const nextQueue = createBuffer(device, bufferUsage, memory.queueBytes, "plasius.wavefront.nextQueue");
|
|
11379
|
+
const hitBuffer = createBuffer(device, bufferUsage, memory.hitBytes, "plasius.wavefront.hitBuffer");
|
|
11184
11380
|
const accumulationBuffer = createBuffer(
|
|
11185
11381
|
device,
|
|
11186
11382
|
bufferUsage,
|
|
11187
|
-
accumulationBytes,
|
|
11383
|
+
memory.accumulationBytes,
|
|
11188
11384
|
"plasius.wavefront.accumulation"
|
|
11189
11385
|
);
|
|
11190
11386
|
const pathVertexBuffer = createBuffer(
|
|
11191
11387
|
device,
|
|
11192
11388
|
bufferUsage,
|
|
11193
|
-
pathVertexBytes,
|
|
11389
|
+
memory.pathVertexBytes,
|
|
11194
11390
|
"plasius.wavefront.pathVertices"
|
|
11195
11391
|
);
|
|
11196
11392
|
const sceneObjectBuffer = createBuffer(
|
|
11197
11393
|
device,
|
|
11198
11394
|
constants.buffer.STORAGE | constants.buffer.COPY_DST,
|
|
11199
|
-
|
|
11395
|
+
memory.sceneObjectBytes,
|
|
11200
11396
|
"plasius.wavefront.sceneObjects"
|
|
11201
11397
|
);
|
|
11202
11398
|
const triangleBuffer = createBuffer(
|
|
11203
11399
|
device,
|
|
11204
11400
|
constants.buffer.STORAGE | constants.buffer.COPY_DST,
|
|
11205
|
-
|
|
11401
|
+
memory.triangleBytes,
|
|
11206
11402
|
"plasius.wavefront.triangles"
|
|
11207
11403
|
);
|
|
11208
11404
|
const bvhNodeBuffer = createBuffer(
|
|
11209
11405
|
device,
|
|
11210
11406
|
constants.buffer.STORAGE | constants.buffer.COPY_DST,
|
|
11211
|
-
|
|
11407
|
+
memory.bvhCombinedBytes,
|
|
11212
11408
|
"plasius.wavefront.bvhNodes"
|
|
11213
11409
|
);
|
|
11214
11410
|
const meshVertexBuffer = createBuffer(
|
|
11215
11411
|
device,
|
|
11216
11412
|
constants.buffer.STORAGE | constants.buffer.COPY_DST,
|
|
11217
|
-
|
|
11413
|
+
memory.meshVertexBytes,
|
|
11218
11414
|
"plasius.wavefront.meshVertices"
|
|
11219
11415
|
);
|
|
11220
11416
|
const meshIndexBuffer = createBuffer(
|
|
11221
11417
|
device,
|
|
11222
11418
|
constants.buffer.STORAGE | constants.buffer.COPY_DST,
|
|
11223
|
-
|
|
11419
|
+
memory.meshIndexBytes,
|
|
11224
11420
|
"plasius.wavefront.meshIndices"
|
|
11225
11421
|
);
|
|
11226
11422
|
const meshRangeBuffer = createBuffer(
|
|
11227
11423
|
device,
|
|
11228
11424
|
constants.buffer.STORAGE | constants.buffer.COPY_DST,
|
|
11229
|
-
|
|
11425
|
+
memory.meshRangeBytes,
|
|
11230
11426
|
"plasius.wavefront.meshRanges"
|
|
11231
11427
|
);
|
|
11232
11428
|
const environmentPortalBuffer = createBuffer(
|
|
11233
11429
|
device,
|
|
11234
11430
|
constants.buffer.STORAGE | constants.buffer.COPY_DST,
|
|
11235
|
-
|
|
11431
|
+
memory.environmentPortalBytes,
|
|
11236
11432
|
"plasius.wavefront.environmentPortals"
|
|
11237
11433
|
);
|
|
11238
11434
|
const bvhLeafRefBuffer = createBuffer(
|
|
11239
11435
|
device,
|
|
11240
11436
|
constants.buffer.STORAGE | constants.buffer.COPY_DST,
|
|
11241
|
-
|
|
11437
|
+
memory.bvhLeafReferenceBytes,
|
|
11242
11438
|
"plasius.wavefront.bvhLeafRefs"
|
|
11243
11439
|
);
|
|
11244
11440
|
const tiles = createTiles(config.width, config.height, config.tileSize);
|
|
11245
|
-
const
|
|
11246
|
-
const configBufferStride = alignTo(
|
|
11247
|
-
CONFIG_BUFFER_BYTES,
|
|
11248
|
-
Number.isFinite(uniformOffsetAlignment) && uniformOffsetAlignment > 0 ? uniformOffsetAlignment : CONFIG_BUFFER_BYTES
|
|
11249
|
-
);
|
|
11441
|
+
const configBufferStride = memory.configBufferStride;
|
|
11250
11442
|
const outputConfigSlotCount = config.deferredPathResolve ? 0 : tiles.length;
|
|
11251
11443
|
const frameConfigSlotCount = Math.max(
|
|
11252
11444
|
1,
|
|
@@ -11255,26 +11447,25 @@ async function createWavefrontPathTracingComputeRenderer(options = {}) {
|
|
|
11255
11447
|
const configBuffer = createBuffer(
|
|
11256
11448
|
device,
|
|
11257
11449
|
constants.buffer.UNIFORM | constants.buffer.COPY_DST,
|
|
11258
|
-
|
|
11450
|
+
memory.frameConfigBytes,
|
|
11259
11451
|
"plasius.wavefront.frameConfig"
|
|
11260
11452
|
);
|
|
11261
|
-
const bvhBuildConfigSlots = 1 + config.bvhSortStages.length + config.bvhBuildLevels.length;
|
|
11262
11453
|
const bvhBuildConfigBuffer = createBuffer(
|
|
11263
11454
|
device,
|
|
11264
11455
|
constants.buffer.UNIFORM | constants.buffer.COPY_DST,
|
|
11265
|
-
|
|
11456
|
+
memory.bvhBuildConfigBytes,
|
|
11266
11457
|
"plasius.wavefront.bvhBuildConfig"
|
|
11267
11458
|
);
|
|
11268
11459
|
const counterBuffer = createBuffer(
|
|
11269
11460
|
device,
|
|
11270
11461
|
constants.buffer.STORAGE | constants.buffer.COPY_DST | constants.buffer.COPY_SRC,
|
|
11271
|
-
|
|
11462
|
+
memory.counterBytes,
|
|
11272
11463
|
"plasius.wavefront.counters"
|
|
11273
11464
|
);
|
|
11274
11465
|
const activeDispatchBuffer = createBuffer(
|
|
11275
11466
|
device,
|
|
11276
11467
|
constants.buffer.INDIRECT | constants.buffer.COPY_DST,
|
|
11277
|
-
|
|
11468
|
+
memory.indirectDispatchBytes,
|
|
11278
11469
|
"plasius.wavefront.activeDispatchArgs"
|
|
11279
11470
|
);
|
|
11280
11471
|
let packedScene = packWavefrontSceneObjects(config.sceneObjects, config.sceneObjectCapacity);
|