@carbonenginejs/runtime-trinity 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,6 +12,9 @@ import { Tr2PostProcessAttributes as _Tr2PostProcessAttrib } from '../../postPro
12
12
  import { EveComponentType } from '../EveComponentTypes.js';
13
13
  import { EveUpdateContext as _EveUpdateContext } from '../EveUpdateContext.js';
14
14
  import { EveEffectRoot2 as _EveEffectRoot } from '../spaceObject/EveEffectRoot2.js';
15
+ import { EveCamera as _EveCamera } from '../camera/EveCamera.js';
16
+ import { CjsPerFrameLayouts } from '../../trinityCore/rawData/CjsPerFrameLayouts.js';
17
+ import { RawData } from '../../trinityCore/rawData/RawData.js';
15
18
  import { screenToProjection, convertProjectionCoordToWorldPickRay } from '../../trinityCore/pickRay.js';
16
19
 
17
20
  let _initProto, _initClass, _init_visualizeMethod, _init_extra_visualizeMethod, _init_envMap1ResPath, _init_extra_envMap1ResPath, _init_envMap2ResPath, _init_extra_envMap2ResPath, _init_envMap3ResPath, _init_extra_envMap3ResPath, _init_lowQualityNebulaResPath, _init_extra_lowQualityNebulaResPath, _init_lowQualityNebulaMixResPath, _init_extra_lowQualityNebulaMixResPath, _init_envMapResPath, _init_extra_envMapResPath, _init_fogColor, _init_extra_fogColor, _init_sunDirection, _init_extra_sunDirection, _init_ambientColor, _init_extra_ambientColor, _init_shLightingManager, _init_extra_shLightingManager, _init_combinedPostProcessAttributes, _init_extra_combinedPostProcessAttributes, _init_dataTextureMgr, _init_extra_dataTextureMgr, _init_dynamicObjectReflectionEnabled, _init_extra_dynamicObjectReflectionEnabled, _init_componentRegistry, _init_extra_componentRegistry, _init_cameraAttachmentParent, _init_extra_cameraAttachmentParent, _init_postProcessDebug, _init_extra_postProcessDebug, _init_curveSets, _init_extra_curveSets, _init_defaultDiffuseRoughness, _init_extra_defaultDiffuseRoughness, _init_fogStart, _init_extra_fogStart, _init_fogEnd, _init_extra_fogEnd, _init_reflectionIntensity, _init_extra_reflectionIntensity, _init_distanceFields, _init_extra_distanceFields, _init_backgroundEffect, _init_extra_backgroundEffect, _init_backgroundReflectionIntensity, _init_extra_backgroundReflectionIntensity, _init_nebulaIntensity, _init_extra_nebulaIntensity, _init_display, _init_extra_display, _init_backgroundRenderingEnabled, _init_extra_backgroundRenderingEnabled, _init_update, _init_extra_update, _init_impostorManager, _init_extra_impostorManager, _init_lensflares, _init_extra_lensflares, _init_externalParameters, _init_extra_externalParameters, _init_fogMax, _init_extra_fogMax, _init_staticParticles, _init_extra_staticParticles, _init_debugRenderer, _init_extra_debugRenderer, _init_objects, _init_extra_objects, _init_uiObjects, _init_extra_uiObjects, _init_backgroundObjects, _init_extra_backgroundObjects, _init_planets, _init_extra_planets, _init_raytracingManager, _init_extra_raytracingManager, _init_reflectionBackLightingColor, _init_extra_reflectionBackLightingColor, _init_reflectionBackLightingContrast, _init_extra_reflectionBackLightingContrast, _init_reflectionProbe, _init_extra_reflectionProbe, _init_volumetricsRenderer, _init_extra_volumetricsRenderer, _init_starfield, _init_extra_starfield, _init_planetScale, _init_extra_planetScale, _init_planetCameraScale, _init_extra_planetCameraScale, _init_subSurfaceScattering, _init_extra_subSurfaceScattering, _init_shadowQualitySetting, _init_extra_shadowQualitySetting, _init_sunDiffuseColor, _init_extra_sunDiffuseColor, _init_sunDiffuseColorWithDynamicLights, _init_extra_sunDiffuseColorWithDynamicLights, _init_envMapRotation, _init_extra_envMapRotation, _init_ballpark, _init_extra_ballpark, _init_name, _init_extra_name, _init_sunBall, _init_extra_sunBall, _init_postprocess, _init_extra_postprocess, _init_virtualCameraSystem, _init_extra_virtualCameraSystem, _init_warpTunnel, _init_extra_warpTunnel, _init_perFrameDebug, _init_extra_perFrameDebug, _init_cascadedShadowMap, _init_extra_cascadedShadowMap, _init_updateTime, _init_extra_updateTime, _init_useSunDiffuseColorWithDynamicLights, _init_extra_useSunDiffuseColorWithDynamicLights, _init_envMap, _init_extra_envMap, _init_envMap2, _init_extra_envMap2, _init_envMap3, _init_extra_envMap3;
@@ -19,6 +22,23 @@ let _initProto, _initClass, _init_visualizeMethod, _init_extra_visualizeMethod,
19
22
  // Module scratch for the per-frame sun-direction read (assume-dirty).
