@aura3d/rendering 1.3.3 → 1.4.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.
Files changed (314) hide show
  1. package/dist/ForwardPass.js +7 -1
  2. package/dist/ForwardPass.js.map +1 -1
  3. package/dist/MorphTarget.d.ts +1 -0
  4. package/dist/MorphTarget.d.ts.map +1 -1
  5. package/dist/MorphTarget.js.map +1 -1
  6. package/dist/Renderer.js +7 -1
  7. package/dist/Renderer.js.map +1 -1
  8. package/package.json +38 -4
  9. package/src/ArchitecturalLightingFixtures.ts +0 -241
  10. package/src/ArchitecturalMaterialCatalog.ts +0 -130
  11. package/src/ArchitecturalMeasurementFixtures.ts +0 -155
  12. package/src/BRDFLut.ts +0 -47
  13. package/src/CameraFraming.ts +0 -200
  14. package/src/CanonicalSceneFixtures.ts +0 -95
  15. package/src/CascadedShadowMaps.ts +0 -449
  16. package/src/ColorManagement.ts +0 -127
  17. package/src/CullingFixtures.ts +0 -280
  18. package/src/DecalGeometry.ts +0 -26
  19. package/src/DepthPass.ts +0 -110
  20. package/src/EnvironmentBackgroundPass.ts +0 -194
  21. package/src/EnvironmentBackgroundResources.ts +0 -309
  22. package/src/EnvironmentLighting.ts +0 -96
  23. package/src/EnvironmentMapResources.ts +0 -1026
  24. package/src/EnvironmentPipeline.ts +0 -69
  25. package/src/EnvironmentPlatform.ts +0 -1306
  26. package/src/EnvironmentPreset.ts +0 -155
  27. package/src/Exposure.ts +0 -66
  28. package/src/ExternalParityRenderPreset.ts +0 -725
  29. package/src/ForwardPass.ts +0 -1663
  30. package/src/FrameVisualMetrics.ts +0 -301
  31. package/src/Geometry.ts +0 -461
  32. package/src/GeometryPrimitives.ts +0 -2
  33. package/src/HDRRenderPipeline.ts +0 -94
  34. package/src/IBL.ts +0 -86
  35. package/src/IndexBuffer.ts +0 -57
  36. package/src/InstancedPBRMaterial.ts +0 -186
  37. package/src/InstancedUnlitMaterial.ts +0 -60
  38. package/src/Instancing.ts +0 -19
  39. package/src/LightCollector.ts +0 -82
  40. package/src/LightUniforms.ts +0 -47
  41. package/src/LightingDebug.ts +0 -80
  42. package/src/LightingDefaults.ts +0 -79
  43. package/src/LightingRig.ts +0 -301
  44. package/src/LineGeometry.ts +0 -2
  45. package/src/Material.ts +0 -209
  46. package/src/MaterialBinding.ts +0 -131
  47. package/src/MaterialInstance.ts +0 -59
  48. package/src/MaterialPresets.ts +0 -272
  49. package/src/MorphTarget.ts +0 -123
  50. package/src/MorphTargetPlan.ts +0 -178
  51. package/src/MorphUnlitMaterial.ts +0 -60
  52. package/src/NormalMappedPBRMaterial.ts +0 -188
  53. package/src/OceanFixtures.ts +0 -318
  54. package/src/PBRLightingDefaults.ts +0 -12
  55. package/src/PBRMaterial.ts +0 -442
  56. package/src/PMREM.ts +0 -53
  57. package/src/PbrReference.ts +0 -681
  58. package/src/PostProcessPass.ts +0 -2507
  59. package/src/ProceduralTextureFixtures.ts +0 -393
  60. package/src/ProductTurntableFixtures.ts +0 -815
  61. package/src/Raycaster.ts +0 -21
  62. package/src/ReflectionProbe.ts +0 -13
  63. package/src/ReflectionSurfaces.ts +0 -219
  64. package/src/RenderBackend.ts +0 -43
  65. package/src/RenderDebugViews.ts +0 -138
  66. package/src/RenderDevice.ts +0 -836
  67. package/src/RenderGraph.ts +0 -194
  68. package/src/RenderPass.ts +0 -27
  69. package/src/RenderPipeline.ts +0 -101
  70. package/src/RenderQueue.ts +0 -12
  71. package/src/RenderState.ts +0 -12
  72. package/src/Renderer.ts +0 -2626
  73. package/src/RendererDebugOverlay.ts +0 -80
  74. package/src/RendererFeatureGates.ts +0 -150
  75. package/src/RendererPostprocessPlan.ts +0 -279
  76. package/src/RendererTiming.ts +0 -251
  77. package/src/RendererVisualPipelineReport.ts +0 -836
  78. package/src/ResourceLifecycle.ts +0 -21
  79. package/src/Sampler.ts +0 -37
  80. package/src/SceneOptimization.ts +0 -518
  81. package/src/ShaderChunks.ts +0 -393
  82. package/src/ShaderLibrary.ts +0 -2766
  83. package/src/ShaderModule.ts +0 -36
  84. package/src/ShaderPreprocessor.ts +0 -260
  85. package/src/ShaderReflection.ts +0 -201
  86. package/src/ShadowMap.ts +0 -237
  87. package/src/ShadowPass.ts +0 -198
  88. package/src/ShadowProjection.ts +0 -115
  89. package/src/SkinnedLitMaterial.ts +0 -397
  90. package/src/SkinnedUnlitMaterial.ts +0 -63
  91. package/src/SkinningBounds.ts +0 -131
  92. package/src/SpaceEnvironmentFixtures.ts +0 -200
  93. package/src/SpriteGeometry.ts +0 -21
  94. package/src/StereoCameraRig.ts +0 -127
  95. package/src/StereoEffects.ts +0 -274
  96. package/src/TerrainFixtures.ts +0 -180
  97. package/src/Texture.ts +0 -307
  98. package/src/TextureBinding.ts +0 -91
  99. package/src/TexturedPBRMaterial.ts +0 -1112
  100. package/src/TexturedUnlitMaterial.ts +0 -67
  101. package/src/ToneMapping.ts +0 -105
  102. package/src/UniformBinder.ts +0 -16
  103. package/src/UniformLayout.ts +0 -129
  104. package/src/UnlitMaterial.ts +0 -75
  105. package/src/VegetationFixtures.ts +0 -314
  106. package/src/VertexBuffer.ts +0 -120
  107. package/src/VertexFormat.ts +0 -171
  108. package/src/VoxelWorldFixtures.ts +0 -280
  109. package/src/WeatherFixtures.ts +0 -223
  110. package/src/WebGL2Device.ts +0 -2280
  111. package/src/WebGL2StateCache.ts +0 -330
  112. package/src/WebGPUDevice.ts +0 -2877
  113. package/src/WebGPURenderToTextureProof.ts +0 -139
  114. package/src/advanced-runtime/AdvancedRenderer.ts +0 -73
  115. package/src/advanced-runtime/index.ts +0 -9
  116. package/src/animation/AnimationMaterialStyle.ts +0 -32
  117. package/src/animation/AnimationRenderPreset.ts +0 -45
  118. package/src/animation/AnimationToonMaterial.ts +0 -387
  119. package/src/animation/AnimationVisualQuality.ts +0 -71
  120. package/src/animation/applyAnimationRenderPreset.ts +0 -180
  121. package/src/animation/index.ts +0 -5
  122. package/src/cinematic/BloomPass.ts +0 -26
  123. package/src/cinematic/CinematicDepthComposition.ts +0 -30
  124. package/src/cinematic/CinematicEvidence.ts +0 -123
  125. package/src/cinematic/CinematicLightingRig.ts +0 -144
  126. package/src/cinematic/CinematicMaterialPresets.ts +0 -130
  127. package/src/cinematic/CinematicPostProcess.ts +0 -83
  128. package/src/cinematic/DepthHazePass.ts +0 -30
  129. package/src/cinematic/EmissivePracticalLightSystem.ts +0 -45
  130. package/src/cinematic/FilmGrainPass.ts +0 -24
  131. package/src/cinematic/FogVolumeSystem.ts +0 -30
  132. package/src/cinematic/GlowCardSystem.ts +0 -44
  133. package/src/cinematic/RainParticleSystem.ts +0 -151
  134. package/src/cinematic/VignettePass.ts +0 -25
  135. package/src/cinematic/WetReflectionApproximation.ts +0 -27
  136. package/src/cinematic/index.ts +0 -14
  137. package/src/effects/CollisionModule.ts +0 -64
  138. package/src/effects/ColorModule.ts +0 -60
  139. package/src/effects/ForceModule.ts +0 -25
  140. package/src/effects/GPUParticleBackend.ts +0 -569
  141. package/src/effects/Particle.ts +0 -108
  142. package/src/effects/ParticleDiagnostics.ts +0 -224
  143. package/src/effects/ParticleEffectPresets.ts +0 -147
  144. package/src/effects/ParticleEmitter.ts +0 -326
  145. package/src/effects/ParticleModule.ts +0 -26
  146. package/src/effects/ParticleRenderPass.ts +0 -117
  147. package/src/effects/ParticleRenderer.ts +0 -132
  148. package/src/effects/ParticleSystem.ts +0 -333
  149. package/src/effects/SizeModule.ts +0 -56
  150. package/src/effects/TrailModule.ts +0 -72
  151. package/src/effects/VelocityModule.ts +0 -75
  152. package/src/effects/index.ts +0 -15
  153. package/src/index.ts +0 -925
  154. package/src/materials/AlphaSorting.ts +0 -30
  155. package/src/materials/MaterialExtensions.ts +0 -42
  156. package/src/materials/PhysicalMaterial.ts +0 -133
  157. package/src/materials/TransmissionPass.ts +0 -51
  158. package/src/performance/BVH.ts +0 -18
  159. package/src/performance/Batcher.ts +0 -2
  160. package/src/performance/FrustumCuller.ts +0 -9
  161. package/src/performance/LOD.ts +0 -20
  162. package/src/performance/Octree.ts +0 -10
  163. package/src/performance/RenderItemSorting.ts +0 -170
  164. package/src/performance/RendererStats.ts +0 -43
  165. package/src/performance/ResourceBudget.ts +0 -44
  166. package/src/postprocess/BloomPass.ts +0 -28
  167. package/src/postprocess/CinematicDiagnostics.ts +0 -642
  168. package/src/postprocess/ColorGradingPass.ts +0 -24
  169. package/src/postprocess/DepthOfFieldPass.ts +0 -12
  170. package/src/postprocess/EffectComposer.ts +0 -349
  171. package/src/postprocess/SSAOPass.ts +0 -20
  172. package/src/postprocess/index.ts +0 -34
  173. package/src/production-runtime/AnimationControlsPipeline.ts +0 -77
  174. package/src/production-runtime/PBRHDRPipeline.ts +0 -381
  175. package/src/production-runtime/ProductionEffectsPipeline.ts +0 -85
  176. package/src/production-runtime/ProductionRendererTypes.ts +0 -136
  177. package/src/production-runtime/ProductionRuntimeRenderer.ts +0 -172
  178. package/src/production-runtime/ProductionWebGL2Renderer.ts +0 -313
  179. package/src/production-runtime/ProductionWebGPURenderer.ts +0 -396
  180. package/src/production-runtime/TransmissionBackdropCapture.ts +0 -130
  181. package/src/production-runtime/animation/MorphTargetRenderer.ts +0 -2
  182. package/src/production-runtime/animation/SkinningRenderer.ts +0 -2
  183. package/src/production-runtime/backends/RendererBackend.ts +0 -17
  184. package/src/production-runtime/backends/WebGL2RendererBackend.ts +0 -30
  185. package/src/production-runtime/backends/WebGPURendererBackend.ts +0 -24
  186. package/src/production-runtime/backends/webgl2/WebGL2Buffer.ts +0 -2
  187. package/src/production-runtime/backends/webgl2/WebGL2Capabilities.ts +0 -2
  188. package/src/production-runtime/backends/webgl2/WebGL2RenderTarget.ts +0 -2
  189. package/src/production-runtime/backends/webgl2/WebGL2Shader.ts +0 -2
  190. package/src/production-runtime/backends/webgl2/WebGL2StateCache.ts +0 -1
  191. package/src/production-runtime/backends/webgl2/WebGL2Texture.ts +0 -2
  192. package/src/production-runtime/backends/webgpu/WebGPUBuffer.ts +0 -2
  193. package/src/production-runtime/backends/webgpu/WebGPUCapabilities.ts +0 -2
  194. package/src/production-runtime/backends/webgpu/WebGPURenderTarget.ts +0 -2
  195. package/src/production-runtime/backends/webgpu/WebGPUShader.ts +0 -2
  196. package/src/production-runtime/backends/webgpu/WebGPUTexture.ts +0 -2
  197. package/src/production-runtime/color/ColorManagement.ts +0 -3
  198. package/src/production-runtime/color/ToneMapping.ts +0 -7
  199. package/src/production-runtime/diagnostics/FrameCapture.ts +0 -2
  200. package/src/production-runtime/diagnostics/GPUCapabilities.ts +0 -2
  201. package/src/production-runtime/diagnostics/RendererStats.ts +0 -2
  202. package/src/production-runtime/environment/EnvironmentMap.ts +0 -1
  203. package/src/production-runtime/environment/HDRLoader.ts +0 -57
  204. package/src/production-runtime/environment/PMREMGenerator.ts +0 -713
  205. package/src/production-runtime/framegraph/FrameGraph.ts +0 -18
  206. package/src/production-runtime/framegraph/RenderPass.ts +0 -15
  207. package/src/production-runtime/geometry/ProjectedDecalGeometry.ts +0 -439
  208. package/src/production-runtime/index.ts +0 -127
  209. package/src/production-runtime/lights/LightManager.ts +0 -7
  210. package/src/production-runtime/lights/ShadowMapRenderer.ts +0 -5
  211. package/src/production-runtime/materials/GLTFMaterialAdapter.ts +0 -6
  212. package/src/production-runtime/materials/GLTFPBRMaterialAdapter.ts +0 -2
  213. package/src/production-runtime/materials/MaterialCompiler.ts +0 -7
  214. package/src/production-runtime/materials/MaterialTextureBindings.ts +0 -5
  215. package/src/production-runtime/materials/PBRMaterial.ts +0 -2
  216. package/src/production-runtime/materials/PBRShaderFeatures.ts +0 -2
  217. package/src/production-runtime/passes/ContactShadowPass.ts +0 -184
  218. package/src/production-runtime/passes/DepthPrepass.ts +0 -7
  219. package/src/production-runtime/passes/OpaquePass.ts +0 -7
  220. package/src/production-runtime/passes/ShadowPass.ts +0 -7
  221. package/src/production-runtime/passes/SkyboxPass.ts +0 -7
  222. package/src/production-runtime/passes/ToneMappingPass.ts +0 -7
  223. package/src/production-runtime/passes/TransparentPass.ts +0 -7
  224. package/src/production-runtime/postprocess/BloomPass.ts +0 -51
  225. package/src/production-runtime/postprocess/ColorGradingPass.ts +0 -49
  226. package/src/production-runtime/postprocess/DOFPass.ts +0 -47
  227. package/src/production-runtime/postprocess/FXAAPass.ts +0 -53
  228. package/src/production-runtime/postprocess/ProductionEffectComposer.ts +0 -78
  229. package/src/production-runtime/postprocess/ProductionPostProcessTypes.ts +0 -174
  230. package/src/production-runtime/postprocess/SSAOPass.ts +0 -45
  231. package/src/production-runtime/resources/GPUBuffer.ts +0 -2
  232. package/src/production-runtime/resources/GPUTexture.ts +0 -2
  233. package/src/production-runtime/resources/RenderTarget.ts +0 -3
  234. package/src/production-runtime/resources/ResourceCache.ts +0 -7
  235. package/src/production-runtime/scene/Camera.ts +0 -1
  236. package/src/production-runtime/scene/Lights.ts +0 -2
  237. package/src/production-runtime/scene/RenderableMesh.ts +0 -2
  238. package/src/production-runtime/scene/RenderablePrimitive.ts +0 -1
  239. package/src/production-runtime/scene/RenderableScene.ts +0 -4
  240. package/src/production-runtime/shaders/ShaderProgramLibrary.ts +0 -7
  241. package/src/production-runtime/shaders/chunks/brdf.glsl +0 -2
  242. package/src/production-runtime/shaders/chunks/ibl.glsl +0 -3
  243. package/src/production-runtime/shaders/chunks/pbr.frag.glsl +0 -47
  244. package/src/production-runtime/shaders/chunks/pbr.vert.glsl +0 -8
  245. package/src/production-runtime/shaders/chunks/shadows.glsl +0 -2
  246. package/src/production-runtime/shaders/wgsl/pbr.wgsl +0 -3
  247. package/src/production-runtime/shaders/wgsl/postprocess.wgsl +0 -2
  248. package/src/production-runtime/shaders/wgsl/skybox.wgsl +0 -2
  249. package/src/shaders/depth.frag.glsl +0 -5
  250. package/src/shaders/depth.vert.glsl +0 -8
  251. package/src/shaders/pbr-direct.frag.glsl +0 -687
  252. package/src/shaders/pbr-direct.vert.glsl +0 -18
  253. package/src/shaders/unlit.frag.glsl +0 -18
  254. package/src/shaders/unlit.vert.glsl +0 -13
  255. package/src/shadows/CascadedShadowPipeline.ts +0 -53
  256. package/src/shadows/ContactShadows.ts +0 -106
  257. package/src/shadows/ShadowDebugViews.ts +0 -46
  258. package/src/threejs-compatibility/InstancingSystem.ts +0 -17
  259. package/src/threejs-compatibility/LightingSystem.ts +0 -22
  260. package/src/threejs-compatibility/MaterialSystem.ts +0 -9
  261. package/src/threejs-compatibility/RenderTargetSystem.ts +0 -35
  262. package/src/threejs-compatibility/RendererDiagnostics.ts +0 -61
  263. package/src/threejs-compatibility/SceneRenderer.ts +0 -34
  264. package/src/threejs-compatibility/ShadowSystem.ts +0 -19
  265. package/src/threejs-compatibility/TextureSystem.ts +0 -19
  266. package/src/threejs-compatibility/ThreeCompatRenderer.ts +0 -90
  267. package/src/threejs-compatibility/TransparencySystem.ts +0 -19
  268. package/src/threejs-compatibility/index.ts +0 -29
  269. package/src/threejs-compatibility/performance/BVH.ts +0 -14
  270. package/src/threejs-compatibility/performance/FrustumCulling.ts +0 -10
  271. package/src/threejs-compatibility/performance/Instancing.ts +0 -4
  272. package/src/threejs-compatibility/performance/LODSystem.ts +0 -16
  273. package/src/threejs-compatibility/performance/OcclusionCulling.ts +0 -6
  274. package/src/threejs-compatibility/performance/RaycastAcceleration.ts +0 -12
  275. package/src/threejs-compatibility/performance/RendererProfiler.ts +0 -19
  276. package/src/threejs-compatibility/performance/TextureStreaming.ts +0 -4
  277. package/src/threejs-compatibility/performance/index.ts +0 -12
  278. package/src/threejs-compatibility/postprocess/BloomPass.ts +0 -16
  279. package/src/threejs-compatibility/postprocess/ColorGradingPass.ts +0 -16
  280. package/src/threejs-compatibility/postprocess/DepthOfFieldPass.ts +0 -21
  281. package/src/threejs-compatibility/postprocess/EffectComposer.ts +0 -14
  282. package/src/threejs-compatibility/postprocess/FXAAPass.ts +0 -15
  283. package/src/threejs-compatibility/postprocess/MotionBlurPass.ts +0 -20
  284. package/src/threejs-compatibility/postprocess/OutlinePass.ts +0 -21
  285. package/src/threejs-compatibility/postprocess/PostProcessTypes.ts +0 -169
  286. package/src/threejs-compatibility/postprocess/RenderPass.ts +0 -9
  287. package/src/threejs-compatibility/postprocess/SMAAPass.ts +0 -15
  288. package/src/threejs-compatibility/postprocess/SSAOPass.ts +0 -21
  289. package/src/threejs-compatibility/postprocess/ShaderPass.ts +0 -7
  290. package/src/threejs-compatibility/postprocess/TAAPass.ts +0 -15
  291. package/src/threejs-compatibility/postprocess/VignettePass.ts +0 -16
  292. package/src/threejs-compatibility/postprocess/index.ts +0 -15
  293. package/src/threejs-compatibility/shaders/NodeMaterial.ts +0 -21
  294. package/src/threejs-compatibility/shaders/RawShaderMaterial.ts +0 -6
  295. package/src/threejs-compatibility/shaders/ShaderDiagnostics.ts +0 -17
  296. package/src/threejs-compatibility/shaders/ShaderMaterial.ts +0 -18
  297. package/src/threejs-compatibility/shaders/ThreeCompatShaderChunks.ts +0 -6
  298. package/src/threejs-compatibility/shaders/Uniforms.ts +0 -18
  299. package/src/threejs-compatibility/shaders/index.ts +0 -9
  300. package/src/threejs-compatibility/vfx/GPUPointCloud.ts +0 -7
  301. package/src/threejs-compatibility/vfx/LineRenderer.ts +0 -13
  302. package/src/threejs-compatibility/vfx/ParticleSystem.ts +0 -23
  303. package/src/threejs-compatibility/vfx/SpriteSystem.ts +0 -14
  304. package/src/threejs-compatibility/vfx/TrailRenderer.ts +0 -8
  305. package/src/threejs-compatibility/vfx/VFXDiagnostics.ts +0 -23
  306. package/src/threejs-compatibility/vfx/index.ts +0 -9
  307. package/src/threejs-example-parity/index.ts +0 -205
  308. package/src/webgpu/WebGPUBuffer.ts +0 -1
  309. package/src/webgpu/WebGPUCompute.ts +0 -2
  310. package/src/webgpu/WebGPUPipelineCache.ts +0 -15
  311. package/src/webgpu/WebGPUPostProcess.ts +0 -2
  312. package/src/webgpu/WebGPUTexture.ts +0 -2
  313. package/tsconfig.json +0 -26
  314. package/vitest.config.ts +0 -20
