Skip to content

Iris API

Kerudion edited this page Jul 5, 2025 · 12 revisions

What is this?

This is an API for shader developers, which allows to change how Chunks Fade In injects into Iris shaders. Added in v2.0.6, Distant Horizons support added in v3.0.0.


Implementing support (if it doesn't work as is)

The automatically injected fragment modifier for fading can be incorrect. Since v3.0.0 fading is done by sampling sky (also this sky buffer has DH terrain if it's installed) instead of how it was before - just with the fog color. So, if your sky is rendered not in gbuffers_skybasic, it will break.

The "skyLod" buffer is sampleable via vec3 cfi_sampleSkyLodTexture() in gbuffers_skybasic, gbuffers_skytextured, dh_terrain and dh_water, but only if fade is enabled. It's lifecycle is:

  • Blits right after MC sky pass – gbuffers_skybasic and gbuffers_skytextured.
  • Usable in dh_terrain and dh_water, will contain what your sky pass outputted.
  • Blits right after DH LOD pass – dh_terrain and dh_water.
  • Usable in gbuffers_terrain and gbuffers_water, will contain both sky and LODs.

Most useful functions (only for fragment shader):

The way you implement all of this is not important, but here are some ideas:

  • (if you support DH) In dh_terrain and dh_water:
    • Calculate your sky color and fade it with LOD color. Also store the LOD color in a buffer (you can use skyLod buffer).
    • OR
    • Do not fade here, instead fade later in a deferred pass by sampling the fade factor. Just store the LOD color and fade factor (for example as alpha) in a buffer (you can use skyLod buffer).
  • In gbuffers_terrain and gbuffers_water:
    • (if you support DH) Sample the LOD color and fade with it. If a LOD has not been drawn, instead fade by calculating sky color.
    • OR
    • (if you support DH) Sample the LOD color and fade with it. Then output into a buffer (maybe same as for LODs), writing new color and fade factor.
    • OR
    • (if you don't support DH) Calculate your sky color and fade it with the chunk color.
    • OR
    • (if you don't support DH) Do not fade here, instead fade later in a deferred pass by sampling the fade factor. Just store the color and fade factor (for example as alpha) in a buffer.

Usable defines

Place these #define ... somewhere in your shader source. They affect only a single program.

CHUNKS_FADE_IN_FORCE_DEFINES

Forces the injection of config defines in any program.

CHUNKS_FADE_IN_NO_MOD_INJECT

Disables:

CHUNKS_FADE_IN_NO_FRAG_MOD_INJECT

Disables:

CHUNKS_FADE_IN_NO_VERT_MOD_INJECT

Disables:

CHUNKS_FADE_IN_NO_CURVATURE

Disables:

CHUNKS_FADE_IN_NO_INJECT

Leaves ONLY:


Injected defines

These are injected always, only into shadow, gbuffers_terrain and gbuffers_water programs, unless forced by CHUNKS_FADE_IN_FORCE_DEFINES.

#define CHUNKS_FADE_IN_ENABLED

// if fade enabled:
#define CFI_FADE_FULL 0
#define CFI_FADE_LINED 1
#define CFI_FADE_BLOCK 2
#define CFI_FADE_VERTEX 3
// "Fade type"
#define CFI_FADE /* ordinal from above */

// if animation enabled:
#define CFI_ANIMATION_FULL 0
#define CFI_ANIMATION_SCALE 1
#define CFI_ANIMATION_JAGGED 2
#define CFI_ANIMATION_DISPLACEMENT 3
// "Animation type"
#define CFI_ANIMATION /* ordinal from above */

// if curvature enabled:
#define CFI_CURVATURE /* [-65536; 65536] */

API functions

They are injected only in gbuffers_terrain, gbuffers_water, shadow, dh_terrain, dh_water and dh_shadow programs.

Vertex

(DH) void cfi_initOutVars() πŸ”—

Initializes all of the internal out variables with default localPos and worldPos.

(DH) void cfi_initOutVars(vec3 localPos, vec3 worldPos) πŸ”—

localPos - position of the vertex in the LOD mesh.
worldPos - position of the vertex in the world, where (0, 0, 0) is the camera.

Initializes all of the internal out variables.

vec3 cfi_calculateDisplacement() πŸ”—

Calculates displacement (see cfi_calculateDisplacement(vec3 localPos) below) with the default local position provided by Sodium.

Example:

gl_Position += cfi_calculateDisplacement();

vec3 cfi_calculateDisplacement(vec3 localPos) πŸ”—

Calculates displacement. localPos must be a local position in the chunk. localPos is used by "DISPLACEMENT" (for calculating a random seed) and by "SCALE" (for scaling) animation types.

Example:

gl_Position += cfi_calculateDisplacement(gl_Vertex);

vec3 cfi_calculateCurvature() πŸ”—

Calculates displacement (see cfi_calculateCurvature(vec3 globalPos) below) with the default global position provided by Sodium.

Example:

gl_Position += cfi_calculateCurvature();

vec3 cfi_calculateCurvature(vec3 globalPos) πŸ”—

Calculates world curvature. globalPos must be the position relative to the camera.

Example:

gl_Position += cfi_calculateCurvature(gl_Position);

vec4 cfi_getFadeData() πŸ”—

Returns the current offset (x, y, z) and fade factor (w, 0.0 is unfaded, 1.0 is fully faded).

Example:

gl_Position += cfi_getFadeData().xyz;

Fragment

(DH) bool cfi_dhLodIsMasked() πŸ”—

Returns true if the the current LOD pixel is in a chunk that is built, rendered and fully faded. Uses default local and worls positions.

Example:

if (cfi_dhLodIsMasked()) {
    discard;
}

(DH) bool cfi_dhLodIsMasked(vec3 localPos, vec3 worldPos) πŸ”—

localPos - position of the vertex in the LOD mesh.
worldPos - position of the vertex in the world, where (0, 0, 0) is the camera.

Returns true if the the current LOD pixel is in a chunk that is built, rendered and fully faded.

Example:

if (cfi_dhLodIsMasked(gl_Position, gl_Vertex)) {
    discard;
}

vec3 cfi_applySkyLodFade(vec3 fullyFaded) πŸ”—

Mixes sky color (and/or DH LOD color) (read more here) with fullyFaded based on cfi_applyFade().

Example:

gl_FragData[0].rgb = cfi_applySkyLodFade(gl_FragData[0].rgb);

vec3 cfi_applyFogFade(vec3 fullyFaded) πŸ”—

Mixes fog color with fullyFaded based on cfi_applyFade(). This is an outdated method to do fading, please fade with sky with cfi_applySkyLodFade.

Example:

gl_FragData[0].rgb = cfi_applyFogFade(gl_FragData[0].rgb);

vec3 cfi_applyFade(vec3 fullyUnfaded, vec3 fullyFaded) πŸ”—

Mixes fullyUnfaded and fullyFaded based on cfi_calculateFade().

Example:

gl_FragData[0].rgb = cfi_applyFade(vec3(1.0), gl_FragData[0].rgb);

float cfi_calculateFade() πŸ”—

Calculates current fade, including all the different fading types.

Example:

gl_FragData[0].rgb = mix(vec3(1.0), gl_FragData[0].rgb, cfi_calculateFade());

vec3 cfi_sampleSkyLodTexture() πŸ”—

Samples the skyLod buffer.


Injected variables

Vertex in

struct cfi_ChunkFadeData { vec4 fadeData; };
layout(std140) uniform cfi_ubo_ChunkFadeDatas { cfi_ChunkFadeData cfi_ChunkFadeDatas[256]; };

The cfi_ChunkFadeDatas is indexed by the _draw_id (index of the current Sodium render section inside of a render region, which is a 8x4x8 area of chunks).

Vertex out

#ifndef CHUNKS_FADE_IN_NO_INJECT
flat out float cfi_FadeFactor;

#if CFI_FADE == CFI_FADE_BLOCK
out vec3 cfi_BlockSeed;
#endif

#if CFI_FADE == CFI_FADE_LINED
out float cfi_RefFactor;
#endif

#if CFI_FADE == CFI_FADE_VERTEX
flat out float cfi_RefFactor;
#endif
#endif

Fragment in

#ifndef CHUNKS_FADE_IN_NO_INJECT
flat in float cfi_FadeFactor;

#if CFI_FADE == CFI_FADE_BLOCK
in vec3 cfi_BlockSeed;
#endif

#if CFI_FADE == CFI_FADE_LINED
in float cfi_RefFactor;
#endif

#if CFI_FADE == CFI_FADE_VERTEX
flat in float cfi_RefFactor;
#endif
#endif

Injected code

You can see their source directly in FadeShader.java.

Vertex

Out vars initializer πŸ”—

This piece of code initializes output variables.

Vert init modifier πŸ”—

This piece of code applies displacement and curvature.

Fragment modifier πŸ”—

This piece of code takes the first output color, and adds fading with sky only if it's vec3 or float (in shadows).