20
23
  const sunDirectionScratch = vec3.create();
21
24
 
25
+ // Module scratch for the per-frame constant fills. Two are needed because the
26
+ // composed result and one operand are live at the same time; neither survives
27
+ // the call that wrote it.
28
+ const perFrameMatrixScratch = mat4.create();
29
+ const perFrameLastProjectionScratch = mat4.create();
30
+ const ZERO4 = Object.freeze([0, 0, 0, 0]);
31
+ const ZERO_JITTER = vec4.create();
32
+
33
+ // EveSpaceScene.cpp:3196-3199 - the four froxel-fog slice distances, constant
34
+ // every frame.
35
+ const VOLUMETRIC_SLICES = Object.freeze([1000, 10000, 100000, 1000000]);
36
+
37
+ // Flip y and change the range from (-1, +1) to (0, 1): Carbon's
38
+ // `ScalingMatrix(0.5, -0.5, 1) * TranslationMatrix(0.5, 0.5, 0)`
39
+ // (EveSpaceScene.cpp:3179), pre-built because it never changes.
40
+ const SHADOW_CLIP_TO_UV = mat4.fromValues(0.5, 0, 0, 0, 0, -0.5, 0, 0, 0, 0, 1, 0, 0.5, 0.5, 0, 1);
41
+
22
42
  // The scene-root parent transform for the visibility pass (Carbon
23
43
  // EveSpaceScene.cpp:1441 `const Matrix& identity = IdentityMatrix()`). Module
24
44
  // const, NEVER mutated - objects in m_objects are scene roots.
@@ -60,6 +80,13 @@ const IDENTITY = mat4.create();
60
80
  // (cpp:1524), so every receiver's secondary-lighting coefficients are
61
81
  // current for the frame being submitted. Skipped entirely when the scene
62
82
  // carries no shLightingManager.
83
+ // 10c. `scene.PopulatePerFramePSData(renderContext, frame, shadowMap)` then
84
+ // `scene.PopulatePerFrameVSData(renderContext, frame)` - Carbon's order at
85
+ // cpp:1424-1425, PS first, because the pixel fill is what resolves
86
+ // m_upscalingAmount that the vertex fill then reads. Runs after GatherLights
87
+ // so the blended sun colour is current. The engine binds the two records at
88
+ // Tr2Renderer::GetPerFrame{VS,PS}StartRegister; their layouts are published
89
+ // on the `/perframe` subpath.
63
90
  // 11. (driver/engine, optional) `for (const lf of scene.lensflares)
64
91
  // lf?.PrepareRender?.(frustum)` (cpp:1419-1422; the JS lensflare shell has
65
92
  // no method yet - pure no-op today).
