@carbonenginejs/runtime 0.1.0-alpha.6 → 0.1.0-alpha.7

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.

Potentially problematic release.


This version of @carbonenginejs/runtime might be problematic. Click here for more details.

Files changed (92) hide show
  1. package/dist/global/consts/effectPaths.js +4 -1
  2. package/dist/global/consts/effectPaths.js.map +1 -1
  3. package/dist/global/consts/index.js +1 -1
  4. package/dist/global/index.js +1 -1
  5. package/dist/index.js +3 -3
  6. package/dist/resource/format/carbonEffect/carbonEffectBackendBlock.js +19 -2
  7. package/dist/resource/format/carbonEffect/carbonEffectBackendBlock.js.map +1 -1
  8. package/dist/resource/format/index.js +1 -1
  9. package/dist/resource/formats/hlsl/core/carbonTypedViews.js +121 -65
  10. package/dist/resource/formats/hlsl/core/carbonTypedViews.js.map +1 -1
  11. package/dist/resource/formats/webgl/core/glsl/DxbcGlslEmitter.js +10 -7
  12. package/dist/resource/formats/webgl/core/glsl/DxbcGlslEmitter.js.map +1 -1
  13. package/dist/resource/formats/webgpu/core/effectBackendBodySet.js +3 -1
  14. package/dist/resource/formats/webgpu/core/effectBackendBodySet.js.map +1 -1
  15. package/dist/resource/formats/webgpu/core/packageEffect.js +5 -0
  16. package/dist/resource/formats/webgpu/core/packageEffect.js.map +1 -1
  17. package/dist/resource/formats/webgpu/core/wgsl/emitWgsl.js +20 -0
  18. package/dist/resource/formats/webgpu/core/wgsl/emitWgsl.js.map +1 -1
  19. package/dist/resource/formats/webgpu/core/wgsl/emulatedAddressing.js +93 -4
  20. package/dist/resource/formats/webgpu/core/wgsl/emulatedAddressing.js.map +1 -1
  21. package/dist/resource/formats/webgpu/core/wgsl/lowerBindingLayout.js +74 -64
  22. package/dist/resource/formats/webgpu/core/wgsl/lowerBindingLayout.js.map +1 -1
  23. package/dist/resource/formats/webgpu/core/wgsl/lowerFragmentProgram.js +16 -7
  24. package/dist/resource/formats/webgpu/core/wgsl/lowerFragmentProgram.js.map +1 -1
  25. package/dist/resource/formats/webgpu/core/wgsl/wgslTypedViews.js +69 -27
  26. package/dist/resource/formats/webgpu/core/wgsl/wgslTypedViews.js.map +1 -1
  27. package/dist/resource/geometry/registerGeometryResources.js +10 -1
  28. package/dist/resource/geometry/registerGeometryResources.js.map +1 -1
  29. package/dist/sof/EveSOFDNA.js +4 -2
  30. package/dist/sof/EveSOFDNA.js.map +1 -1
  31. package/dist/sof/EveSOFDataMgr.js +83 -69
  32. package/dist/sof/EveSOFDataMgr.js.map +1 -1
  33. package/dist/trinity/core/Tr2Denoiser.js +6 -1
  34. package/dist/trinity/core/Tr2Denoiser.js.map +1 -1
  35. package/dist/trinity/core/Tr2ShadowMap.js +7 -2
  36. package/dist/trinity/core/Tr2ShadowMap.js.map +1 -1
  37. package/dist/trinity/core/context/Tr2RenderContext.js +43 -0
  38. package/dist/trinity/core/context/Tr2RenderContext.js.map +1 -1
  39. package/dist/trinity/core/device/Tr2GpuStructuredBuffer.js +134 -0
  40. package/dist/trinity/core/device/Tr2GpuStructuredBuffer.js.map +1 -0
  41. package/dist/trinity/core/index.js +1 -0
  42. package/dist/trinity/core/index.js.map +1 -1
  43. package/dist/trinity/core/lighting/Tr2LightManager.js +410 -124
  44. package/dist/trinity/core/lighting/Tr2LightManager.js.map +1 -1
  45. package/dist/trinity/eve/effect/lensflare/EveLensflare.js +303 -312
  46. package/dist/trinity/eve/effect/lensflare/EveLensflare.js.map +1 -1
  47. package/dist/trinity/eve/effect/lensflare/EveOccluder.js +117 -0
  48. package/dist/trinity/eve/effect/lensflare/EveOccluder.js.map +1 -0
  49. package/dist/trinity/eve/index.js +1 -0
  50. package/dist/trinity/eve/index.js.map +1 -1
  51. package/dist/trinity/eve/scene/EveSpaceScene.js +286 -6
  52. package/dist/trinity/eve/scene/EveSpaceScene.js.map +1 -1
  53. package/dist/trinity/eve/scene/EveSpaceSceneRenderDriver.js +212 -32
  54. package/dist/trinity/eve/scene/EveSpaceSceneRenderDriver.js.map +1 -1
  55. package/dist/trinity/generated/eve/effect/index.js +0 -1
  56. package/dist/trinity/generated/eve/effect/index.js.map +1 -1
  57. package/dist/trinity/generated/eve/index.js +0 -1
  58. package/dist/trinity/generated/eve/index.js.map +1 -1
  59. package/dist/trinity/generated/index.js +0 -2
  60. package/dist/trinity/generated/index.js.map +1 -1
  61. package/dist/trinity/generated/trinityCore/index.js +0 -1
  62. package/dist/trinity/generated/trinityCore/index.js.map +1 -1
  63. package/dist/trinity/index.js +2 -2
  64. package/dist/trinity/postProcess/Tr2PostProcessRenderer.js +4 -1
  65. package/dist/trinity/postProcess/Tr2PostProcessRenderer.js.map +1 -1
  66. package/dist/trinity/postProcess/Tr2SSAO.js +282 -21
  67. package/dist/trinity/postProcess/Tr2SSAO.js.map +1 -1
  68. package/dist/trinity/shader/parameter/Tr2RuntimeTextureParameter.js +71 -53
  69. package/dist/trinity/shader/parameter/Tr2RuntimeTextureParameter.js.map +1 -1
  70. package/dist/trinityal/webgpu/CjsWebgpuRenderContextAL.js +81 -18
  71. package/dist/trinityal/webgpu/CjsWebgpuRenderContextAL.js.map +1 -1
  72. package/dist/trinityal/webgpu/CjsWebgpuResourceSetAL.js +46 -4
  73. package/dist/trinityal/webgpu/CjsWebgpuResourceSetAL.js.map +1 -1
  74. package/dist/trinityal/webgpu/CjsWebgpuShaderAL.js +32 -1
  75. package/dist/trinityal/webgpu/CjsWebgpuShaderAL.js.map +1 -1
  76. package/dist/trinityal/webgpu/CjsWebgpuShaderProgramAL.js +27 -0
  77. package/dist/trinityal/webgpu/CjsWebgpuShaderProgramAL.js.map +1 -1
  78. package/dist/trinityal/webgpu/CjsWebgpuTextureAL.js +29 -4
  79. package/dist/trinityal/webgpu/CjsWebgpuTextureAL.js.map +1 -1
  80. package/dist/trinityal/webgpu/core/CjsWebgpuPsoDescription.js +32 -2
  81. package/dist/trinityal/webgpu/core/CjsWebgpuPsoDescription.js.map +1 -1
  82. package/dist/trinityal/webgpu/core/CjsWebgpuUtils.js +57 -5
  83. package/dist/trinityal/webgpu/core/CjsWebgpuUtils.js.map +1 -1
  84. package/dist/trinityal/webgpu/core/CjsWebgpuWorkQueue.js +111 -5
  85. package/dist/trinityal/webgpu/core/CjsWebgpuWorkQueue.js.map +1 -1
  86. package/docs/trinity/reference/classes/generated.md +20 -20
  87. package/docs/trinity/reference/classes/post-process.md +1 -1
  88. package/package.json +1 -1
  89. package/dist/trinity/generated/eve/effect/EveOccluder.js +0 -38
  90. package/dist/trinity/generated/eve/effect/EveOccluder.js.map +0 -1
  91. package/dist/trinity/generated/trinityCore/Tr2GpuStructuredBuffer.js +0 -48
  92. package/dist/trinity/generated/trinityCore/Tr2GpuStructuredBuffer.js.map +0 -1
