@plasius/gpu-renderer 0.1.15 → 0.2.0
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 +5 -3
- package/README.md +8 -0
- package/dist/index.cjs +251 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +248 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.d.ts +78 -0
- package/src/index.js +3 -0
- package/src/wavefront-compute.js +280 -0
package/CHANGELOG.md
CHANGED
|
@@ -23,10 +23,12 @@ All notable changes to this project will be documented in this file.
|
|
|
23
23
|
- **Security**
|
|
24
24
|
- (placeholder)
|
|
25
25
|
|
|
26
|
-
## [0.
|
|
26
|
+
## [0.2.0] - 2026-06-05
|
|
27
27
|
|
|
28
28
|
- **Added**
|
|
29
|
-
-
|
|
29
|
+
- Added deterministic wavefront reference helpers for primary-ray creation,
|
|
30
|
+
triangle-hit evaluation, nearest-hit selection, and environment-miss
|
|
31
|
+
fallback alongside regression tests for task-level acceptance coverage.
|
|
30
32
|
|
|
31
33
|
- **Changed**
|
|
32
34
|
- (placeholder)
|
|
@@ -287,4 +289,4 @@ All notable changes to this project will be documented in this file.
|
|
|
287
289
|
[0.1.11]: https://github.com/Plasius-LTD/gpu-renderer/releases/tag/v0.1.11
|
|
288
290
|
[0.1.12]: https://github.com/Plasius-LTD/gpu-renderer/releases/tag/v0.1.12
|
|
289
291
|
[0.1.14]: https://github.com/Plasius-LTD/gpu-renderer/releases/tag/v0.1.14
|
|
290
|
-
[0.
|
|
292
|
+
[0.2.0]: https://github.com/Plasius-LTD/gpu-renderer/releases/tag/v0.2.0
|
package/README.md
CHANGED
|
@@ -242,6 +242,9 @@ renderer.bindXrManager(xr, {
|
|
|
242
242
|
- `createRayTracingRenderPlan(options)`
|
|
243
243
|
- `createWavefrontPathTracingComputeRenderer(options)`
|
|
244
244
|
- `createWavefrontPathTracingComputeConfig(options)`
|
|
245
|
+
- `createWavefrontReferenceRay(config, options?)`
|
|
246
|
+
- `intersectWavefrontReferenceTriangle(ray, triangle, options?)`
|
|
247
|
+
- `traceWavefrontReferenceTriangles(config, ray, triangles, options?)`
|
|
245
248
|
- `normalizeWavefrontMesh(input)`
|
|
246
249
|
- `createWavefrontGpuMeshSource(meshes)`
|
|
247
250
|
- `createWavefrontBvhSortStages(itemCount)`
|
|
@@ -260,6 +263,11 @@ renderer.bindXrManager(xr, {
|
|
|
260
263
|
- `rendererWorkerProfileNames`
|
|
261
264
|
- `rendererWorkerManifests`
|
|
262
265
|
|
|
266
|
+
The reference helpers mirror the renderer WGSL camera and triangle-hit math in
|
|
267
|
+
deterministic JavaScript so tests and downstream tooling can validate primary
|
|
268
|
+
ray generation, barycentrics, nearest-hit selection, and environment misses
|
|
269
|
+
without standing up a WebGPU device.
|
|
270
|
+
|
|
263
271
|
## Demo
|
|
264
272
|
|
|
265
273
|
Run the demo server from the repo root:
|
package/dist/index.cjs
CHANGED
|
@@ -32,11 +32,13 @@ __export(index_exports, {
|
|
|
32
32
|
createWavefrontPathTracingComputeConfig: () => createWavefrontPathTracingComputeConfig,
|
|
33
33
|
createWavefrontPathTracingComputeRenderer: () => createWavefrontPathTracingComputeRenderer,
|
|
34
34
|
createWavefrontPathTracingPlan: () => createWavefrontPathTracingPlan,
|
|
35
|
+
createWavefrontReferenceRay: () => createWavefrontReferenceRay,
|
|
35
36
|
defaultRendererClearColor: () => defaultRendererClearColor,
|
|
36
37
|
defaultRendererWorkerProfile: () => defaultRendererWorkerProfile,
|
|
37
38
|
estimateWavefrontPathTracingMemory: () => estimateWavefrontPathTracingMemory,
|
|
38
39
|
getRendererWorkerManifest: () => getRendererWorkerManifest,
|
|
39
40
|
getRendererWorkerProfile: () => getRendererWorkerProfile,
|
|
41
|
+
intersectWavefrontReferenceTriangle: () => intersectWavefrontReferenceTriangle,
|
|
40
42
|
normalizeWavefrontMesh: () => normalizeWavefrontMesh,
|
|
41
43
|
normalizeWavefrontSceneObject: () => normalizeWavefrontSceneObject,
|
|
42
44
|
packWavefrontBvhNodes: () => packWavefrontBvhNodes,
|
|
@@ -56,6 +58,7 @@ __export(index_exports, {
|
|
|
56
58
|
rendererWorkerQueueClass: () => rendererWorkerQueueClass,
|
|
57
59
|
supportsWavefrontPathTracingCompute: () => supportsWavefrontPathTracingCompute,
|
|
58
60
|
supportsWebGpu: () => supportsWebGpu,
|
|
61
|
+
traceWavefrontReferenceTriangles: () => traceWavefrontReferenceTriangles,
|
|
59
62
|
wavefrontMaterialKinds: () => wavefrontMaterialKinds,
|
|
60
63
|
wavefrontPathTracingComputeLimits: () => wavefrontPathTracingComputeLimits,
|
|
61
64
|
wavefrontSceneObjectKinds: () => wavefrontSceneObjectKinds
|
|
@@ -231,6 +234,25 @@ function normalize(value, fallback = [0, 0, 1]) {
|
|
|
231
234
|
}
|
|
232
235
|
return [value[0] / length, value[1] / length, value[2] / length];
|
|
233
236
|
}
|
|
237
|
+
function hashUint32(value) {
|
|
238
|
+
let x = value >>> 0;
|
|
239
|
+
x = ((x >>> 16 ^ x) >>> 0) * 73244475 >>> 0;
|
|
240
|
+
x = ((x >>> 16 ^ x) >>> 0) * 73244475 >>> 0;
|
|
241
|
+
return (x >>> 16 ^ x) >>> 0;
|
|
242
|
+
}
|
|
243
|
+
function mixSeed(pixelId, sampleId, bounce, frameIndex, dimension) {
|
|
244
|
+
let x = (pixelId >>> 0) * 747796405 ^ (sampleId >>> 0) * 2891336453 ^ (bounce >>> 0) * 277803737 ^ (frameIndex >>> 0) * 1442695041 ^ (dimension >>> 0) * 1597334677;
|
|
245
|
+
x >>>= 0;
|
|
246
|
+
x ^= x >>> 16;
|
|
247
|
+
x = x * 2146121005 >>> 0;
|
|
248
|
+
x ^= x >>> 15;
|
|
249
|
+
x = x * 2221713035 >>> 0;
|
|
250
|
+
x ^= x >>> 16;
|
|
251
|
+
return x >>> 0;
|
|
252
|
+
}
|
|
253
|
+
function random01FromSeed(seed) {
|
|
254
|
+
return (hashUint32(seed) & 16777215) / 16777215;
|
|
255
|
+
}
|
|
234
256
|
function getArrayLikeLength(value) {
|
|
235
257
|
return Array.isArray(value) || ArrayBuffer.isView(value) ? value.length : 0;
|
|
236
258
|
}
|
|
@@ -829,6 +851,29 @@ function resolveEnvironmentLighting(input, environmentColor, ambientColor) {
|
|
|
829
851
|
exposure: Math.max(1e-4, readFiniteNumber("environmentLighting.exposure", source.exposure, DEFAULT_ENVIRONMENT_LIGHTING.exposure))
|
|
830
852
|
});
|
|
831
853
|
}
|
|
854
|
+
function evaluateReferenceEnvironmentRadiance(config, origin, direction) {
|
|
855
|
+
void origin;
|
|
856
|
+
const rayDirection = normalize(direction, [0, 1, 0]);
|
|
857
|
+
const upFactor = clamp(rayDirection[1] * 0.5 + 0.5, 0, 1);
|
|
858
|
+
const sunDirection = normalize(
|
|
859
|
+
config.environmentLighting?.sunDirection ?? DEFAULT_ENVIRONMENT_LIGHTING.sunDirection,
|
|
860
|
+
DEFAULT_ENVIRONMENT_LIGHTING.sunDirection
|
|
861
|
+
);
|
|
862
|
+
const sunGlow = Math.pow(clamp(dot(rayDirection, sunDirection), 0, 1), 192);
|
|
863
|
+
const horizonColor = config.environmentLighting?.horizonColor ?? DEFAULT_ENVIRONMENT_LIGHTING.horizonColor;
|
|
864
|
+
const zenithColor = config.environmentLighting?.zenithColor ?? DEFAULT_ENVIRONMENT_LIGHTING.zenithColor;
|
|
865
|
+
const sunColor = config.environmentLighting?.sunColor ?? DEFAULT_ENVIRONMENT_LIGHTING.sunColor;
|
|
866
|
+
const intensity = Math.max(
|
|
867
|
+
1e-4,
|
|
868
|
+
Number(config.environmentLighting?.intensity ?? DEFAULT_ENVIRONMENT_LIGHTING.intensity)
|
|
869
|
+
);
|
|
870
|
+
return Object.freeze([
|
|
871
|
+
(horizonColor[0] * (1 - upFactor) + zenithColor[0] * upFactor + sunColor[0] * sunGlow) * intensity,
|
|
872
|
+
(horizonColor[1] * (1 - upFactor) + zenithColor[1] * upFactor + sunColor[1] * sunGlow) * intensity,
|
|
873
|
+
(horizonColor[2] * (1 - upFactor) + zenithColor[2] * upFactor + sunColor[2] * sunGlow) * intensity,
|
|
874
|
+
1
|
|
875
|
+
]);
|
|
876
|
+
}
|
|
832
877
|
function resolveEnvironmentPortalMode(value, hasPortals) {
|
|
833
878
|
if (value === void 0 || value === null) {
|
|
834
879
|
return hasPortals ? 2 : 0;
|
|
@@ -1357,6 +1402,209 @@ function createTiles(width, height, tileSize) {
|
|
|
1357
1402
|
}
|
|
1358
1403
|
return Object.freeze(tiles);
|
|
1359
1404
|
}
|
|
1405
|
+
function normalizeReferenceTile(config, tileInput = {}) {
|
|
1406
|
+
const tileX = clamp(
|
|
1407
|
+
readNonNegativeInteger("tile.x", tileInput.x, 0),
|
|
1408
|
+
0,
|
|
1409
|
+
Math.max(0, config.width - 1)
|
|
1410
|
+
);
|
|
1411
|
+
const tileY = clamp(
|
|
1412
|
+
readNonNegativeInteger("tile.y", tileInput.y, 0),
|
|
1413
|
+
0,
|
|
1414
|
+
Math.max(0, config.height - 1)
|
|
1415
|
+
);
|
|
1416
|
+
const tileWidth = clamp(
|
|
1417
|
+
readPositiveInteger("tile.width", tileInput.width, config.width - tileX),
|
|
1418
|
+
1,
|
|
1419
|
+
config.width - tileX
|
|
1420
|
+
);
|
|
1421
|
+
const tileHeight = clamp(
|
|
1422
|
+
readPositiveInteger("tile.height", tileInput.height, config.height - tileY),
|
|
1423
|
+
1,
|
|
1424
|
+
config.height - tileY
|
|
1425
|
+
);
|
|
1426
|
+
return Object.freeze({
|
|
1427
|
+
x: tileX,
|
|
1428
|
+
y: tileY,
|
|
1429
|
+
width: tileWidth,
|
|
1430
|
+
height: tileHeight
|
|
1431
|
+
});
|
|
1432
|
+
}
|
|
1433
|
+
function repairReferenceShadingNormal(geometricNormal, shadingNormal) {
|
|
1434
|
+
const normal = normalize(shadingNormal, geometricNormal);
|
|
1435
|
+
return dot(normal, geometricNormal) < 0 ? scale(normal, -1) : normal;
|
|
1436
|
+
}
|
|
1437
|
+
function readOptionalMaxDistance(value) {
|
|
1438
|
+
if (value === void 0 || value === null) {
|
|
1439
|
+
return Number.POSITIVE_INFINITY;
|
|
1440
|
+
}
|
|
1441
|
+
const numeric = Number(value);
|
|
1442
|
+
if (!Number.isFinite(numeric) || numeric <= 0) {
|
|
1443
|
+
throw new Error("maxDistance must be a positive finite number when provided.");
|
|
1444
|
+
}
|
|
1445
|
+
return numeric;
|
|
1446
|
+
}
|
|
1447
|
+
function createWavefrontReferenceRay(config, options = {}) {
|
|
1448
|
+
if (!config || typeof config !== "object") {
|
|
1449
|
+
throw new Error("config must be a wavefront path tracing config.");
|
|
1450
|
+
}
|
|
1451
|
+
const tile = normalizeReferenceTile(config, options.tile);
|
|
1452
|
+
const tilePixelCount = tile.width * tile.height;
|
|
1453
|
+
const pixelIndex = readNonNegativeInteger("pixelIndex", options.pixelIndex, 0);
|
|
1454
|
+
if (pixelIndex >= tilePixelCount) {
|
|
1455
|
+
throw new Error(`pixelIndex ${pixelIndex} exceeds tile capacity ${tilePixelCount}.`);
|
|
1456
|
+
}
|
|
1457
|
+
const sampleIndex = readNonNegativeInteger("sampleIndex", options.sampleIndex, 0);
|
|
1458
|
+
const frameIndex = readNonNegativeInteger("frameIndex", options.frameIndex, config.frameIndex ?? 0);
|
|
1459
|
+
const jitterScale = clamp(readFiniteNumber("jitterScale", options.jitterScale, 0.35), 0, 1);
|
|
1460
|
+
const localX = pixelIndex % tile.width;
|
|
1461
|
+
const localY = Math.floor(pixelIndex / tile.width);
|
|
1462
|
+
const pixelX = tile.x + localX;
|
|
1463
|
+
const pixelY = tile.y + localY;
|
|
1464
|
+
const sourcePixelId = pixelY * config.width + pixelX;
|
|
1465
|
+
const jitterX = random01FromSeed(mixSeed(sourcePixelId, sampleIndex, 0, frameIndex, 1)) - 0.5;
|
|
1466
|
+
const jitterY = random01FromSeed(mixSeed(sourcePixelId, sampleIndex, 0, frameIndex, 2)) - 0.5;
|
|
1467
|
+
const ndcX = (pixelX + 0.5 + jitterX * jitterScale) / config.width * 2 - 1;
|
|
1468
|
+
const ndcY = 1 - (pixelY + 0.5 + jitterY * jitterScale) / config.height * 2;
|
|
1469
|
+
const viewX = ndcX * config.camera.tanHalfFovY * config.camera.aspect;
|
|
1470
|
+
const viewY = ndcY * config.camera.tanHalfFovY;
|
|
1471
|
+
const direction = normalize(
|
|
1472
|
+
add(
|
|
1473
|
+
add(config.camera.forward, scale(config.camera.right, viewX)),
|
|
1474
|
+
scale(config.camera.up, viewY)
|
|
1475
|
+
),
|
|
1476
|
+
config.camera.forward
|
|
1477
|
+
);
|
|
1478
|
+
return Object.freeze({
|
|
1479
|
+
rayId: pixelIndex,
|
|
1480
|
+
parentRayId: 4294967295,
|
|
1481
|
+
sourcePixelId,
|
|
1482
|
+
sampleId: sampleIndex,
|
|
1483
|
+
bounce: 0,
|
|
1484
|
+
mediumRefId: 0,
|
|
1485
|
+
flags: 0,
|
|
1486
|
+
origin: Object.freeze([...config.camera.position]),
|
|
1487
|
+
direction: Object.freeze(direction),
|
|
1488
|
+
throughput: Object.freeze([1, 1, 1, 1]),
|
|
1489
|
+
pixelX,
|
|
1490
|
+
pixelY
|
|
1491
|
+
});
|
|
1492
|
+
}
|
|
1493
|
+
function intersectWavefrontReferenceTriangle(ray, triangle, options = {}) {
|
|
1494
|
+
if (!ray || typeof ray !== "object") {
|
|
1495
|
+
throw new Error("ray must be a wavefront reference ray.");
|
|
1496
|
+
}
|
|
1497
|
+
if (!triangle || typeof triangle !== "object") {
|
|
1498
|
+
throw new Error("triangle must be a wavefront triangle record.");
|
|
1499
|
+
}
|
|
1500
|
+
const maxDistance = readOptionalMaxDistance(options.maxDistance);
|
|
1501
|
+
const triangleIndex = readNonNegativeInteger("triangleIndex", options.triangleIndex, 0);
|
|
1502
|
+
const edge1 = subtract(triangle.v1, triangle.v0);
|
|
1503
|
+
const edge2 = subtract(triangle.v2, triangle.v0);
|
|
1504
|
+
const pvec = cross(ray.direction, edge2);
|
|
1505
|
+
const determinant = dot(edge1, pvec);
|
|
1506
|
+
if (Math.abs(determinant) < 1e-7) {
|
|
1507
|
+
return null;
|
|
1508
|
+
}
|
|
1509
|
+
const invDet = 1 / determinant;
|
|
1510
|
+
const tvec = subtract(ray.origin, triangle.v0);
|
|
1511
|
+
const u = dot(tvec, pvec) * invDet;
|
|
1512
|
+
if (u < 0 || u > 1) {
|
|
1513
|
+
return null;
|
|
1514
|
+
}
|
|
1515
|
+
const qvec = cross(tvec, edge1);
|
|
1516
|
+
const v = dot(ray.direction, qvec) * invDet;
|
|
1517
|
+
if (v < 0 || u + v > 1) {
|
|
1518
|
+
return null;
|
|
1519
|
+
}
|
|
1520
|
+
const distance = dot(edge2, qvec) * invDet;
|
|
1521
|
+
if (distance <= 1e-3 || distance > maxDistance) {
|
|
1522
|
+
return null;
|
|
1523
|
+
}
|
|
1524
|
+
const geometric = normalize(cross(edge1, edge2), [0, 1, 0]);
|
|
1525
|
+
const frontFace = dot(ray.direction, geometric) < 0;
|
|
1526
|
+
const orientedGeometric = frontFace ? geometric : scale(geometric, -1);
|
|
1527
|
+
const w = 1 - u - v;
|
|
1528
|
+
const interpolated = [
|
|
1529
|
+
triangle.n0[0] * w + triangle.n1[0] * u + triangle.n2[0] * v,
|
|
1530
|
+
triangle.n0[1] * w + triangle.n1[1] * u + triangle.n2[1] * v,
|
|
1531
|
+
triangle.n0[2] * w + triangle.n1[2] * u + triangle.n2[2] * v
|
|
1532
|
+
];
|
|
1533
|
+
const shadingNormal = repairReferenceShadingNormal(orientedGeometric, interpolated);
|
|
1534
|
+
const uv = [
|
|
1535
|
+
triangle.uv0[0] * w + triangle.uv1[0] * u + triangle.uv2[0] * v,
|
|
1536
|
+
triangle.uv0[1] * w + triangle.uv1[1] * u + triangle.uv2[1] * v
|
|
1537
|
+
];
|
|
1538
|
+
const position = add(ray.origin, scale(ray.direction, distance));
|
|
1539
|
+
return Object.freeze({
|
|
1540
|
+
hitType: "surface",
|
|
1541
|
+
rayId: ray.rayId,
|
|
1542
|
+
sourcePixelId: ray.sourcePixelId,
|
|
1543
|
+
distance,
|
|
1544
|
+
entityId: triangle.meshId,
|
|
1545
|
+
instanceId: 0,
|
|
1546
|
+
primitiveId: triangle.triangleId,
|
|
1547
|
+
materialId: triangle.materialKind,
|
|
1548
|
+
materialRefId: triangle.materialRefId,
|
|
1549
|
+
mediumRefId: triangle.mediumRefId,
|
|
1550
|
+
barycentrics: Object.freeze([w, u, v]),
|
|
1551
|
+
uv: Object.freeze(uv),
|
|
1552
|
+
geometricNormal: Object.freeze(orientedGeometric),
|
|
1553
|
+
shadingNormal: Object.freeze(shadingNormal),
|
|
1554
|
+
frontFace,
|
|
1555
|
+
triangleIndex,
|
|
1556
|
+
triangleId: triangle.triangleId,
|
|
1557
|
+
position: Object.freeze(position),
|
|
1558
|
+
color: triangle.color,
|
|
1559
|
+
emission: triangle.emission,
|
|
1560
|
+
material: triangle.material
|
|
1561
|
+
});
|
|
1562
|
+
}
|
|
1563
|
+
function createWavefrontReferenceEnvironmentHit(config, ray) {
|
|
1564
|
+
const radiance = evaluateReferenceEnvironmentRadiance(config, ray.origin, ray.direction);
|
|
1565
|
+
return Object.freeze({
|
|
1566
|
+
hitType: "environment",
|
|
1567
|
+
rayId: ray.rayId,
|
|
1568
|
+
sourcePixelId: ray.sourcePixelId,
|
|
1569
|
+
distance: -1,
|
|
1570
|
+
entityId: 0,
|
|
1571
|
+
instanceId: 0,
|
|
1572
|
+
primitiveId: 0,
|
|
1573
|
+
materialId: 0,
|
|
1574
|
+
materialRefId: 0,
|
|
1575
|
+
mediumRefId: 0,
|
|
1576
|
+
barycentrics: Object.freeze([0, 0, 0]),
|
|
1577
|
+
uv: Object.freeze([0, 0]),
|
|
1578
|
+
geometricNormal: Object.freeze(scale(ray.direction, -1)),
|
|
1579
|
+
shadingNormal: Object.freeze(scale(ray.direction, -1)),
|
|
1580
|
+
frontFace: true,
|
|
1581
|
+
triangleIndex: -1,
|
|
1582
|
+
triangleId: -1,
|
|
1583
|
+
position: Object.freeze(add(ray.origin, scale(ray.direction, 1e3))),
|
|
1584
|
+
color: Object.freeze([0, 0, 0, 0]),
|
|
1585
|
+
emission: radiance,
|
|
1586
|
+
material: Object.freeze([1, 0, 1, 1])
|
|
1587
|
+
});
|
|
1588
|
+
}
|
|
1589
|
+
function traceWavefrontReferenceTriangles(config, ray, triangles, options = {}) {
|
|
1590
|
+
if (!config || typeof config !== "object") {
|
|
1591
|
+
throw new Error("config must be a wavefront path tracing config.");
|
|
1592
|
+
}
|
|
1593
|
+
const source = Array.isArray(triangles) ? triangles : [];
|
|
1594
|
+
let nearestHit = null;
|
|
1595
|
+
let nearestDistance = readOptionalMaxDistance(options.maxDistance);
|
|
1596
|
+
source.forEach((triangle, index) => {
|
|
1597
|
+
const hit = intersectWavefrontReferenceTriangle(ray, triangle, {
|
|
1598
|
+
maxDistance: Number.isFinite(nearestDistance) ? nearestDistance : void 0,
|
|
1599
|
+
triangleIndex: index
|
|
1600
|
+
});
|
|
1601
|
+
if (hit && hit.distance < nearestDistance) {
|
|
1602
|
+
nearestDistance = hit.distance;
|
|
1603
|
+
nearestHit = hit;
|
|
1604
|
+
}
|
|
1605
|
+
});
|
|
1606
|
+
return nearestHit ?? createWavefrontReferenceEnvironmentHit(config, ray);
|
|
1607
|
+
}
|
|
1360
1608
|
function clampTileSizeForDevice(config, device) {
|
|
1361
1609
|
const limit = Number(device?.limits?.maxStorageBufferBindingSize);
|
|
1362
1610
|
if (!Number.isFinite(limit) || limit <= 0) {
|
|
@@ -4896,11 +5144,13 @@ var defaultRendererClearColor = DEFAULT_CLEAR_COLOR;
|
|
|
4896
5144
|
createWavefrontPathTracingComputeConfig,
|
|
4897
5145
|
createWavefrontPathTracingComputeRenderer,
|
|
4898
5146
|
createWavefrontPathTracingPlan,
|
|
5147
|
+
createWavefrontReferenceRay,
|
|
4899
5148
|
defaultRendererClearColor,
|
|
4900
5149
|
defaultRendererWorkerProfile,
|
|
4901
5150
|
estimateWavefrontPathTracingMemory,
|
|
4902
5151
|
getRendererWorkerManifest,
|
|
4903
5152
|
getRendererWorkerProfile,
|
|
5153
|
+
intersectWavefrontReferenceTriangle,
|
|
4904
5154
|
normalizeWavefrontMesh,
|
|
4905
5155
|
normalizeWavefrontSceneObject,
|
|
4906
5156
|
packWavefrontBvhNodes,
|
|
@@ -4920,6 +5170,7 @@ var defaultRendererClearColor = DEFAULT_CLEAR_COLOR;
|
|
|
4920
5170
|
rendererWorkerQueueClass,
|
|
4921
5171
|
supportsWavefrontPathTracingCompute,
|
|
4922
5172
|
supportsWebGpu,
|
|
5173
|
+
traceWavefrontReferenceTriangles,
|
|
4923
5174
|
wavefrontMaterialKinds,
|
|
4924
5175
|
wavefrontPathTracingComputeLimits,
|
|
4925
5176
|
wavefrontSceneObjectKinds
|