Class IrisExtendedShaderAccess

java.lang.Object
com.hbm_m.client.render.shader.IrisExtendedShaderAccess

public final class IrisExtendedShaderAccess extends Object
Reflective bridge to Iris/Oculus internals that exposes the ShaderInstance (an ExtendedShader when Iris is active) to be used for our own raw GL draws while a shader pack is in use.

Iris does not provide a public API for this; we rely on:


   Iris.getPipelineManager().getPipelineNullable()
      instanceof ShaderRenderingPipeline srp
      ? srp.getShaderMap().getShader(ShaderKey.BLOCK_ENTITY)
      : null;
 
If Iris is not loaded, lookup fails, or any exception occurs, this class returns the vanilla simple block_lit shader so the renderer still produces output.
  • Method Details

    • getPipelineGeneration

      public static long getPipelineGeneration()
      Returns:
      current pipeline generation; consumers compare against a stored value.
    • tickPass

      public static void tickPass()
      Bump the pass counter so the next getBlockShader(boolean) call re-resolves shader instances. Call from a render-level stage event handler that fires once per frame (e.g. AFTER_BLOCK_ENTITIES).

      Also samples the current Iris WorldRenderingPipeline identity and bumps pipelineGeneration whenever it changes, then immediately invalidates all shader/uniform caches via invalidateShaderCache() and IrisRenderBatch.invalidateCaches(). This is the central dispatch point for pipeline-rebuild detection; called once per frame from InstancedRenderFrame.onBeforeBlockEntities (before BER).

    • invalidateShaderCache

      public static void invalidateShaderCache()
      Drop cached shader instances immediately - used when the Iris pipeline is known to have been rebuilt (F3+T, shader pack swap) and we cannot afford to wait for the next tickPass().

      Resolved shader-key arrays survive - ShaderKey enum values do not change across pipeline rebuilds, only the ShaderInstance they map to, which we re-resolve on the next call anyway.

    • getBlockShader

      public static net.minecraft.client.renderer.ShaderInstance getBlockShader(boolean shadowPass)
      Returns an ShaderInstance suitable for rendering block entity geometry under the currently-active shader pack. When no Iris pipeline is available this returns the vanilla ModShaders.getBlockLitSimpleShader() as a safe fallback.
      Parameters:
      shadowPass - when true, attempts to fetch a SHADOW_* variant first
    • setCurrentRenderedBlockEntity

      public static int setCurrentRenderedBlockEntity(int value)
      Pack shaders (notably BSL) read the blockEntityId uniform and switch branches based on blockEntityId / 100: 155 triggers EMISSIVE_RECOLOR which paints the surface with the warm blocklightCol (the mysterious "solid red" texture players see), 252 triggers the DrawEndPortal path, and so on.

      Iris updates this uniform from CapturedRenderingState.currentRenderedBlockEntity before each block entity. Our raw GL batch never tells Iris which BE we are about to draw, so the uniform sticks at whatever the previously rendered BE left behind - and which BE that is depends on the camera frustum, hence the "sometimes red, sometimes fine" symptom that scales worse with batching (a poisoned value affects every instance in the batch). Calling this with 0 before our flush forces a neutral block id that does not match any of BSL's special-case branches, and restoring the previous value in finally keeps Iris's own subsequent draws unaffected.

      Returns:
      the previous value, or Integer.MIN_VALUE if reflection was unavailable. Pass that result back to restoreCurrentRenderedBlockEntity(int).
    • restoreCurrentRenderedBlockEntity

      public static void restoreCurrentRenderedBlockEntity(int previous)
      Counterpart to setCurrentRenderedBlockEntity(int). No-op when previous == Integer.MIN_VALUE.
    • isReflectionAvailable

      public static boolean isReflectionAvailable()
      Returns whether the reflective path resolved successfully (i.e. Iris classes were found). Call sites can use this to decide whether attempting Iris-specific behaviour is worthwhile.