@@ -6,7 +6,7 @@ import { mat4 } from '#math/mat4';
6
6
  import { Tr2GpuUsage, PixelFormat, TextureType, Tr2LoadAction, Tr2StoreAction } from '#consts/render-context';
7
7
  import { Tr2SubresourceData, Tr2ColorAttachment, Tr2DepthAttachment } from '#trinityal';
8
8
  import { AntiAliasingQuality, AmbientOcclusionQuality, EveVisualizeMethod } from '../../generated/eve/enums.js';
9
- import { ShadowQuality, Tr2VolumerticQuality } from '../../generated/trinityCore/enums.js';
9
+ import { ShadowQuality, SSAOQuality, TR2SHADERMODEL, Tr2VolumerticQuality } from '../../generated/trinityCore/enums.js';
10
10
  import { Quality } from '../../generated/postProcess/enums.js';
11
11
  import { RenderingMode, TriBatchType } from '#consts/graphics';
12
12
  import '../../core/batch/CjsBatchManager.js';
@@ -14,6 +14,9 @@ import { TriFrustum } from '../../core/view/TriFrustum.js';
14
14
  import { GpuResourceHandle } from '../../core/Tr2GpuResourcePool/GpuResourceHandle.js';
15
15
  import { Tr2GpuResourcePool } from '../../core/Tr2GpuResourcePool/Tr2GpuResourcePool.js';
