Skip to content

Repository files navigation

OculusSMECompat

Keeps StoryModEngine's GPU instancing (InstancedShader/InstanceFlush/InstanceBatchCollector/ InstanceBatchBuffers) alive under an active Oculus/Iris shader pack, with the pack's own lighting applied to instanced geometry, instead of falling back to slow immediate-mode rendering whenever a pack is active.

Full design/rationale: see the plan this was implemented from (starry-hopping-ullman.md) for the research this is based on and why each design choice was made.

Pinned versions - re-verify on every bump

This addon works by mixin-injecting into Oculus's own internal, unstable classes (net.irisshaders.iris.*) - not a public API. Every version below was individually confirmed by decompiling the real jar, not assumed from general Iris/Oculus knowledge:

  • Oculus 1.20.1-1.8.0 (Modrinth). Resolved to commit 5751a2f6b8ffb1293a4239b6717006ba97d8c8fb on the 1.20.1-new branch of github.com/Asek3/Oculus (no git tag exists for this release - resolved by Modrinth publish-timestamp + changelog cross-reference).
  • Embeddium 0.3.14+mc1.20.1 (Modrinth version string; Oculus's own gradle.properties at the matching commit pins the same release as 0.3.14-git.8af1729+mc1.20.1 via a different maven mirror - same jar content, different version-string convention between the two repositories).

Before bumping either version, re-verify these specific facts against the new jar (javap -p or a decompiler like CFR is enough - no full IDE/dev-environment needed for this step):

  1. net.irisshaders.iris.pipeline.IrisRenderingPipeline still has a private createShader(String, ProgramSource, ProgramId, AlphaTest, VertexFormat, FogMode, boolean, boolean, boolean, boolean) overload with this exact signature, and still takes ProgramSet only as a constructor parameter (never stored as a field) - both assumptions mixin/IrisRenderingPipelineMixin.java depends on directly.
  2. net.irisshaders.iris.shaderpack.programs.ProgramSource still has a private 8-arg constructor (String name, String vertexSource, String geometrySource, String tessControlSource, String tessEvalSource, String fragmentSource, ProgramDirectives directives, ProgramSet parent) - what mixin/ProgramSourceAccessor.java invokes.
  3. ProgramSet still exposes getGbuffersEntities()/getGbuffersBasic()/getGbuffersTextured()/ getGbuffersTexturedLit() as public Optional<ProgramSource> getters.
  4. Oculus still shades io.github.douira.glsl_transformer (the AST-transform library shader/ InstancedVertexMerger.java uses) directly into its own jar rather than requiring it as a separate Gradle dependency (confirmed by inspecting the jar's contents, not the Modrinth page) - and that its SingleASTTransformer/Root.replaceReferenceExpressions/Root.rename/TranslationUnit.parseAndInjectNodes API shape (mirrored from Oculus's own pipeline.transform.transformer.VanillaTransformer/EntityPatcher usage) hasn't changed.
  5. ProgramId.Entities and ShaderKey.ENTITIES_CUTOUT's parameterization (AlphaTests.ONE_TENTH_ALPHA, FogMode.PER_VERTEX, not intensity/fullbright/glint/text) still match what OculusInstancingIntegration passes to createShader.

If any of these have changed shape, the mixins will most likely fail to apply (a loud, visible startup error, not a silent misrender - Mixin logs apply failures) or compileJava will fail outright, since none of this is reflection-based. That's a deliberate trade-off: better a build failure pointing straight at what changed than a mixin that half-applies and misrenders quietly.

Known v1 limitations

Deliberately out of scope for this change (see the plan's "Future extension points" for how to pick these up):

  • No shadow-map participation. Instanced NPCs render with correct pack lighting but don't appear in the pack's shadow map.
  • No pack-authorable override shader. Always merges into the pack's own gbuffers_entities (falling back through gbuffers_basic/gbuffers_textured/gbuffers_textured_lit) - a pack can't ship a bespoke instancing shader the way it optionally can for iris-flw-compat's Flywheel integration.
  • Overlay tint doesn't carry through (entity hurt-flash/heal-flash tint). Iris's own entity-format patching unconditionally injects a per-vertex overlay-texel attribute and reads it directly, and that injection happens inside Iris's own patch pass - after this addon's own merge step has already handed off its output - so there is no text-level hook available to redirect it to this engine's per-instance InstanceOverlay attribute the way the lightmap coordinate is redirected. This is a status-effect indicator, not lighting, so it's out of scope for what this change is actually about.
  • Packs calling the legacy ftransform() built-in directly (instead of referencing gl_Vertex/ gl_ModelViewMatrix themselves) won't pick up the per-instance transform, because Iris's own patcher injects its own ftransform() implementation (in terms of gl_Vertex) after this addon's merge runs, using the genuine per-vertex position rather than this engine's per-instance transform of it. A legacy GLSL 1.10-era pattern most modern packs don't use.

See shader/InstancedVertexMerger.java's class doc for the exact substitution strategy and why each of the above is out of reach for a vertex-only merge.

Verification status

gradlew compileJava succeeds against the real Oculus/Embeddium jars (via Modrinth's maven, fg.deobf) and a freshly-built StoryModEngine jar - confirms every signature above and the glsl-transformer API usage compile as written. Not yet verified: actual visual behavior in-game (mixins applying at runtime, the merged shader linking without GL errors, lighting actually matching the pack). Per the plan's build-tooling research, that needs a built jar installed in a real Forge 1.20.1 launcher instance (Forge installer, not gradlew runClient) with Oculus + Embeddium + StoryModEngine + this addon all present - a third-party Mixin dependency's refmap-remapping behaves differently between ForgeGradle's dev environment and a real production launch, so a dev-only smoke test would not be trustworthy for this part even if it ran without errors.

To do that verification pass:

  1. ./gradlew build this project and StoryModEngine (in that dependency order).
  2. Install both mods' jars, plus Oculus 1.20.1-1.8.0 and Embeddium 0.3.14+mc1.20.1, into a real Forge 1.20.1-47.4.22 instance.
  3. Load into a world with an Iris/Oculus-compatible shader pack active (e.g. Complementary or BSL), spawn instanced NPCs, and confirm: instancing stays on the fast path (check the log for [OculusSMECompat] Instancing now lit by the active pack's own '...' program.); lit NPCs visibly respond to the pack's sun angle/ambient occlusion/color grading; toggling the pack off cleanly reverts to vanilla-correct lighting; a pack with an unusual/minimal gbuffers_entities (or none at all) falls back to the existing immediate-draw path without crashing.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages