Repository navigation
OMSI 2 illuminated material rendering compatibility - #2942
Conversation
Use the active night texture alpha only for static, fully clear blended vehicle materials. Preserve explicit masks and generated texture coverage and cover the shader paths with GPU regressions.
thibautgnt
left a comment
There was a problem hiding this comment.
Thanks @dev-Younte, nicely scoped. The synthetic before/after captures across all three paths make the change easy to judge, the flag reuses a spare bit without touching the uniform layout, and leaving explicit transmaps alone is the right call. One guard before merge.
Blocking
- A night map without an alpha channel turns the whole clear quad opaque.
night_coverage(crates/omsi-scene/src/vehicles.rs:1260) only checks that a night texture exists, and the shader then takessample_nightmap(uv).aas coverage (shaders/scene/02_bindings.wgsl:212). A 24-bit BMP/JPG or DXT1 night map samples alpha 1 everywhere, so a clear lamp, or an invisiblecoverthat writes depth to hide what's behind it, goes from invisible to an opaque rectangle around its artwork. Plain RGB night maps are very common in OMSI content. Your case (lcd_needle_on.tga) has real alpha. Please also require that the night texture has an alpha channel, as the transmap path already does withself.textures.has_alpha(...), or show that the original also makes such a quad opaque.
Smaller
vehicles.rs:1092and:1156build the sametex.is_some() && !freetex && !rain_layer && mirror_index(&tex_name).is_none()twice: compute it once aslet static_diffuse = …;and addtext_item/script_itemfor the item.shaders.rs:59-60: please keep the_separators in the snapshot numbers (124_812,0xb4bf_f042_faf9_df38) like the lines you replaced.tests.rs:mod night_coverage;goes in alphabetical order, beforemod prepass_reach;.- No CPU test covers the slot rules (transmap, freetex, mirror and text/script exclusions); the GPU test is
#[ignore]and never runs in CI. A small scene-side unit test onnight_coverage(...)would protect them.
Test builds for 1ca8825
|
|
Thank you for the careful review, @thibautgnt. Addressed in bc2f727, with the original commit retained and current The missing alpha guard was a real regression risk. Night coverage now requires a successfully loaded night map and
Release rendering still fails locally in repeated The description has been updated with the scoped results and limits, preserving the existing screenshots. The new GitHub runs currently await maintainer approval ( |
thibautgnt
left a comment
There was a problem hiding this comment.
Thanks @dev-Younte, that's a thorough follow-up. The alpha guard now works like the transmap path (the same repaint-substituted name and self.textures.has_alpha(...), and an item without its own night map takes the base map with its alpha flag). static_diffuse is computed once and the text/script exclusions apply to the item, the snapshot separators are back, mod night_coverage; is in order, and the four new scene-side tests cover the slot rules. Merges cleanly with main. Approving.
Smaller (no need to hold the merge)
crates/omsi-scene/src/vehicles/night_coverage.rs:70: the"missing night"row has the same inputs as"RGB night"above it, so it doesn't test a missing map (that case is covered bynight_map_metadata_follows_repaint_substitution_and_missing_items). Drop it or relabel it.crates/omsi-render/src/tests/night_coverage.rs: the new RGB case runs withenabled: false, so it's the same as the disabled case below it; the scene guard is what protects RGB maps.
thibautgnt
left a comment
There was a problem hiding this comment.
Sorry @dev-Younte, I have to take my approval back after running it. On macOS (Apple M4 Pro, Metal) this branch makes Apple's shader compiler crash on the scene pipeline at 4x MSAA:
ERROR omsi_render::gpu::open] Apple M4 Pro: the renderer's pipelines failed (4x MSAA): Validation Error
In Device::create_render_pipeline, label = 'omsi'
Internal error in ShaderStages(VERTEX | FRAGMENT) shader: new_render_pipeline_state: NSError { code: 2,
localizedDescription: "Compilation failed due to an interrupted connection: XPC_ERROR_CONNECTION_INTERRUPTED. This error occurred after multiple retries.", domain: "AGXMetalG16X" }
The game then falls back to 1x MSAA, so every Mac player would lose anti-aliasing. It's reproducible: 18 such errors in each run of scripts/bench-window.sh (plain and Enhanced) with main + this PR alone, none with main. The GPU tests pass because they don't build the 4x MSAA scene pipeline.
Since the only shader change is the night coverage path (night_coverage in 02_bindings.wgsl and its use in the vanilla and enhanced shading), that's very likely what trips the Metal compiler: it may be the extra sample_nightmap in the alpha path, or a branch on the new flag bit. Could you try computing the coverage from the night sample the shader already takes (one texture read, no second call), and check it on Metal at 4x MSAA? If you don't have a Mac, tell me and I'll test a new commit.
Share each shading path’s night-map sample between coverage and lighting. Preserve the material flag, alpha guards, transmap precedence and uniform layout. Exercise production 1x/4x scene pipelines and actual multisampled render targets, and replace redundant test rows with fractional-alpha coverage.
|
Thank you, @thibautgnt. Follow-up 1ca8825 reuses one night-map sample for coverage and lighting in both shading paths. The coverage helper now receives the sampled alpha instead of performing another texture read. Vehicle/terrain UVs, lighting factors, the alpha/RGB guard, repaint metadata, item inheritance, explicit transmaps and dynamic-material exclusions are preserved; the Rust uniform layout is unchanged. On this Apple M1 Pro, macOS 27.2, Metal, the original
I also removed the duplicate CPU row and replaced the redundant disabled RGB GPU row with a fractional-alpha blending case; RGB eligibility remains protected by the scene tests. Could you please retest this commit on your M4 Pro, including plain/Enhanced 4x MSAA? The targeted check is: MTL_DEBUG_LAYER=1 RUST_LOG=omsi_render=info cargo test --locked -p omsi-render --lib night_coverage -- --ignored --nocapture --test-threads=1The new official workflows currently await maintainer approval ( |
|
One additional detail for reproducibility: here is the exact hardware and software configuration used for my macOS Metal tests.
|
thibautgnt
left a comment
There was a problem hiding this comment.
Thanks a lot @dev-Younte, and thanks for the thorough Metal testing on your M1 Pro. The new commit does exactly what I asked: one night-map read now feeds both the coverage and the lighting, in Vanilla and in Enhanced, and night_coverage is a plain select on the alpha it's given. The UVs and conditions are unchanged, terrain light map path included, and the new 4x MSAA GPU test checking the targets' real sample counts covers the gap I pointed out.
I reran scripts/bench-window.sh (plain and Enhanced) on the Apple M4 Pro with main + this PR: no pipeline errors and 4x MSAA kept in both modes. Approving.
|
Merged, thanks @dev-Younte! Illuminated instruments now look as in OMSI 2, and the single night-map read keeps Metal happy at 4x MSAA. Thanks for the careful testing. |
What changes for the player?
Illuminated instruments using a fully transparent diffuse placeholder now show their night texture's artwork and silhouette. This restores missing gauge needles and circular rims in Classic, Vanilla+ and Enhanced rendering.
How to test
Automated verification (primary; no vehicle mod required)
Run the Rust library tests and synthetic GPU regression first. Neither command requires the Elec City Town mod or its vehicle resources. Vehicle files, textures and models are not included in this PR and are not needed by these automated checks.
The first command runs the renderer and scene library tests, including shader snapshots, uniform validation and GLSL generation. The second explicitly runs the otherwise ignored synthetic GPU regression and requires a graphics adapter; its geometry and textures are generated by the test.
The GPU test covers 11 cases in each of Classic, Vanilla+ and Enhanced (33 cases total): coloured/white artwork, an RGB night map with no alpha, inactive/missing/transparent night maps, ordinary diffuse coverage, alpha-test/opaque materials and explicit masks. Four non-ignored scene-side CPU tests protect eligibility, dynamic-texture exclusions, selected-map alpha metadata, repaint substitution and item inheritance. It verifies renderer-level coverage handling, not vehicle-loader integration or a full vehicle run.
Optional in-game verification
If you already have OMSI 2 and a separately installed Elec City Town (
LFELEC_TOWN_PIEV.bus), you can additionally check the actual vehicle:This optional check is not a prerequisite for running the automated tests above. The scope of the existing combined-build in-game feedback is documented separately below.
Screenshots
These synthetic renderer-level comparisons use identical geometry, UVs, camera, lighting, clear diffuse texture and white night artwork on freshly compiled upstream and PR 1 alone. The patched fixture enables the new
night_alphaselector for the eligible material. This isolates the rendering change; it does not exercise the vehicle loader or constitute a PR-1-only vehicle run. No original vehicle assets are used.ccc79522cfad33beThe owner manually confirmed white pointers/rims and normal N/D/R operation on Windows using a combined 0.3.37 Debug build with this fix and a separate visibility proposal. Earlier MAN D86 renders also passed in that combined build. These are not PR-1-only vehicle runs or evidence that this PR fixes gear overlap.
What does this change, and why?
The affected material uses an entirely transparent diffuse picture (
lcd_needle.tga) and stores its visible artwork and alpha in the night picture (lcd_needle_on.tga). OMSI 2 displays the illuminated artwork. openOMSI adds the night RGB but retains the zero diffuse alpha, making the geometry invisible during blending.For loaded static blended vehicle materials in the existing fully-clear cover classification, coverage now comes from the active night texture only when that map loads successfully and the texture loader reports alpha. RGB night maps retain diffuse coverage. DXT1 follows the loader's actual transparent-index detection rather than a format-name blacklist. The GPU texture and alpha metadata use the same repaint-substituted path and are inherited together by material items. A spare material flag selects a shared helper in both shading paths, without changing the uniform layout. Material switching preserves the unpowered state.
Explicit transmaps retain priority. Ordinary coverage, alpha-tested/opaque materials, generated text/script textures, changing textures, mirrors, rain films and freetex retain their current rules. There are no vehicle-specific conditions or dependencies on the separate visibility proposal.
Changed files:
omsi-scene/src/vehicles.rs,vehicle_materials.rs: select coverage for base/switched materials.omsi-scene/src/vehicles/night_coverage.rs: shared eligibility/map helpers and four non-ignored CPU regression tests.omsi-render/src/resources/materials.rs: encode the flag and enforce coverage guards.omsi-render/src/shaders/scene/02_bindings.wgsl,09_vanilla.wgsl, andshaders/enhanced/04_shade.wgsl: apply night alpha.omsi-render/src/shaders.rs: update intentional snapshots.omsi-render/src/tests.rs,tests/night_coverage.rs: GPU regressions.All paths above are under
crates/.Initial validation of
cfad33beagainst upstreamccc795229068ae2764ac35897aaeb80a3c9882ab, Windows x64 GNU:cargo build --locked --release -p omsi-app --bin openomsi); a waited--versionprocess exits 0.Review follow-up validation (
bc2f7274)The review revision was validated independently of the variable proposal, against upstream
mainat1f6ff3890038c38cbf95c499f1ae11f4268fcc82(Windows x64 GNU; local checks on 2026-10-18):--versioninvocations exit 0. Debug still captures of the actual TGA instruments retain white pointers/rims in Vanilla and Enhanced. These are PR-1-only still captures, not a new driving/animation test or combined-build validation. Release rendering remains unsuccessful as described below.static_diffuseis shared, base/item text/script exclusions are explicit, snapshot numeric separators are retained, and the renderer test module is alphabetized. The earlier screenshot comparisons remain at their original revisions. Full-workspace tests and new platform CI are separate from these scoped local results.What could break?
Other add-ons may use this pattern; exhaustive vehicle compatibility and Metal/mobile remain untested locally. Official CI results are tracked separately in the Checks tab; scoped local results do not establish a full-workspace pass. Clear slots disabling depth testing/writing remain outside the existing cover classification. Physics, inputs, saves and network protocols are unchanged.
Earlier full-workspace tests hit a GNU/LLD duplicate-resource link error. Excluding the app yielded 2,325 passed / 1 failed / 101 ignored; the codepage failure also reproduces on unchanged upstream on this Korean Windows host.
Release rendering of the review follow-up was tested and still fails locally: a fresh debugger run stops on a renderer-pipeline worker in repeated
D3DCompiler_47.dllframes. A retained unmodified-upstream control at the earlier base shows the same recursion pattern (the update to that earlier base was README-only). An unpatched Release runtime control at1f6ff389was not rerun. The internal FXC/backend cause remains unconfirmed and is not fixed here. Successful compilation and--versionare not renderer-startup passes.Checklist
cargo test --workspaceandcargo build --releasepassNew or changed interface texts are in(no text changes)crates/omsi-app/locales/app.yml, in every language I can