@@ -88,7 +115,7 @@ new class extends _identity {
88
115
  } = _applyDecs2311(this, [type.define({
89
116
  className: "EveSpaceScene",
90
117
  family: "eve/scene"
91
- })], [[[io, io.readwrite, type, type.int32, void 0, schema.enum("EveVisualizeMethod")], 16, "visualizeMethod"], [[io, io.notify, io, io.persist, type, type.string], 16, "envMap1ResPath"], [[io, io.notify, io, io.persist, type, type.string], 16, "envMap2ResPath"], [[io, io.notify, io, io.persist, type, type.string], 16, "envMap3ResPath"], [[io, io.notify, io, io.persist, type, type.string], 16, "lowQualityNebulaResPath"], [[io, io.notify, io, io.persist, type, type.string], 16, "lowQualityNebulaMixResPath"], [[io, io.notify, io, io.persist, type, type.string], 16, "envMapResPath"], [[io, io.persist, type, type.color], 16, "fogColor"], [[io, io.persist, type, type.vec3], 16, "sunDirection"], [[io, io.persist, type, type.color], 16, "ambientColor"], [[io, io.persistOnly, void 0, type.model("Tr2ShLightingManager")], 16, "shLightingManager"], [[io, io.read, void 0, type.objectRef("Tr2PostProcessAttributes")], 16, "combinedPostProcessAttributes"], [[io, io.read, void 0, type.objectRef("Tr2DataTextureManager")], 16, "dataTextureMgr"], [[io, io.readwrite, type, type.boolean], 16, "dynamicObjectReflectionEnabled"], [[io, io.read, void 0, type.objectRef("EveComponentRegistry")], 16, "componentRegistry"], [type.model("EveEffectRoot2"), 0, "cameraAttachmentParent"], [type.rawStruct("BluePy"), 0, "postProcessDebug"], [[io, io.persist, void 0, type.list("TriCurveSet")], 16, "curveSets"], [[io, io.persist, type, type.float32], 16, "defaultDiffuseRoughness"], [[io, io.persist, type, type.float32], 16, "fogStart"], [[io, io.persist, type, type.float32], 16, "fogEnd"], [[io, io.notify, io, io.persist, type, type.float32], 16, "reflectionIntensity"], [[io, io.read, void 0, type.list("EveDistanceField")], 16, "distanceFields"], [[io, io.persist, void 0, type.model("Tr2Effect")], 16, "backgroundEffect"], [[io, io.persist, type, type.float32], 16, "backgroundReflectionIntensity"], [[io, io.persist, type, type.float32], 16, "nebulaIntensity"], [[io, io.persist, type, type.boolean], 16, "display"], [[io, io.persist, type, type.boolean], 16, "backgroundRenderingEnabled"], [[io, io.persist, type, type.boolean], 16, "update"], [[io, io.readwrite, void 0, type.objectRef("Tr2ImpostorManager")], 16, "impostorManager"], [[io, io.persist, void 0, type.list("EveLensflare")], 16, "lensflares"], [[io, io.persist, void 0, type.list("Tr2ExternalParameter")], 16, "externalParameters"], [[io, io.persist, type, type.float32], 16, "fogMax"], [[io, io.read, void 0, type.list("EveSceneStaticParticles")], 16, "staticParticles"], [[io, io.readwrite, void 0, type.objectRef("Tr2DebugRenderer")], 16, "debugRenderer"], [[io, io.persist, void 0, type.list("IEveSpaceObject2")], 16, "objects"], [[io, io.persist, void 0, type.list("IEveSpaceObject2")], 16, "uiObjects"], [[io, io.persist, void 0, type.list("IEveSpaceObject2")], 16, "backgroundObjects"], [[io, io.persist, void 0, type.list("EvePlanet")], 16, "planets"], [[io, io.readwrite, void 0, type.objectRef("Tr2RaytracingManager")], 16, "raytracingManager"], [[io, io.notify, io, io.persist, type, type.color], 16, "reflectionBackLightingColor"], [[io, io.notify, io, io.persist, type, type.float32], 16, "reflectionBackLightingContrast"], [[io, io.notify, io, io.readwrite, void 0, type.objectRef("Tr2ReflectionProbe")], 16, "reflectionProbe"], [[io, io.read, void 0, type.objectRef("Tr2VolumetricsRenderer")], 16, "volumetricsRenderer"], [[io, io.persist, void 0, type.model("EveStarfield")], 16, "starfield"], [[io, io.persist, type, type.float32], 16, "planetScale"], [[io, io.persist, type, type.float32], 16, "planetCameraScale"], [[io, io.read, void 0, type.objectRef("Tr2SSSSS")], 16, "subSurfaceScattering"], [[io, io.notify, io, io.readwrite, type, type.int32, void 0, schema.enum("ShadowQuality")], 16, "shadowQualitySetting"], [[io, io.persist, type, type.color], 16, "sunDiffuseColor"], [[io, io.persist, type, type.color], 16, "sunDiffuseColorWithDynamicLights"], [[io, io.persist, type, type.quat], 16, "envMapRotation"], [[io, io.readwrite, void 0, type.objectRef("IEveBallpark")], 16, "ballpark"], [[io, io.persist, type, type.string], 16, "name"], [[io, io.persist, void 0, type.model("ITriVectorFunction")], 16, "sunBall"], [[io, io.persist, void 0, type.model("Tr2PostProcess2")], 16, "postprocess"], [[io, io.persist, void 0, type.model("EveVirtualCameraSystem")], 16, "virtualCameraSystem"], [[io, io.readwrite, void 0, type.objectRef("IEveSpaceObject2")], 16, "warpTunnel"], [[io, io.readwrite, type, type.float32], 16, "perFrameDebug"], [[io, io.persist, void 0, type.model("Tr2ShadowMap")], 16, "cascadedShadowMap"], [[io, io.read, type, type.float64], 16, "updateTime"], [[io, io.persist, type, type.boolean], 16, "useSunDiffuseColorWithDynamicLights"], [[io, io.read, void 0, type.objectRef("ITr2TextureProvider")], 16, "envMap1"], [[io, io.read, void 0, type.objectRef("ITr2TextureProvider")], 16, "envMap2"], [[io, io.read, void 0, type.objectRef("ITr2TextureProvider")], 16, "envMap3"], [[carbon, carbon.method, impl, impl.adapted], 18, "Update"], [[carbon, carbon.method, impl, impl.notImplemented], 18, "PickObject"], [[carbon, carbon.method, impl, impl.notImplemented], 18, "PickAsyncObject"], [[carbon, carbon.method, impl, impl.notImplemented], 18, "PickObjectAndAreaID"], [[carbon, carbon.method, impl, impl.implemented], 18, "PickInfinity"], [[carbon, carbon.method, impl, impl.adapted, void 0, impl.reason("Carbon's g_enablePostProcessDebugging global becomes the scene-scoped enablePostProcessDebugging field; the debug payload is a plain object, null when off.")], 18, "UpdatePostProcessAttributes"], [[carbon, carbon.method, impl, impl.implemented], 18, "GetPostProcess"], [[carbon, carbon.method, impl, impl.adapted, void 0, impl.reason("Carbon's Tr2ParallelFor becomes a sequential pass; the receivers touch only their own per-object records.")], 18, "UpdateShLighting"], [[carbon, carbon.method, impl, impl.implemented], 18, "ReregisterEntities"], [[carbon, carbon.method, impl, impl.implemented], 18, "ClearComponentRegistry"], [[carbon, carbon.method, impl, impl.implemented], 18, "GetPostProcessDebug"], [[carbon, carbon.method, impl, impl.implemented], 18, "UpdateScene"]], 0, void 0, CjsModel));
118
+ })], [[[io, io.readwrite, type, type.int32, void 0, schema.enum("EveVisualizeMethod")], 16, "visualizeMethod"], [[io, io.notify, io, io.persist, type, type.string], 16, "envMap1ResPath"], [[io, io.notify, io, io.persist, type, type.string], 16, "envMap2ResPath"], [[io, io.notify, io, io.persist, type, type.string], 16, "envMap3ResPath"], [[io, io.notify, io, io.persist, type, type.string], 16, "lowQualityNebulaResPath"], [[io, io.notify, io, io.persist, type, type.string], 16, "lowQualityNebulaMixResPath"], [[io, io.notify, io, io.persist, type, type.string], 16, "envMapResPath"], [[io, io.persist, type, type.color], 16, "fogColor"], [[io, io.persist, type, type.vec3], 16, "sunDirection"], [[io, io.persist, type, type.color], 16, "ambientColor"], [[io, io.persistOnly, void 0, type.model("Tr2ShLightingManager")], 16, "shLightingManager"], [[io, io.read, void 0, type.objectRef("Tr2PostProcessAttributes")], 16, "combinedPostProcessAttributes"], [[io, io.read, void 0, type.objectRef("Tr2DataTextureManager")], 16, "dataTextureMgr"], [[io, io.readwrite, type, type.boolean], 16, "dynamicObjectReflectionEnabled"], [[io, io.read, void 0, type.objectRef("EveComponentRegistry")], 16, "componentRegistry"], [type.model("EveEffectRoot2"), 0, "cameraAttachmentParent"], [type.rawStruct("BluePy"), 0, "postProcessDebug"], [[io, io.persist, void 0, type.list("TriCurveSet")], 16, "curveSets"], [[io, io.persist, type, type.float32], 16, "defaultDiffuseRoughness"], [[io, io.persist, type, type.float32], 16, "fogStart"], [[io, io.persist, type, type.float32], 16, "fogEnd"], [[io, io.notify, io, io.persist, type, type.float32], 16, "reflectionIntensity"], [[io, io.read, void 0, type.list("EveDistanceField")], 16, "distanceFields"], [[io, io.persist, void 0, type.model("Tr2Effect")], 16, "backgroundEffect"], [[io, io.persist, type, type.float32], 16, "backgroundReflectionIntensity"], [[io, io.persist, type, type.float32], 16, "nebulaIntensity"], [[io, io.persist, type, type.boolean], 16, "display"], [[io, io.persist, type, type.boolean], 16, "backgroundRenderingEnabled"], [[io, io.persist, type, type.boolean], 16, "update"], [[io, io.readwrite, void 0, type.objectRef("Tr2ImpostorManager")], 16, "impostorManager"], [[io, io.persist, void 0, type.list("EveLensflare")], 16, "lensflares"], [[io, io.persist, void 0, type.list("Tr2ExternalParameter")], 16, "externalParameters"], [[io, io.persist, type, type.float32], 16, "fogMax"], [[io, io.read, void 0, type.list("EveSceneStaticParticles")], 16, "staticParticles"], [[io, io.readwrite, void 0, type.objectRef("Tr2DebugRenderer")], 16, "debugRenderer"], [[io, io.persist, void 0, type.list("IEveSpaceObject2")], 16, "objects"], [[io, io.persist, void 0, type.list("IEveSpaceObject2")], 16, "uiObjects"], [[io, io.persist, void 0, type.list("IEveSpaceObject2")], 16, "backgroundObjects"], [[io, io.persist, void 0, type.list("EvePlanet")], 16, "planets"], [[io, io.readwrite, void 0, type.objectRef("Tr2RaytracingManager")], 16, "raytracingManager"], [[io, io.notify, io, io.persist, type, type.color], 16, "reflectionBackLightingColor"], [[io, io.notify, io, io.persist, type, type.float32], 16, "reflectionBackLightingContrast"], [[io, io.notify, io, io.readwrite, void 0, type.objectRef("Tr2ReflectionProbe")], 16, "reflectionProbe"], [[io, io.read, void 0, type.objectRef("Tr2VolumetricsRenderer")], 16, "volumetricsRenderer"], [[io, io.persist, void 0, type.model("EveStarfield")], 16, "starfield"], [[io, io.persist, type, type.float32], 16, "planetScale"], [[io, io.persist, type, type.float32], 16, "planetCameraScale"], [[io, io.read, void 0, type.objectRef("Tr2SSSSS")], 16, "subSurfaceScattering"], [[io, io.notify, io, io.readwrite, type, type.int32, void 0, schema.enum("ShadowQuality")], 16, "shadowQualitySetting"], [[io, io.persist, type, type.color], 16, "sunDiffuseColor"], [[io, io.persist, type, type.color], 16, "sunDiffuseColorWithDynamicLights"], [[io, io.persist, type, type.quat], 16, "envMapRotation"], [[io, io.readwrite, void 0, type.objectRef("IEveBallpark")], 16, "ballpark"], [[io, io.persist, type, type.string], 16, "name"], [[io, io.persist, void 0, type.model("ITriVectorFunction")], 16, "sunBall"], [[io, io.persist, void 0, type.model("Tr2PostProcess2")], 16, "postprocess"], [[io, io.persist, void 0, type.model("EveVirtualCameraSystem")], 16, "virtualCameraSystem"], [[io, io.readwrite, void 0, type.objectRef("IEveSpaceObject2")], 16, "warpTunnel"], [[io, io.readwrite, type, type.float32], 16, "perFrameDebug"], [[io, io.persist, void 0, type.model("Tr2ShadowMap")], 16, "cascadedShadowMap"], [[io, io.read, type, type.float64], 16, "updateTime"], [[io, io.persist, type, type.boolean], 16, "useSunDiffuseColorWithDynamicLights"], [[io, io.read, void 0, type.objectRef("ITr2TextureProvider")], 16, "envMap1"], [[io, io.read, void 0, type.objectRef("ITr2TextureProvider")], 16, "envMap2"], [[io, io.read, void 0, type.objectRef("ITr2TextureProvider")], 16, "envMap3"], [[carbon, carbon.method, impl, impl.adapted], 18, "Update"], [[carbon, carbon.method, impl, impl.notImplemented], 18, "PickObject"], [[carbon, carbon.method, impl, impl.notImplemented], 18, "PickAsyncObject"], [[carbon, carbon.method, impl, impl.notImplemented], 18, "PickObjectAndAreaID"], [[carbon, carbon.method, impl, impl.implemented], 18, "PickInfinity"], [[carbon, carbon.method, impl, impl.adapted, void 0, impl.reason("Carbon's g_enablePostProcessDebugging global becomes the scene-scoped enablePostProcessDebugging field; the debug payload is a plain object, null when off.")], 18, "UpdatePostProcessAttributes"], [[carbon, carbon.method, impl, impl.implemented], 18, "GetPostProcess"], [[carbon, carbon.method, impl, impl.adapted, void 0, impl.reason("Carbon's Tr2ParallelFor becomes a sequential pass; the receivers touch only their own per-object records.")], 18, "UpdateShLighting"], [[carbon, carbon.method, impl, impl.adapted, void 0, impl.reason("Tr2Renderer view statics and the ESM's render-target/viewport sizes are engine state; the driver supplies them in `frame`.")], 18, "PopulatePerFrameVSData"], [[carbon, carbon.method, impl, impl.adapted, void 0, impl.reason("Tr2Renderer statics, the ESM viewport, Tr2LightManager's atlas settings and the upscaler's mip bias are engine state; the driver supplies them in `frame`.")], 18, "PopulatePerFramePSData"], [[carbon, carbon.method, impl, impl.implemented], 18, "ReregisterEntities"], [[carbon, carbon.method, impl, impl.implemented], 18, "ClearComponentRegistry"], [[carbon, carbon.method, impl, impl.implemented], 18, "GetPostProcessDebug"], [[carbon, carbon.method, impl, impl.implemented], 18, "UpdateScene"]], 0, void 0, CjsModel));
92
119
  }
93
120
  /** m_visualizeMethod (EveVisualizeMethod - enum EveVisualizeMethod) [READWRITE, ENUM] */
94
121
  visualizeMethod = (_initProto(this), _init_visualizeMethod(this, 0));
@@ -313,6 +340,21 @@ new class extends _identity {
313
340
  currentNebulaIntensity = 0;
314
341
  currentReflectionIntensity = 0;
315
342
 
343
+ // Carbon m_viewLast / m_projectionLast / m_jitterMatrix
344
+ // (EveSpaceScene.h:296-297, protected): the previous frame's camera, which
345
+ // the per-frame vertex block hands to the shader for motion vectors.
346
+ viewLast = mat4.create();
347
+ projectionLast = mat4.create();
348
+ jitterMatrix = mat4.create();
349
+
350
+ // Carbon m_jitter (EveSpaceScene.h:624) - xy: projection offset, zw: pixel
351
+ // offset. The per-frame pixel block reports only whether it is non-zero.
352
+ jitter = vec4.create();
353
+
354
+ // Carbon m_upscalingAmount (EveSpaceScene.h:623, =1 by default at cpp:221).
355
+ // Reset by the per-frame pixel fill and raised by an upscaler, if any.
356
+ upscalingAmount = 1;
357
+
316
358
  // Carbon g_eveSpaceSceneDynamicLighting (registered setting
317
359
  // "eveSpaceSceneDynamicLighting", cpp:109-110, default false) - scoped to
318
360
  // the scene instead of a module global.
@@ -735,6 +777,250 @@ new class extends _identity {
735
777
  return updated;
736
778
  }
737
779
 
780
+ /**
781
+ * The scene's own per-frame vertex record (Carbon m_perFrameVS,
782
+ * EveSpaceScene.h:300). Persistent, not arena-leased: it is rewritten each
783
+ * frame and bound once, and the PS fill reads m_upscalingAmount back out of
784
+ * the same pass.
785
+ */
786
+ #perFrameVS = RawData.create("EveSpaceScenePerFrameVSData");
787
+
788
+ /** Carbon m_perFramePS (EveSpaceScene.h:240). */
789
+ #perFramePS = RawData.create("EveSpaceScenePerFramePSData");
790
+
791
+ /** The record PopulatePerFrameVSData fills. */
792
+ GetPerFrameVSData() {
793
+ return this.#perFrameVS;
794
+ }
795
+
796
+ /** The record PopulatePerFramePSData fills. */
797
+ GetPerFramePSData() {
798
+ return this.#perFramePS;
799
+ }
800
+
801
+ /**
802
+ * Fills the per-frame VERTEX constants (Carbon
803
+ * EveSpaceScene::PopulatePerFrameVSData, cpp:3015-3068).
804
+ *
805
+ * Adapted in one respect, the same way StampFrameContext is: Carbon reads
806
+ * the camera off `Tr2Renderer` statics and the render-target/viewport sizes
807
+ * off `renderContext.m_esm`, neither of which exists GPU-free here. The
808
+ * driver passes them in `frame` instead. Everything the scene itself owns -
809
+ * sun, fog, env-map rotation, the previous frame's view/projection - is read
810
+ * from the scene, as Carbon does.
811
+ *
812
+ * Matrices are stored TRANSPOSED because the shaders are column_major, with
813
+ * one deliberate exception Carbon calls out at cpp:3023: the value wanted for
814
+ * `ViewInverseTransposeMat` is already a transpose, so transposing it again
815
+ * cancels and the inverse view goes in as-is.
816
+ *
817
+ * @param {Object} renderContext - the frame's Tr2RenderContext
818
+ * @param {Object} [frame] - the engine-supplied state Carbon reads statically
819
+ * @param {Number} [frame.renderTargetWidth]
820
+ * @param {Number} [frame.renderTargetHeight]
821
+ * @param {Number} [frame.aspectRatio]
822
+ * @param {Number} [frame.animationTime] - Tr2Renderer::GetAnimationTime
823
+ * @param {Object|null} [frame.deviceViewport] - {width, height}
824
+ * @param {Object|null} [frame.projectionTransform] - the NON reversed-depth
825
+ * projection, which Carbon uses only to recover the field of view
826
+ * @param {Object} [out] - the record to fill; defaults to the scene's own
827
+ * @returns {Object} the filled record
828
+ */
829
+ PopulatePerFrameVSData(renderContext, frame = {}, out = this.#perFrameVS) {
830
+ const view = renderContext.GetViewTransform();
831
+ const projection = renderContext.GetProjection();
832
+
833
+ // column_major for shaders
834
+ out.SetAndTranspose("ViewMat", view);
835
+ out.SetAndTranspose("ProjectionMat", projection);
836
+
837
+ // Carbon `view * proj` (row-vector); gl-matrix swaps the operands.
838
+ mat4.multiply(perFrameMatrixScratch, projection, view);
839
+ out.SetAndTranspose("ViewProjectionMat", perFrameMatrixScratch);
840
+
841
+ // Needs the transposed, but the shader also wants column_major, so it is
842
+ // transpose(transpose(m)) == m (cpp:3023-3024).
843
+ mat4.transpose(perFrameMatrixScratch, renderContext.GetInverseViewTransform());
844
+ out.SetAndTranspose("ViewInverseTransposeMat", perFrameMatrixScratch);
845
+
846
+ // Carbon `m_projectionLast * m_jitterMatrix` then `m_viewLast * that`.
847
+ mat4.multiply(perFrameLastProjectionScratch, this.jitterMatrix, this.projectionLast);
848
+ out.SetAndTranspose("ProjLast", perFrameLastProjectionScratch);
849
+ out.SetAndTranspose("ViewLast", this.viewLast);
850
+ mat4.multiply(perFrameMatrixScratch, perFrameLastProjectionScratch, this.viewLast);
851
+ out.SetAndTranspose("ViewProjectionLast", perFrameMatrixScratch);
852
+
853
+ // Each scene has a nebula, and that can be rotated and inverted by scaling.
854
+ mat4.fromQuat(perFrameMatrixScratch, this.envMapRotation);
855
+ out.SetAndTranspose("EnvMapRotationMat", perFrameMatrixScratch);
856
+ this.#FillSunData(out);
857
+ out.Set("TargetResolution", [frame.renderTargetWidth ?? 0, frame.renderTargetHeight ?? 0]);
858
+ this.#FillFovXY(out, frame);
859
+
860
+ // Guarded so a zero-width fog band cannot divide by zero (cpp:3049-3054).
861
+ let distance = this.fogEnd - this.fogStart;
862
+ if (Math.abs(distance) < 1e-5) {
863
+ distance = 1e-5;
864
+ }
865
+ out.Set("FogFactors", [this.fogEnd / distance, 1 / distance, this.fogMax]);
866
+
867
+ // Derived from SetupViewport in Tr2Renderer.cpp (cpp:3056-3062).
868
+ const viewport = renderContext.GetViewport();
869
+ const device = frame.deviceViewport ?? viewport;
870
+ if (viewport && device) {
871
+ out.Set("ViewportAdjustment", [viewport.x < 0 ? -1 : 1, viewport.y + viewport.height > (frame.renderTargetHeight ?? 0) ? -1 : 1, device.width / viewport.width, device.height / viewport.height]);
872
+ }
873
+ out.Set("Time", frame.animationTime ?? 0);
874
+ out.Set("Upscaling", this.upscalingAmount);
875
+ out.Set("ViewportSize", device ? [device.width, device.height] : [0, 0]);
876
+ return out;
877
+ }
878
+
879
+ /**
880
+ * Fills the per-frame PIXEL constants (Carbon
881
+ * EveSpaceScene::PopulatePerFramePSData, cpp:3075-3202). Same `frame`
882
+ * adaptation as the vertex fill.
883
+ *
884
+ * The cascaded-shadow block (ShadowMapValues / CascadeRanges /
885
+ * ShadowMatrixVal / SplitInfo) is filled only when a shadow map is passed,
886
+ * exactly as Carbon's `if( shadowMap )` gate does; without one the record
887
+ * keeps the shadows-disabled defaults the catalog declares.
888
+ *
889
+ * @param {Object} renderContext - the frame's Tr2RenderContext
890
+ * @param {Object} [frame] - as PopulatePerFrameVSData, plus:
891
+ * @param {Number} [frame.frameIndex] - Tr2Renderer::GetCurrentFrameCounter
892
+ * @param {Number} [frame.gammaBrightness]
893
+ * @param {Number} [frame.sceneMipLodBias] - the upscaler's bias, plus the
894
+ * scene post-process's own; the upscaling info is engine state
895
+ * @param {Number} [frame.inverseShadowMapAtlasSize] - 0 with no light manager
896
+ * @param {Number} [frame.shadowMapAtlasEntryMinSizeLog2]
897
+ * @param {Object|null} [shadowMap] - the cascaded shadow map, or null
898
+ * @param {Object} [out] - the record to fill; defaults to the scene's own
899
+ * @returns {Object} the filled record
900
+ */
901
+ PopulatePerFramePSData(renderContext, frame = {}, shadowMap = null, out = this.#perFramePS) {
902
+ const projection = renderContext.GetProjection();
903
+ out.SetAndTranspose("ViewMat", renderContext.GetViewTransform());
904
+
905
+ // transpose(transpose(m)) == m, as in the vertex fill (cpp:3079-3080).
906
+ mat4.transpose(perFrameMatrixScratch, renderContext.GetInverseViewTransform());
907
+ out.SetAndTranspose("ViewInverseTransposeMat", perFrameMatrixScratch);
908
+ mat4.fromQuat(perFrameMatrixScratch, this.envMapRotation);
909
+ out.SetAndTranspose("EnvMapRotationMat", perFrameMatrixScratch);
910
+ this.#FillSunData(out);
911
+
912
+ // The pixel fill alone overrides the sun's alpha with the roughness
913
+ // (cpp:3087) - the vertex fill leaves the blended colour's own alpha.
914
+ out.Set("SunDiffuseColor", [this.currentSunColor[0], this.currentSunColor[1], this.currentSunColor[2], this.defaultDiffuseRoughness]);
915
+ out.Set("AmbientColor", [this.ambientColor[0], this.ambientColor[1], this.ambientColor[2]]);
916
+ out.Set("ReflectionIntensity", this.currentReflectionIntensity);
917
+ out.Set("FogColor", [this.fogColor[0], this.fogColor[1], this.fogColor[2], this.fogMax]);
918
+ out.Set("GammaBrightness", frame.gammaBrightness ?? 0);
919
+ out.Set("TargetResolution", [frame.renderTargetWidth ?? 0, frame.renderTargetHeight ?? 0]);
920
+ this.#FillFovXY(out, frame);
921
+
922
+ // Shadows are disabled by default (cpp:3107).
923
+ out.Set("ShadowCameraRange", [1, 0]);
924
+ const viewport = renderContext.GetViewport();
925
+ const device = frame.deviceViewport ?? viewport;
926
+ out.Set("ViewportOffset", viewport ? [viewport.x, viewport.y] : [0, 0]);
927
+ out.Set("ViewportSize", device ? [device.width, device.height] : [0, 0]);
928
+ out.Set("Time", frame.animationTime ?? 0);
929
+ out.Set("FrameIndex", frame.frameIndex ?? 0);
930
+ out.Set("Jittering", vec4.exactEquals(this.jitter, ZERO_JITTER) ? 0 : 1);
931
+
932
+ // Carbon stores 1 << m_shadowQuality, not the enum value.
933
+ out.Set("ShadowQuality", 1 << this.shadowQualitySetting);
934
+ out.Set("InverseShadowMapAtlasSize", frame.inverseShadowMapAtlasSize ?? 0);
935
+ out.Set("ShadowMapAtlasEntryMinSizeLog2", frame.shadowMapAtlasEntryMinSizeLog2 ?? 0);
936
+ out.Set("ShadowMapSettings", [1, 1, 0, 0]);
937
+ out.Set("ShadowLightness", 0);
938
+ out.Set("DepthMapSampleCount", 1); // legacy
939
+
940
+ // The reversed-depth projection's _43/_33, which the shader uses to turn a
941
+ // depth sample back into a view-space distance (cpp:3140-3142).
942
+ out.Set("ProjectionToView", [projection[14], projection[10]]);
943
+
944
+ // Carbon resets m_upscalingAmount here and lets the upscaler raise it; with
945
+ // no upscaler the scene stays at 1 and only the post-process bias applies.
946
+ this.upscalingAmount = frame.upscalingAmount ?? 1;
947
+ out.Set("Upscaling", this.upscalingAmount);
948
+ out.Set("SceneMipLodBias", frame.sceneMipLodBias ?? 0);
949
+ if (shadowMap) {
950
+ this.#FillShadowCascades(out, shadowMap, renderContext);
951
+ }
952
+
953
+ // m_perFrameVS.ProjectionMat is already transposed (cpp:3192-3193).
954
+ mat4.transpose(perFrameMatrixScratch, projection);
955
+ mat4.invert(perFrameMatrixScratch, perFrameMatrixScratch);
956
+ out.SetAndTranspose("ProjectionInverseMat", perFrameMatrixScratch);
957
+ out.Set("Debug", this.perFrameDebug);
958
+ out.Set("VolumetricSlices", VOLUMETRIC_SLICES);
959
+ this.volumetricsRenderer?.PopulatePerFrameData?.(out);
960
+ return out;
961
+ }
962
+
963
+ /**
964
+ * The SunData block both fills share (cpp:3035-3039 / 3085-3089). The
965
+ * direction is normalized AND negated: shaders work with the direction TO
966
+ * the light, not the direction it travels.
967
+ */
968
+ #FillSunData(out) {
969
+ vec3.normalize(sunDirectionScratch, this.sunDirection);
970
+ out.Set("SunDirWorld", [-sunDirectionScratch[0], -sunDirectionScratch[1], -sunDirectionScratch[2]]);
971
+ out.Set("SunDiffuseColor", this.currentSunColor);
972
+ }
973
+
974
+ /**
975
+ * FOV both ways - width in x, height in y (cpp:3046-3047 / 3103-3104).
976
+ * Carbon recovers it from the NON reversed-depth projection, so a driver
977
+ * that reverses depth must pass the original in `frame.projectionTransform`.
978
+ */
979
+ #FillFovXY(out, frame) {
980
+ const source = frame.projectionTransform;
981
+ const fovY = source ? _EveCamera.CalculateFovFromProjection(source) : 0;
982
+ out.Set("FovXY", [fovY * (frame.aspectRatio ?? 1), fovY]);
983
+ }
984
+
985
+ /**
986
+ * The cascaded-shadow block (cpp:3163-3190). Each cascade's shadow matrix is
987
+ * rebased into the current view, flipped in y, remapped from (-1,+1) to
988
+ * (0,1), then scaled and offset into its cell of the 8x2 atlas.
989
+ */
990
+ #FillShadowCascades(out, shadowMap, renderContext) {
991
+ const split = shadowMap.perSplitData ?? shadowMap.m_perSplitData ?? {};
992
+ for (let index = 0; index < 4; index++) {
993
+ out.SetIndex("ShadowMapValues", index, split.ShadowMapValues?.[index] ?? ZERO4);
994
+ }
995
+ for (let index = 0; index < 16; index++) {
996
+ out.SetIndex("CascadeRanges", index, split.CascadeRanges?.[index] ?? ZERO4);
997
+ }
998
+ const inverseView = renderContext.GetInverseViewTransform();
999
+ const cellsX = 8;
1000
+ const cellsY = 2;
1001
+ for (let index = 0; index < CjsPerFrameLayouts.SHADOW_FRUSTUM_COUNT; index++) {
1002
+ const stored = split.ShadowMatrixVal?.[index];
1003
+ if (!stored) {
1004
+ continue;
1005
+ }
1006
+
1007
+ // Carbon `inverseView * Transpose(stored)`; gl-matrix swaps operands.
1008
+ mat4.transpose(perFrameLastProjectionScratch, stored);
1009
+ mat4.multiply(perFrameMatrixScratch, perFrameLastProjectionScratch, inverseView);
1010
+
1011
+ // Flip y and change the range from (-1, +1) to (0, 1).
1012
+ mat4.multiply(perFrameMatrixScratch, SHADOW_CLIP_TO_UV, perFrameMatrixScratch);
1013
+
1014
+ // Then into this cascade's cell of the 8x2 atlas.
1015
+ mat4.identity(perFrameLastProjectionScratch);
1016
+ mat4.translate(perFrameLastProjectionScratch, perFrameLastProjectionScratch, [index % cellsX / cellsX, Math.floor(index / cellsX) / cellsY, 0]);
1017
+ mat4.scale(perFrameLastProjectionScratch, perFrameLastProjectionScratch, [1 / cellsX, 1 / cellsY, 1]);
1018
+ mat4.multiply(perFrameMatrixScratch, perFrameLastProjectionScratch, perFrameMatrixScratch);
1019
+ out.SetAndTransposeIndex("ShadowMatrixVal", index, perFrameMatrixScratch);
1020
+ }
1021
+ out.Set("SplitInfo", split.SplitInfo ?? ZERO4);
1022
+ }
1023
+
738
1024
  /** Carbon method ReregisterEntities (MAP_METHOD_AND_WRAP, cpp:4064-4089).
739
1025
  * Guarded no-op after ClearComponentRegistry has nulled the registry
740
1026
  * (destroy-only path; Carbon would never call this afterwards). */