@@ -1,836 +0,0 @@
1
- import {
2
- createExternalParityColorManagementPolicy,
3
- type A3DColorManagementPolicy,
4
- type A3DColorSpace,
5
- type A3DTextureSemantic
6
- } from "./ColorManagement";
7
- import {
8
- createToneMappingCalibration,
9
- type BloomOptions,
10
- type ChromaticAberrationOptions,
11
- type ColorGradeOptions,
12
- type ContactShadowPostProcessOptions,
13
- type DepthOfFieldOptions,
14
- type FXAAOptions,
15
- type FilmGrainOptions,
16
- type MotionBlurOptions,
17
- type OutlineOptions,
18
- type PostProcessColorSpace,
19
- type SSAOOptions,
20
- type SSROptions,
21
- type TAAOptions,
22
- type ToneMappingCalibration,
23
- type ToneMappingOperator,
24
- type ToneMappingOptions,
25
- type ToneMappingPresetName
26
- } from "./PostProcessPass";
27
- import {
28
- createRendererPostprocessPlanDiagnostics,
29
- type RendererPostprocessExecutionMode,
30
- type RendererPostprocessPlanDiagnostics
31
- } from "./RendererPostprocessPlan";
32
- import { listExternalParityToneMappingPresets } from "./ToneMapping";
33
- import type {
34
- RenderDevice,
35
- RenderDeviceCapability,
36
- RenderDeviceDiagnostics,
37
- RenderTargetDescriptor
38
- } from "./RenderDevice";
39
-
40
- export type RendererVisualPipelineStatus = "supported" | "partial" | "unsupported";
41
- export type RendererVisualTargetFormat = Extract<RenderTargetDescriptor["format"], "rgba8" | "rgba16f" | "rgba32f">;
42
- export type RendererVisualPostprocessPassName =
43
- | "tone-mapping"
44
- | "color-grade"
45
- | "bloom"
46
- | "chromatic-aberration"
47
- | "film-grain"
48
- | "depth-of-field"
49
- | "motion-blur"
50
- | "contact-shadow"
51
- | "ssao"
52
- | "ssr"
53
- | "taa"
54
- | "outline"
55
- | "fxaa";
56
-
57
- export type RendererUnsupportedVisualCapability =
58
- | "display-p3-output"
59
- | "rec2020-output"
60
- | "hdr-display-swapchain"
61
- | "automatic-png-color-profile";
62
-
63
- export interface RendererVisualPostprocessDescriptor {
64
- readonly targetFormat?: RendererVisualTargetFormat;
65
- readonly toneMapping?: ToneMappingOptions | false;
66
- readonly colorGrade?: ColorGradeOptions | boolean;
67
- readonly bloom?: BloomOptions | boolean;
68
- readonly chromaticAberration?: ChromaticAberrationOptions | boolean;
69
- readonly filmGrain?: FilmGrainOptions | boolean;
70
- readonly depthOfField?: DepthOfFieldOptions | false;
71
- readonly motionBlur?: MotionBlurOptions | false;
72
- readonly contactShadow?: ContactShadowPostProcessOptions | false;
73
- readonly ssao?: SSAOOptions | false;
74
- readonly ssr?: SSROptions | false;
75
- readonly taa?: TAAOptions | false;
76
- readonly outline?: OutlineOptions | boolean;
77
- readonly fxaa?: FXAAOptions | boolean;
78
- }
79
-
80
- export interface RendererCanvasBackingInput {
81
- readonly cssWidth: number;
82
- readonly cssHeight: number;
83
- readonly devicePixelRatio: number;
84
- readonly actualWidth?: number;
85
- readonly actualHeight?: number;
86
- }
87
-
88
- export interface RendererCanvasBackingReport {
89
- readonly status: RendererVisualPipelineStatus;
90
- readonly cssWidth: number;
91
- readonly cssHeight: number;
92
- readonly devicePixelRatio: number;
93
- readonly expectedWidth: number;
94
- readonly expectedHeight: number;
95
- readonly actualWidth?: number;
96
- readonly actualHeight?: number;
97
- readonly effectiveDevicePixelRatio?: number;
98
- readonly backingStoreMatchesDisplay: boolean;
99
- readonly warnings: readonly string[];
100
- }
101
-
102
- export interface RendererScreenshotConsistencyInput {
103
- readonly width: number;
104
- readonly height: number;
105
- readonly byteLength: number;
106
- readonly expectedWidth: number;
107
- readonly expectedHeight: number;
108
- readonly expectedByteLength?: number;
109
- readonly colorSpace?: A3DColorSpace;
110
- }
111
-
112
- export interface RendererScreenshotConsistencyReport {
113
- readonly status: RendererVisualPipelineStatus;
114
- readonly width: number;
115
- readonly height: number;
116
- readonly byteLength: number;
117
- readonly expectedWidth: number;
118
- readonly expectedHeight: number;
119
- readonly expectedByteLength: number;
120
- readonly colorSpace: A3DColorSpace;
121
- readonly pixelFormat: "rgba8";
122
- readonly readbackMatchesBackingStore: boolean;
123
- readonly colorProfileEmbedded: false;
124
- readonly warnings: readonly string[];
125
- }
126
-
127
- export interface RendererCaptureQualityInput {
128
- readonly cssWidth: number;
129
- readonly cssHeight: number;
130
- readonly backingWidth: number;
131
- readonly backingHeight: number;
132
- readonly screenshotWidth: number;
133
- readonly screenshotHeight: number;
134
- readonly captureCssWidth?: number;
135
- readonly captureCssHeight?: number;
136
- readonly devicePixelRatio?: number;
137
- readonly minimumEffectiveDpr?: number;
138
- readonly label?: string;
139
- }
140
-
141
- export interface RendererCaptureQualityReport {
142
- readonly status: RendererVisualPipelineStatus;
143
- readonly label?: string;
144
- readonly cssWidth: number;
145
- readonly cssHeight: number;
146
- readonly backingWidth: number;
147
- readonly backingHeight: number;
148
- readonly screenshotWidth: number;
149
- readonly screenshotHeight: number;
150
- readonly captureCssWidth: number;
151
- readonly captureCssHeight: number;
152
- readonly devicePixelRatio?: number;
153
- readonly minimumEffectiveDpr: number;
154
- readonly effectiveBackingDprX: number;
155
- readonly effectiveBackingDprY: number;
156
- readonly effectiveCaptureDprX: number;
157
- readonly effectiveCaptureDprY: number;
158
- readonly captureToBackingScaleX: number;
159
- readonly captureToBackingScaleY: number;
160
- readonly capturesFullCanvas: boolean;
161
- readonly fullCanvasPixelMatch: boolean;
162
- readonly captureDownsamplesCanvas: boolean;
163
- readonly captureUpscalesCanvas: boolean;
164
- readonly meetsMinimumEffectiveDpr: boolean;
165
- readonly warnings: readonly string[];
166
- }
167
-
168
- export interface RendererFrameCadenceInput {
169
- readonly targetFrameMs?: number;
170
- readonly renderMs?: number;
171
- readonly loopMs?: number;
172
- readonly frameIntervalMs?: number;
173
- readonly readbackMs?: number;
174
- readonly screenshotCaptureOverheadMs?: number;
175
- readonly sampleCount?: number;
176
- }
177
-
178
- export interface RendererFrameCadenceReport {
179
- readonly status: RendererVisualPipelineStatus;
180
- readonly targetFrameMs: number;
181
- readonly renderMs?: number;
182
- readonly loopMs?: number;
183
- readonly frameIntervalMs?: number;
184
- readonly readbackMs?: number;
185
- readonly screenshotCaptureOverheadMs?: number;
186
- readonly sampleCount?: number;
187
- readonly renderBudgetRatio?: number;
188
- readonly loopBudgetRatio?: number;
189
- readonly frameIntervalBudgetRatio?: number;
190
- readonly readbackBudgetRatio?: number;
191
- readonly captureOverheadFrames?: number;
192
- readonly loopHeadroomMs?: number;
193
- readonly stableForCapture: boolean;
194
- readonly warnings: readonly string[];
195
- }
196
-
197
- export interface RendererVisualPipelineReportOptions {
198
- readonly device: RenderDevice;
199
- readonly width: number;
200
- readonly height: number;
201
- readonly postprocess?: RendererVisualPostprocessDescriptor | boolean;
202
- readonly colorManagement?: A3DColorManagementPolicy;
203
- readonly canvas?: RendererCanvasBackingInput;
204
- readonly screenshot?: Omit<RendererScreenshotConsistencyInput, "expectedWidth" | "expectedHeight" | "colorSpace"> & {
205
- readonly colorSpace?: A3DColorSpace;
206
- };
207
- readonly capture?: RendererCaptureQualityInput;
208
- readonly frameCadence?: RendererFrameCadenceInput;
209
- readonly diagnostics?: RenderDeviceDiagnostics;
210
- }
211
-
212
- export interface RendererVisualColorReport {
213
- readonly lightingColorSpace: "linear";
214
- readonly outputColorSpace: A3DColorSpace;
215
- readonly supportedOutputColorSpaces: readonly A3DColorSpace[];
216
- readonly unsupportedOutputColorSpaces: readonly ["display-p3", "rec2020"];
217
- readonly texturePolicy: Readonly<Record<A3DTextureSemantic, A3DColorSpace>>;
218
- readonly ldrFallbackAllowed: boolean;
219
- readonly fallbackBehavior: string;
220
- }
221
-
222
- export interface RendererVisualToneMappingReport {
223
- readonly status: RendererVisualPipelineStatus;
224
- readonly enabled: boolean;
225
- readonly operator?: ToneMappingOperator;
226
- readonly exposure?: number;
227
- readonly whitePoint?: number;
228
- readonly gamma?: number;
229
- readonly inputColorSpace?: PostProcessColorSpace;
230
- readonly outputColorSpace?: PostProcessColorSpace;
231
- readonly calibration?: ToneMappingCalibration;
232
- readonly availablePresets: readonly ToneMappingPresetName[];
233
- readonly warnings: readonly string[];
234
- }
235
-
236
- export interface RendererVisualPostprocessReport {
237
- readonly status: RendererVisualPipelineStatus;
238
- readonly enabled: boolean;
239
- readonly passNames: readonly RendererVisualPostprocessPassName[];
240
- readonly targetFormat: RendererVisualTargetFormat;
241
- readonly sourceTargetFormat: RendererVisualTargetFormat;
242
- readonly executionMode: RendererPostprocessExecutionMode;
243
- readonly nativePresentation: boolean;
244
- readonly usesReadback: boolean;
245
- readonly missingInputs: readonly string[];
246
- readonly readbackPassNames: readonly RendererVisualPostprocessPassName[];
247
- readonly rendererOwnedPassNames: readonly RendererVisualPostprocessPassName[];
248
- readonly clarityWarnings: readonly string[];
249
- readonly forwardOutputColorSpace: PostProcessColorSpace;
250
- readonly presentationColorSpace: A3DColorSpace;
251
- readonly renderTargetWidth: number;
252
- readonly renderTargetHeight: number;
253
- readonly plan?: RendererPostprocessPlanDiagnostics;
254
- readonly warnings: readonly string[];
255
- }
256
-
257
- export interface RendererVisualHdrTargetReport {
258
- readonly status: RendererVisualPipelineStatus;
259
- readonly requested: boolean;
260
- readonly supportedByBackend: boolean;
261
- readonly capabilityAdvertised: boolean;
262
- readonly targetFormat: RendererVisualTargetFormat;
263
- readonly fallbackFormat?: "rgba8";
264
- readonly toneMappingRequired: boolean;
265
- readonly warnings: readonly string[];
266
- }
267
-
268
- export interface RendererVisualPipelineReport {
269
- readonly status: RendererVisualPipelineStatus;
270
- readonly backend: RenderDevice["kind"];
271
- readonly renderer: string;
272
- readonly width: number;
273
- readonly height: number;
274
- readonly capabilities: readonly RenderDeviceCapability[];
275
- readonly color: RendererVisualColorReport;
276
- readonly toneMapping: RendererVisualToneMappingReport;
277
- readonly hdrTarget: RendererVisualHdrTargetReport;
278
- readonly postprocess: RendererVisualPostprocessReport;
279
- readonly canvas?: RendererCanvasBackingReport;
280
- readonly screenshot?: RendererScreenshotConsistencyReport;
281
- readonly capture?: RendererCaptureQualityReport;
282
- readonly frameCadence?: RendererFrameCadenceReport;
283
- readonly diagnostics?: RenderDeviceDiagnostics;
284
- readonly unsupportedCapabilities: Readonly<Record<RendererUnsupportedVisualCapability, string>>;
285
- readonly warnings: readonly string[];
286
- }
287
-
288
- const SUPPORTED_OUTPUT_COLOR_SPACES: readonly A3DColorSpace[] = ["linear", "srgb"];
289
- const UNSUPPORTED_OUTPUT_COLOR_SPACES = ["display-p3", "rec2020"] as const;
290
- const HDR_FORMATS: readonly RendererVisualTargetFormat[] = ["rgba16f", "rgba32f"];
291
-
292
- const UNSUPPORTED_CAPABILITIES: Readonly<Record<RendererUnsupportedVisualCapability, string>> = {
293
- "display-p3-output": "Renderer output color space is limited to linear or sRGB; display-p3 output is not exposed.",
294
- "rec2020-output": "Renderer output color space is limited to linear or sRGB; Rec.2020 output is not exposed.",
295
- "hdr-display-swapchain": "HDR render targets can be tone-mapped, but HDR display swapchain output is not exposed.",
296
- "automatic-png-color-profile": "Screenshot readback is RGBA8 bytes; PNG/ICC profile tagging is owned by the caller."
297
- };
298
-
299
- export function createRendererVisualPipelineReport(
300
- options: RendererVisualPipelineReportOptions
301
- ): RendererVisualPipelineReport {
302
- assertPositiveInteger(options.width, "width");
303
- assertPositiveInteger(options.height, "height");
304
-
305
- const capabilities = [...(options.device.info.capabilities ?? [])];
306
- const capabilitySet = new Set<RenderDeviceCapability>(capabilities);
307
- const colorManagement = options.colorManagement ?? createExternalParityColorManagementPolicy();
308
- const postprocess = normalizePostprocess(options.postprocess);
309
- const postprocessEnabled = postprocess !== undefined;
310
- const passNames = postprocess ? collectPostprocessPassNames(postprocess) : [];
311
- const targetFormat = postprocess ? resolvePostprocessTargetFormat(capabilitySet, postprocess) : "rgba8";
312
- const postprocessPlan = postprocess
313
- ? createRendererPostprocessPlanDiagnostics(postprocess, {
314
- sourceTargetFormat: targetFormat,
315
- targetFormat,
316
- nativeLdrPostprocess: Boolean(options.device.presentLdrPostprocess),
317
- rendererDepthAvailable: capabilitySet.has("depth-textures")
318
- })
319
- : undefined;
320
- const hdrTarget = createHdrTargetReport(capabilitySet, targetFormat, postprocess?.toneMapping);
321
- const toneMapping = createToneMappingReport(postprocess, targetFormat);
322
- const postprocessReport = createPostprocessReport({
323
- enabled: postprocessEnabled,
324
- passNames,
325
- targetFormat,
326
- plan: postprocessPlan,
327
- width: options.width,
328
- height: options.height,
329
- presentationColorSpace: colorManagement.outputColorSpace,
330
- hdrTargetStatus: hdrTarget.status,
331
- toneMappingStatus: toneMapping.status
332
- });
333
- const canvas = options.canvas ? evaluateRendererCanvasBacking(options.canvas) : undefined;
334
- const screenshot = options.screenshot
335
- ? evaluateRendererScreenshotConsistency({
336
- ...options.screenshot,
337
- expectedWidth: options.width,
338
- expectedHeight: options.height,
339
- colorSpace: options.screenshot.colorSpace ?? colorManagement.outputColorSpace
340
- })
341
- : undefined;
342
- const capture = options.capture ? evaluateRendererCaptureQuality(options.capture) : undefined;
343
- const frameCadence = options.frameCadence ? evaluateRendererFrameCadence(options.frameCadence) : undefined;
344
- const warnings = [
345
- ...hdrTarget.warnings,
346
- ...toneMapping.warnings,
347
- ...postprocessReport.warnings,
348
- ...(canvas?.warnings ?? []),
349
- ...(screenshot?.warnings ?? []),
350
- ...(capture?.warnings ?? []),
351
- ...(frameCadence?.warnings ?? [])
352
- ];
353
-
354
- return {
355
- status: combineStatuses([
356
- hdrTarget.status,
357
- toneMapping.status,
358
- postprocessReport.status,
359
- canvas?.status,
360
- screenshot?.status,
361
- capture?.status,
362
- frameCadence?.status
363
- ]),
364
- backend: options.device.kind,
365
- renderer: options.device.info.renderer,
366
- width: options.width,
367
- height: options.height,
368
- capabilities,
369
- color: {
370
- lightingColorSpace: colorManagement.lightingColorSpace,
371
- outputColorSpace: colorManagement.outputColorSpace,
372
- supportedOutputColorSpaces: SUPPORTED_OUTPUT_COLOR_SPACES,
373
- unsupportedOutputColorSpaces: UNSUPPORTED_OUTPUT_COLOR_SPACES,
374
- texturePolicy: colorManagement.texturePolicy,
375
- ldrFallbackAllowed: colorManagement.allowLdrFallback,
376
- fallbackBehavior: colorManagement.fallbackBehavior
377
- },
378
- toneMapping,
379
- hdrTarget,
380
- postprocess: postprocessReport,
381
- ...(canvas ? { canvas } : {}),
382
- ...(screenshot ? { screenshot } : {}),
383
- ...(capture ? { capture } : {}),
384
- ...(frameCadence ? { frameCadence } : {}),
385
- ...(options.diagnostics ? { diagnostics: options.diagnostics } : {}),
386
- unsupportedCapabilities: UNSUPPORTED_CAPABILITIES,
387
- warnings
388
- };
389
- }
390
-
391
- export function evaluateRendererCanvasBacking(input: RendererCanvasBackingInput): RendererCanvasBackingReport {
392
- assertPositiveFinite(input.cssWidth, "cssWidth");
393
- assertPositiveFinite(input.cssHeight, "cssHeight");
394
- assertPositiveFinite(input.devicePixelRatio, "devicePixelRatio");
395
- const expectedWidth = Math.max(1, Math.round(input.cssWidth * input.devicePixelRatio));
396
- const expectedHeight = Math.max(1, Math.round(input.cssHeight * input.devicePixelRatio));
397
- const hasActualDimensions = input.actualWidth !== undefined && input.actualHeight !== undefined;
398
- const matches = hasActualDimensions
399
- ? input.actualWidth === expectedWidth && input.actualHeight === expectedHeight
400
- : false;
401
- const warnings = createCanvasBackingWarnings(input, expectedWidth, expectedHeight, hasActualDimensions, matches);
402
-
403
- return {
404
- status: matches ? "supported" : "partial",
405
- cssWidth: input.cssWidth,
406
- cssHeight: input.cssHeight,
407
- devicePixelRatio: input.devicePixelRatio,
408
- expectedWidth,
409
- expectedHeight,
410
- ...(input.actualWidth !== undefined ? { actualWidth: input.actualWidth } : {}),
411
- ...(input.actualHeight !== undefined ? { actualHeight: input.actualHeight } : {}),
412
- ...(hasActualDimensions ? { effectiveDevicePixelRatio: round(input.actualWidth! / input.cssWidth) } : {}),
413
- backingStoreMatchesDisplay: matches,
414
- warnings
415
- };
416
- }
417
-
418
- export function evaluateRendererScreenshotConsistency(
419
- input: RendererScreenshotConsistencyInput
420
- ): RendererScreenshotConsistencyReport {
421
- assertPositiveInteger(input.width, "width");
422
- assertPositiveInteger(input.height, "height");
423
- assertPositiveInteger(input.expectedWidth, "expectedWidth");
424
- assertPositiveInteger(input.expectedHeight, "expectedHeight");
425
- assertPositiveInteger(input.byteLength, "byteLength");
426
- if (input.expectedByteLength !== undefined) assertPositiveInteger(input.expectedByteLength, "expectedByteLength");
427
- const expectedByteLength = input.expectedByteLength ?? input.expectedWidth * input.expectedHeight * 4;
428
- const dimensionsMatch = input.width === input.expectedWidth && input.height === input.expectedHeight;
429
- const bytesMatch = input.byteLength === expectedByteLength;
430
- const warnings: string[] = [];
431
- if (!dimensionsMatch) {
432
- warnings.push(`Screenshot readback ${input.width}x${input.height} does not match renderer backing store ${input.expectedWidth}x${input.expectedHeight}.`);
433
- }
434
- if (!bytesMatch) {
435
- warnings.push(`Screenshot byte length ${input.byteLength} does not match expected RGBA8 byte length ${expectedByteLength}.`);
436
- }
437
- warnings.push("Screenshot readback reports RGBA8 pixels; embedded PNG/ICC color profiles are not guaranteed by the renderer.");
438
-
439
- return {
440
- status: dimensionsMatch && bytesMatch ? "supported" : "partial",
441
- width: input.width,
442
- height: input.height,
443
- byteLength: input.byteLength,
444
- expectedWidth: input.expectedWidth,
445
- expectedHeight: input.expectedHeight,
446
- expectedByteLength,
447
- colorSpace: input.colorSpace ?? "srgb",
448
- pixelFormat: "rgba8",
449
- readbackMatchesBackingStore: dimensionsMatch && bytesMatch,
450
- colorProfileEmbedded: false,
451
- warnings
452
- };
453
- }
454
-
455
- export function evaluateRendererCaptureQuality(input: RendererCaptureQualityInput): RendererCaptureQualityReport {
456
- assertPositiveFinite(input.cssWidth, "cssWidth");
457
- assertPositiveFinite(input.cssHeight, "cssHeight");
458
- assertPositiveInteger(input.backingWidth, "backingWidth");
459
- assertPositiveInteger(input.backingHeight, "backingHeight");
460
- assertPositiveInteger(input.screenshotWidth, "screenshotWidth");
461
- assertPositiveInteger(input.screenshotHeight, "screenshotHeight");
462
- if (input.captureCssWidth !== undefined) assertPositiveFinite(input.captureCssWidth, "captureCssWidth");
463
- if (input.captureCssHeight !== undefined) assertPositiveFinite(input.captureCssHeight, "captureCssHeight");
464
- if (input.devicePixelRatio !== undefined) assertPositiveFinite(input.devicePixelRatio, "devicePixelRatio");
465
- if (input.minimumEffectiveDpr !== undefined) assertPositiveFinite(input.minimumEffectiveDpr, "minimumEffectiveDpr");
466
-
467
- const captureCssWidth = input.captureCssWidth ?? input.cssWidth;
468
- const captureCssHeight = input.captureCssHeight ?? input.cssHeight;
469
- const minimumEffectiveDpr = input.minimumEffectiveDpr ?? 1;
470
- const effectiveBackingDprX = input.backingWidth / input.cssWidth;
471
- const effectiveBackingDprY = input.backingHeight / input.cssHeight;
472
- const effectiveCaptureDprX = input.screenshotWidth / captureCssWidth;
473
- const effectiveCaptureDprY = input.screenshotHeight / captureCssHeight;
474
- const captureToBackingScaleX = effectiveCaptureDprX / effectiveBackingDprX;
475
- const captureToBackingScaleY = effectiveCaptureDprY / effectiveBackingDprY;
476
- const capturesFullCanvas = nearlyEqual(captureCssWidth, input.cssWidth) && nearlyEqual(captureCssHeight, input.cssHeight);
477
- const fullCanvasPixelMatch = capturesFullCanvas
478
- && input.screenshotWidth === input.backingWidth
479
- && input.screenshotHeight === input.backingHeight;
480
- const captureDownsamplesCanvas = captureToBackingScaleX < 0.98 || captureToBackingScaleY < 0.98;
481
- const captureUpscalesCanvas = captureToBackingScaleX > 1.02 || captureToBackingScaleY > 1.02;
482
- const meetsMinimumEffectiveDpr = effectiveBackingDprX >= minimumEffectiveDpr && effectiveBackingDprY >= minimumEffectiveDpr;
483
- const warnings = createCaptureQualityWarnings({
484
- ...input,
485
- captureCssWidth,
486
- captureCssHeight,
487
- minimumEffectiveDpr,
488
- effectiveBackingDprX,
489
- effectiveBackingDprY,
490
- effectiveCaptureDprX,
491
- effectiveCaptureDprY,
492
- captureDownsamplesCanvas,
493
- captureUpscalesCanvas,
494
- fullCanvasPixelMatch,
495
- capturesFullCanvas,
496
- meetsMinimumEffectiveDpr
497
- });
498
-
499
- return {
500
- status: warnings.length > 0 ? "partial" : "supported",
501
- ...(input.label ? { label: input.label } : {}),
502
- cssWidth: input.cssWidth,
503
- cssHeight: input.cssHeight,
504
- backingWidth: input.backingWidth,
505
- backingHeight: input.backingHeight,
506
- screenshotWidth: input.screenshotWidth,
507
- screenshotHeight: input.screenshotHeight,
508
- captureCssWidth,
509
- captureCssHeight,
510
- ...(input.devicePixelRatio !== undefined ? { devicePixelRatio: input.devicePixelRatio } : {}),
511
- minimumEffectiveDpr,
512
- effectiveBackingDprX: round(effectiveBackingDprX),
513
- effectiveBackingDprY: round(effectiveBackingDprY),
514
- effectiveCaptureDprX: round(effectiveCaptureDprX),
515
- effectiveCaptureDprY: round(effectiveCaptureDprY),
516
- captureToBackingScaleX: round(captureToBackingScaleX),
517
- captureToBackingScaleY: round(captureToBackingScaleY),
518
- capturesFullCanvas,
519
- fullCanvasPixelMatch,
520
- captureDownsamplesCanvas,
521
- captureUpscalesCanvas,
522
- meetsMinimumEffectiveDpr,
523
- warnings
524
- };
525
- }
526
-
527
- export function evaluateRendererFrameCadence(input: RendererFrameCadenceInput): RendererFrameCadenceReport {
528
- const targetFrameMs = input.targetFrameMs ?? 16.667;
529
- assertPositiveFinite(targetFrameMs, "targetFrameMs");
530
- if (input.renderMs !== undefined) assertNonNegativeFinite(input.renderMs, "renderMs");
531
- if (input.loopMs !== undefined) assertNonNegativeFinite(input.loopMs, "loopMs");
532
- if (input.frameIntervalMs !== undefined) assertNonNegativeFinite(input.frameIntervalMs, "frameIntervalMs");
533
- if (input.readbackMs !== undefined) assertNonNegativeFinite(input.readbackMs, "readbackMs");
534
- if (input.screenshotCaptureOverheadMs !== undefined) assertNonNegativeFinite(input.screenshotCaptureOverheadMs, "screenshotCaptureOverheadMs");
535
- if (input.sampleCount !== undefined) assertPositiveInteger(input.sampleCount, "sampleCount");
536
-
537
- const renderBudgetRatio = input.renderMs !== undefined ? input.renderMs / targetFrameMs : undefined;
538
- const loopBudgetRatio = input.loopMs !== undefined ? input.loopMs / targetFrameMs : undefined;
539
- const frameIntervalBudgetRatio = input.frameIntervalMs !== undefined ? input.frameIntervalMs / targetFrameMs : undefined;
540
- const readbackBudgetRatio = input.readbackMs !== undefined ? input.readbackMs / targetFrameMs : undefined;
541
- const captureOverheadFrames = input.screenshotCaptureOverheadMs !== undefined ? input.screenshotCaptureOverheadMs / targetFrameMs : undefined;
542
- const loopHeadroomMs = input.loopMs !== undefined ? targetFrameMs - input.loopMs : undefined;
543
- const warnings = createFrameCadenceWarnings({
544
- ...input,
545
- targetFrameMs,
546
- renderBudgetRatio,
547
- loopBudgetRatio,
548
- frameIntervalBudgetRatio,
549
- readbackBudgetRatio,
550
- captureOverheadFrames
551
- });
552
-
553
- return {
554
- status: warnings.length > 0 ? "partial" : "supported",
555
- targetFrameMs: round(targetFrameMs),
556
- ...(input.renderMs !== undefined ? { renderMs: round(input.renderMs) } : {}),
557
- ...(input.loopMs !== undefined ? { loopMs: round(input.loopMs) } : {}),
558
- ...(input.frameIntervalMs !== undefined ? { frameIntervalMs: round(input.frameIntervalMs) } : {}),
559
- ...(input.readbackMs !== undefined ? { readbackMs: round(input.readbackMs) } : {}),
560
- ...(input.screenshotCaptureOverheadMs !== undefined ? { screenshotCaptureOverheadMs: round(input.screenshotCaptureOverheadMs) } : {}),
561
- ...(input.sampleCount !== undefined ? { sampleCount: input.sampleCount } : {}),
562
- ...(renderBudgetRatio !== undefined ? { renderBudgetRatio: round(renderBudgetRatio) } : {}),
563
- ...(loopBudgetRatio !== undefined ? { loopBudgetRatio: round(loopBudgetRatio) } : {}),
564
- ...(frameIntervalBudgetRatio !== undefined ? { frameIntervalBudgetRatio: round(frameIntervalBudgetRatio) } : {}),
565
- ...(readbackBudgetRatio !== undefined ? { readbackBudgetRatio: round(readbackBudgetRatio) } : {}),
566
- ...(captureOverheadFrames !== undefined ? { captureOverheadFrames: round(captureOverheadFrames) } : {}),
567
- ...(loopHeadroomMs !== undefined ? { loopHeadroomMs: round(loopHeadroomMs) } : {}),
568
- stableForCapture: warnings.length === 0,
569
- warnings
570
- };
571
- }
572
-
573
- function normalizePostprocess(
574
- postprocess: RendererVisualPipelineReportOptions["postprocess"]
575
- ): RendererVisualPostprocessDescriptor | undefined {
576
- if (postprocess === undefined || postprocess === false) return undefined;
577
- if (postprocess === true) return {};
578
- return postprocess;
579
- }
580
-
581
- function collectPostprocessPassNames(postprocess: RendererVisualPostprocessDescriptor): readonly RendererVisualPostprocessPassName[] {
582
- const passes: RendererVisualPostprocessPassName[] = [];
583
- if (postprocess.bloom) passes.push("bloom");
584
- if (postprocess.toneMapping !== false) passes.push("tone-mapping");
585
- if (postprocess.colorGrade) passes.push("color-grade");
586
- if (postprocess.chromaticAberration) passes.push("chromatic-aberration");
587
- if (postprocess.filmGrain) passes.push("film-grain");
588
- if (postprocess.depthOfField) passes.push("depth-of-field");
589
- if (postprocess.motionBlur) passes.push("motion-blur");
590
- if (postprocess.contactShadow) passes.push("contact-shadow");
591
- if (postprocess.ssao) passes.push("ssao");
592
- if (postprocess.ssr) passes.push("ssr");
593
- if (postprocess.taa) passes.push("taa");
594
- if (postprocess.outline) passes.push("outline");
595
- if (postprocess.fxaa) passes.push("fxaa");
596
- return passes;
597
- }
598
-
599
- function resolvePostprocessTargetFormat(
600
- capabilities: ReadonlySet<RenderDeviceCapability>,
601
- postprocess: RendererVisualPostprocessDescriptor
602
- ): RendererVisualTargetFormat {
603
- if (postprocess.targetFormat) return postprocess.targetFormat;
604
- if (postprocess.toneMapping === false) return "rgba8";
605
- return capabilities.has("hdr-render-targets") ? "rgba16f" : "rgba8";
606
- }
607
-
608
- function createHdrTargetReport(
609
- capabilities: ReadonlySet<RenderDeviceCapability>,
610
- targetFormat: RendererVisualTargetFormat,
611
- toneMapping: ToneMappingOptions | false | undefined
612
- ): RendererVisualHdrTargetReport {
613
- const requested = HDR_FORMATS.includes(targetFormat);
614
- const capabilityAdvertised = capabilities.has("hdr-render-targets");
615
- const warnings: string[] = [];
616
- if (requested && !capabilityAdvertised) {
617
- warnings.push(`HDR postprocess target ${targetFormat} was requested, but the backend does not advertise hdr-render-targets.`);
618
- }
619
- if (requested && toneMapping === false) {
620
- warnings.push(`HDR postprocess target ${targetFormat} requires tone mapping before RGBA8 presentation.`);
621
- }
622
-
623
- return {
624
- status: warnings.length > 0 ? "unsupported" : "supported",
625
- requested,
626
- supportedByBackend: !requested || capabilityAdvertised,
627
- capabilityAdvertised,
628
- targetFormat,
629
- ...(requested && !capabilityAdvertised ? { fallbackFormat: "rgba8" } : {}),
630
- toneMappingRequired: requested,
631
- warnings
632
- };
633
- }
634
-
635
- function createToneMappingReport(
636
- postprocess: RendererVisualPostprocessDescriptor | undefined,
637
- targetFormat: RendererVisualTargetFormat
638
- ): RendererVisualToneMappingReport {
639
- const availablePresets = listExternalParityToneMappingPresets().map((preset) => preset.name);
640
- if (!postprocess || postprocess.toneMapping === false) {
641
- const warnings = HDR_FORMATS.includes(targetFormat)
642
- ? [`HDR target ${targetFormat} cannot be presented honestly without tone mapping.`]
643
- : [];
644
- return {
645
- status: warnings.length > 0 ? "unsupported" : "supported",
646
- enabled: false,
647
- availablePresets,
648
- warnings
649
- };
650
- }
651
-
652
- const options = postprocess.toneMapping ?? {};
653
- const resolved = {
654
- exposure: options.exposure ?? 1,
655
- whitePoint: options.whitePoint ?? 1,
656
- gamma: options.gamma ?? 2.2,
657
- operator: options.operator ?? "reinhard",
658
- inputColorSpace: options.inputColorSpace ?? "linear",
659
- outputColorSpace: options.outputColorSpace ?? "srgb"
660
- } satisfies Required<ToneMappingOptions>;
661
- const warnings: string[] = [];
662
- if (resolved.outputColorSpace !== "srgb") {
663
- warnings.push(`Tone mapping outputColorSpace is ${resolved.outputColorSpace}; screenshot and browser presentation consistency is strongest with srgb.`);
664
- }
665
-
666
- return {
667
- status: warnings.length > 0 ? "partial" : "supported",
668
- enabled: true,
669
- operator: resolved.operator,
670
- exposure: resolved.exposure,
671
- whitePoint: resolved.whitePoint,
672
- gamma: resolved.gamma,
673
- inputColorSpace: resolved.inputColorSpace,
674
- outputColorSpace: resolved.outputColorSpace,
675
- calibration: createToneMappingCalibration(resolved),
676
- availablePresets,
677
- warnings
678
- };
679
- }
680
-
681
- function createPostprocessReport(options: {
682
- readonly enabled: boolean;
683
- readonly passNames: readonly RendererVisualPostprocessPassName[];
684
- readonly targetFormat: RendererVisualTargetFormat;
685
- readonly plan?: RendererPostprocessPlanDiagnostics;
686
- readonly width: number;
687
- readonly height: number;
688
- readonly presentationColorSpace: A3DColorSpace;
689
- readonly hdrTargetStatus: RendererVisualPipelineStatus;
690
- readonly toneMappingStatus: RendererVisualPipelineStatus;
691
- }): RendererVisualPostprocessReport {
692
- const warnings: string[] = [];
693
- if (options.enabled && options.passNames.length === 0) {
694
- warnings.push("Postprocess is enabled with no passes; renderer will copy/present the forward target without color changes.");
695
- }
696
- if (options.plan && options.plan.missingInputs.length > 0) {
697
- warnings.push(`Postprocess plan is missing required inputs: ${options.plan.missingInputs.join(", ")}.`);
698
- }
699
- if (options.hdrTargetStatus === "unsupported" || options.toneMappingStatus === "unsupported") {
700
- warnings.push("Postprocess plan is not executable as requested; renderer guards will reject unsupported HDR presentation.");
701
- }
702
- const executionMode = options.plan?.executionMode ?? "none";
703
-
704
- return {
705
- status: combineStatuses([
706
- options.hdrTargetStatus,
707
- options.toneMappingStatus,
708
- warnings.length > 0 ? "partial" : "supported"
709
- ]),
710
- enabled: options.enabled,
711
- passNames: options.passNames,
712
- targetFormat: options.targetFormat,
713
- sourceTargetFormat: options.plan?.sourceTargetFormat ?? options.targetFormat,
714
- executionMode,
715
- nativePresentation: executionMode === "renderer-owned-fused-ldr-native",
716
- usesReadback: (options.plan?.readbackPassNames.length ?? 0) > 0,
717
- missingInputs: options.plan?.missingInputs ?? [],
718
- readbackPassNames: options.plan?.readbackPassNames ?? [],
719
- rendererOwnedPassNames: options.plan?.rendererOwnedPassNames ?? [],
720
- clarityWarnings: options.plan?.clarityWarnings ?? [],
721
- forwardOutputColorSpace: options.enabled ? "linear" : "srgb",
722
- presentationColorSpace: options.presentationColorSpace,
723
- renderTargetWidth: options.width,
724
- renderTargetHeight: options.height,
725
- ...(options.plan ? { plan: options.plan } : {}),
726
- warnings
727
- };
728
- }
729
-
730
- function combineStatuses(statuses: readonly (RendererVisualPipelineStatus | undefined)[]): RendererVisualPipelineStatus {
731
- if (statuses.includes("unsupported")) return "unsupported";
732
- if (statuses.includes("partial")) return "partial";
733
- return "supported";
734
- }
735
-
736
- function createCanvasBackingWarnings(
737
- input: RendererCanvasBackingInput,
738
- expectedWidth: number,
739
- expectedHeight: number,
740
- hasActualDimensions: boolean,
741
- matches: boolean
742
- ): readonly string[] {
743
- if (!hasActualDimensions) {
744
- return [`Canvas backing store dimensions were not provided; expected ${expectedWidth}x${expectedHeight} for CSS ${input.cssWidth}x${input.cssHeight} at DPR ${input.devicePixelRatio}.`];
745
- }
746
- if (!matches) {
747
- return [`Canvas backing store ${input.actualWidth}x${input.actualHeight} does not match CSS ${input.cssWidth}x${input.cssHeight} at DPR ${input.devicePixelRatio}; expected ${expectedWidth}x${expectedHeight}.`];
748
- }
749
- return [];
750
- }
751
-
752
- function createCaptureQualityWarnings(input: RendererCaptureQualityInput & {
753
- readonly captureCssWidth: number;
754
- readonly captureCssHeight: number;
755
- readonly minimumEffectiveDpr: number;
756
- readonly effectiveBackingDprX: number;
757
- readonly effectiveBackingDprY: number;
758
- readonly effectiveCaptureDprX: number;
759
- readonly effectiveCaptureDprY: number;
760
- readonly captureDownsamplesCanvas: boolean;
761
- readonly captureUpscalesCanvas: boolean;
762
- readonly fullCanvasPixelMatch: boolean;
763
- readonly capturesFullCanvas: boolean;
764
- readonly meetsMinimumEffectiveDpr: boolean;
765
- }): readonly string[] {
766
- const warnings: string[] = [];
767
- if (!input.meetsMinimumEffectiveDpr) {
768
- warnings.push(`Canvas backing DPR ${round(input.effectiveBackingDprX)}x${round(input.effectiveBackingDprY)} is below the requested minimum ${input.minimumEffectiveDpr}.`);
769
- }
770
- if (input.devicePixelRatio !== undefined && (input.effectiveBackingDprX < input.devicePixelRatio * 0.98 || input.effectiveBackingDprY < input.devicePixelRatio * 0.98)) {
771
- warnings.push(`Canvas backing DPR ${round(input.effectiveBackingDprX)}x${round(input.effectiveBackingDprY)} is below devicePixelRatio ${input.devicePixelRatio}; a max-edge clamp or resize mismatch may be reducing effective capture detail.`);
772
- }
773
- if (input.captureDownsamplesCanvas) {
774
- warnings.push(`Screenshot capture DPR ${round(input.effectiveCaptureDprX)}x${round(input.effectiveCaptureDprY)} is below canvas backing DPR ${round(input.effectiveBackingDprX)}x${round(input.effectiveBackingDprY)}; browser capture is downsampling renderer detail.`);
775
- }
776
- if (input.captureUpscalesCanvas) {
777
- warnings.push(`Screenshot capture DPR ${round(input.effectiveCaptureDprX)}x${round(input.effectiveCaptureDprY)} is above canvas backing DPR ${round(input.effectiveBackingDprX)}x${round(input.effectiveBackingDprY)}; screenshot pixels may be upscaled from renderer output.`);
778
- }
779
- if (input.capturesFullCanvas && !input.fullCanvasPixelMatch) {
780
- warnings.push(`Full-canvas screenshot ${input.screenshotWidth}x${input.screenshotHeight} does not match canvas backing ${input.backingWidth}x${input.backingHeight}.`);
781
- }
782
- return warnings;
783
- }
784
-
785
- function createFrameCadenceWarnings(input: RendererFrameCadenceInput & {
786
- readonly targetFrameMs: number;
787
- readonly renderBudgetRatio?: number;
788
- readonly loopBudgetRatio?: number;
789
- readonly frameIntervalBudgetRatio?: number;
790
- readonly readbackBudgetRatio?: number;
791
- readonly captureOverheadFrames?: number;
792
- }): readonly string[] {
793
- const warnings: string[] = [];
794
- if (input.renderBudgetRatio !== undefined && input.renderBudgetRatio > 1) {
795
- warnings.push(`Render work ${round(input.renderBudgetRatio)}x exceeds the ${round(input.targetFrameMs)}ms frame budget.`);
796
- }
797
- if (input.loopBudgetRatio !== undefined && input.loopBudgetRatio > 1) {
798
- warnings.push(`Total loop work ${round(input.loopBudgetRatio)}x exceeds the ${round(input.targetFrameMs)}ms frame budget.`);
799
- }
800
- if (input.frameIntervalBudgetRatio !== undefined && input.frameIntervalBudgetRatio > 1.25) {
801
- warnings.push(`Observed frame interval ${round(input.frameIntervalBudgetRatio)}x exceeds the target cadence; capture may land on a stalled frame.`);
802
- }
803
- if (input.readbackBudgetRatio !== undefined && input.readbackBudgetRatio > 0.5) {
804
- warnings.push(`Readback cost ${round(input.readbackBudgetRatio)}x of the frame budget can affect capture cadence.`);
805
- }
806
- if (input.captureOverheadFrames !== undefined && input.captureOverheadFrames > 1) {
807
- warnings.push(`Screenshot capture overhead spans ${round(input.captureOverheadFrames)} frame budgets; visual review captures may include stall artifacts.`);
808
- }
809
- return warnings;
810
- }
811
-
812
- function assertPositiveInteger(value: number, name: string): void {
813
- if (!Number.isInteger(value) || value <= 0) {
814
- throw new Error(`${name} must be a positive integer.`);
815
- }
816
- }
817
-
818
- function assertNonNegativeFinite(value: number, name: string): void {
819
- if (!Number.isFinite(value) || value < 0) {
820
- throw new Error(`${name} must be a finite non-negative number.`);
821
- }
822
- }
823
-
824
- function assertPositiveFinite(value: number, name: string): void {
825
- if (!Number.isFinite(value) || value <= 0) {
826
- throw new Error(`${name} must be a finite positive number.`);
827
- }
828
- }
829
-
830
- function nearlyEqual(left: number, right: number): boolean {
831
- return Math.abs(left - right) <= 0.001;
832
- }
833
-
834
- function round(value: number): number {
835
- return Number(value.toFixed(4));
836
- }