16
16
  import { Tr2Renderer as _Tr2Renderer } from '../../core/Tr2Renderer.js';
17
+ import { Tr2ShadowMap as _Tr2ShadowMap } from '../../core/Tr2ShadowMap.js';
18
+ import { Tr2LightManager as _Tr2LightManager } from '../../core/lighting/Tr2LightManager.js';
19
+ import { COMPUTE_LIGHT_LISTS_EFFECT_PATH } from '#consts/effectPaths';
17
20
  import { Tr2TextureReference as _Tr2TextureReference } from '../../core/Tr2TextureReference.js';
18
21
  import { Tr2VariableStore as _Tr2VariableStore } from '../../core/variable/Tr2VariableStore.js';
19
22
  import { Tr2PostProcessRenderer as _Tr2PostProcessRender } from '../../postProcess/Tr2PostProcessRenderer.js';
@@ -155,9 +158,15 @@ new class extends _identity {
155
158
  /** The provider "DepthMap" is registered with; it holds this frame's scene depth. */
156
159
  #depthMapReference = new _Tr2TextureReference();
157
160
 
158
- /** The provider "SSAOMap" is registered with: the empty SSAO, or nothing. */
161
+ /** The provider "SSAOMap" is registered with: the SSAO, the empty SSAO, or nothing. */
159
162
  #ssaoMapReference = new _Tr2TextureReference();
160
163
 
164
+ /** The provider "SpaceSceneNormalMap" is registered with: the depth pass's normals. */
165
+ #normalMapReference = new _Tr2TextureReference();
166
+
167
+ /** The provider "EveSpaceSceneOpaqueMap" is registered with: the opaque colour copy. */
168
+ _opaqueMapReference = new _Tr2TextureReference();
169
+
161
170
  /**
162
171
  * m_viewLast / m_projectionLast (EveSpaceSceneRenderDriver.h:147-149): the
163
172
  * previous frame's camera. The driver owns them, not the scene, because
@@ -168,12 +177,9 @@ new class extends _identity {
168
177
  _projectionLast = mat4.create();
169
178
 
170
179
  /**
171
- * The batch types this driver submits, in submission order.
172
- *
173
- * Carbon's main pass draws OPAQUE then DECAL (EveSpaceScene.cpp:2725/2731),
174
- * with transparent and additive following in the same pass (:2758). Only the
175
- * first two are submitted here; the rest are a later insertion at the marked
176
- * point in #Submit.
180
+ * The opaque family, in submission order: Carbon's RenderOpaqueBatches
181
+ * draws OPAQUE then DECAL (EveSpaceScene.cpp:1124-1150). The transparent
182
+ * family follows after the opaque copy; see _SubmitTransparent.
177
183
  */
178
184
 
179
185
  /** The standard states Carbon applies before each accumulator (EveSpaceScene.cpp:1139-1142). */
@@ -223,10 +229,10 @@ new class extends _identity {
223
229
  *
224
230
  * The spine of Carbon's Execute, in Carbon's order. NOT here, each an
225
231
  * insertion into this same sequence: the background node, the reflection
226
- * pass, the depth prepass, shadows, SSAO, the light-list update, the
227
- * distortion map, transparent and additive submission, the scene overlay,
228
- * lensflare occlusion queries and 3D UI. The scene renders into its own
229
- * colour and depth, plus TAA's velocity map and opaque copy when
232
+ * pass, shadows, the light-list update, the distortion map, the scene
233
+ * overlay and 3D UI. The scene renders into
234
+ * its own colour and depth, plus the depth pass's normal map when ambient
235
+ * occlusion is on and TAA's velocity map and opaque copy when
230
236
  * anti-aliasing is on, and the post process draws it into the destination.
231
237
  *
232
238
  * Rendering-disabled is not a no-op in Carbon either: the scene still
@@ -238,6 +244,11 @@ new class extends _identity {
238
244
  if (!renderContext || !this.Validate()) return false;
239
245
  const target = Array.isArray(destinations) ? destinations[0] ?? null : destinations;
240
246
 
247
+ // Step 1 of EveSpaceScene's driver order: the update context carries the
248
+ // frame's render context, whose view the scene's view-dependent updates
249
+ // read (billboards, the flare occluders' transforms).
250
+ this.scene.updateContext.renderContext = renderContext;
251
+
241
252
  // RENDERING DISABLED (cpp:408-419): camera onto the renderer and the scene
242
253
  // update, so simulation keeps running - and nothing else. No target borrow,
243
254
  // no clear, no camera update.
@@ -306,8 +317,8 @@ new class extends _identity {
306
317
  _Tr2VariableStore.GlobalStore().RegisterVariable("DepthMap", this.#depthMapReference);
307
318
  }
308
319
 
309
- // cpp:550 - the shadow pass's textures as globals. No shadow pass is
310
- // ported, so every resource is empty and the white fallbacks go in.
320
+ // The shadow globals start empty, with the white fallbacks: the shadow
321
+ // pass fills them for the main pass only (cpp:550, 557).
311
322
  _EveSpaceScene.registerWithVariableStore(_EveSpaceSceneRenderD.#noShadowResources, this.#gpuResourcePool);
312
323
  const submitted = this.#RenderMainPass(renderContext, offscreen);
313
324
 
@@ -344,6 +355,18 @@ new class extends _identity {
344
355
  // (cpp:625-626); the pool reclaims the depth texture after this.
345
356
  this.#RegisterSSAOMap(_EveSpaceSceneRenderD.getEmptySSAO(this.#gpuResourcePool));
346
357
  this.#depthMapReference.SetTexture(null);
358
+
359
+ // The normal map is an Execute local in Carbon (cpp:514), never handed
360
+ // to the post process.
361
+ if (offscreen?.normal) {
362
+ this.#gpuResourcePool.Free(offscreen.normal);
363
+ offscreen.normal = null;
364
+ }
365
+
366
+ // So are the shadow resources (cpp:526).
367
+ for (const handle of Object.values(offscreen?.shadows ?? {})) {
368
+ if (handle.IsValid()) this.#gpuResourcePool.Free(handle);
369
+ }
347
370
  if (offscreen && !handedOff) this.#EndOffscreen(offscreen);
348
371
  }
349
372
  }
@@ -433,6 +456,14 @@ new class extends _identity {
433
456
  renderContext.SetProjection(this.scene.jitteredProjection);
434
457
  this.scene.BlendLightingOverrides();
435
458
  this.scene.UpdateFogSettings();
459
+
460
+ // The light manager exists only while dynamic lighting is on
461
+ // (EveSpaceScene.cpp:1378-1388), and publishes its buffers before the gather.
462
+ if (this.scene.dynamicLightingEnabled) {
463
+ _Tr2LightManager.getOrCreateInstance(COMPUTE_LIGHT_LISTS_EFFECT_PATH).SetVariableStore();
464
+ } else {
465
+ _Tr2LightManager.deleteInstance();
466
+ }
436
467
  this.scene.UpdateVisibility?.(renderContext.GetInverseViewTransform?.() ?? null);
437
468
  const map = this.#Collect(this.scene.GetRenderables?.([]) ?? [], renderContext);
438
469
 
@@ -440,6 +471,10 @@ new class extends _identity {
440
471
  // reflection - go through the variable store (UpdateVariableStore,
441
472
  // EveSpaceScene.cpp:1390-1397).
442
473
  this.scene.UpdateVariableStore();
474
+
475
+ // The dynamic lights, after the gather (EveSpaceScene.cpp:1398-1416).
476
+ const lightManager = _Tr2LightManager.getInstance();
477
+ if (lightManager) this.scene.GatherLights(lightManager);
443
478
  if (offscreen) offscreen.velocity = this._GetVelocityMapIfNeeded(offscreen.size);
444
479
 
445
480
  // "The lensflares need a special pre-render update" (cpp:1419-1422): after
@@ -464,10 +499,38 @@ new class extends _identity {
464
499
  // block for compute as well, which dynamic exposure reads Time from.
465
500
  this.scene.ApplyPerFrameData(renderContext);
466
501
 
502
+ // THE DEPTH PASS (cpp:514-521): depth and, when AO or a forced map wants
503
+ // it, the normal map, before shadows and SSAO read them. The depth
504
+ // buffer stays bound; the scene colour is back in slot 0 afterwards.
505
+ if (offscreen && map) {
506
+ offscreen.normal = this._GetNormalMapIfNeeded(offscreen.size);
507
+ this.scene.RenderDepthPass(offscreen.depth.Get(), offscreen.normal?.Get() ?? null, null, renderContext, this.depthPassTechnique, map);
508
+ }
509
+ this.#normalMapReference.SetTexture(offscreen?.normal?.Get() ?? null);
510
+ _Tr2VariableStore.GlobalStore().RegisterVariable("SpaceSceneNormalMap", this.#normalMapReference);
511
+
467
512
  // Carbon gates the main pass on the scene's display flag AND this switch
468
513
  // (cpp:527).
469
514
  if (!this.mainPassRenderingEnabled || this.scene.display === false) return false;
515
+
516
+ // SHADOWS (cpp:529-532), after the depth pass: the cascaded shadow map and
517
+ // its screen-space factor, held until the frame ends.
518
+ if (offscreen) offscreen.shadows = this.scene.RenderShadows(offscreen.depth.Get(), offscreen.normal?.Get() ?? null, this.#gpuResourcePool, renderContext, this.#renderer);
519
+
520
+ // SSAO (cpp:534-537), after the shadows and before the main pass samples
521
+ // SSAOMap.
522
+ if (offscreen) this.#RegisterSSAOMap(this._RenderSSAO(offscreen.depth.Get(), offscreen.normal?.Get() ?? null, renderContext));
523
+
524
+ // The light lists, against this frame's depth read-only (cpp:539-546).
525
+ if (offscreen && lightManager) {
526
+ renderContext.SetReadOnlyDepth(true);
527
+ lightManager.UpdateLists(offscreen.depth.Get(), renderContext);
528
+ renderContext.SetReadOnlyDepth(false);
529
+ }
470
530
  if (offscreen) offscreen.opaque = this._GetOpaqueColorMapIfNeeded(offscreen.size);
531
+
532
+ // cpp:550 - the shadow pass's textures as globals, for the main pass.
533
+ if (offscreen?.shadows) _EveSpaceScene.registerWithVariableStore(offscreen.shadows, this.#gpuResourcePool);
471
534
  const velocity = offscreen?.velocity?.Get() ?? null;
472
535
  const opaque = offscreen?.opaque?.Get() ?? null;
473
536
  const esm = renderContext.GetEffectStateManager();
@@ -495,9 +558,8 @@ new class extends _identity {
495
558
  }
496
559
 
497
560
  // THE OPAQUE COLOUR COPY (EveSpaceScene.cpp:2738-2750): the scene colour
498
- // after the opaque family, which TAA reads as CurrentFrameOpaque. Carbon
499
- // also publishes it as EveSpaceSceneOpaqueMap in the global variable store
500
- // for transparent shaders; nothing here submits those yet, so it is not.
561
+ // after the opaque family, which TAA reads as CurrentFrameOpaque and
562
+ // transparent shaders read as the global EveSpaceSceneOpaqueMap.
501
563
  if (opaque) {
502
564
  renderContext.RenderPassHint(new Tr2ColorAttachment(Tr2LoadAction.DONT_CARE, Tr2StoreAction.STORE), null);
503
565
  esm.PushDepthStencilBuffer(null);
@@ -509,29 +571,112 @@ new class extends _identity {
509
571
  esm.PopRenderTarget();
510
572
  esm.PopDepthStencilBuffer();
511
573
  }
574
+ this._opaqueMapReference.SetTexture(opaque);
575
+ _Tr2VariableStore.GlobalStore().RegisterVariable("EveSpaceSceneOpaqueMap", this._opaqueMapReference);
512
576
  }
577
+
578
+ // THE TRANSPARENT FAMILY (EveSpaceScene.cpp:2758). Carbon runs subsurface
579
+ // scattering, the jittered-projection refresh and the volumetrics between
580
+ // the opaque copy and this (cpp:2752-2757); none of those are ported.
581
+ submitted = this._SubmitTransparent(map, renderContext) || submitted;
582
+
583
+ // cpp:557 - the shadow globals are emptied after the main pass.
584
+ if (offscreen?.shadows) _EveSpaceScene.registerWithVariableStore(_EveSpaceSceneRenderD.#noShadowResources, this.#gpuResourcePool);
513
585
  return submitted;
514
586
  }
515
587
 
516
588
  /**
517
- * Carbon's private PropagateSettings (cpp:212-231), the anti-aliasing part: the
518
- * setting creates, updates or removes the TAA effect on the scene's default
519
- * post process, whose quality is the setting's value.
589
+ * Carbon's private PropagateSettings (cpp:212-280), the anti-aliasing and
590
+ * ambient-occlusion parts. Anti-aliasing creates, updates or removes the TAA
591
+ * effect on the scene's default post process, whose quality is the
592
+ * setting's value. Ambient occlusion enables the SSAO, when there is one,
593
+ * at the quality the setting maps to.
520
594
  *
521
- * Adapted: Carbon's shadow, AO, volumetric and upscaling propagation follows
522
- * in the same method; none of those passes run in this driver yet.
595
+ * Adapted: Carbon's shadow propagation sits between the two, and its
596
+ * post-process quality, volumetric and upscaling propagation follow; none
597
+ * of those passes run in this driver yet.
523
598
  *
524
599
  * @returns {void}
525
600
  */
526
601
  _PropagateSettings() {
527
602
  const postprocess = this.scene.postprocess;
528
- if (!postprocess) return;
529
- if (this.antiAliasingQuality === AntiAliasingQuality.Disabled) {
530
- postprocess.SetTaa(null);
531
- return;
603
+ if (postprocess) {
604
+ if (this.antiAliasingQuality === AntiAliasingQuality.Disabled) {
605
+ postprocess.SetTaa(null);
606
+ } else {
607
+ if (!postprocess.GetTaaIfAvailable()) postprocess.SetTaa(new _Tr2PPTaaEffect());
608
+ postprocess.GetTaaIfAvailable().quality = this.antiAliasingQuality;
609
+ }
610
+ }
611
+
612
+ // Shadow quality (cpp:233-255): the cascaded shadow map exists at LOW and
613
+ // HIGH. Carbon's raytracing manager is not ported, so RAYTRACED has none.
614
+ if (this.shadowQuality === ShadowQuality.SHADOW_DISABLED || this.shadowQuality === ShadowQuality.SHADOW_RAYTRACED) {
615
+ this.scene.cascadedShadowMap = null;
616
+ } else if (!this.scene.cascadedShadowMap) {
617
+ this.scene.cascadedShadowMap = new _Tr2ShadowMap();
618
+ }
619
+ this.scene.shadowQualitySetting = this.shadowQuality;
620
+ if (this.SSAO) {
621
+ if (this.aoQuality === AmbientOcclusionQuality.Disabled) {
622
+ this.SSAO.Enable(false);
623
+ } else {
624
+ this.SSAO.Enable(true);
625
+ switch (this.aoQuality) {
626
+ case AmbientOcclusionQuality.Low:
627
+ this.SSAO.SetQuality(SSAOQuality.LOW, true);
628
+ break;
629
+ case AmbientOcclusionQuality.Medium:
630
+ this.SSAO.SetQuality(SSAOQuality.MEDIUM, false);
631
+ break;
632
+ default:
633
+ this.SSAO.SetQuality(SSAOQuality.HIGHEST, false);
634
+ break;
635
+ }
636
+ }
532
637
  }
533
- if (!postprocess.GetTaaIfAvailable()) postprocess.SetTaa(new _Tr2PPTaaEffect());
534
- postprocess.GetTaaIfAvailable().quality = this.antiAliasingQuality;
638
+ }
639
+
640
+ /**
641
+ * Carbon's private RenderSSAO (cpp:360-382): the SSAO filtered from the
642
+ * depth and normal maps with depth bound read-only, or the empty SSAO when
643
+ * there is none.
644
+ *
645
+ * Adapted: Carbon's `temporal` is also true under a temporal upscaler,
646
+ * which is not ported, so only the post process's TAA sets it.
647
+ *
648
+ * @param {object} depthMap The scene depth.
649
+ * @param {object|null} normalMap The depth pass's normal map.
650
+ * @param {object} renderContext The frame's context.
651
+ * @returns {GpuResourceHandle} The SSAO texture.
652
+ */
653
+ _RenderSSAO(depthMap, normalMap, renderContext) {
654
+ let ssao = new GpuResourceHandle();
655
+ if (this.scene.display && this.SSAO) {
656
+ renderContext.SetReadOnlyDepth(true);
657
+ const scenePostProcess = this.scene.postprocess;
658
+ const temporal = scenePostProcess !== null && scenePostProcess.GetTaaIfAvailable() !== null;
659
+ ssao = this.SSAO.Filter(depthMap, normalMap, this.#gpuResourcePool, renderContext, temporal);
660
+ renderContext.SetReadOnlyDepth(false);
661
+ }
662
+ return ssao.IsValid() ? ssao : _EveSpaceSceneRenderD.getEmptySSAO(this.#gpuResourcePool);
663
+ }
664
+
665
+ /**
666
+ * Carbon's GetNormalMapIfNeeded (cpp:672-685): an R10G10B10A2_UNORM map
667
+ * when ambient occlusion or ray-traced shadows want normals, on any shader
668
+ * model but the lowest, or when forced.
669
+ *
670
+ * Adapted: Carbon also allocates it for a named render-job output; none
671
+ * exists here.
672
+ *
673
+ * @param {{width: number, height: number}} size The render size.
674
+ * @returns {GpuResourceHandle|null} The map, or null.
675
+ */
676
+ _GetNormalMapIfNeeded(size) {
677
+ const wanted = (this.aoQuality !== AmbientOcclusionQuality.Disabled || this.shadowQuality === ShadowQuality.SHADOW_RAYTRACED) && _Tr2Renderer.GetShaderModel() !== TR2SHADERMODEL.TR2SM_3_0_LO;
678
+ if (!wanted && !this.forceNormalMap) return null;
679
+ return this.#TempTexture("normalMap", size, PixelFormat.PIXEL_FORMAT_R10G10B10A2_UNORM);
535
680
  }
536
681
 
537
682
  /**
@@ -615,7 +760,11 @@ new class extends _identity {
615
760
  depth: texture("depthBuffer", PixelFormat.PIXEL_FORMAT_D32_FLOAT, Tr2GpuUsage.DEPTH_STENCIL | Tr2GpuUsage.SHADER_RESOURCE),
616
761
  // Borrowed by the main pass when TAA needs them (#RenderMainPass).
617
762
  velocity: null,
618
- opaque: null
763
+ opaque: null,
764
+ // Borrowed for the depth pass when AO needs it; the driver's to free.
765
+ normal: null,
766
+ // The shadow pass's ShadowResources; the driver's to free.
767
+ shadows: null
619
768
  };
620
769
  }
621
770
 
@@ -675,13 +824,43 @@ new class extends _identity {
675
824
  renderContext.GetEffectStateManager().ApplyStandardStates(_EveSpaceSceneRenderD.#standardStatesFor[batchType]);
676
825
  submitted = renderContext.RenderBatches(accumulator) || submitted;
677
826
  }
827
+ return submitted;
828
+ }
678
829
 
679
- // Transparent, additive and distortion submission belongs here, after the
680
- // opaque family and before the overlay, exactly as Carbon orders them.
681
-
830
+ /**
831
+ * Carbon's RenderTransparentBatches (EveSpaceScene.cpp:1156-1178): the
832
+ * transparent accumulator under RM_ALPHA, then the additive one under
833
+ * RM_ALPHA_ADDITIVE. Transparent batches were sorted back to front at
834
+ * collection. Carbon's whole colour pass runs with read-only depth
835
+ * (cpp:2710, 2771); ours makes the transparent family read-only, so these
836
+ * test against the scene depth without writing it.
837
+ *
838
+ * Distortion (cpp:2759-2762) follows in Carbon and is not ported.
839
+ *
840
+ * @param {object|null} map The batch map `#Collect` produced.
841
+ * @param {object} renderContext Recording render context.
842
+ * @returns {boolean} Whether anything was submitted.
843
+ */
844
+ _SubmitTransparent(map, renderContext) {
845
+ if (!map) return false;
846
+ const esm = renderContext.GetEffectStateManager();
847
+ let submitted = false;
848
+ renderContext.SetReadOnlyDepth(true);
849
+ try {
850
+ for (const [batchType, renderingMode] of _EveSpaceSceneRenderD._transparentFamily) {
851
+ const accumulator = map.GetAccumulator(batchType);
852
+ if (!accumulator) continue;
853
+ esm.ApplyStandardStates(renderingMode);
854
+ submitted = renderContext.RenderBatches(accumulator) || submitted;
855
+ }
856
+ } finally {
857
+ renderContext.SetReadOnlyDepth(false);
858
+ }
682
859
  return submitted;
683
860
  }
684
861
 
862
+ /** The transparent family and the standard states each is drawn under (cpp:1170-1173). */
863
+
685
864
  /**
686
865
  * Puts this frame's projection and view onto the render context, and derives
687
866
  * the frustum the scene culls against.
@@ -728,6 +907,7 @@ new class extends _identity {
728
907
  pointLightShadowMap: new GpuResourceHandle(),
729
908
  pointLightShadowDepth: new GpuResourceHandle()
730
909
  };
910
+ _transparentFamily = Object.freeze([[TriBatchType.TRIBATCHTYPE_TRANSPARENT, RenderingMode.RM_ALPHA], [TriBatchType.TRIBATCHTYPE_ADDITIVE, RenderingMode.RM_ALPHA_ADDITIVE]]);
731
911
  AmbientOcclusionQuality = AmbientOcclusionQuality;
732
912
  AntiAliasingQuality = AntiAliasingQuality;
733
913
  EveVisualizeMethod = EveVisualizeMethod;