diff --git a/Aetheria.Unity/Packages/manifest.json b/Aetheria.Unity/Packages/manifest.json index 81b013bb6..8157370e3 100644 --- a/Aetheria.Unity/Packages/manifest.json +++ b/Aetheria.Unity/Packages/manifest.json @@ -9,6 +9,6 @@ "org.gamecult.cultlib": "https://github.com/GameCult/CultLib.git?path=/unity/org.gamecult.cultlib#cultlib-unity-v1.0.15", "org.gamecult.eve.plugin-fields": "https://github.com/GameCult/EvePlugins.git?path=/plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields#eve-plugin-fields-unity-v0.2.3", "org.gamecult.eve.surface": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.surface#eveunity-surface-v0.2.2", - "org.gamecult.eve.unity-scene": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.57" + "org.gamecult.eve.unity-scene": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.58" } } diff --git a/Aetheria.Unity/Packages/packages-lock.json b/Aetheria.Unity/Packages/packages-lock.json index 704fa9d67..9e32cf4c2 100644 --- a/Aetheria.Unity/Packages/packages-lock.json +++ b/Aetheria.Unity/Packages/packages-lock.json @@ -144,7 +144,7 @@ "hash": "140e1bd963a0033e66777a3b2c5fe6e9c97dfe32" }, "org.gamecult.eve.unity-scene": { - "version": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.57", + "version": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.58", "depth": 0, "source": "git", "dependencies": { @@ -155,7 +155,7 @@ "com.unity.render-pipelines.universal": "17.4.0", "com.unity.modules.particlesystem": "1.0.0" }, - "hash": "0974154fa7c7982c9a8ea0ca006d2698a53e1235" + "hash": "02203ff134570c301ce58969397c296ee14e69ee" }, "com.unity.modules.assetbundle": { "version": "1.0.0", diff --git a/Assets/Editor/AetheriaGravityFogVerifier.cs b/Assets/Editor/AetheriaGravityFogVerifier.cs new file mode 100644 index 000000000..d9d380725 --- /dev/null +++ b/Assets/Editor/AetheriaGravityFogVerifier.cs @@ -0,0 +1,35 @@ +using System; +using System.IO; +using UnityEditor; +using UnityEngine; + +namespace Aetheria.Editor +{ + internal static class AetheriaGravityFogVerifier + { + internal static void VerifyCameraProjection(Shader shader, bool requireAuthoredSource) + { + if (shader == null) + throw new ArgumentNullException(nameof(shader)); + var shaderPath = AssetDatabase.GetAssetPath(shader); + var source = string.IsNullOrWhiteSpace(shaderPath) || !File.Exists(shaderPath) + ? "" + : File.ReadAllText(shaderPath); + if (string.IsNullOrWhiteSpace(source)) + { + if (requireAuthoredSource) + throw new InvalidOperationException("Gravity-fog authored shader source is unavailable for verification."); + return; + } + + const string forwardRay = "float3(i.vsray, 1.0)"; + var first = source.IndexOf(forwardRay, StringComparison.Ordinal); + var second = first < 0 + ? -1 + : source.IndexOf(forwardRay, first + forwardRay.Length, StringComparison.Ordinal); + if (second < 0) + throw new InvalidOperationException( + "Gravity-fog raymarching and temporal reprojection must both use the historical positive-Z Unity shader camera transform."); + } + } +} diff --git a/Assets/Editor/AetheriaGravityFogVerifier.cs.meta b/Assets/Editor/AetheriaGravityFogVerifier.cs.meta new file mode 100644 index 000000000..079d6ccbb --- /dev/null +++ b/Assets/Editor/AetheriaGravityFogVerifier.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: f3c24b224fdb4ec4a5bc071e0bd4bcf4 diff --git a/Assets/Editor/EveAssetBundleBuilder.cs b/Assets/Editor/EveAssetBundleBuilder.cs index 96d532aaf..20a1f616e 100644 --- a/Assets/Editor/EveAssetBundleBuilder.cs +++ b/Assets/Editor/EveAssetBundleBuilder.cs @@ -58,6 +58,11 @@ namespace Aetheria.Editor AetheriaStardustContinuityVerifier.VerifyTemporalDitherMaterial( authoredStardustMaterial, requireAuthoredSource: true); + var authoredGravityFogShader = AssetDatabase.LoadAssetAtPath( + "Assets/Shaders/Raymarching/CloudShader.shader"); + AetheriaGravityFogVerifier.VerifyCameraProjection( + authoredGravityFogShader, + requireAuthoredSource: true); var manifest = BuildPipeline.BuildAssetBundles( output, @@ -616,6 +621,9 @@ namespace Aetheria.Editor var gravityFog = LoadAuthoredAsset(bundle, assetNames, "Assets/Shaders/Raymarching/CloudShader.shader"); if (gravityFog == null || !gravityFog.isSupported) throw new InvalidOperationException("Aetheria Eve bundle has no supported gravity-fog volume shader."); + AetheriaGravityFogVerifier.VerifyCameraProjection( + gravityFog, + requireAuthoredSource: false); var dither = LoadAuthoredAsset(bundle, assetNames, "Assets/Resources/LDR_LLL1_0.png"); if (dither == null) throw new InvalidOperationException("Aetheria Eve bundle has no pre-generated volume dither texture."); diff --git a/Assets/Shaders/Raymarching/CloudShader.shader b/Assets/Shaders/Raymarching/CloudShader.shader index 05718a266..12efb6a55 100644 --- a/Assets/Shaders/Raymarching/CloudShader.shader +++ b/Assets/Shaders/Raymarching/CloudShader.shader @@ -95,6 +95,7 @@ Shader "Aetheria/CloudShader" float density = c.a; if (density <= 0.0f) { + result.intTransmittance = 0; return; } float extinction = _ExtinctionCoefficient * density / (1-fade); @@ -102,7 +103,7 @@ Shader "Aetheria/CloudShader" float clampedExtinction = max(extinction, 1e-7); float transmittance = exp(-extinction * stepsize); - float3 luminance = c.rgb * _NebulaLuminance * density; + float3 luminance = c.rgb * _NebulaLuminance; float3 integScatt = (luminance - luminance * transmittance) / clampedExtinction; float depthWeight = result.intTransmittance * (1-transmittance); //Is it a better idea to use (1-transmittance) * intTransmittance as depth weight? diff --git a/docs/aetheria-perfect-machine-map.md b/docs/aetheria-perfect-machine-map.md index e868b9205..d4be194a5 100644 --- a/docs/aetheria-perfect-machine-map.md +++ b/docs/aetheria-perfect-machine-map.md @@ -1191,6 +1191,11 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted. drives logical `flowScroll` through an advertised scale. The provider variant maps logical camera-to-world and flow-scroll ports to native uniforms; the generic runtime does not use local gameplay time or provider identifiers. + The provider shader constructs both its raymarch and temporal-reprojection + rays using the historical Unity shader camera transform, whose local forward + is positive Z. EveUnity `0.3.58` supplies that transform instead of the + negative-Z `Camera.cameraToWorldMatrix`; provider bundle verification rejects + divergence between the two passes. - Semantic split: `gravity.height` is the negative gameplay terrain projection; `fog.surface_height` is the positive visual displacement the fossil `PowerBrush` camera supplied to `_NebulaSurfaceHeight`. Both derive from the @@ -1250,7 +1255,13 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted. placed the camera below the fog surface. The controlled zero-noise run was a diagnostic, not the adopted rendering contract. Blue tint, luminance, patch structure, gravity-wave readability, and world geometry remain open visual - parity work. + parity work. The restored historical-camera/scattering witness uses bundle + `e299b50ded9c9ba8964c567964c30342b9b13323665b20e740210b4806dd6e66` + with released EveUnity `0.3.58` and passes cold lowering in 51.0 seconds. + Its cloud structure and Stardust occupy the same projected gravity surface, + but the frame is severely overexposed. That is open evidence against the + current tint/post-process projection, not permission to alter the fossil + scattering law again. ### Daemon Asset Content Delivery diff --git a/docs/original-game-migration-matrix.md b/docs/original-game-migration-matrix.md index 0bc481b57..d24ea8967 100644 --- a/docs/original-game-migration-matrix.md +++ b/docs/original-game-migration-matrix.md @@ -35,7 +35,7 @@ validation proves contract shape, not wiring, exclusivity, lowering, or parity. | Render channels | Unity layers/culling masks | provider surface policy + runtime asset variant | semantic channel exclusions | EveUnity native layer mapping | wired, exclusive, and lowered: the pilot surface excludes the semantic `map` channel; the Unity asset variant maps `map` to its authored native layer; EveUnity subtracts that layer from the configured camera mask; portable state contains no Unity layer or mask; provider conversion preserves the source icon shader's unlit lighting model; the released witness proves the pilot camera excludes map glyphs while the map camera retains readable white glyphs without a scene light | preserve the channel proof while world presentation and transport continue to evolve | | Minimap/tactical map | `ZoneRenderer`, map cameras | daemon world facts | explicit map projections | Unity and Electron | facts fragmented; generic lowerers absent | same state in both runtimes | | Celestial world | `ZoneRenderer`, body/asteroid prefab scripts | daemon render projection plus provider assets | ordinary generic Eve entity SoA rows | EveUnity generic entity/prefab lowerer | wired, exclusive, projected, and lowered: daemon orbit and terrain queries emit stable presentation-only identities for suns, planets, gas giants, and live asteroid instances; provider packaging extracts only each advertised visual child and strips fossil scripts/physics; released EveUnity `0.3.51` applies semantic scale around provider-authored local scale and contains no celestial or Aetheria branch. The released warm witness records eleven bodies and eighteen asteroids with provider refs and enabled renderers, including seven celestial instances intersecting the pilot frustum | body material/light readability, close-range composition matching the fossil, asteroid variation, and Electron lowering | -| Fields/fog/gravity | zone renderer and shaders | daemon/plugin semantics | Fields plugin documents | EveUnity fields lowerer | daemon publishes canonical gravity/fog splat layers through `field.volume3d`; Eve Fields `0.2.3` owns portable `PowerPulse` and `AnimatedRadialCosine` semantics; Aetheria emits the fossil global animated simplex/cellular/ambient stack, body-owned radial waves, and separate negative gameplay `gravity.height` and positive visual `fog.surface_height`; the shared camera-relative lattice spans 1536 world units as 256 six-unit Stardust cells, rasterizes gravity at eight texels per cell into 2048 texels, and snaps the viewport by one six-unit cell; daemon entities follow fossil terrain height plus hull grid offset after Ymir XZ motion; released EveUnity `0.3.57` lowers the authored topology, one shared snapped viewport frame for fog and Stardust, provider shader ABI, pre-postprocess URP pass, provider-requested TAA, provider-material temporal coverage inputs, authoritative flow time, explicit camera matrix, and float32 packed-output diagnostics without provider code. The provider bundle runs the actual Stardust compute shader across X, Y, and diagonal one-cell remaps and proves 705 overlapping world cells remain bit-identical after buffer reassignment; an asymmetric GPU fixture proves positive world X samples positive texture X instead of retaining the deleted fossil gravity camera's two-axis reversal; its source gate rejects replacement of temporal dithering with a fixed alpha threshold. The released warm witness proves identical fog/particle grid centers and live dither/frame bindings drive 65,536 rendered particles while the map camera remains isolated. The flight post-process bundle gate verifies serialized ACES, exposure/contrast, bloom, vignette, and film-grain components | restore readable patch structure, gravity waves, surrounding world geometry, and final luminance/composition parity; visual parity remains explicitly open | +| Fields/fog/gravity | zone renderer and shaders | daemon/plugin semantics | Fields plugin documents | EveUnity fields lowerer | daemon publishes canonical gravity/fog splat layers through `field.volume3d`; Eve Fields `0.2.3` owns portable `PowerPulse` and `AnimatedRadialCosine` semantics; Aetheria emits the fossil global animated simplex/cellular/ambient stack, body-owned radial waves, and separate negative gameplay `gravity.height` and positive visual `fog.surface_height`; the shared camera-relative lattice spans 1536 world units as 256 six-unit Stardust cells, rasterizes gravity at eight texels per cell into 2048 texels, and snaps the viewport by one six-unit cell; daemon entities follow fossil terrain height plus hull grid offset after Ymir XZ motion; released EveUnity `0.3.58` lowers the authored topology, one shared snapped viewport frame for fog and Stardust, provider shader ABI, pre-postprocess URP pass, provider-requested TAA, provider-material temporal coverage inputs, authoritative flow time, the historical positive-Z Unity shader camera transform, and float32 packed-output diagnostics without provider code. The provider bundle runs the actual Stardust compute shader across X, Y, and diagonal one-cell remaps and proves 705 overlapping world cells remain bit-identical after buffer reassignment; an asymmetric GPU fixture proves positive world X samples positive texture X instead of retaining the deleted fossil gravity camera's two-axis reversal; its source gate rejects replacement of temporal dithering with a fixed alpha threshold. A separate gravity-fog gate requires raymarch and temporal reprojection to share the historical positive-Z camera convention. The flight post-process bundle gate verifies serialized ACES, exposure/contrast, bloom, vignette, and film-grain components | restore readable patch structure, gravity waves, surrounding world geometry, and final luminance/composition parity; visual parity remains explicitly open | | HUD/schematic | ARPG HUD and `SchematicDisplay` | Eve composition from daemon facts | semantic status/components | EveUnity UI | provider-authored transparent cockpit is wired, projected, and lowered through generic UI Toolkit panes, metrics, and progress components for hull, shield, capacitor, temperature, cargo, weapon cooldown/groups, selected target, target lock, target shield, and target hull; the original armor/equipment schematic and transient warning choreography remain reference-only | schematic topology, warning timelines, dynamic action state, and composited live capture | | Hit/lock/warnings | `ActionGameManager` feedback | daemon event facts | transient feedback stream | VFX/UI/audio | bounded deduplicated game-event ledger and Eve `feedback.stream` wired for pickup outcomes, projectile launch/impact, entity damage, alive-to-dead destruction, authoritative weapon reload chronology, lock start/acquired/lost chronology, and episode-deduplicated `weapon.fire.refused` facts for insufficient energy or missing ammunition; every lock transition carries authored weapon identity, target, reason, and prior/current progress, while reconnect priming prevents retained events from replaying as new feedback | add thermal and docking event families, negative transaction fixtures, provider lock audio/effect roles, and broader runtime effect consumption | | Assets | `Assets/Resources` | Aetheria provider | asset catalog + CultMesh CDN | runtime cache/load | provider manifests name deterministic bundle-internal paths and now project each typed hull prefab through the same asset key in Eve scene and SoA identity state; the authoring build derives presentation-only prefabs, strips non-Eve gameplay scripts, externalizes embedded effects, preserves source material semantics, and verifies the loaded bundle ABI; released EveUnity `0.3.57` resolves Unity's lowercase bundle names against authored-case advertised keys. The released cold witness begins with an empty cache, transfers the 56,168,017-byte body through `cultmesh.content.v1`, atomically promotes its exact SHA-256 with no partial, selects `SharedFileMapping`, and lowers the shield-free hull while preserving pilot/map isolation | provider-to-client network zero-copy, shared-memory delivery, and GPU zero-copy remain open; the managed network session still copies and fragments payload bytes before verified promotion |