@meimu/mutracer 0.3.0 → 0.3.1
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 +222 -0
- package/LICENSES/FidelityFX-FSR.txt +19 -0
- package/LICENSES/pbrt-v4-Apache-2.0.txt +202 -0
- package/THIRD_PARTY_NOTICES.md +18 -4
- package/dist/assets/bvh.worker.js +1 -1
- package/dist/mutracer.umd.js +6260 -5580
- package/docs/api.md +45 -18
- package/docs/materials.md +4 -2
- package/docs/performance.md +7 -0
- package/docs/post-processing.md +62 -9
- package/docs/progressive-rendering.md +3 -0
- package/docs/sampling.md +4 -0
- package/docs/technical/acceleration.md +52 -0
- package/docs/technical/aovs.md +79 -0
- package/docs/technical/caustics.md +109 -0
- package/docs/technical/continuous-spectrum.md +29 -0
- package/docs/technical/display-upscale.md +82 -0
- package/docs/technical/openpbr.md +99 -0
- package/docs/technical/pbrt-import.md +168 -0
- package/docs/technical/tiling.md +74 -0
- package/docs/technical/webgl.md +53 -0
- package/docs/viewer.md +11 -1
- package/lib/Display.d.ts +19 -5
- package/lib/Display.js +10 -7
- package/lib/Display.js.map +1 -1
- package/lib/Engine.d.ts +2 -1
- package/lib/Engine.js +30 -2
- package/lib/Engine.js.map +1 -1
- package/lib/Render.d.ts +20 -11
- package/lib/Render.js +32 -7
- package/lib/Render.js.map +1 -1
- package/lib/main.d.ts +3 -1
- package/lib/main.js +1 -0
- package/lib/main.js.map +1 -1
- package/lib/oidn.d.ts +1 -1
- package/lib/renderer/AovPrimitiveCache.js +39 -8
- package/lib/renderer/AovPrimitiveCache.js.map +1 -1
- package/lib/renderer/DisplayPostProcess.d.ts +8 -3
- package/lib/renderer/DisplayPostProcess.js +51 -18
- package/lib/renderer/DisplayPostProcess.js.map +1 -1
- package/lib/renderer/MaterialData.js +7 -2
- package/lib/renderer/MaterialData.js.map +1 -1
- package/lib/renderer/RenderingPipeline.d.ts +7 -1
- package/lib/renderer/RenderingPipeline.js.map +1 -1
- package/lib/renderer/TileRender.d.ts +2 -2
- package/lib/renderer/TileRender.js +128 -7
- package/lib/renderer/TileRender.js.map +1 -1
- package/lib/renderer/WGPUAov.d.ts +6 -1
- package/lib/renderer/WGPUAov.js +108 -14
- package/lib/renderer/WGPUAov.js.map +1 -1
- package/lib/renderer/WGPUCanvasSurface.js +12 -1
- package/lib/renderer/WGPUCanvasSurface.js.map +1 -1
- package/lib/renderer/WGPUEnvMapDistribution.js +19 -19
- package/lib/renderer/WGPUFullQuadPass.js +3 -3
- package/lib/renderer/WGPURayTraceOutput.js +12 -12
- package/lib/renderer/WGPURayTracePass.d.ts +17 -4
- package/lib/renderer/WGPURayTracePass.js +194 -71
- package/lib/renderer/WGPURayTracePass.js.map +1 -1
- package/lib/renderer/WGPURenderingPipeline.js +46 -40
- package/lib/renderer/WGPURenderingPipeline.js.map +1 -1
- package/lib/renderer/WebGLAov.js +3 -3
- package/lib/renderer/WebGLAov.js.map +1 -1
- package/lib/renderer/WebGLFullQuadPass.d.ts +1 -1
- package/lib/renderer/WebGLFullQuadPass.js +8 -2
- package/lib/renderer/WebGLFullQuadPass.js.map +1 -1
- package/lib/renderer/WebGLJNLMDenoiser.js +66 -66
- package/lib/renderer/WebGLJNLMDenoiser.js.map +1 -1
- package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
- package/lib/renderer/WebGLRayTracePass.d.ts +14 -10
- package/lib/renderer/WebGLRayTracePass.js +115 -111
- package/lib/renderer/WebGLRayTracePass.js.map +1 -1
- package/lib/renderer/WebGLRenderingPipeline.js +10 -3
- package/lib/renderer/WebGLRenderingPipeline.js.map +1 -1
- package/lib/renderer/WebGLSkyBaker.js +57 -57
- package/lib/renderer/aov.d.ts +13 -1
- package/lib/renderer/aov.js +21 -2
- package/lib/renderer/aov.js.map +1 -1
- package/lib/renderer/aovDisplay.js +2 -2
- package/lib/renderer/aovDisplay.js.map +1 -1
- package/lib/renderer/binnedSahBvh.d.ts +2 -1
- package/lib/renderer/binnedSahBvh.js +24 -17
- package/lib/renderer/binnedSahBvh.js.map +1 -1
- package/lib/renderer/bvhAccel.d.ts +3 -1
- package/lib/renderer/bvhAccel.js +36 -6
- package/lib/renderer/bvhAccel.js.map +1 -1
- package/lib/renderer/cameraUniform.d.ts +1 -1
- package/lib/renderer/cameraUniform.js +6 -2
- package/lib/renderer/cameraUniform.js.map +1 -1
- package/lib/renderer/compactVertices.d.ts +14 -0
- package/lib/renderer/compactVertices.js +124 -0
- package/lib/renderer/compactVertices.js.map +1 -0
- package/lib/renderer/easu.d.ts +11 -0
- package/lib/renderer/easu.js +156 -0
- package/lib/renderer/easu.js.map +1 -0
- package/lib/renderer/geometryUpdateState.d.ts +1 -0
- package/lib/renderer/geometryUpdateState.js.map +1 -1
- package/lib/renderer/geometryUpdates.js +3 -2
- package/lib/renderer/geometryUpdates.js.map +1 -1
- package/lib/renderer/glsl/aovDisplay.frag.js +5 -5
- package/lib/renderer/glsl/aovReflectance.glsl.js +35 -35
- package/lib/renderer/glsl/aovReflectanceSamples.glsl.js +1 -1
- package/lib/renderer/glsl/aovTrace.frag.js +44 -36
- package/lib/renderer/glsl/aovTrace.frag.js.map +1 -1
- package/lib/renderer/glsl/chunks/cameraProjection.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/cameraProjection.glsl.js +16 -0
- package/lib/renderer/glsl/chunks/cameraProjection.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/cameraRay.glsl.d.ts +1 -1
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js +9 -16
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/emissiveLight.glsl.js +8 -8
- package/lib/renderer/glsl/chunks/envMap.glsl.js +67 -67
- package/lib/renderer/glsl/chunks/intersect.glsl.js +390 -375
- package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +120 -120
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +562 -562
- package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
- package/lib/renderer/glsl/chunks/random.glsl.js +4 -4
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +37 -35
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js +70 -74
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.d.ts +1 -1
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +107 -88
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +11 -11
- package/lib/renderer/glsl/chunks/sampling.glsl.js +77 -77
- package/lib/renderer/glsl/chunks/sobol.glsl.js +70 -70
- package/lib/renderer/glsl/chunks/spectralPrefix.glsl.d.ts +6 -0
- package/lib/renderer/glsl/chunks/spectralPrefix.glsl.js +47 -0
- package/lib/renderer/glsl/chunks/spectralPrefix.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
- package/lib/renderer/glsl/chunks/uvProjection.glsl.js +11 -11
- package/lib/renderer/glsl/depthQuery.frag.js +12 -6
- package/lib/renderer/glsl/depthQuery.frag.js.map +1 -1
- package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +10 -10
- package/lib/renderer/glsl/rayTrace.frag.js +233 -170
- package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
- package/lib/renderer/glsl/shadowCatcher.frag.js +10 -9
- package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
- package/lib/renderer/glsl/webglPipeline.frag.js +58 -58
- package/lib/renderer/gpuMemory.js +1 -1
- package/lib/renderer/gpuMemory.js.map +1 -1
- package/lib/renderer/openPbrEnergyLut.d.ts +2 -1
- package/lib/renderer/openPbrEnergyLut.js +18 -1
- package/lib/renderer/openPbrEnergyLut.js.map +1 -1
- package/lib/renderer/pathLimits.d.ts +5 -4
- package/lib/renderer/pathLimits.js +6 -5
- package/lib/renderer/pathLimits.js.map +1 -1
- package/lib/renderer/prepareMeshBVH.d.ts +2 -0
- package/lib/renderer/prepareMeshBVH.js +5 -3
- package/lib/renderer/prepareMeshBVH.js.map +1 -1
- package/lib/renderer/progressiveScheduler.js +1 -1
- package/lib/renderer/progressiveScheduler.js.map +1 -1
- package/lib/renderer/renderPipeline.d.ts +4 -0
- package/lib/renderer/renderPipeline.js +1 -0
- package/lib/renderer/renderPipeline.js.map +1 -1
- package/lib/renderer/researchTransport.d.ts +1 -1
- package/lib/renderer/researchTransport.js.map +1 -1
- package/lib/renderer/sceneAssembly.d.ts +1 -1
- package/lib/renderer/sceneAssembly.js +4 -3
- package/lib/renderer/sceneAssembly.js.map +1 -1
- package/lib/renderer/sceneChangeDetector.d.ts +1 -1
- package/lib/renderer/sceneChangeDetector.js +3 -1
- package/lib/renderer/sceneChangeDetector.js.map +1 -1
- package/lib/renderer/sceneLayoutSchema.d.ts +1 -0
- package/lib/renderer/sceneLayoutSchema.js +2 -2
- package/lib/renderer/sceneLayoutSchema.js.map +1 -1
- package/lib/renderer/scenePreparation.d.ts +3 -2
- package/lib/renderer/scenePreparation.js +18 -2
- package/lib/renderer/scenePreparation.js.map +1 -1
- package/lib/renderer/scratchSampling.js +6 -6
- package/lib/renderer/spectrum.js +2 -2
- package/lib/renderer/staticBvhPreparation.d.ts +9 -0
- package/lib/renderer/staticBvhPreparation.js +8 -2
- package/lib/renderer/staticBvhPreparation.js.map +1 -1
- package/lib/renderer/surfaceHit.d.ts +10 -0
- package/lib/renderer/surfaceHit.js +22 -0
- package/lib/renderer/surfaceHit.js.map +1 -0
- package/lib/renderer/tangentRequirements.d.ts +2 -0
- package/lib/renderer/tangentRequirements.js +7 -0
- package/lib/renderer/tangentRequirements.js.map +1 -0
- package/lib/renderer/textureAtlas.d.ts +4 -0
- package/lib/renderer/textureAtlas.js +48 -2
- package/lib/renderer/textureAtlas.js.map +1 -1
- package/lib/renderer/webgl.js +4 -0
- package/lib/renderer/webgl.js.map +1 -1
- package/lib/renderer/webglVertexAttributes.d.ts +17 -0
- package/lib/renderer/webglVertexAttributes.js +44 -0
- package/lib/renderer/webglVertexAttributes.js.map +1 -0
- package/lib/renderer/wgpuBindlessSource.js +2 -2
- package/lib/renderer/wgpuMaterialConstants.js +4 -3
- package/lib/renderer/wgpuMaterialConstants.js.map +1 -1
- package/lib/renderer/wgpuSceneUniform.js +2 -2
- package/lib/renderer/wgpuSceneUniform.js.map +1 -1
- package/lib/renderer/wgpuShaderSource.d.ts +15 -0
- package/lib/renderer/wgpuShaderSource.js +1 -1
- package/lib/renderer/wgpuShaderSource.js.map +1 -1
- package/lib/renderer/wgsl/aovCompact.wgsl.d.ts +4 -0
- package/lib/renderer/wgsl/aovCompact.wgsl.js +26 -0
- package/lib/renderer/wgsl/aovCompact.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/aovDisplay.wgsl.js +9 -9
- package/lib/renderer/wgsl/aovReflectance.wgsl.js +39 -39
- package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js +1 -1
- package/lib/renderer/wgsl/aovResolve.wgsl.d.ts +4 -0
- package/lib/renderer/wgsl/aovResolve.wgsl.js +21 -2
- package/lib/renderer/wgsl/aovResolve.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/aovSnapshot.wgsl.js +2 -2
- package/lib/renderer/wgsl/aovSnapshot.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/aovTrace.wgsl.js +31 -31
- package/lib/renderer/wgsl/aovTraceDisplay.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/aovTraceDisplay.wgsl.js +56 -0
- package/lib/renderer/wgsl/aovTraceDisplay.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/bloom.wgsl.js +18 -18
- package/lib/renderer/wgsl/causticLight.compute.d.ts +1 -1
- package/lib/renderer/wgsl/causticLight.compute.js +121 -119
- package/lib/renderer/wgsl/causticLight.compute.js.map +1 -1
- package/lib/renderer/wgsl/chunks/background.wgsl.js +46 -46
- package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js +4 -4
- package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/caustics.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js +30 -30
- package/lib/renderer/wgsl/chunks/intersect.wgsl.d.ts +6 -2
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js +550 -542
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +18 -16
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +2 -1
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +70 -69
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +593 -593
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +118 -118
- package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +4 -1
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +32 -26
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +114 -114
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +159 -137
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +8 -8
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js +74 -74
- package/lib/renderer/wgsl/chunks/sobol.wgsl.js +74 -74
- package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.d.ts +6 -0
- package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.js +66 -0
- package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +11 -11
- package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.js +61 -0
- package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/compose.frag.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/compose.frag.wgsl.js +99 -97
- package/lib/renderer/wgsl/compose.frag.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
- package/lib/renderer/wgsl/depthQuery.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/depthQuery.wgsl.js +11 -2
- package/lib/renderer/wgsl/depthQuery.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/easu.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/easu.wgsl.js +80 -0
- package/lib/renderer/wgsl/easu.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/easuDetail.wgsl.d.ts +21 -0
- package/lib/renderer/wgsl/easuDetail.wgsl.js +230 -0
- package/lib/renderer/wgsl/easuDetail.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/jnlm.compute.js +74 -74
- package/lib/renderer/wgsl/jnlm.compute.js.map +1 -1
- package/lib/renderer/wgsl/offlineAdaptive.compute.js +26 -26
- package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js +3 -3
- package/lib/renderer/wgsl/photonMap.compute.js +89 -89
- package/lib/renderer/wgsl/proceduralSky.compute.js +61 -61
- package/lib/renderer/wgsl/rayTrace.compute.d.ts +14 -0
- package/lib/renderer/wgsl/rayTrace.compute.js +395 -333
- package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
- package/lib/scene/Scene.js.map +1 -1
- package/lib/settings/render.d.ts +11 -0
- package/lib/settings/render.js +1 -0
- package/lib/settings/render.js.map +1 -1
- package/lib/util/fromTHREE.js +21 -14
- package/lib/util/fromTHREE.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -1
- package/package.json +5 -2
- package/lib/oidnBundledWeights.cdn.d.ts +0 -2
- package/lib/oidnBundledWeights.cdn.js +0 -5
- package/lib/oidnBundledWeights.cdn.js.map +0 -1
- package/lib/renderer/bvh.worker.d.ts +0 -1
- package/lib/renderer/bvh.worker.js +0 -16
- package/lib/renderer/bvh.worker.js.map +0 -1
- package/lib/renderer/bvhWorkerBuild.d.ts +0 -13
- package/lib/renderer/bvhWorkerBuild.js +0 -17
- package/lib/renderer/bvhWorkerBuild.js.map +0 -1
- package/lib/renderer/lightCore.d.ts +0 -12
- package/lib/renderer/lightCore.js +0 -13
- package/lib/renderer/lightCore.js.map +0 -1
- package/lib/renderer/materialCore.d.ts +0 -8
- package/lib/renderer/materialCore.js +0 -9
- package/lib/renderer/materialCore.js.map +0 -1
- package/lib/scene/PixelTexture.d.ts +0 -6
- package/lib/scene/PixelTexture.js +0 -10
- package/lib/scene/PixelTexture.js.map +0 -1
- package/lib/util/studioLighting.d.ts +0 -18
- package/lib/util/studioLighting.js +0 -36
- package/lib/util/studioLighting.js.map +0 -1
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { areaDownsampleShader, easuShader } from './wgsl/easu.wgsl.js';
|
|
2
|
+
import { albedoDownsampleShader, easuDetailShader, guidedCoefficientShader, toneLutShader, EASU_DETAIL, TONE_LUT_SIZE } from './wgsl/easuDetail.wgsl.js';
|
|
3
|
+
import { borrowedAovRevision } from './WGPUAov.js';
|
|
4
|
+
import { TONE_MAPPING_MODES } from './wgsl/compose.frag.wgsl.js';
|
|
5
|
+
/** Creates an edge-adaptive display-space upscale pass (AMD FSR 1 EASU), without sharpening. Register with outputSize: (_, display) => display. WebGPU only; supports rgba8unorm and extended-range rgba16float, including alpha. Copies inputs that already have the output size and area-averages larger ones. Default EASU alone. */
|
|
6
|
+
export function createEasuPass(options = {}) { return createEasuPassImpl({ albedoDetail: options.albedoDetail }); }
|
|
7
|
+
const DETAIL_AOVS = ['diffuseColor', 'specularColor', 'depth'];
|
|
8
|
+
/** @internal Plain albedo ratios (guided false), the separate-lobe approximation and depth-guided silhouettes are retained for comparisons; not package exports. */
|
|
9
|
+
export function createEasuPassImpl(options = {}, separate = false, silhouettes = false, guided = true) {
|
|
10
|
+
const detailEnabled = options.albedoDetail ?? false;
|
|
11
|
+
let warnedConfiguration = false;
|
|
12
|
+
const [min, max] = options.ratioRange ?? EASU_DETAIL.ratioRange;
|
|
13
|
+
const depth = options.depthThreshold ?? EASU_DETAIL.depthThreshold, coverage = options.coverageThreshold ?? EASU_DETAIL.coverageThreshold;
|
|
14
|
+
if (![min, max, depth, coverage].every(Number.isFinite) || min <= 0 || max < min || depth <= 0 || coverage <= 0 || coverage > 1)
|
|
15
|
+
throw new RangeError('Invalid EASU detail compensation options.');
|
|
16
|
+
const devices = new Map();
|
|
17
|
+
const retire = (device, resources) => {
|
|
18
|
+
// This callback's encoder is submitted after it returns.
|
|
19
|
+
void Promise.resolve().then(() => device.queue.onSubmittedWorkDone()).catch(() => { }).then(() => resources.forEach(resource => resource.destroy()));
|
|
20
|
+
};
|
|
21
|
+
const guideFormats = silhouettes ? ['rgba16float', 'rgba16float', 'rg32float'] : ['rgba16float', 'rgba16float'];
|
|
22
|
+
const owned = (state) => [...(state.scratch ?? []), ...(state.tone ? [state.tone] : []), ...(state.fit ?? [])];
|
|
23
|
+
const pass = ctx => {
|
|
24
|
+
const { device, encoder, input, output, render } = ctx;
|
|
25
|
+
// Nothing to upscale, for example a full-resolution render beside a reduced preview.
|
|
26
|
+
if (input.width === output.width && input.height === output.height) {
|
|
27
|
+
encoder.copyTextureToTexture({ texture: input }, { texture: output }, [input.width, input.height]);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
for (const [previous, old] of devices)
|
|
31
|
+
if (previous !== device) {
|
|
32
|
+
retire(previous, owned(old));
|
|
33
|
+
devices.delete(previous);
|
|
34
|
+
}
|
|
35
|
+
let state = devices.get(device);
|
|
36
|
+
if (!state) {
|
|
37
|
+
state = { pipelines: new Map() };
|
|
38
|
+
devices.set(device, state);
|
|
39
|
+
}
|
|
40
|
+
const pipeline = (key, code, formats) => {
|
|
41
|
+
let value = state.pipelines.get(key);
|
|
42
|
+
if (!value) {
|
|
43
|
+
const module = device.createShaderModule({ label: key, code });
|
|
44
|
+
value = device.createRenderPipeline({ label: key, layout: 'auto', vertex: { module, entryPoint: 'vertex' },
|
|
45
|
+
fragment: { module, entryPoint: 'fragment', targets: formats.map(format => ({ format })) } });
|
|
46
|
+
state.pipelines.set(key, value);
|
|
47
|
+
}
|
|
48
|
+
return value;
|
|
49
|
+
};
|
|
50
|
+
const buffer = (values) => {
|
|
51
|
+
const value = device.createBuffer({ size: 16, usage: GPUBufferUsage.UNIFORM, mappedAtCreation: true });
|
|
52
|
+
new Float32Array(value.getMappedRange()).set(values);
|
|
53
|
+
value.unmap();
|
|
54
|
+
retire(device, [value]);
|
|
55
|
+
return value;
|
|
56
|
+
};
|
|
57
|
+
if (input.width >= output.width && input.height >= output.height) {
|
|
58
|
+
// EASU is an enlargement filter; larger renders are area averaged instead.
|
|
59
|
+
const down = pipeline(`Area downsample ${output.format}`, areaDownsampleShader, [output.format]);
|
|
60
|
+
const group = device.createBindGroup({ layout: down.getBindGroupLayout(0), entries: [{ binding: 0, resource: input.createView() }, { binding: 1, resource: { buffer: buffer([output.width, output.height, 0, 0]) } }] });
|
|
61
|
+
const draw = encoder.beginRenderPass({ label: 'Area downsample', colorAttachments: [{ view: output.createView(), loadOp: 'clear', storeOp: 'store' }] });
|
|
62
|
+
draw.setPipeline(down);
|
|
63
|
+
draw.setBindGroup(0, group);
|
|
64
|
+
draw.draw(3);
|
|
65
|
+
draw.end();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (detailEnabled && !warnedConfiguration && (render.aovResolution !== 'display' || !DETAIL_AOVS.every(kind => render.aovs.includes(kind)))) {
|
|
69
|
+
warnedConfiguration = true;
|
|
70
|
+
console.warn("EASU albedoDetail needs the displayed render to enable diffuseColor, specularColor and depth AOVs with aovResolution 'display'; upscaling without detail.");
|
|
71
|
+
}
|
|
72
|
+
const aovs = detailEnabled ? DETAIL_AOVS.map(kind => render.getAovTexture(kind)) : [];
|
|
73
|
+
const detail = aovs.length === 3 && aovs.every(image => image && image.width === output.width && image.height === output.height);
|
|
74
|
+
const entries = [{ binding: 0, resource: input.createView() }, { binding: 1, resource: { buffer: buffer([output.width, output.height, min, max]) } }];
|
|
75
|
+
if (detail) {
|
|
76
|
+
// Cached images are recorded on their own submission so a failed chain cannot leave them stale.
|
|
77
|
+
let cache;
|
|
78
|
+
const cached = () => cache ??= device.createCommandEncoder({ label: 'EASU cache' });
|
|
79
|
+
if (!state.scratch || state.scratch.length !== guideFormats.length || state.scratch[0].width !== input.width || state.scratch[0].height !== input.height) {
|
|
80
|
+
if (state.scratch)
|
|
81
|
+
retire(device, state.scratch);
|
|
82
|
+
// Low diffuse and specular albedo, then (for silhouettes) nearest hit depth with hit coverage.
|
|
83
|
+
state.scratch = guideFormats.map((format, index) => device.createTexture({ label: `EASU low guide ${index}`, size: [input.width, input.height], format, usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT }));
|
|
84
|
+
state.key = undefined;
|
|
85
|
+
}
|
|
86
|
+
// Low albedo depends only on the AOV contents and beauty size; reuse it across presents.
|
|
87
|
+
const key = [state.scratch[0], ...aovs, ...aovs.map(image => borrowedAovRevision.get(image))];
|
|
88
|
+
if (!state.key || key.some((value, index) => value !== state.key[index])) {
|
|
89
|
+
const down = pipeline(`Albedo area downsample ${silhouettes}`, albedoDownsampleShader(silhouettes), guideFormats);
|
|
90
|
+
const group = device.createBindGroup({ layout: down.getBindGroupLayout(0), entries: [
|
|
91
|
+
{ binding: 0, resource: aovs[0].createView() }, { binding: 1, resource: aovs[1].createView() },
|
|
92
|
+
{ binding: 2, resource: { buffer: buffer([input.width, input.height, 0, 0]) } }, { binding: 3, resource: aovs[2].createView() }
|
|
93
|
+
] });
|
|
94
|
+
const draw = cached().beginRenderPass({ label: 'Albedo area downsample', colorAttachments: state.scratch.map(image => ({ view: image.createView(), loadOp: 'clear', storeOp: 'store' })) });
|
|
95
|
+
draw.setPipeline(down);
|
|
96
|
+
draw.setBindGroup(0, group);
|
|
97
|
+
draw.draw(3);
|
|
98
|
+
draw.end();
|
|
99
|
+
state.key = key;
|
|
100
|
+
}
|
|
101
|
+
aovs.forEach((image, index) => entries.push({ binding: 2 + index, resource: image.createView() }));
|
|
102
|
+
entries.push({ binding: 5, resource: state.scratch[0].createView() }, { binding: 6, resource: state.scratch[1].createView() });
|
|
103
|
+
if (silhouettes)
|
|
104
|
+
entries.push({ binding: 10, resource: state.scratch[2].createView() });
|
|
105
|
+
entries.push({ binding: 7, resource: { buffer: buffer([EASU_DETAIL.minimumAlbedo, coverage, depth, EASU_DETAIL.depthTolerance]) } });
|
|
106
|
+
// The ratio is applied through the same grading and tone mapping as the composed image,
|
|
107
|
+
// tabulated once per display setting.
|
|
108
|
+
const display = render._engine.display, extended = output.format === 'rgba16float';
|
|
109
|
+
const tone = [TONE_MAPPING_MODES[display.toneMapping] ?? 0, extended ? 16 : 1, display.toneMappingExposure, extended ? 1 : 0];
|
|
110
|
+
const grading = [display.contrast, display.saturation, display.temperature, display.tint];
|
|
111
|
+
const toneKey = [...tone, ...grading].join(',');
|
|
112
|
+
state.tone ??= device.createTexture({ label: 'EASU tone table', size: [TONE_LUT_SIZE, 2], format: 'rgba32float', usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT });
|
|
113
|
+
if (state.toneKey !== toneKey) {
|
|
114
|
+
const build = pipeline('EASU tone table', toneLutShader, ['rgba32float']);
|
|
115
|
+
const group = device.createBindGroup({ layout: build.getBindGroupLayout(0), entries: [{ binding: 0, resource: { buffer: buffer(tone) } }, { binding: 1, resource: { buffer: buffer(grading) } }] });
|
|
116
|
+
const draw = cached().beginRenderPass({ label: 'EASU tone table', colorAttachments: [{ view: state.tone.createView(), loadOp: 'clear', storeOp: 'store' }] });
|
|
117
|
+
draw.setPipeline(build);
|
|
118
|
+
draw.setBindGroup(0, group);
|
|
119
|
+
draw.draw(3);
|
|
120
|
+
draw.end();
|
|
121
|
+
state.toneKey = toneKey;
|
|
122
|
+
}
|
|
123
|
+
const toneEntries = [{ binding: 8, resource: state.tone.createView() }, { binding: 9, resource: { buffer: buffer([tone[1], EASU_DETAIL.guidedEpsilon, 0, 0]) } }];
|
|
124
|
+
entries.push(...toneEntries);
|
|
125
|
+
if (cache)
|
|
126
|
+
device.queue.submit([cache.finish()]);
|
|
127
|
+
if (guided) {
|
|
128
|
+
// The local albedo-radiance fit depends on this frame's image, so it runs on every present.
|
|
129
|
+
if (!state.fit || state.fit[0].width !== input.width || state.fit[0].height !== input.height) {
|
|
130
|
+
if (state.fit)
|
|
131
|
+
retire(device, state.fit);
|
|
132
|
+
state.fit = ['slope', 'offset'].map(name => device.createTexture({ label: `EASU albedo ${name}`, size: [input.width, input.height], format: 'rgba16float', usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT }));
|
|
133
|
+
}
|
|
134
|
+
const fit = pipeline('EASU albedo fit', guidedCoefficientShader, ['rgba16float', 'rgba16float']);
|
|
135
|
+
const group = device.createBindGroup({ layout: fit.getBindGroupLayout(0), entries: [{ binding: 0, resource: input.createView() },
|
|
136
|
+
{ binding: 1, resource: state.scratch[0].createView() }, { binding: 2, resource: state.scratch[1].createView() }, ...toneEntries] });
|
|
137
|
+
const draw = encoder.beginRenderPass({ label: 'EASU albedo fit', colorAttachments: state.fit.map(image => ({ view: image.createView(), loadOp: 'clear', storeOp: 'store' })) });
|
|
138
|
+
draw.setPipeline(fit);
|
|
139
|
+
draw.setBindGroup(0, group);
|
|
140
|
+
draw.draw(3);
|
|
141
|
+
draw.end();
|
|
142
|
+
entries.push({ binding: 11, resource: state.fit[0].createView() }, { binding: 12, resource: state.fit[1].createView() });
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
const upscale = pipeline(`FSR 1 EASU ${detail ? `detail ${separate} ${silhouettes} ${guided}` : 'color'} ${output.format}`, detail ? easuDetailShader(separate, silhouettes, guided) : easuShader, [output.format]);
|
|
146
|
+
const group = device.createBindGroup({ layout: upscale.getBindGroupLayout(0), entries });
|
|
147
|
+
const draw = encoder.beginRenderPass({ label: 'FSR 1 EASU', colorAttachments: [{ view: output.createView(), loadOp: 'clear', storeOp: 'store' }] });
|
|
148
|
+
draw.setPipeline(upscale);
|
|
149
|
+
draw.setBindGroup(0, group);
|
|
150
|
+
draw.draw(3);
|
|
151
|
+
draw.end();
|
|
152
|
+
};
|
|
153
|
+
return Object.assign(pass, { dispose() { for (const [device, state] of devices)
|
|
154
|
+
retire(device, owned(state)); devices.clear(); } });
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=easu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"easu.js","sourceRoot":"","sources":["../../src/renderer/easu.ts"],"names":[],"mappings":"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","sourcesContent":["import type {PostProcess} from '../Display.js';\nimport {areaDownsampleShader, easuShader} from './wgsl/easu.wgsl.js';\nimport {albedoDownsampleShader, easuDetailShader, guidedCoefficientShader, toneLutShader, EASU_DETAIL, TONE_LUT_SIZE} from './wgsl/easuDetail.wgsl.js';\nimport {borrowedAovRevision} from './WGPUAov.js';\nimport {TONE_MAPPING_MODES} from './wgsl/compose.frag.wgsl.js';\n\n/** createEasuPass options. */\nexport interface EasuOptions {\n /** Recover surface texture detail from the displayed render's diffuseColor, specularColor and depth AOVs, traced with aovResolution 'display'. Default false. Warns once when the displayed render lacks that configuration; frames whose AOVs are not ready or do not match the output size use EASU alone. Unsupported surfaces and silhouettes receive no compensation. */ albedoDetail?: boolean;\n}\n/** @internal Detail tuning kept for comparisons; not package options. */\nexport interface EasuTuning extends EasuOptions {\n /** Per-channel linear compensation bounds, positive finite min <= max. Default [0.7, 1.43]. */ ratioRange?: readonly [number, number];\n /** Relative departure of neighboring inverse depth from a plane that marks a silhouette, positive finite. Default 0.02. */ depthThreshold?: number;\n /** Minimum valid AOV coverage in (0,1]. Default 0.95. */ coverageThreshold?: number;\n}\n/** A display pass with optional scratch images. Dispose after unregistering; it may be used again. */\nexport type EasuPass = PostProcess & {dispose(): void};\n/** Creates an edge-adaptive display-space upscale pass (AMD FSR 1 EASU), without sharpening. Register with outputSize: (_, display) => display. WebGPU only; supports rgba8unorm and extended-range rgba16float, including alpha. Copies inputs that already have the output size and area-averages larger ones. Default EASU alone. */\nexport function createEasuPass(options: EasuOptions = {}): EasuPass { return createEasuPassImpl({albedoDetail: options.albedoDetail}); }\n\nconst DETAIL_AOVS = ['diffuseColor', 'specularColor', 'depth'] as const;\n\n/** @internal Plain albedo ratios (guided false), the separate-lobe approximation and depth-guided silhouettes are retained for comparisons; not package exports. */\nexport function createEasuPassImpl(options: EasuTuning = {}, separate = false, silhouettes = false, guided = true): EasuPass {\n const detailEnabled = options.albedoDetail ?? false;\n let warnedConfiguration = false;\n const [min, max] = options.ratioRange ?? EASU_DETAIL.ratioRange;\n const depth = options.depthThreshold ?? EASU_DETAIL.depthThreshold, coverage = options.coverageThreshold ?? EASU_DETAIL.coverageThreshold;\n if (![min,max,depth,coverage].every(Number.isFinite) || min <= 0 || max < min || depth <= 0 || coverage <= 0 || coverage > 1) throw new RangeError('Invalid EASU detail compensation options.');\n const devices = new Map<GPUDevice, {pipelines: Map<string, GPURenderPipeline>; scratch?: GPUTexture[]; key?: unknown[]; tone?: GPUTexture; toneKey?: string; fit?: GPUTexture[]}>();\n const retire = (device: GPUDevice, resources: (GPUTexture | GPUBuffer)[]) => {\n // This callback's encoder is submitted after it returns.\n void Promise.resolve().then(() => device.queue.onSubmittedWorkDone()).catch(() => {}).then(() => resources.forEach(resource => resource.destroy()));\n };\n const guideFormats: GPUTextureFormat[] = silhouettes ? ['rgba16float','rgba16float','rg32float'] : ['rgba16float','rgba16float'];\n const owned = (state: {scratch?: GPUTexture[]; tone?: GPUTexture; fit?: GPUTexture[]}) => [...(state.scratch ?? []), ...(state.tone ? [state.tone] : []), ...(state.fit ?? [])];\n const pass: PostProcess = ctx => {\n const {device, encoder, input, output, render} = ctx;\n // Nothing to upscale, for example a full-resolution render beside a reduced preview.\n if (input.width === output.width && input.height === output.height) {\n encoder.copyTextureToTexture({texture: input}, {texture: output}, [input.width, input.height]);\n return;\n }\n for (const [previous, old] of devices) if (previous !== device) {retire(previous,owned(old));devices.delete(previous);}\n let state = devices.get(device);\n if (!state) {state = {pipelines: new Map()}; devices.set(device, state);}\n const pipeline = (key: string, code: string, formats: GPUTextureFormat[]) => {\n let value = state!.pipelines.get(key);\n if (!value) {\n const module = device.createShaderModule({label: key, code});\n value = device.createRenderPipeline({label: key, layout: 'auto', vertex: {module,entryPoint:'vertex'},\n fragment: {module,entryPoint:'fragment',targets:formats.map(format => ({format}))}});\n state!.pipelines.set(key, value);\n }\n return value;\n };\n const buffer = (values: number[]) => {\n const value = device.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM,mappedAtCreation:true});\n new Float32Array(value.getMappedRange()).set(values);value.unmap();retire(device,[value]);return value;\n };\n if (input.width >= output.width && input.height >= output.height) {\n // EASU is an enlargement filter; larger renders are area averaged instead.\n const down = pipeline(`Area downsample ${output.format}`,areaDownsampleShader,[output.format]);\n const group = device.createBindGroup({layout:down.getBindGroupLayout(0),entries:[{binding:0,resource:input.createView()},{binding:1,resource:{buffer:buffer([output.width,output.height,0,0])}}]});\n const draw = encoder.beginRenderPass({label:'Area downsample',colorAttachments:[{view:output.createView(),loadOp:'clear',storeOp:'store'}]});\n draw.setPipeline(down);draw.setBindGroup(0,group);draw.draw(3);draw.end();\n return;\n }\n if (detailEnabled && !warnedConfiguration && (render.aovResolution !== 'display' || !DETAIL_AOVS.every(kind => render.aovs.includes(kind)))) {\n warnedConfiguration = true;\n console.warn(\"EASU albedoDetail needs the displayed render to enable diffuseColor, specularColor and depth AOVs with aovResolution 'display'; upscaling without detail.\");\n }\n const aovs = detailEnabled ? DETAIL_AOVS.map(kind => render.getAovTexture(kind)) : [];\n const detail = aovs.length === 3 && aovs.every(image => image && image.width === output.width && image.height === output.height);\n const entries: GPUBindGroupEntry[] = [{binding:0,resource:input.createView()}, {binding:1,resource:{buffer:buffer([output.width,output.height,min,max])}}];\n if (detail) {\n // Cached images are recorded on their own submission so a failed chain cannot leave them stale.\n let cache: GPUCommandEncoder | undefined;\n const cached = () => cache ??= device.createCommandEncoder({label: 'EASU cache'});\n if (!state.scratch || state.scratch.length !== guideFormats.length || state.scratch[0].width !== input.width || state.scratch[0].height !== input.height) {\n if(state.scratch)retire(device,state.scratch);\n // Low diffuse and specular albedo, then (for silhouettes) nearest hit depth with hit coverage.\n state.scratch = guideFormats.map((format, index) => device.createTexture({label:`EASU low guide ${index}`,size:[input.width,input.height],format,usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.RENDER_ATTACHMENT}));\n state.key = undefined;\n }\n // Low albedo depends only on the AOV contents and beauty size; reuse it across presents.\n const key = [state.scratch[0], ...aovs, ...aovs.map(image => borrowedAovRevision.get(image!))];\n if (!state.key || key.some((value, index) => value !== state.key![index])) {\n const down = pipeline(`Albedo area downsample ${silhouettes}`,albedoDownsampleShader(silhouettes),guideFormats);\n const group = device.createBindGroup({layout:down.getBindGroupLayout(0),entries:[\n {binding:0,resource:aovs[0]!.createView()},{binding:1,resource:aovs[1]!.createView()},\n {binding:2,resource:{buffer:buffer([input.width,input.height,0,0])}},{binding:3,resource:aovs[2]!.createView()}\n ]});\n const draw = cached().beginRenderPass({label:'Albedo area downsample',colorAttachments:state.scratch.map(image=>({view:image.createView(),loadOp:'clear',storeOp:'store'}))});\n draw.setPipeline(down);draw.setBindGroup(0,group);draw.draw(3);draw.end();\n state.key = key;\n }\n aovs.forEach((image,index)=>entries.push({binding:2+index,resource:image!.createView()}));\n entries.push({binding:5,resource:state.scratch[0].createView()},{binding:6,resource:state.scratch[1].createView()});\n if (silhouettes) entries.push({binding:10,resource:state.scratch[2].createView()});\n entries.push({binding:7,resource:{buffer:buffer([EASU_DETAIL.minimumAlbedo,coverage,depth,EASU_DETAIL.depthTolerance])}});\n // The ratio is applied through the same grading and tone mapping as the composed image,\n // tabulated once per display setting.\n const display = render._engine.display, extended = output.format === 'rgba16float';\n const tone = [TONE_MAPPING_MODES[display.toneMapping] ?? 0, extended ? 16 : 1, display.toneMappingExposure, extended ? 1 : 0];\n const grading = [display.contrast, display.saturation, display.temperature, display.tint];\n const toneKey = [...tone, ...grading].join(',');\n state.tone ??= device.createTexture({label:'EASU tone table',size:[TONE_LUT_SIZE,2],format:'rgba32float',usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.RENDER_ATTACHMENT});\n if (state.toneKey !== toneKey) {\n const build = pipeline('EASU tone table',toneLutShader,['rgba32float']);\n const group = device.createBindGroup({layout:build.getBindGroupLayout(0),entries:[{binding:0,resource:{buffer:buffer(tone)}},{binding:1,resource:{buffer:buffer(grading)}}]});\n const draw = cached().beginRenderPass({label:'EASU tone table',colorAttachments:[{view:state.tone.createView(),loadOp:'clear',storeOp:'store'}]});\n draw.setPipeline(build);draw.setBindGroup(0,group);draw.draw(3);draw.end();\n state.toneKey = toneKey;\n }\n const toneEntries: GPUBindGroupEntry[] = [{binding:8,resource:state.tone.createView()},{binding:9,resource:{buffer:buffer([tone[1],EASU_DETAIL.guidedEpsilon,0,0])}}];\n entries.push(...toneEntries);\n if (cache) device.queue.submit([cache.finish()]);\n if (guided) {\n // The local albedo-radiance fit depends on this frame's image, so it runs on every present.\n if (!state.fit || state.fit[0].width !== input.width || state.fit[0].height !== input.height) {\n if (state.fit) retire(device, state.fit);\n state.fit = ['slope','offset'].map(name => device.createTexture({label:`EASU albedo ${name}`,size:[input.width,input.height],format:'rgba16float',usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.RENDER_ATTACHMENT}));\n }\n const fit = pipeline('EASU albedo fit',guidedCoefficientShader,['rgba16float','rgba16float']);\n const group = device.createBindGroup({layout:fit.getBindGroupLayout(0),entries:[{binding:0,resource:input.createView()},\n {binding:1,resource:state.scratch[0].createView()},{binding:2,resource:state.scratch[1].createView()},...toneEntries]});\n const draw = encoder.beginRenderPass({label:'EASU albedo fit',colorAttachments:state.fit.map(image=>({view:image.createView(),loadOp:'clear',storeOp:'store'}))});\n draw.setPipeline(fit);draw.setBindGroup(0,group);draw.draw(3);draw.end();\n entries.push({binding:11,resource:state.fit[0].createView()},{binding:12,resource:state.fit[1].createView()});\n }\n }\n const upscale = pipeline(`FSR 1 EASU ${detail ? `detail ${separate} ${silhouettes} ${guided}` : 'color'} ${output.format}`,detail ? easuDetailShader(separate, silhouettes, guided) : easuShader,[output.format]);\n const group = device.createBindGroup({layout:upscale.getBindGroupLayout(0),entries});\n const draw = encoder.beginRenderPass({label:'FSR 1 EASU',colorAttachments:[{view:output.createView(),loadOp:'clear',storeOp:'store'}]});\n draw.setPipeline(upscale);draw.setBindGroup(0,group);draw.draw(3);draw.end();\n };\n return Object.assign(pass, {dispose() {for(const [device,state] of devices) retire(device,owned(state));devices.clear();}});\n}\n"]}
|
|
@@ -18,6 +18,7 @@ export interface GeometryUpdateRegion {
|
|
|
18
18
|
}
|
|
19
19
|
export interface GeometryUpdateState<M extends GeometryUpdateMesh = GeometryUpdateMesh> {
|
|
20
20
|
geometry: Geometry;
|
|
21
|
+
mergedAttributes?: boolean;
|
|
21
22
|
geometries: Geometry[];
|
|
22
23
|
geometryRegions: Map<Geometry, GeometryUpdateRegion>;
|
|
23
24
|
geometryStates: Map<Geometry, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geometryUpdateState.js","sourceRoot":"","sources":["../../src/renderer/geometryUpdateState.ts"],"names":[],"mappings":"","sourcesContent":["import type Geometry from '../scene/Geometry.js';\nimport type MaterialState from '../scene/MaterialState.js';\nimport type { vec3 } from '../math.js';\nimport type { FlattendBVH } from './bvhAccel.js';\n\n// The update algorithm needs no renderer resources or browser scene facade.\nexport interface GeometryUpdateMesh { geometry: Geometry; materials: MaterialState[]; }\nexport interface GeometryUpdateBinding<M extends GeometryUpdateMesh = GeometryUpdateMesh> {\n mesh: M;\n geometry: Geometry;\n bvhBounds: [vec3.Vec3Array, vec3.Vec3Array];\n}\nexport interface GeometryUpdateRegion { vertexOffset: number; indexOffset: number; materialIndices: number[]; }\nexport interface GeometryUpdateState<M extends GeometryUpdateMesh = GeometryUpdateMesh> {\n geometry: Geometry;\n geometries: Geometry[];\n geometryRegions: Map<Geometry, GeometryUpdateRegion>;\n geometryStates: Map<Geometry, {topologyVersion: number; indices: Geometry['indices']['array']; indexCount: number}>;\n instanceBindings: GeometryUpdateBinding<M>[];\n blases: {bvh: FlattendBVH}[];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"geometryUpdateState.js","sourceRoot":"","sources":["../../src/renderer/geometryUpdateState.ts"],"names":[],"mappings":"","sourcesContent":["import type Geometry from '../scene/Geometry.js';\nimport type MaterialState from '../scene/MaterialState.js';\nimport type { vec3 } from '../math.js';\nimport type { FlattendBVH } from './bvhAccel.js';\n\n// The update algorithm needs no renderer resources or browser scene facade.\nexport interface GeometryUpdateMesh { geometry: Geometry; materials: MaterialState[]; }\nexport interface GeometryUpdateBinding<M extends GeometryUpdateMesh = GeometryUpdateMesh> {\n mesh: M;\n geometry: Geometry;\n bvhBounds: [vec3.Vec3Array, vec3.Vec3Array];\n}\nexport interface GeometryUpdateRegion { vertexOffset: number; indexOffset: number; materialIndices: number[]; }\nexport interface GeometryUpdateState<M extends GeometryUpdateMesh = GeometryUpdateMesh> {\n geometry: Geometry;\n mergedAttributes?: boolean;\n geometries: Geometry[];\n geometryRegions: Map<Geometry, GeometryUpdateRegion>;\n geometryStates: Map<Geometry, {topologyVersion: number; indices: Geometry['indices']['array']; indexCount: number}>;\n instanceBindings: GeometryUpdateBinding<M>[];\n blases: {bvh: FlattendBVH}[];\n}\n"]}
|
|
@@ -107,9 +107,10 @@ export function updatePreparedGeometries(prepared, changed, options = {}) {
|
|
|
107
107
|
blases.push({ blas: bvh, offset });
|
|
108
108
|
}
|
|
109
109
|
geometry.version = source.version;
|
|
110
|
-
|
|
110
|
+
if (prepared.mergedAttributes !== false)
|
|
111
|
+
copyRegion(source, prepared.geometry, region, topologyChanged, deformationOnly);
|
|
111
112
|
const count = source.vertexCount, previousVertices = vertices[vertices.length - 1];
|
|
112
|
-
if (previousVertices && previousVertices.first + previousVertices.count === region.vertexOffset && previousVertices.topologyChanged === topologyChanged && previousVertices.deformationOnly === deformationOnly)
|
|
113
|
+
if (prepared.mergedAttributes !== false && previousVertices && previousVertices.first + previousVertices.count === region.vertexOffset && previousVertices.topologyChanged === topologyChanged && previousVertices.deformationOnly === deformationOnly)
|
|
113
114
|
previousVertices.count += count;
|
|
114
115
|
else
|
|
115
116
|
vertices.push({ first: region.vertexOffset, count, topologyChanged, deformationOnly });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geometryUpdates.js","sourceRoot":"","sources":["../../src/renderer/geometryUpdates.ts"],"names":[],"mappings":"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","sourcesContent":["import {matrixStorage, copyNumericStorage} from '../math/storage.js';\nimport { getGeometryBvh, setGeometryBvh } from './geometryBvh.js';\nimport { writeMaterialIndices } from './materialIndices.js';\nimport { isDeformationUpdate } from '../scene/geometryChanges.js';\nimport type Geometry from '../scene/Geometry.js';\nimport { Attribute } from '../scene/Geometry.js';\nimport { attributeValue, type AttributeData } from '../scene/attributeData.js';\nimport { hasGeneratedVertexTangents } from '../util/geometry.js';\nimport { buildBLAS, refitBLAS, type FlattendBVH } from './bvhAccel.js';\nimport type { GeometryUpdateState, GeometryUpdateMesh, GeometryUpdateRegion, GeometryUpdateBinding } from './geometryUpdateState.js';\nimport {computeGeometryBounds, getBvhBounds } from './geometryBvhBounds.js';\n\ntype Prepared = GeometryUpdateState;\ntype BindingIndices<M extends GeometryUpdateMesh> = {source: Map<Geometry, GeometryUpdateBinding<M>[]>; prepared: Map<Geometry, GeometryUpdateBinding<M>[]>};\nconst vertexAttributes = ['position', 'normal', 'uv', 'uv1', 'color', 'tangent', 'materialIndex'] as const;\n// Box only the identity: widening a generic preparation record for a native\n// WeakMap key can otherwise make a copy instead of retaining the caller's key.\nconst bindingIndices = new WeakMap<object, BindingIndices<GeometryUpdateMesh>>();\nfunction indices<M extends GeometryUpdateMesh>(prepared: GeometryUpdateState<M>) {\n // The prepared object's identity owns its binding type; entries are never\n // shared between preparations with different mesh types.\n let maps = bindingIndices.get(prepared) as BindingIndices<M> | undefined;\n if (!maps) {\n maps = { source: new Map(), prepared: new Map() };\n for (const binding of prepared.instanceBindings) {\n for (const [map, geometry] of [[maps.source, binding.mesh.geometry], [maps.prepared, binding.geometry]] as const) {\n let bindings = map.get(geometry);\n if (!bindings) map.set(geometry, bindings = []);\n bindings.push(binding);\n }\n }\n bindingIndices.set(prepared, maps);\n }\n return maps;\n}\n\n/** Displaced geometry must be prepared as a whole. */\nexport function canUpdateGeometries<M extends GeometryUpdateMesh>(prepared: GeometryUpdateState<M>, geometries: readonly Geometry[]) {\n return geometries.every(geometry => {\n const bindings = indices(prepared).source.get(geometry) ?? [];\n return bindings.length > 0 && bindings.every(b => !b.mesh.materials.some(m => m.displacementMap) &&\n b.geometry.position.array === geometry.position.array);\n });\n}\n\n/** Rewrites only a geometry's existing region, preserving global material indices. */\nfunction copyRegion(source: Geometry, merged: Geometry, region: GeometryUpdateRegion, topologyChanged: boolean, deformationOnly: boolean) {\n const { vertexOffset, indexOffset, materialIndices } = region;\n const count = source.vertexCount;\n for (const name of vertexAttributes) {\n if (name === 'materialIndex' || deformationOnly && name !== 'position' && name !== 'normal' && name !== 'tangent') continue;\n const target = merged[name]; if (!target) continue;\n const attribute = name === 'uv1' ? source.uv1 ?? source.uv : source[name];\n const offset = vertexOffset * target.itemSize;\n if (attribute && attribute.itemSize !== target.itemSize) {\n for (let v = 0; v < count; v++) for (let c = 0; c < target.itemSize; c++) {\n target.array[offset + v * target.itemSize + c] = c < attribute.itemSize ? attribute.array[v * attribute.itemSize + c] : name === 'tangent' && !hasGeneratedVertexTangents(source) ? 2 : 0;\n }\n }\n else if (attribute) target.array.set(attribute.array, offset);\n else target.array.fill(name === 'color' ? 1 : 0, offset, offset + count * target.itemSize);\n }\n if (!topologyChanged) return;\n writeMaterialIndices(source, materialIndices, merged.materialIndex!.array, vertexOffset);\n const indices = source.indexArray;\n for (let i = 0; i < indices.length; i++) writeIndex(merged, indexOffset + i, indices[i] + vertexOffset);\n}\n\n/** Constant-time topology detection; markUpdated also covers in-place index edits. */\nexport function geometryTopologyChanged(prepared: {geometryStates: Prepared['geometryStates']} | undefined, source: Geometry) {\n const state = prepared?.geometryStates.get(source);\n return !!state && (state.topologyVersion !== source.topologyVersion ||\n state.indices !== source.indices.array || state.indexCount !== source.indexArray.length);\n}\n\nexport interface GeometryUpdateOptions {\n softwareBvhs?: boolean;\n displacement?: Map<Geometry, {scale: number; ranges: Float32Array}>;\n}\n\n/** Refits/rebuilds changed BLASes and refreshes all shared instances' cached bounds. */\nexport function updatePreparedGeometries<M extends GeometryUpdateMesh>(prepared: GeometryUpdateState<M>, changed: ReadonlySet<Geometry>, options: GeometryUpdateOptions = {}) {\n const vertices: { first: number; count: number; topologyChanged: boolean; deformationOnly: boolean }[] = [];\n const blases: { blas: FlattendBVH; offset: number }[] = [];\n const meshes = new Set<M>();\n let resized = false, relocated = false, offset = 0;\n const updated = new Map<Geometry, FlattendBVH>();\n prepared.geometries.forEach((geometry, i) => {\n const source = indices(prepared).prepared.get(geometry)?.[0].mesh.geometry ?? geometry;\n const previous = i < prepared.blases.length ? prepared.blases[i].bvh : undefined;\n if (changed.has(source)) {\n const region = prepared.geometryRegions.get(geometry)!;\n const topologyChanged = geometryTopologyChanged(prepared, source);\n const deformationOnly = !topologyChanged && isDeformationUpdate(source);\n if (options.softwareBvhs !== false) {\n const displacement = options.displacement?.get(geometry);\n const key = displacement ? geometry : source;\n let bvh = updated.get(key);\n if (!bvh) {\n bvh = displacement ? getGeometryBvh(geometry) ?? getGeometryBvh(source) : getGeometryBvh(source);\n const detail = displacement ? {normal: source.normal.array,\n scale: displacement.scale, ranges: displacement.ranges} : undefined;\n if (topologyChanged || !bvh || source.dynamic && bvh.builder !== 'builtin' || !refitBLAS(bvh, source, detail)) {\n bvh = buildBLAS(source, displacement?.scale, displacement?.ranges);\n }\n setGeometryBvh(source, bvh); updated.set(key, bvh);\n }\n setGeometryBvh(geometry, bvh);\n prepared.blases[i].bvh = bvh;\n resized ||= previous?.buffer.byteLength !== bvh.buffer.byteLength;\n relocated ||= previous?.buffer.byteLength !== bvh.buffer.byteLength || previous?.layout !== bvh.layout;\n blases.push({blas: bvh, offset});\n }\n geometry.version = source.version;\n copyRegion(source, prepared.geometry, region, topologyChanged, deformationOnly);\n const count = source.vertexCount, previousVertices = vertices[vertices.length - 1];\n if (previousVertices && previousVertices.first + previousVertices.count === region.vertexOffset && previousVertices.topologyChanged === topologyChanged && previousVertices.deformationOnly === deformationOnly) previousVertices.count += count;\n else vertices.push({first: region.vertexOffset, count, topologyChanged, deformationOnly});\n for (const binding of indices(prepared).prepared.get(geometry) ?? []) {\n const bounds = options.softwareBvhs === false ? computeGeometryBounds(geometry) : getBvhBounds(geometry);\n // Keep shared bound arrays: native generic-record values read from a Map\n // can be copies, so replacing their tuple does not update the owner view.\n copyNumericStorage(binding.bvhBounds[0], matrixStorage(bounds[0]));\n copyNumericStorage(binding.bvhBounds[1], matrixStorage(bounds[1]));\n meshes.add(binding.mesh);\n }\n }\n if (i < prepared.blases.length) offset += prepared.blases[i].bvh.buffer.byteLength;\n });\n for (const source of changed) prepared.geometryStates.set(source, { topologyVersion: source.topologyVersion,\n indices: source.indices.array, indexCount: source.indexArray.length });\n return { vertices, blases, meshes, resized, relocated };\n}\n\nfunction writeIndex(geometry: Geometry, index: number, value: number) {\n const array = geometry.indexArray;\n array[index] = value;\n}\n\nfunction packAttribute<T extends AttributeData>(attribute: Attribute<T> | undefined,\n output: Float32Array, stride: number, offset: number, first: number, count: number, outputFirst = first) {\n if (!attribute) return;\n const array = attribute.array, size = attribute.itemSize;\n let destination = outputFirst * stride + offset, source = first * size;\n if (size === 1) {\n for (let i = 0; i < count; i++, destination += stride, source += size) {\n output[destination] = attributeValue(array, source);\n }\n return;\n }\n if (size === 2) {\n for (let i = 0; i < count; i++, destination += stride, source += size) {\n output[destination] = attributeValue(array, source);\n output[destination + 1] = attributeValue(array, source + 1);\n }\n return;\n }\n if (size === 3) {\n for (let i = 0; i < count; i++, destination += stride, source += size) {\n output[destination] = attributeValue(array, source);\n output[destination + 1] = attributeValue(array, source + 1);\n output[destination + 2] = attributeValue(array, source + 2);\n }\n return;\n }\n if (size === 4) {\n for (let i = 0; i < count; i++, destination += stride, source += size) {\n output[destination] = attributeValue(array, source);\n output[destination + 1] = attributeValue(array, source + 1);\n output[destination + 2] = attributeValue(array, source + 2);\n output[destination + 3] = attributeValue(array, source + 3);\n }\n return;\n }\n for (let i = 0; i < count; i++, destination += stride, source += size) {\n for (let c = 0; c < size; c++) output[destination + c] = attributeValue(array, source + c);\n }\n}\n\n/** Packs the same interleaved vertex layout for full and partial GPU uploads. */\nexport function packVertexAttributes(geometry: Geometry, output: Float32Array, stride: number,\n offsets: readonly number[], first: number, count: number, includeMaterialIndex = true, deformationOnly = false, outputFirst = first) {\n packAttribute(geometry.position, output, stride, offsets[0], first, count, outputFirst);\n packAttribute(geometry.normal, output, stride, offsets[1], first, count, outputFirst);\n if (!deformationOnly) {\n packAttribute(geometry.uv, output, stride, offsets[2], first, count, outputFirst);\n packAttribute(geometry.uv1, output, stride, offsets[3], first, count, outputFirst);\n packAttribute(geometry.color, output, stride, offsets[4], first, count, outputFirst);\n }\n packAttribute(geometry.tangent, output, stride, offsets[5], first, count, outputFirst);\n if (includeMaterialIndex) packAttribute(geometry.materialIndex, output, stride, offsets[6], first, count, outputFirst);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"geometryUpdates.js","sourceRoot":"","sources":["../../src/renderer/geometryUpdates.ts"],"names":[],"mappings":"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","sourcesContent":["import {matrixStorage, copyNumericStorage} from '../math/storage.js';\nimport { getGeometryBvh, setGeometryBvh } from './geometryBvh.js';\nimport { writeMaterialIndices } from './materialIndices.js';\nimport { isDeformationUpdate } from '../scene/geometryChanges.js';\nimport type Geometry from '../scene/Geometry.js';\nimport { Attribute } from '../scene/Geometry.js';\nimport { attributeValue, type AttributeData } from '../scene/attributeData.js';\nimport { hasGeneratedVertexTangents } from '../util/geometry.js';\nimport { buildBLAS, refitBLAS, type FlattendBVH } from './bvhAccel.js';\nimport type { GeometryUpdateState, GeometryUpdateMesh, GeometryUpdateRegion, GeometryUpdateBinding } from './geometryUpdateState.js';\nimport {computeGeometryBounds, getBvhBounds } from './geometryBvhBounds.js';\n\ntype Prepared = GeometryUpdateState;\ntype BindingIndices<M extends GeometryUpdateMesh> = {source: Map<Geometry, GeometryUpdateBinding<M>[]>; prepared: Map<Geometry, GeometryUpdateBinding<M>[]>};\nconst vertexAttributes = ['position', 'normal', 'uv', 'uv1', 'color', 'tangent', 'materialIndex'] as const;\n// Box only the identity: widening a generic preparation record for a native\n// WeakMap key can otherwise make a copy instead of retaining the caller's key.\nconst bindingIndices = new WeakMap<object, BindingIndices<GeometryUpdateMesh>>();\nfunction indices<M extends GeometryUpdateMesh>(prepared: GeometryUpdateState<M>) {\n // The prepared object's identity owns its binding type; entries are never\n // shared between preparations with different mesh types.\n let maps = bindingIndices.get(prepared) as BindingIndices<M> | undefined;\n if (!maps) {\n maps = { source: new Map(), prepared: new Map() };\n for (const binding of prepared.instanceBindings) {\n for (const [map, geometry] of [[maps.source, binding.mesh.geometry], [maps.prepared, binding.geometry]] as const) {\n let bindings = map.get(geometry);\n if (!bindings) map.set(geometry, bindings = []);\n bindings.push(binding);\n }\n }\n bindingIndices.set(prepared, maps);\n }\n return maps;\n}\n\n/** Displaced geometry must be prepared as a whole. */\nexport function canUpdateGeometries<M extends GeometryUpdateMesh>(prepared: GeometryUpdateState<M>, geometries: readonly Geometry[]) {\n return geometries.every(geometry => {\n const bindings = indices(prepared).source.get(geometry) ?? [];\n return bindings.length > 0 && bindings.every(b => !b.mesh.materials.some(m => m.displacementMap) &&\n b.geometry.position.array === geometry.position.array);\n });\n}\n\n/** Rewrites only a geometry's existing region, preserving global material indices. */\nfunction copyRegion(source: Geometry, merged: Geometry, region: GeometryUpdateRegion, topologyChanged: boolean, deformationOnly: boolean) {\n const { vertexOffset, indexOffset, materialIndices } = region;\n const count = source.vertexCount;\n for (const name of vertexAttributes) {\n if (name === 'materialIndex' || deformationOnly && name !== 'position' && name !== 'normal' && name !== 'tangent') continue;\n const target = merged[name]; if (!target) continue;\n const attribute = name === 'uv1' ? source.uv1 ?? source.uv : source[name];\n const offset = vertexOffset * target.itemSize;\n if (attribute && attribute.itemSize !== target.itemSize) {\n for (let v = 0; v < count; v++) for (let c = 0; c < target.itemSize; c++) {\n target.array[offset + v * target.itemSize + c] = c < attribute.itemSize ? attribute.array[v * attribute.itemSize + c] : name === 'tangent' && !hasGeneratedVertexTangents(source) ? 2 : 0;\n }\n }\n else if (attribute) target.array.set(attribute.array, offset);\n else target.array.fill(name === 'color' ? 1 : 0, offset, offset + count * target.itemSize);\n }\n if (!topologyChanged) return;\n writeMaterialIndices(source, materialIndices, merged.materialIndex!.array, vertexOffset);\n const indices = source.indexArray;\n for (let i = 0; i < indices.length; i++) writeIndex(merged, indexOffset + i, indices[i] + vertexOffset);\n}\n\n/** Constant-time topology detection; markUpdated also covers in-place index edits. */\nexport function geometryTopologyChanged(prepared: {geometryStates: Prepared['geometryStates']} | undefined, source: Geometry) {\n const state = prepared?.geometryStates.get(source);\n return !!state && (state.topologyVersion !== source.topologyVersion ||\n state.indices !== source.indices.array || state.indexCount !== source.indexArray.length);\n}\n\nexport interface GeometryUpdateOptions {\n softwareBvhs?: boolean;\n displacement?: Map<Geometry, {scale: number; ranges: Float32Array}>;\n}\n\n/** Refits/rebuilds changed BLASes and refreshes all shared instances' cached bounds. */\nexport function updatePreparedGeometries<M extends GeometryUpdateMesh>(prepared: GeometryUpdateState<M>, changed: ReadonlySet<Geometry>, options: GeometryUpdateOptions = {}) {\n const vertices: { first: number; count: number; topologyChanged: boolean; deformationOnly: boolean }[] = [];\n const blases: { blas: FlattendBVH; offset: number }[] = [];\n const meshes = new Set<M>();\n let resized = false, relocated = false, offset = 0;\n const updated = new Map<Geometry, FlattendBVH>();\n prepared.geometries.forEach((geometry, i) => {\n const source = indices(prepared).prepared.get(geometry)?.[0].mesh.geometry ?? geometry;\n const previous = i < prepared.blases.length ? prepared.blases[i].bvh : undefined;\n if (changed.has(source)) {\n const region = prepared.geometryRegions.get(geometry)!;\n const topologyChanged = geometryTopologyChanged(prepared, source);\n const deformationOnly = !topologyChanged && isDeformationUpdate(source);\n if (options.softwareBvhs !== false) {\n const displacement = options.displacement?.get(geometry);\n const key = displacement ? geometry : source;\n let bvh = updated.get(key);\n if (!bvh) {\n bvh = displacement ? getGeometryBvh(geometry) ?? getGeometryBvh(source) : getGeometryBvh(source);\n const detail = displacement ? {normal: source.normal.array,\n scale: displacement.scale, ranges: displacement.ranges} : undefined;\n if (topologyChanged || !bvh || source.dynamic && bvh.builder !== 'builtin' || !refitBLAS(bvh, source, detail)) {\n bvh = buildBLAS(source, displacement?.scale, displacement?.ranges);\n }\n setGeometryBvh(source, bvh); updated.set(key, bvh);\n }\n setGeometryBvh(geometry, bvh);\n prepared.blases[i].bvh = bvh;\n resized ||= previous?.buffer.byteLength !== bvh.buffer.byteLength;\n relocated ||= previous?.buffer.byteLength !== bvh.buffer.byteLength || previous?.layout !== bvh.layout;\n blases.push({blas: bvh, offset});\n }\n geometry.version = source.version;\n if (prepared.mergedAttributes !== false) copyRegion(source, prepared.geometry, region, topologyChanged, deformationOnly);\n const count = source.vertexCount, previousVertices = vertices[vertices.length - 1];\n if (prepared.mergedAttributes !== false && previousVertices && previousVertices.first + previousVertices.count === region.vertexOffset && previousVertices.topologyChanged === topologyChanged && previousVertices.deformationOnly === deformationOnly) previousVertices.count += count;\n else vertices.push({first: region.vertexOffset, count, topologyChanged, deformationOnly});\n for (const binding of indices(prepared).prepared.get(geometry) ?? []) {\n const bounds = options.softwareBvhs === false ? computeGeometryBounds(geometry) : getBvhBounds(geometry);\n // Keep shared bound arrays: native generic-record values read from a Map\n // can be copies, so replacing their tuple does not update the owner view.\n copyNumericStorage(binding.bvhBounds[0], matrixStorage(bounds[0]));\n copyNumericStorage(binding.bvhBounds[1], matrixStorage(bounds[1]));\n meshes.add(binding.mesh);\n }\n }\n if (i < prepared.blases.length) offset += prepared.blases[i].bvh.buffer.byteLength;\n });\n for (const source of changed) prepared.geometryStates.set(source, { topologyVersion: source.topologyVersion,\n indices: source.indices.array, indexCount: source.indexArray.length });\n return { vertices, blases, meshes, resized, relocated };\n}\n\nfunction writeIndex(geometry: Geometry, index: number, value: number) {\n const array = geometry.indexArray;\n array[index] = value;\n}\n\nfunction packAttribute<T extends AttributeData>(attribute: Attribute<T> | undefined,\n output: Float32Array, stride: number, offset: number, first: number, count: number, outputFirst = first) {\n if (!attribute) return;\n const array = attribute.array, size = attribute.itemSize;\n let destination = outputFirst * stride + offset, source = first * size;\n if (size === 1) {\n for (let i = 0; i < count; i++, destination += stride, source += size) {\n output[destination] = attributeValue(array, source);\n }\n return;\n }\n if (size === 2) {\n for (let i = 0; i < count; i++, destination += stride, source += size) {\n output[destination] = attributeValue(array, source);\n output[destination + 1] = attributeValue(array, source + 1);\n }\n return;\n }\n if (size === 3) {\n for (let i = 0; i < count; i++, destination += stride, source += size) {\n output[destination] = attributeValue(array, source);\n output[destination + 1] = attributeValue(array, source + 1);\n output[destination + 2] = attributeValue(array, source + 2);\n }\n return;\n }\n if (size === 4) {\n for (let i = 0; i < count; i++, destination += stride, source += size) {\n output[destination] = attributeValue(array, source);\n output[destination + 1] = attributeValue(array, source + 1);\n output[destination + 2] = attributeValue(array, source + 2);\n output[destination + 3] = attributeValue(array, source + 3);\n }\n return;\n }\n for (let i = 0; i < count; i++, destination += stride, source += size) {\n for (let c = 0; c < size; c++) output[destination + c] = attributeValue(array, source + c);\n }\n}\n\n/** Packs the same interleaved vertex layout for full and partial GPU uploads. */\nexport function packVertexAttributes(geometry: Geometry, output: Float32Array, stride: number,\n offsets: readonly number[], first: number, count: number, includeMaterialIndex = true, deformationOnly = false, outputFirst = first) {\n packAttribute(geometry.position, output, stride, offsets[0], first, count, outputFirst);\n packAttribute(geometry.normal, output, stride, offsets[1], first, count, outputFirst);\n if (!deformationOnly) {\n packAttribute(geometry.uv, output, stride, offsets[2], first, count, outputFirst);\n packAttribute(geometry.uv1, output, stride, offsets[3], first, count, outputFirst);\n packAttribute(geometry.color, output, stride, offsets[4], first, count, outputFirst);\n }\n packAttribute(geometry.tangent, output, stride, offsets[5], first, count, outputFirst);\n if (includeMaterialIndex) packAttribute(geometry.materialIndex, output, stride, offsets[6], first, count, outputFirst);\n}\n"]}
|
|
@@ -9,7 +9,7 @@ export default new FragmentShader({
|
|
|
9
9
|
mapping: Shader.uniform('vec4'), idComponent: Shader.uniform('int')
|
|
10
10
|
},
|
|
11
11
|
main: /* glsl */ `
|
|
12
|
-
uint
|
|
12
|
+
uint xo(uint v) {
|
|
13
13
|
v = (v ^ (v >> 16u)) * 0x7feb352du;
|
|
14
14
|
v = (v ^ (v >> 15u)) * 0x846ca68bu;
|
|
15
15
|
return v ^ (v >> 16u);
|
|
@@ -36,16 +36,16 @@ color = srgb(clamp(r.xyz / max(r.w, 1.0), 0.0, 1.0));
|
|
|
36
36
|
} else if (kind == 5) {
|
|
37
37
|
uvec4 ids = texelFetch(identity, p, 0);
|
|
38
38
|
alpha = ids.x == 0xffffffffu ? 0.0 : 1.0;
|
|
39
|
-
uint h =
|
|
39
|
+
uint h = xo(ids[idComponent]);
|
|
40
40
|
color = .2 + .8 * vec3(float(h & 255u), float((h >> 8u) & 255u),
|
|
41
41
|
float((h >> 16u) & 255u)) / 255.0;
|
|
42
42
|
} else {
|
|
43
43
|
vec4 m = texelFetch(motion, p, 0);
|
|
44
44
|
alpha = m.w == 3.0 ? 1.0 : 0.0;
|
|
45
|
-
float
|
|
46
|
-
if (
|
|
45
|
+
float gT = length(m.xy), hue = 0.0;
|
|
46
|
+
if (gT > 0.0) hue = fract(atan(m.y, m.x) / 6.28318530718 + 1.0);
|
|
47
47
|
vec3 v = abs(fract(vec3(hue) + vec3(0.0, 2.0 / 3.0, 1.0 / 3.0)) * 6.0 - 3.0);
|
|
48
|
-
color = clamp(v - 1.0, 0.0, 1.0) * clamp(
|
|
48
|
+
color = clamp(v - 1.0, 0.0, 1.0) * clamp(gT / mapping.w, 0.0, 1.0);
|
|
49
49
|
}
|
|
50
50
|
if (alpha <= 0.0) color = vec3(0.0);
|
|
51
51
|
out_color = vec4(color, clamp(alpha, 0.0, 1.0));
|
|
@@ -1,58 +1,58 @@
|
|
|
1
1
|
import proposals from './aovReflectanceSamples.glsl.js';
|
|
2
2
|
// GLSL mirror of the shared 256-proposal, fused OpenPBR reflection quadrature.
|
|
3
3
|
export default proposals + /* glsl */ `
|
|
4
|
-
void aovReflectance(OpenPbrPreparedBsdf prepared, bool
|
|
4
|
+
void aovReflectance(OpenPbrPreparedBsdf prepared, bool rV, bool lp, out vec3 diffuse, out vec3 specular) {
|
|
5
5
|
diffuse=vec3(0.0); specular=vec3(0.0);
|
|
6
6
|
vec3 view = prepared.viewLocal;
|
|
7
7
|
if (view.z <= 1e-6) { return; }
|
|
8
8
|
OpenPbrResolvedMaterial material = prepared.material;
|
|
9
9
|
vec2 alpha = vec2(material.alphaX, material.alphaY);
|
|
10
|
-
float
|
|
11
|
-
float
|
|
12
|
-
float
|
|
10
|
+
float mG = aD(view, alpha);
|
|
11
|
+
float jw = prepared.weights[OPENPBR_LOBE_DIFFUSE];
|
|
12
|
+
float fZ = prepared.weights[OPENPBR_LOBE_METAL];
|
|
13
13
|
float specularWeight = prepared.weights[OPENPBR_LOBE_SPECULAR];
|
|
14
|
-
float
|
|
15
|
-
if (
|
|
16
|
-
|
|
14
|
+
float dY = 1.0;
|
|
15
|
+
if (lp && prepared.dielectricMsProbability > 0.0) {
|
|
16
|
+
dY = max(aZ(prepared.refractionEtaTOverEtaI, prepared.specularAlpha), 1e-12);
|
|
17
17
|
}
|
|
18
|
-
vec3
|
|
19
|
-
float
|
|
20
|
-
float
|
|
18
|
+
vec3 cf = normalize(vec3(alpha, 1.0) * view);
|
|
19
|
+
float rU = min(cf.z, 1.0);
|
|
20
|
+
float ku = 1.0 + rU;
|
|
21
21
|
uint count = 256u;
|
|
22
22
|
for (uint i = 0u; i < uint(NO_UNROLL(256)); i++) {
|
|
23
|
-
uint
|
|
24
|
-
vec2 u = vec2((float(
|
|
25
|
-
fract(float(reverseBits(
|
|
26
|
-
vec4 proposal =
|
|
23
|
+
uint pair = i / 2u;
|
|
24
|
+
vec2 u = vec2((float(pair) + 0.5) / float(count / 2u),
|
|
25
|
+
fract(float(reverseBits(pair)) * 2.3283064365386963e-10 + 0.37));
|
|
26
|
+
vec4 proposal = ht[pair];
|
|
27
27
|
|
|
28
|
-
bool
|
|
28
|
+
bool hP = prepared.specularAlpha < 0.001;
|
|
29
29
|
vec3 light = vec3(proposal.xy, sqrt(max(0.0, 1.0 - dot(proposal.xy, proposal.xy))));
|
|
30
|
-
if (
|
|
30
|
+
if (hP) { light = aM(u); }
|
|
31
31
|
if ((i & 1u) != 0u) {
|
|
32
|
-
float
|
|
33
|
-
float
|
|
34
|
-
vec3 aa = normalize(vec3(alpha, 1.0) * vec3(
|
|
35
|
-
if (
|
|
32
|
+
float kM = (1.0 - u.y) * ku;
|
|
33
|
+
float dw = sqrt(max(0.0, (kM + (1.0 - rU)) * (u.y * ku)));
|
|
34
|
+
vec3 aa = normalize(vec3(alpha, 1.0) * vec3(cf.xy + dw * proposal.zw, kM));
|
|
35
|
+
if (hP) { aa = aA(view, alpha, u); }
|
|
36
36
|
light = reflect(-view, aa);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
if (light.z <= 0.0) { continue; }
|
|
40
40
|
vec3 aa = normalize(view + light);
|
|
41
|
-
float specularPdf =
|
|
41
|
+
float specularPdf = mG * sampling_ggx_ndf(aa, alpha) / (4.0 * view.z);
|
|
42
42
|
float pdf = 0.5 * (light.z * INVPI + specularPdf);
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
vec3 au = openpbr_to_local(prepared.basis, openpbr_to_world(prepared.basis, light));
|
|
46
46
|
if (au.z <= 0.0) { continue; }
|
|
47
47
|
float scale = abs(au.z) / (pdf * float(count));
|
|
48
|
-
if (
|
|
48
|
+
if (rV && jw > 0.0) {
|
|
49
49
|
float compensation = prepared.diffuseSpecularEnergyCompensation * ar(
|
|
50
50
|
prepared.specularEtaTOverEtaI, prepared.specularAlpha, abs(au.z));
|
|
51
51
|
float unusedPdf = 0.0;
|
|
52
|
-
diffuse +=
|
|
52
|
+
diffuse += jw * bB(material, prepared.diffuseColor,
|
|
53
53
|
view, au, compensation, unusedPdf) * scale;
|
|
54
54
|
}
|
|
55
|
-
if (
|
|
55
|
+
if (lp) {
|
|
56
56
|
vec3 evaluatedHalf = normalize(view + au);
|
|
57
57
|
float viewHalf = abs(dot(view, evaluatedHalf));
|
|
58
58
|
vec3 fresnel = vec3(0.0);
|
|
@@ -61,22 +61,22 @@ vec3 dielectric = vec3(ae(viewHalf, material.relativeIor));
|
|
|
61
61
|
if (material.thinWalled) { dielectric = aq(dielectric, material.transmissionWeight); }
|
|
62
62
|
fresnel += specularWeight * material.specularColor * dielectric;
|
|
63
63
|
}
|
|
64
|
-
if (
|
|
65
|
-
fresnel +=
|
|
64
|
+
if (fZ > 0.0) {
|
|
65
|
+
fresnel += fZ * material.specularWeight * openpbr_metal_fresnel(viewHalf,
|
|
66
66
|
material.baseWeight * material.baseColor, material.specularColor);
|
|
67
67
|
}
|
|
68
|
-
float
|
|
68
|
+
float sT = sampling_ggx_ndf(evaluatedHalf, alpha) * mG
|
|
69
69
|
* aD(au, alpha) / (4.0 * max(au.z * view.z, 1e-8));
|
|
70
|
-
vec3 reflection = fresnel *
|
|
71
|
-
if (
|
|
72
|
-
float
|
|
73
|
-
reflection +=
|
|
70
|
+
vec3 reflection = fresnel * sT;
|
|
71
|
+
if (fZ > 0.0 && prepared.metalMsFactor > 0.0) {
|
|
72
|
+
float cA = min(prepared.metalMsFactor * aR(prepared.specularAlpha, au.z), 1.0 / max(au.z, 1e-8));
|
|
73
|
+
reflection += fZ * prepared.metalMsScale * cA * INVPI;
|
|
74
74
|
}
|
|
75
75
|
if (prepared.dielectricMsProbability > 0.0) {
|
|
76
|
-
float
|
|
77
|
-
prepared.refractionEtaTOverEtaI, prepared.specularAlpha, abs(au.z)) /
|
|
78
|
-
float
|
|
79
|
-
reflection += prepared.dielectricMsReflectionScale *
|
|
76
|
+
float pX = prepared.dielectricMsViewLoss * aV(
|
|
77
|
+
prepared.refractionEtaTOverEtaI, prepared.specularAlpha, abs(au.z)) / dY;
|
|
78
|
+
float cA = min(pX * prepared.dielectricMsReflectionRatio, 1.0 / abs(au.z));
|
|
79
|
+
reflection += prepared.dielectricMsReflectionScale * cA * INVPI;
|
|
80
80
|
}
|
|
81
81
|
specular += reflection * scale;
|
|
82
82
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Generated by scripts/generate-aov-reflectance-samples.mjs; do not edit.
|
|
2
2
|
// xy: concentric cosine disk; zw: spherical-cap azimuth cosine/sine.
|
|
3
3
|
export default /* glsl */ `
|
|
4
|
-
const vec4
|
|
4
|
+
const vec4 ht[128] = vec4[128](
|
|
5
5
|
vec4(-0.971247852, -0.202764958, 0.999698818, 0.0245412290),
|
|
6
6
|
vec4(-0.808660269, 0.547487736, 0.997290432, 0.0735645667),
|
|
7
7
|
vec4(-0.942509234, 0.187289074, 0.992479563, 0.122410677),
|