OptiFine-format shader packs, on Minecraft's native Vulkan renderer
Minecraft now ships a native Vulkan renderer alongside the OpenGL one. Every shader pack that exists was written for OpenGL, and none of them run on it.
Vitrail runs them anyway, unmodified. It reads an OptiFine-format pack out
of shaderpacks/, translates its GLSL once when the pack loads, and hands it to
the compiler the game already embeds. Nothing translates while a frame is drawn.
It started as a question, whether packs written for OpenGL over more than a decade could run untouched on the renderer that now ships with the game, and as one person's side project, worked on every day since July. Contributors have joined along the way, and it is still an early one: the backend it runs on is marked experimental by the game itself.
It is built the way a lot of software gets built now, and it would not exist otherwise: AI tools do most of the typing and the debugging, and a human decides what gets built, tests it against real packs and against Iris, and carries the blame for every bug. What was taken from Iris and from Kroppeb's stareval is credited file by file in the project's NOTICE, under the same licence. If any of that matters to you, now you know. If the mod is useful, there is a coffee link below, and the issues are where I answer.
Before you install: it is a beta
- The Vulkan backend is experimental, marked so by the game itself: the setting you have to turn on reads "Prefer Vulkan (Experimental)".
- The world goes through your pack: terrain, water, shadows, sky, clouds, weather, particles, mobs, block entities, the held hand, name plates and signs. What still comes from the game, the engine names in its log when a place first draws, and that list shrinks release by release.
- Some packs still come out wrong in places, and a wrong picture is worse than a missing one. The table of packs actually tried starts from what you see and names the cause.
- If what you want today is a finished picture, use Iris on the OpenGL backend instead. It does that job well, and it is the reference this engine is checked against, frame against frame.
Bring your own pack
Vitrail is the engine, not the pack, and it can ship none: the packs belong to their authors and their licences do not allow redistribution. These are the best known of the packs it draws.
- Bliss
- BSL
- Complementary Reimagined
- Complementary Unbound
- Euphoria Patches
- I Like Vanilla
- Lux
- Mellow
- Photon
- Sildur's Vibrant
- Solas
- Spooklementary
- iterationT (on Bilibili, not on Modrinth or CurseForge)
Every other pack in the table of packs actually tried draws as well, and the table says how close each one comes to Iris. A pack absent from it is one I have not loaded, not one that is unsupported.
After you install
- Switch the game to Vulkan and restart it. Video Settings, "Prefer Vulkan (Experimental)". The backend is picked when the game boots, so it takes effect on the next launch.
- Pick your pack with
I. It opens the shader pack screen,Rreads the pack again from disk andKturns shaders off and back on. All three can be rebound in the game's controls, under Vitrail. - If the frame rate comes up short, there is a slider for it. Video Settings, on Vitrail's own page, "Render Scale": the world is drawn at 25 to 100 percent of the window and brought back to full size before the interface, so menus, chat and the F3 screen stay sharp whatever the scale.
- Distant Horizons is compatible, and your pack's own DH programs draw its far terrain. On Fabric, install it like any other mod. On NeoForge its current release still crashes on the Vulkan renderer (its own texture unwrapper, not this mod), so install this build by hand instead.
- Chloride is not needed, and if you run it, five of its settings decide what reaches your pack: Fast Chests and Fast Beds on the Performance page, Max Entity Distance, Max Monster Distance and Max Block Entity Distance on the Entities page. Vitrail names in the log at startup any it finds on.
Client only, one jar for Fabric and NeoForge. Iris can stay installed beside it, on the Sodium version Iris asks for, which Vitrail runs on too: on Vulkan Vitrail draws, on OpenGL Iris does, and switching the backend in the video settings switches engines. The install guide has the rest.
Links and credits
If a pack or a mod does not work with Vitrail, please open an issue. A pack that draws wrong, a mod that clashes, a crash: every report helps, and if you want to take part, pull requests are very welcome.
Source, what goes through a pack today, the changelog and the full compatibility notes are all at Vitrail-Shaders. It is also on CurseForge.
LGPL-3.0-only. Parts of the pack loader and of the value catalogue are adapted from Iris, which is LGPL-3.0 as well, and the expression grammar is Kroppeb's stareval. What was taken and what was changed on the way is recorded file by file in the project's NOTICE.
All Versions
+ Add Version| Name | Game version | Platforms | Published | Downloads | Actions |
|---|---|---|---|---|---|
| 11d ago | 1 | ||||
| 11d ago | 1 | ||||
| 27d ago | 1 | ||||
| 27d ago | 1 | ||||
| 1mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 | ||||
| 2mo ago | 1 |
Kturns shaders off and back on**, as it does under Iris. Turning them back on returns to
because it fails to load, is no longer in the folder or none was picked, shaders stay off and
the line says why, so the next press tries again. The key can be moved in the game's controls,
under Vitrail, beside the two that open the settings and reload the pack.
### Fixed
- Distant Horizons' own clouds stay out of a pack that asks for that.** With Distant Horizons
dhClouds=off, as Complementary does. They were hardest to miss under blindness, where thepack's own clouds go dark and Distant Horizons' stayed bright. They are now held off for as long
as such a pack is loaded, as Iris does, and your own Distant Horizons setting is left as it was.
- Distant Horizons' menu says who holds a setting it will not let you move.** Where a pack
its clouds wherever a pack asks. The menu showed those lines locked and "controlled by
UNKNOWN", and Distant Horizons wrote a warning in the log for each. They are now held under
Vitrail's name, on a Distant Horizons recent enough to take one.
- Mining a block shows its cracks again on 26.3.** With a shader pack loaded, the crack overlay
the frame than 26.2 did, among the solid features, and Vitrail was only waiting for it among the
translucent ones. It is now drawn with the pack's
gbuffers_damagedblock at either moment, so thecrack over stone and the crack over glass both show.
- Banners show their colours and patterns again on 26.3.** With a shader pack loaded, every
26.2 drew them with the translucent ones, and Vitrail only served them at the later moment, so
the game painted the colours itself underneath the pack's cloth. They are drawn with the pack's
translucent block program at the moment the game draws them, as under Iris.
- Bliss-based packs draw again, Eclipse among them.** Three things stood in their way, the
- A pack may keep data in a one dimensional image. Bliss keeps a line of block data that way,
them. One dimensional images now pass those checks, as three dimensional ones already did.
- A pack may define a macro twice with different bodies, which NVIDIA's driver accepts and the
diagonal3. Each use nowgets the body in force where it stands, which is the driver's reading.
- A geometry stage that only passes each corner on is folded into the stage after it on a Mac.
one corner at a time, a counter declared ahead of its loop, the position held in a local), so
the pack's terrain program was set aside and the terrain drawn without it. It is folded now.
- A held item no longer streaks while the player walks, on a Mac.** Under Photon the item in hand
moving. Vitrail puts the game's own picture wherever something the game drew stands in front of
the pack's geometry, and it tells the two apart by comparing the depth the pack's fragment stage
saw with the depth the GPU stored. On a Mac the two can differ by a unit in the last place on
some pixels of a sloped surface, so those pixels read as covered and got the game's colour in
place of the pack's gbuffer. A difference that small no longer counts as something in front.
- The sky no longer turns one flat pink when far terrain is loaded and none of it is in view.**
its depth. On a frame where none of it is on screen, such as looking at the sky from above the
world's build height, Vitrail handed that depth over as a single texel. Photon reads it pixel by
pixel, found far terrain at the camera everywhere past that texel, and painted the whole view in
one pinkish colour. The depth is now the far plane across the whole screen, as the mod's own
image is under Iris.
- A beacon beam's core no longer stops sixteen blocks above the camera.** With the pack drawing
rose and fell with them, while the faint outer glow went on up. Vitrail lets the game's own
picture through wherever the game drew something in front of the pack's, and it took the sky to
stand where the game builds it, sixteen blocks up, so whatever the game drew above that height
lost to the pack's sky. The sky now counts as infinitely far away, as it does under Iris, which
also lifts the same cut from the End, where the game builds its sky a hundred blocks out.
- The name of a player behind a wall shows again with a pack on, on Minecraft 26.3.** The game
dimmed name on its own after the water and the outlines. Vitrail was not catching that last
draw, so the name went into the game's own picture, which the pack's final pass paints over,
and it was simply missing. It is now drawn by the pack like the name of a player in the open,
dimmed as the game dims it. The name of a sneaking player stays hidden behind a wall, as it is
without a pack.
Thanks to elNino0916 for the toggle key, the Distant Horizons clouds and the crack, Jolymmiles for
the Bliss-based packs and the test net, JakobMusix for the beacon beam, DebZakari for the names
behind walls, and Heerless for digging into the bells crash.
Kturns shaders off and back on**, as it does under Iris. Turning them back on returns to
because it fails to load, is no longer in the folder or none was picked, shaders stay off and
the line says why, so the next press tries again. The key can be moved in the game's controls,
under Vitrail, beside the two that open the settings and reload the pack.
### Fixed
- Distant Horizons' own clouds stay out of a pack that asks for that.** With Distant Horizons
dhClouds=off, as Complementary does. They were hardest to miss under blindness, where thepack's own clouds go dark and Distant Horizons' stayed bright. They are now held off for as long
as such a pack is loaded, as Iris does, and your own Distant Horizons setting is left as it was.
- Distant Horizons' menu says who holds a setting it will not let you move.** Where a pack
its clouds wherever a pack asks. The menu showed those lines locked and "controlled by
UNKNOWN", and Distant Horizons wrote a warning in the log for each. They are now held under
Vitrail's name, on a Distant Horizons recent enough to take one.
- Mining a block shows its cracks again on 26.3.** With a shader pack loaded, the crack overlay
the frame than 26.2 did, among the solid features, and Vitrail was only waiting for it among the
translucent ones. It is now drawn with the pack's
gbuffers_damagedblock at either moment, so thecrack over stone and the crack over glass both show.
- Banners show their colours and patterns again on 26.3.** With a shader pack loaded, every
26.2 drew them with the translucent ones, and Vitrail only served them at the later moment, so
the game painted the colours itself underneath the pack's cloth. They are drawn with the pack's
translucent block program at the moment the game draws them, as under Iris.
- Bliss-based packs draw again, Eclipse among them.** Three things stood in their way, the
- A pack may keep data in a one dimensional image. Bliss keeps a line of block data that way,
them. One dimensional images now pass those checks, as three dimensional ones already did.
- A pack may define a macro twice with different bodies, which NVIDIA's driver accepts and the
diagonal3. Each use nowgets the body in force where it stands, which is the driver's reading.
- A geometry stage that only passes each corner on is folded into the stage after it on a Mac.
one corner at a time, a counter declared ahead of its loop, the position held in a local), so
the pack's terrain program was set aside and the terrain drawn without it. It is folded now.
- A held item no longer streaks while the player walks, on a Mac.** Under Photon the item in hand
moving. Vitrail puts the game's own picture wherever something the game drew stands in front of
the pack's geometry, and it tells the two apart by comparing the depth the pack's fragment stage
saw with the depth the GPU stored. On a Mac the two can differ by a unit in the last place on
some pixels of a sloped surface, so those pixels read as covered and got the game's colour in
place of the pack's gbuffer. A difference that small no longer counts as something in front.
- The sky no longer turns one flat pink when far terrain is loaded and none of it is in view.**
its depth. On a frame where none of it is on screen, such as looking at the sky from above the
world's build height, Vitrail handed that depth over as a single texel. Photon reads it pixel by
pixel, found far terrain at the camera everywhere past that texel, and painted the whole view in
one pinkish colour. The depth is now the far plane across the whole screen, as the mod's own
image is under Iris.
- A beacon beam's core no longer stops sixteen blocks above the camera.** With the pack drawing
rose and fell with them, while the faint outer glow went on up. Vitrail lets the game's own
picture through wherever the game drew something in front of the pack's, and it took the sky to
stand where the game builds it, sixteen blocks up, so whatever the game drew above that height
lost to the pack's sky. The sky now counts as infinitely far away, as it does under Iris, which
also lifts the same cut from the End, where the game builds its sky a hundred blocks out.
- The name of a player behind a wall shows again with a pack on, on Minecraft 26.3.** The game
dimmed name on its own after the water and the outlines. Vitrail was not catching that last
draw, so the name went into the game's own picture, which the pack's final pass paints over,
and it was simply missing. It is now drawn by the pack like the name of a player in the open,
dimmed as the game dims it. The name of a sneaking player stays hidden behind a wall, as it is
without a pack.
Thanks to elNino0916 for the toggle key, the Distant Horizons clouds and the crack, Jolymmiles for
the Bliss-based packs and the test net, JakobMusix for the beacon beam, DebZakari for the names
behind walls, and Heerless for digging into the bells crash.
- Minecraft 26.3.** The same source builds a jar for 26.2 and one for 26.3, and each jar refuses
API, and the Sodium 0.9.2 built for 26.3. On NeoForge, Complementary Reimagined draws there as it
does on 26.2: its terrain, water, shadows, sky, sun, moon and stars, mobs, the hand, clouds, rain
and snow, particles and composites, and the game's translucent features the pack does not serve
are composed into its image as on 26.2, and so is Distant Horizons' far terrain, land and water
both, with the pack's own
dh_terrain and dh_water. Compiled shader modules are kept on disk,so a second load of a pack skips the compile. The game's improved transparency is turned off
while a pack draws, as Iris turns it off on the other backend and as on 26.2. One thing is not carried over yet: a program with a geometry stage is
served only where that stage passes each corner on, which is folded into the stage after it, as on
a Mac on either game, and any other such program is set aside with a line in the log.
- The compiling notice in the top-left corner can be turned off.** A Compile Notice switch on
It is on by default, the pack compiles exactly as before either way, and the F3 screen still
says when it is compiling.
### Changed
- Shadow Reuse is off by default.** The shadow map is drawn again on every frame, as Iris draws
engine page for anyone who wants the frames it wins, by keeping the ground of the map for one or
two frames. A value you already set yourself is kept.
### Fixed
- World space reflections show the blocks they reflect instead of black.** A pack can name one
space reflections from the block atlas that way. An atlas is built while the game runs and is no
file of any resource pack, so Vitrail found no file and bound one black texel in its place, and
every block reflected from off screen came out black. A texture the game holds under that name
is now bound as it stands, as Iris binds it.
- Coloured lighting works on a Mac.** Vitrail no longer tells a pack it is running on a Mac.
turned its coloured lighting (Advanced Color Tracing) off and painted an error over the picture
when it was asked for. On a Mac Vitrail draws through Vulkan on Metal, which has what the
setting needs, so it now works there, and so do the improved rain and the rest of what the pack
held back for Apple's driver.
- Shadow comparisons are enabled on a Mac.** The sampler a pack's shadow lookups compare through
nothing enabled it. The driver drew the lookups anyway, but a launch under the Khronos validation
layer had them refused, and the terrain was then drawn with stale textures until the game
crashed. The feature is now enabled wherever those rules apply.
- Moving blocks are drawn through the shader pack instead of falling back to the game's shader.**
which were not served by the pack. They are now routed to the same shader programs Iris uses for
those pipelines and carry what Iris gives them: the real light map, the normal of each face, its
tangent and the other terrain inputs a pack lights a block with.
- SEUS PTGI HRR 3 is no longer set aside as soon as it loads.** Its anti-aliasing header carries
the pack had set them. It then took the code meant for those platforms as the code in use, left
the three programs that include the header without the pieces they call, and since those could
not be built, drew nothing of the pack at all. A line inside a comment no longer decides which
code is in use, nor sets a name. What a pack writes inside a comment about its own buffers, their
format and their mip chain, is read in full as Iris reads it, so Complementary Reimagined and
Unbound with EuphoriaPatches get the buffers their text asks for.
- Photon no longer crashes the game with its water parallax on.** Looking along the water surface,
own sine came out enormous there, and the pack's water kept stepping until the graphics driver
gave up and the game closed with a lost device. The sine now stays between minus one and one for
any value, as the driver's does, and nothing changes wherever it already did.
- Photon loads with cloud shadows turned off.** The pack stops one of its programs with an error
to the shader compiler, which refused the program, and the whole pack with it. Such a message no
longer stops anything, and the pack loads.
- A full screen program reading the quad's corners by their core profile names draws.** A pack
vaPosition or vaUV0 in a core profile composite, deferred or final was handednought for both, so a program that placed its corners from them compiled and drew nothing. Both
now read the quad's own position and texture coordinate under the type the pack declared, as
under Iris.
- A properties file's own defines now count for its sizes, uniforms and identifiers.**
#define or #undef written there was ignored, so a later condition on that name was decidedas if it had never been written, and an image size, a custom uniform or an item or entity
identifier using it came out wrong or not at all. All of them now read the name as the line
above left it, as under Iris. Complementary with Euphoria Patches is the pack that shows it: its
profiles that set entity shadows to off now turn them off.
- A compute reading a texture that could not be loaded still runs.** A pack naming a texture
compute now reads what the full screen pass beside it reads, and runs. A game texture that no
loaded resource pack ships and the game does not hold either now reads the game's missing texture
in every pass, as under Iris, where it read black.
- A pack image that cannot be read no longer turns a buffer black.** When a pack replaced one of
reading that buffer read black. The buffer now keeps what it held before, in full screen,
compute and world passes alike, as under Iris, and the log names the image.
- Shadows no longer sway with the view bobbing after the player is hurt.** Being hit while
then on, for the rest of the session, it handed packs the walk bob inside the projection rather
than beside the camera. BSL and Bliss rebuild positions on screen assuming the projection has no
bob in it, so their shadows, and anything else placed that way, slid with every step. The bob now
stays where packs expect it, as on Iris, whatever tilts the camera.
- iterationRP draws its lighting.** Its lighting programs store into the pack's buffers from
where they were stored as colours, and name several of them through the pack's own defines.
None of the three was served, so the scene stayed dark. All three are now served as under Iris,
and a program whose buffer or view this graphics card cannot store into is set aside with a
line in the log saying so.
- The pass timings table reads real times on a Mac.** With
-Dvitrail.passTimingsset, every
holds. It now asks for one Metal accepts, and each pass reads the card's own time.
- Minecraft 26.3.** The same source builds a jar for 26.2 and one for 26.3, and each jar refuses
API, and the Sodium 0.9.2 built for 26.3. On NeoForge, Complementary Reimagined draws there as it
does on 26.2: its terrain, water, shadows, sky, sun, moon and stars, mobs, the hand, clouds, rain
and snow, particles and composites, and the game's translucent features the pack does not serve
are composed into its image as on 26.2, and so is Distant Horizons' far terrain, land and water
both, with the pack's own
dh_terrain and dh_water. Compiled shader modules are kept on disk,so a second load of a pack skips the compile. The game's improved transparency is turned off
while a pack draws, as Iris turns it off on the other backend and as on 26.2. One thing is not carried over yet: a program with a geometry stage is
served only where that stage passes each corner on, which is folded into the stage after it, as on
a Mac on either game, and any other such program is set aside with a line in the log.
- The compiling notice in the top-left corner can be turned off.** A Compile Notice switch on
It is on by default, the pack compiles exactly as before either way, and the F3 screen still
says when it is compiling.
### Changed
- Shadow Reuse is off by default.** The shadow map is drawn again on every frame, as Iris draws
engine page for anyone who wants the frames it wins, by keeping the ground of the map for one or
two frames. A value you already set yourself is kept.
### Fixed
- World space reflections show the blocks they reflect instead of black.** A pack can name one
space reflections from the block atlas that way. An atlas is built while the game runs and is no
file of any resource pack, so Vitrail found no file and bound one black texel in its place, and
every block reflected from off screen came out black. A texture the game holds under that name
is now bound as it stands, as Iris binds it.
- Coloured lighting works on a Mac.** Vitrail no longer tells a pack it is running on a Mac.
turned its coloured lighting (Advanced Color Tracing) off and painted an error over the picture
when it was asked for. On a Mac Vitrail draws through Vulkan on Metal, which has what the
setting needs, so it now works there, and so do the improved rain and the rest of what the pack
held back for Apple's driver.
- Shadow comparisons are enabled on a Mac.** The sampler a pack's shadow lookups compare through
nothing enabled it. The driver drew the lookups anyway, but a launch under the Khronos validation
layer had them refused, and the terrain was then drawn with stale textures until the game
crashed. The feature is now enabled wherever those rules apply.
- Moving blocks are drawn through the shader pack instead of falling back to the game's shader.**
which were not served by the pack. They are now routed to the same shader programs Iris uses for
those pipelines and carry what Iris gives them: the real light map, the normal of each face, its
tangent and the other terrain inputs a pack lights a block with.
- SEUS PTGI HRR 3 is no longer set aside as soon as it loads.** Its anti-aliasing header carries
the pack had set them. It then took the code meant for those platforms as the code in use, left
the three programs that include the header without the pieces they call, and since those could
not be built, drew nothing of the pack at all. A line inside a comment no longer decides which
code is in use, nor sets a name. What a pack writes inside a comment about its own buffers, their
format and their mip chain, is read in full as Iris reads it, so Complementary Reimagined and
Unbound with EuphoriaPatches get the buffers their text asks for.
- Photon no longer crashes the game with its water parallax on.** Looking along the water surface,
own sine came out enormous there, and the pack's water kept stepping until the graphics driver
gave up and the game closed with a lost device. The sine now stays between minus one and one for
any value, as the driver's does, and nothing changes wherever it already did.
- Photon loads with cloud shadows turned off.** The pack stops one of its programs with an error
to the shader compiler, which refused the program, and the whole pack with it. Such a message no
longer stops anything, and the pack loads.
- A full screen program reading the quad's corners by their core profile names draws.** A pack
vaPosition or vaUV0 in a core profile composite, deferred or final was handednought for both, so a program that placed its corners from them compiled and drew nothing. Both
now read the quad's own position and texture coordinate under the type the pack declared, as
under Iris.
- A properties file's own defines now count for its sizes, uniforms and identifiers.**
#define or #undef written there was ignored, so a later condition on that name was decidedas if it had never been written, and an image size, a custom uniform or an item or entity
identifier using it came out wrong or not at all. All of them now read the name as the line
above left it, as under Iris. Complementary with Euphoria Patches is the pack that shows it: its
profiles that set entity shadows to off now turn them off.
- A compute reading a texture that could not be loaded still runs.** A pack naming a texture
compute now reads what the full screen pass beside it reads, and runs. A game texture that no
loaded resource pack ships and the game does not hold either now reads the game's missing texture
in every pass, as under Iris, where it read black.
- A pack image that cannot be read no longer turns a buffer black.** When a pack replaced one of
reading that buffer read black. The buffer now keeps what it held before, in full screen,
compute and world passes alike, as under Iris, and the log names the image.
- Shadows no longer sway with the view bobbing after the player is hurt.** Being hit while
then on, for the rest of the session, it handed packs the walk bob inside the projection rather
than beside the camera. BSL and Bliss rebuild positions on screen assuming the projection has no
bob in it, so their shadows, and anything else placed that way, slid with every step. The bob now
stays where packs expect it, as on Iris, whatever tilts the camera.
- iterationRP draws its lighting.** Its lighting programs store into the pack's buffers from
where they were stored as colours, and name several of them through the pack's own defines.
None of the three was served, so the scene stayed dark. All three are now served as under Iris,
and a program whose buffer or view this graphics card cannot store into is set aside with a
line in the log saying so.
- The pass timings table reads real times on a Mac.** With
-Dvitrail.passTimingsset, every
holds. It now asks for one Metal accepts, and each pass reads the card's own time.
- A pack's three dimensional lookup table is served whatever it holds.** Some packs ship a block
sampled by height, by sun angle and by view angle, a noise field a cloud is carved out of. The
engine laid out the small ones and turned away any table written in full precision numbers, and
it read no pack file over eight megabytes at all, a limit meant for shader text. It also read
such a table only where the shader asked for it in the plainest of the two ways GLSL offers, and
a program that asked the other way was turned away with its table sitting ready in memory. A pack
hitting any of the three lost every program that read the table: on iterationT that was every
pass it draws the overworld with bar a handful, which left the bare picture on screen with none
of its sky, its clouds or its water put in. Such a table is now read to the length its own
declaration announces, however long the file is, at the precision the pack wrote it, and through
either way of asking.
Where a card cannot blend between two of those values, Apple's among them, the table is read at
its nearest entry instead and the log says so.
- A pack's geometry stage is drawn.** Some packs put a third shader between the two the engine
how coarse the texture on a block face is, whether a sky quad is the moon or the sun. The engine
bound the first and the last and nothing in between, so the last one asked for values nobody had
written and the whole program was turned away: on iterationT that took the terrain and the moon
out of the picture entirely. Those programs now draw.
It needs a card that can run such a shader, which the desktop cards do and Apple's do not. On a
card without one, a geometry stage that only passes each corner of a triangle on is folded into
the shader after it, which is what iterationT's terrain stage does, so its ground is drawn on a
Mac too. That stage also works out how fine a block's texture is from the whole triangle, and the
folded shader works the same size out for each pixel instead. Any other geometry stage is named in
the log on such a card, and the world keeps the game's own shader for that program rather than
drawing it with its middle missing: iterationT's sun and moon stay with the game on a Mac, its
stage telling the moon from the sun by a measure of the whole quad that no single pixel can see.
- A pack may now blend one of a pass's targets differently from the others.** A shader pack can
those lines and then dropped them the moment two targets of one pass disagreed, putting the
program's plain function on all of them. Each line now lands on the target it names, which is
what decides the shape of anything drawn over something else: an overlay that should multiply, a
surface that should add, a second target written straight through while the first blends. The
shadow map is in, the same as anywhere else.
With it,
PER_BUFFER_BLENDING is served, so that name alone no longer turns a pack away. Itneeds a driver that lets the targets of one pass differ; where there is none the name is refused
as before and the whole-program function stands, which is the ground Iris refuses it on too.
- Temporal Fold, a new setting on the engine page.** A world drawn at a lower render scale loses
because it only sees one frame. This blends each frame with the ones before it, matching every
pixel to where it stood a frame ago, so detail one frame missed can come from the frames before
it.
It is off until you turn it on, and the checkbox is greyed out at a render scale of 100 percent,
where there is nothing to rebuild. It costs two more passes and three more images, about 40 MiB of
them at 1920x1080. Things that move on their own can leave a faint trail, because the match is
worked out from the camera and not from what each object did.
- Shadow Reuse, a new setting on the engine page.** Filling the shadow map means walking the whole
frames of a player standing still nothing in that map moves, so it is now kept and reused instead
of drawn again, and the passes that sample it are handed the matrices of the map they actually
have. Measured on a Mac mini M4 with Complementary Reimagined at its defaults, in a savanna beside
a village, in a window of 854x480 with a shadow distance of 32: 116 frames a second with the map
drawn every frame, 133 with it kept. Those figures belong to that window and that distance, not
to every setup: on flat ground with little to draw into the map, putting the kept map back can
cost more than drawing it, and turning the setting off is then the faster choice.
- It does nothing on a pack that voxelises into its shadow pass**, which Complementary Unbound and
the frame reads has to fill it every frame, so the engine refuses the reuse there and says so once
in the log. That is decided from the shadow programs as the pack's settings leave them, so what is
left is every pack that does not voxelise, and the same packs with coloured lighting off.
What is kept is the ground alone. Everything that moves, a mob, a boat, your own shadow, is drawn
into the kept map afresh on every frame, so none of it is ever late. The price is on the ground
itself: a block you place or break casts the shadow it had for as many frames as the setting
keeps. One frame is what it ships at, and the slider goes to two and stops there. Turning it off
restores the previous behaviour exactly.
- A pack that ships no
finalprogram now draws.** Some packs end their chain on their last
screen. What the chain leaves in
colortex0 is now brought to the screen, which is what Irisdoes with the same packs. I Like Vanilla and Pegasus were both refused for it, and both now load.
Neither loaded in a released version, so nothing else they needed was ever visible either. I Like
Vanilla reads the screen under one of the game's texture names, which the entry on those names
covers, and on a Mac its water declares the values it hands on through a shorthand of its own,
now read like the full spelling, where one of them would otherwise take the place of the next and
Apple's graphics refuse it. Pegasus defines one of its settings twice under two values, which
refused every program of it; where the two cannot be told apart the later one now stands, as a
driver takes it, and where a use sits between them the pack is left exactly as it wrote it. Its
terrain, its water, its entities and its particles needed two things more. It builds its texture
reads out of shorthands of its own, and the name
texture inside them was left as written whilethe engine renamed it everywhere else, so those passes read a name nothing declared; the
shorthands are renamed with the rest now. And it compares settings against numbers with a decimal
point, "if the falloff equals 1" with the setting at 1.0, and those lines were read as whole
numbers and then refused. They are now reduced the way a driver reduces them.
- Compute passes are announced as a capability.** They have been running for a while, so a pack
and Noble now load.
More stood between those two packs and their picture, and none of it was ever visible in a
released version, since neither pack loaded at all. Clarity spells the matrix that places a
texture under a plain name rather than the old fixed function one, and nothing here answered that
spelling, so every corner of the sun and of the moon was handed the same texture coordinate and
both came out flat; it also lost two compute programs to a setting
compared against a number with a decimal point, the same reading the Pegasus paragraph above
describes. Noble names, in the shader itself, the format of the image that shader writes to, and
that word was being dropped as the declaration was moved to where this backend wants it, so the
pass never built and nothing wrote its screen space reflections.
Noble keeps what each surface is made of as whole numbers packed out of its colours. Apple's
graphics store and read those numbers wrong, so on a Mac they are packed and read back by plain
arithmetic the engine writes into the shader, and the game's own picture is no longer copied into
a target holding such numbers, which a Mac refuses outright. On any machine, whatever the game
still draws in the pack's place, a mob the pack has no program for among it, is missing from the
targets its terrain and its water write rather than painted in flat, and the log says which.
- The pack is told what you are holding.** A shader recognises an item by the number the pack
carried the pack was told you carried nothing it knew. What that drives on most packs is the
light in your hand, which now follows the item the pack's table names. Both hands are read. The
block you are aiming at and the mount you are riding go through tables of the same kind and are
read with them.
- A pack that says it cannot be drawn without the translucent entity program now loads.**
ones it serves, and the pack was turned away before any of its programs was read, with nothing of
it on screen. The capability itself was already there: a blending entity draw asks for the pack's
gbuffers_entities_translucent and a blending block entity for its gbuffers_block_translucent,each falling back on the opaque file of its own family where the pack ships neither. The name is
now served, and announced as a define beside the others so that a pack testing for it reads the
truth. RenderPearl, which names compute shaders as well, now loads.
Much more stood between RenderPearl and its picture, and none of it was visible in a released
version, since the pack never loaded. It computes in sixteen and eight bit numbers: the line
enabling those types is kept instead of dropped, the card is asked for that arithmetic wherever it
reports it, a colour output declared under one of those types is declared under its ordinary
width, and the values the pack passes between its two stages in a block of its own are passed one
by one, at the cost of the packing it had chosen. Its shared vertex header narrows the block a
vertex stage writes its position through, which the language allows only ahead of any use of
that block, and pasting the headers in moved that line past one, so every vertex stage of the
pack was refused; the line is dropped now and the full block stands. It asks whether the card
has an AMD instruction,
which the shader compiler answered yes on every card and which takes the driver down on a
GeForce, and now gets the card's own answer. It tests its own transparency and keeps a light level
where a transparency usually sits, so the engine's own test is now written only into programs that
fill their first buffer the old way, which is where the reference writes it; otherwise it would
throw away every leaf, every blade of grass and the item in hand. On a Mac, the pack is told which
steps of a program the card lets share values between neighbouring pixels, the one placing the
terrain not among them, and what it includes is decided on the compiler's own answer, so its
water, particles and translucent blocks and mobs are lit by the pack there too. Its picture is
painted with compute shaders, which the entry of that name below covers.
- A pack that paints its picture with compute shaders draws it.** A few packs do their whole
frame into a colour buffer of their own. The engine only ever opened a colour buffer for what a
drawing program painted into or read from, so the buffer such a pack hands the screen was never
opened at all and the program holding the picture was dropped on every frame. Those buffers are
opened now, on the strength of the program that writes them. RenderPearl paints its picture that
way.
Two more things stood between that pack and its picture. It ships two of its lookup tables as
plain blocks of numbers rather than pictures, and the engine read a block of numbers only where
it was a three dimensional table, so the program reading them found nothing under the name and
was dropped; those are read now. And where the engine has to compare shadow depths in arithmetic
rather than on the sampler, it only knew the two plainest ways a shader asks for the comparison,
so a pack asking any other way did not compile at all: it now knows the forms that carry an
offset as well, the offset being how a pack samples the neighbourhood of a texel for a soft
edge, and it is carried through rather than dropped.
- A compute a pack ships for a step of the chain that draws nothing now runs.** It was left out
moment the program it hangs off would have run at, which is what Iris does with it: its family
says whether that falls before the world, before its translucents or after them, and its name says
where it lands among the passes drawn there. A pack reaches that state by shipping the compute and
no drawing program for the step, or by shipping one and switching it off itself, its switch never
naming the compute file. A pack may go further and build every one of its worlds out of such
computes with no full screen pass at all, and such a pack is drawn now as well: RenderPearl is
written that way. Noble computes the sun's illuminance and the sky's coefficients in one, and
everything that lights its world reads what that leaves behind.
- A pack that calls the screen by one of the game's texture names draws its picture.** In a
read the scene under a name that means something else in the world pass,
tex and texture amongthem. Those names read nothing here, so every pass of such a chain worked on black and what
reached the screen was black. They now read the screen, in the compute passes of those stages as
well, and a pack that lays a picture of its own over the first colour target has that picture read
instead, as it does under the reference. The log names them once per pass. I Like Vanilla reads
its screen that way throughout.
- A pack asking for a coarser copy of its shadow map gets one.** A shader pack can ask for the
size it wants: a soft, wide shadow is worked out from a small copy in one read where a sharp one
needs many. The engine kept one size, and a shader asking for any other was silently handed the
full one, so the estimate that decides how soft a shadow edge should be was made from the wrong
picture. The copies are now made, once at the end of the pass that draws the map, and a shader
that names the size it wants gets that size, unless it reads through the hardware comparison,
which always reads the full map.
One pack of those at hand asks: iterationT, on the first of the map's two images, for the width
of its soft shadows. A pack that says nothing keeps one size and pays for nothing. A shader that
leaves the size to be worked out for it, rather than naming one, still reads the full map: that
is a separate limitation of this engine and it is unchanged. The same request on the shadow's
colour buffer stays ignored, and that is the reference's own behaviour rather than an omission:
it makes that copy and then reads the buffer through a setting that can never reach it.
A card that will not copy between two sizes of a depth image, which the reference's own graphics
interface always allowed and this one does not require, keeps a single size and says so in the
log.
- A pack asking for a hard shadow edge gets one.** A shader pack can say that its shadow map is
then bound the map smoothed anyway. They are read now, on the full screen passes, the world's own
programs and the compute passes alike, so one map is read one way across a whole frame.
A pack that says nothing is unchanged, its map staying smoothed, which is where both engines
start. One pack of those at hand does say something: Pegasus, which loads for the first time in
this version, asks for its shadow map to be read without smoothing and gets it. The same request
on the shadow's colour buffer stays ignored, as it is by the engine packs are tuned against.
### Changed
- The compiled shaders kept on disk are two to three times smaller.** Every one of them carried a
driver would need to name a line inside a shader and which nothing else reads. What is stored is
what is read back at every load, so there is less of everything to read, check and hand to the
driver. A compile error still names its line exactly as before.
- A pack read twice in one session is opened once.** Reading a pack means mounting its archive,
into every file that includes one, and all of that was done again from nothing each time: at a
world join, at a portal, and every time you apply a setting. The engine now keeps the archive it
opened and serves the next reading from it where the pack, its settings, its profile and the
values the engine defines for it are all as they were and its files carry the sizes and dates
they had. A setting you changed, or a world that moves those values, still has the pack read
afresh. Only that reading is spared: the pack's textures, its translation and its compiles go as
they did before. A file edited on disk changes its size or its date, so a pack you are editing is
still read as you left it.
- Reloading resources no longer rebuilds the pack.** Pressing F3 and T, or anything else that
again, with the world held back while it happened. A pack's programs come out of its own archive,
which a resource reload does not touch, so the ones being drawn with are kept across it now and
the reload costs the pack nothing. Programs left over from a pack that has been replaced are still
freed there, which is the one thing that ever frees them.
- Joining a world builds the pack once instead of twice.** The pack is read while the client
world brings. That second reading used to come after the first had already built the whole
chain, so everything was compiled and then thrown away; the question of whether the world moved
is asked before the building starts now. Leaving a world and joining another paid the same bill
in a different order, reallocating everything for the first frame and then again for the
reading, and it does not any more. Nothing about the picture changes.
- The pack screen names itself at the bottom left.** Vitrail and its version sit in grey in the
when there is any, so a player with both mods installed can tell which screen is open.
- An empty pack folder offers both stores.** The pack screen with no pack in its folder had one
it opens the page, since Vitrail is on both and a player finds packs where they found the mod.
- The pack list is in the order Iris shows it.** A few packs colour their name with a formatting
after the packs named in plain letters. The codes are left out of the sort now, as Iris does, and
two names that differ only in case keep Iris's order too.
- On OpenGL, Vitrail offers to switch to Vulkan.** Vitrail draws nothing on OpenGL, yet its pack
nothing you could see. Its page in the video settings and NeoForge's Config button now open a
screen saying Vitrail cannot run on OpenGL, with a button that sets the game to Vulkan and closes
it, and one that goes back. Its settings page is no longer listed there, its keys and its lines on
the F3 screen do nothing and show nothing, and the game's own Graphics API setting is where it
always was. Beside Iris it is the same offer, the way Iris's own page offers OpenGL on Vulkan.
### Fixed
- Iris and Vitrail installed together no longer close the game on OpenGL.** Both mods reshape
both installed closed before the title screen. Past it, joining a world with some packs closed the
game again, Reverie among them, because Vitrail still ran parts of its frame inside Iris's; it now
runs none of its frame on a backend it does not draw on. Vitrail now only touches that option
where it draws the world itself and Iris does not, and where Iris draws it no longer puts a red
line in the chat saying the picture is missing, nor answers Iris's reload key, which is also its
own, with a red line of its own. After a startup that ended badly, the backend is kept as it was
set rather than put back to Vulkan while Iris is installed, since Iris has already chosen its side
for that backend. Where Iris draws, Vitrail's key for the pack screen leaves the press to Iris's
own, which sits on the same I, so the I opens Iris's screen alone. On Vulkan, where
Vitrail draws, that I opens Vitrail's screen and not Iris's offer to switch to OpenGL over it.
- Reverie draws on a Mac.** Two of its passes read more textures at once than the sixteen a Mac
Apple's graphics card refused those passes and the pack could not draw there. On a Mac whose card
takes textures as one table, which every Apple Silicon Mac does, a pass reading more than sixteen
is now handed them that way. Every other pass, and every pass on any other machine, is handed its
textures as before.
- A graphics card lost in the middle of a session now closes the game on the error that lost it.**
first, switched the pack or one of its parts off and went on drawing against a card that was gone,
until a later step crashed the game on a report about something else. That error now goes
straight through, so the crash report opens on the lost device itself.
- A pack the graphics card will not build no longer closes the game.** When the card refused one
program reading more textures at once than it has slots for or naming something the way Metal
names its own, the error went all the way up and the game closed on a crash report: on a Mac
that was BSL, Bliss, Reverie and Photon on 0.10.0-beta, which all draw there now through the
entries on them. A pack the card still refuses is put away instead and the world is drawn by the
game, the way it is for a pack refused when it loads, and the settings screen says an error
stopped it.
- Three more programs the graphics card will not build no longer close the game.** The render
its own, and the game's entity programs rebuilt when a pack starts drawing the entities or the
hand were all built in the middle of a frame with nothing to catch a refusal, so a card that
refused one closed the game. The render scale now falls back to a plain stretch, and turns itself
off when nothing builds; that other mod's particles are drawn through the pack's program as it
stands; and the entities and the hand go back to the game for the rest of the session. The log
says which.
- Water no longer goes missing on a Mac.** The engine keeps one drawing pass open across the
pass right after the water had been drawn in it, which Vulkan does not allow; on a Mac that write
cost the water already drawn. The pass is now closed before any such write, unless something is
still drawing into it.
- Banners no longer flicker with light stripes on a Mac.** On Apple Silicon a banner could show
camera moving. A banner is drawn twice at the same place, the cloth and then its colour over it,
by two different programs of the pack, and the Mac's shader compiler was free to round each
program's arithmetic its own way, so the colour could land a hair behind the cloth and be hidden
by it. Every vertex program of a pack now asks for its position to come out identical
wherever two programs compute it with the same code.
- The world stops being shaded twice, and the sides and undersides of blocks come back to the
faces, out of a small table each dimension carries: in the overworld full strength on top, half
underneath and two values between on the sides, which is what gives an unshaded world its relief.
A pack works its own lighting out of the direction each surface faces, so that tint left underneath
darkened everything the pack had already shaded, each face by its own fixed amount and an
underside by half. It showed most where a pack lights a surface the game leaves dark, the plainest
of those being a canopy seen from below. A pack that wants the old behaviour writes
oldLighting=true, which the engine reads now.- A pack no longer brings the game down on a Mac over a name it chose.** Apple hardware has no
every shader into Metal's language, which is C++, and it carries over the names a pack gave its
own functions and variables. A pack that had named something
bias, length_squared or newthen collided with words that language already owns, and Apple's compiler refused the whole pass:
the game came down while it warmed the pack's pipelines up, on one it could not compile. BSL,
Bliss and Photon all came down on a name of their own on 0.10.0-beta. The engine now drops the
names of everything outside a shader never asks for, which is where a pack names its own working
parts, and BSL draws.
The names of what a pack exposes stay, its uniforms and its textures, because the engine binds
those by name; none of the packs tried collides there. Bliss and Photon also needed the entry
below, and draw with it.
- A pack that declares more textures than a pass reads draws on a Mac.** Apple offers one pass
engine hands that pass rather than off the ones its shaders touch. A pack usually declares every
texture it owns in one file all its programs include, so a pass reading thirteen of them was
handed a list of forty-eight and given slot numbers running past the sixteenth: Apple's compiler
refused it and the game came down while it warmed the pack's pipelines up, on a pass wanting
three fewer slots than the hardware has. The engine now numbers a pass off the textures its two
shader stages read between them, which is the count that has to fit, so the numbering is dense
and anything under sixteen gets in. Bliss and Photon draw.
Reverie has two passes whose stages read seventeen and eighteen textures between them, more than
sixteen slots hold however they are numbered, and those two are handed their textures as one table
instead, as the entry on Reverie says. Everywhere else this is invisible: the same textures are
bound as before and the same ones are read, and what changes is only which of them the pass is
given a numbered slot for.
Photon also works out the light its sky casts in a small step that runs on many threads of the
graphics card at once, and those threads share more working memory than Apple's graphics allow,
which leaves the step unbuilt and the sky lighting nothing. On a Mac, such a step now keeps those
numbers in an ordinary buffer when it runs as one batch of threads, which is how Photon runs it,
and works out the same light. A step past the allowance that runs as several batches is still
refused, and the log says so. Every other card is left as it was.
- A shadow read through the hardware comparison names the level it reads.** Where a pack asks
the level of detail to the card, and a card works that out from how the reading coordinate moves
between neighbouring pixels. Inside a loop or a branch, where the pixels beside one another may
not be doing the same thing, that answer is undefined, and a ceiling on the sampler is no guard:
the same ceiling on the other kinds of read was measured not to hold. Those reads already named
their level for exactly that reason, and these did not, though they are the reads a pack makes
most, the four tap shadow filter of both Complementary packs among them. They name it now, and
what they name is always the full map: a read through the comparison never reaches a smaller
copy, even where a shader asks for it, which none of the packs at hand does.
- Smoke, flame and the other solid particles take the colour the pack meant them to.**
see-through ones after the water, and only the second lot were reaching the pack's own
image. The first lot were painted into the game's picture instead and carried in from
there, already finished, so a pack that lights its particles itself was handed a colour
somebody else had already lit: under Photon a campfire's smoke came out a warm haze where
it should be dark, and any pack asking for more than one target had everything past the
first written nowhere. They are now drawn into the targets the pack asked for, as the rest
of the world is.
Packs that had this half handed back to the game altogether get it too: a pack whose
particle program writes a target the world's own picture is not painted into was refused
for a road it no longer travels.
- Water that reads the picture behind it draws its fog and its reflections.** Some packs
while drawing into that same target, for the colour of the world behind the surface and for
what it reflects; that is what OpenGL hands them, the target as it stands. This engine
answered the read with one black pixel, and Sildur's Vibrant Shaders drew its lakes a flat
saturated blue with nothing mirrored in them. The read is now served a copy of the target
taken just ahead of the pass, which holds the world the pass wants to see behind itself, at
the cost of two image copies a frame per such target.
- A pack that declares its own output where another of its branches wrote the old-style one
old-style output and the others declaring their own under the same number, and only one branch is
ever taken. The engine counted the branch nobody took, laid its own output on that number, and six
of the pack's passes were refused for two outputs on one slot. The pack's own declaration takes
the slot now.
- An effect a pack carries from one frame to the next no longer alternates between two images
instead of one being copied over the other, which is the same thing only where the frame wrote
the whole target. Where it wrote part of it, or where the pass that writes it did not run, the
pack was handed one image on one frame and the previous one on the next. It is steady standing
still and shows as the view moves, so it reads as lighting that slides.
- A geometry program drawn before the water sees the world's depth.** The terrain, the mobs, the
and those programs were handed the far plane where a pack asked for that copy, so a shader that
softens or fogs itself against the scene from one of them saw nothing in front of it. They now
read the copy as it stands, which at that point of the frame is the frame before's, exactly what
the reference hands them; the live depth stays out of reach there, being the very image those
programs draw into. Photon reads that copy from its opaque particles and its glowing eyes, and
Pegasus and E-LITE from their terrain, mobs, hand and particles.
- A greyscale picture a pack ships is read as the pack wrote it.** Every grey image came out
out of its own colour space instead of taking the bytes as they were written. A pack that compares
such a picture against a number wrote that number for the picture it made, so the comparison
landed somewhere else: on MakeUp UltraFast the sky carried a solid white cover where the pack
draws a few clouds. The clouds are clouds again, and every grey lookup table, mask and noise field
a pack ships now holds the values it was authored with.
- A pack that sizes a compute step through one of its own settings is no longer run at full
a setting rather than with a number. The name meant nothing to the engine, which then ran the step
over the whole screen. On Reverie the clouds were marched at four times the width and four times
the height the pack asks for, sixteen times the work for the same picture. Those names are now
read at the value the settings give them, so the step covers what the pack asked for and that
march is a sixteenth of what it was; what it gives back in frame rate was not measured. Where a
name stands for nothing the engine can read, the step still covers the whole screen and the log
says which word it could not read.
- The world is no longer painted over by the stage meant to run before it.** Some packs open the
once the world was already drawn instead of ahead of it, so on a pack whose prepare fills the very
image its terrain, its sky or its hand draws into, that table replaced all of them. On MakeUp
UltraFast and on E-LITE the ground vanished behind a pale field, the held item was not there
and the sky stopped being the brightest thing on screen. The stage now runs at the head of the
frame, where the world lands over it, and the begin stage that opens it runs ahead of the shadow
map rather than behind it.
- Switching packs no longer leaves graphics memory behind on packs that use compute shaders.**
pipelines and their buffers when the pack was replaced, so every switch and every press of the
Reload Shaders key added to what was never given back until the game closed. Photon builds its
sky lighting in such a compute, so every switch away from it left one behind.
- The off hand no longer answers for the main one on a pack that asked it not to.** A pack says
before the off hand had a light of its own, and that was being done whatever the pack said. Seven
of the eleven packs tested ask for it to stop: on those, a torch in the off hand was being
reported in both hands at once, so the pack lit the scene from the empty one beside it as well.
- E-LITE's clouds follow the hour of the day.** A pack may declare a value of its own under
the day under the other one and its sky reads it, so it arrived as nought: the count of days was
all the clock the cloud cover had left, and it changed in day-sized steps instead of drifting
through the day. Either keyword now reaches a program that asks for the name, which is what Iris
does with the same pack.
- The log stops calling a value missing from this engine when nothing supplies it anywhere.** A
out of, one belonging to a mod that is not installed, or one it simply misspelt. Those were being
listed as values this engine still owes, which sends whoever reads the log looking for something
that was never written. They are now named for what they are, and a pack gets the same nought under
Iris.
- A pack's quality profile is named instead of reading "Custom".** A profile can list a
ever being recognised: the shader screen and the F3 overlay both fell back to "Custom" on a pack
nobody had touched, and the profile buttons could never land on a name. Photon is the pack this
showed on, where all four of its profiles now read as themselves.
- A pack reloaded while you play no longer comes back with the world drawn in one colour.** On
for about half a minute, and then it put itself right. A pack of that kind keeps its light in
volumes it fills a little at a time rather than writing whole, and it was handed those volumes
still holding whatever had been in that memory, so its first frames spread that instead of light.
They are now emptied once, when they are made, up to a fixed amount of memory for all the volumes
made at the same moment; past it they are left as they come, a precaution kept since emptying at
that moment once coincided with the display driver going down. Photon at its two largest settings
for those volumes goes past it, and there a reload can still bring the one-colour world back.
- RedHat's shadows, and E-LITE's entities and hand.** Two separate names a pack may write that
them: the picture kept the game's own shader there and the pack's effect was missing on those
surfaces alone.
- Eight shadow colour buffers for a pack that asks for them.** A pack declaring
HIGHER_SHADOWCOLOR may now draw the light into shadowcolor0 through shadowcolor7 and readthem back, which is what Iris gives it. Before, a shadow program naming anything above
shadowcolor1 had its whole target list thrown away and drew into the first two instead, whichis still what a pack that does not declare the flag gets, exactly as under Iris. And only the
buffers some program of the pack names are allocated now, so a pack writing
shadowcolor0 alonepays for that one image where it used to pay for two.
- Two more capability flags are announced and no longer refuse a pack**,
HIGHER_SHADOWCOLOR
SSBO. The storage buffers behind the second were already built and filled from a pack'sown
bufferObject lines, and the name was simply never claimed, so a pack that declared it couldnot be drawn at all. A pack requiring either, or both, now loads.
- A pack can read the shadow map under a second, hardware-compared name.**
shadowtex0HWand
shadowtex1HW are bound now, to the same two depth images as shadowtex0 and shadowtex1,and each is compared by the hardware where the pack declares it that way. Both names read back
black before, and a pack declaring it cannot be drawn without
SEPARATE_HARDWARE_SAMPLERS wasrefused at load over that name alone. That name refuses nothing now, though a pack that also
requires a name this engine has not built is still refused, the log listing what it asked for.
Nothing changes for a pack that never writes the two names.
### Changed
- Distant Horizons' far terrain is read out again only once it has changed.** Every frame a pack
once for the land and once for the water, which for a far view is thousands of sections a frame
and the same ones in almost all of them. The listing is now compared against the one the last
reading came out of, and the reading is reused where nothing in it has moved, so a camera
standing still over settled far terrain does the work once instead of on every frame. Walking,
a view distance changed, terrain finishing its generation, anything that really moves the far
view reads it again as before. The picture is the same, and none of this has been measured, so
it says work removed rather than frames gained.
- Picking a pack freezes the game for less time.** Reading a pack walked the same shader files
once more for each of its compute programs, and every one of those walks read the archive again
and pasted the same shared headers together again. A pack is now read once per file and each of
its programs assembled once for as long as it stays open, which is the wait before the picture
appears when you choose a pack, apply a setting, or step through a portal. Nothing about the
picture changes.
- A pack loads its entities, sky, clouds, weather, particles and far terrain in one reading.**
plan and the same program tree for itself before reading its own files, which was most of the
archive walking a load did. They now share one reading, and the report of a pack that used to
hold the title screen and every Apply for a second or two is written from a background thread
instead. On Complementary Unbound the families take under a second of background work where
they took four. Nothing about the picture changes.
### Fixed
- A
#ifdecides like the compiler where one side of an&&or||cannot be worked out.**
X != 0 && 100 / X > 5 with X at zero was left undecided, because theright side was worked out whatever the left one said, and an undecided condition kept its
branch in. The right side is now skipped where the left one has already decided, as the
preprocessor does, so such a branch is left out exactly as the pack meant it to be.
- A pack whose conditionals are written loosely draws, as it draws under Iris.** Reverie Beta
#ifdef with no name after it and one with two names joined by &&, and Photonwrites an
#endif with nothing open for it to close: none of the three is a directive GLSL willtake. Iris hands the compiler what its own preprocessor produced, so nothing of the sort reaches
a compiler there and both packs draw; here the lines went on to the compiler as the pack wrote
them, six of Reverie's programs and three of Photon's would not build, and one program that will
not build stops the whole pack with nothing of it drawn. The three shapes are now read the way
Iris reads them, a nameless one taking the branch it opens, a name followed by anything else
deciding on that name alone, and one with nothing to close being left out of the text, with the
file and the line said once in the log. A pack that writes its conditionals properly is
untouched.
- A value a pack spreads over several lines stops at the end of its own branch.** A
shaders.properties value continued with a backslash was joined before the conditionals aroundit were read, so a value whose last line carried a backslash too swallowed the
#else or#endif that closed its branch, and the conditional around it went dark with them. Photonwrites its moon brightness that way, one line per phase, and both sides of Moon Phase Affects
Brightness were wrong. Switched on, the table never parsed and the constant from the branch
meant to replace it was read instead, so the moon lit the ground the same on every night of the
cycle. Switched off, that constant sat inside the branch the swallowed
#else had left open,no brightness was declared at all, and the shaders read the missing one as zero: the moon gave
no light whatever, and every night away from a torch was as dark as a new moon. The moon now
dims through the cycle with the option on, and is a plain full moon every night with it off.
- A condition continued over several lines with a backslash is read whole.** The pack's
decided on that fragment alone, which stood for true. Photon undefines its waving switches
under one of those, so the include the switches guard was skipped and its terrain and shadow
programs compiled against a function that was not there.
- A pack that writes a constant through a macro is no longer refused whole for it.** A
const whose initialiser the Vulkan compiler would not take loses the keyword at load, andwhether it would was judged on the names written on the line: a macro's name passed whatever
it stood for, so a macro over a value this engine had already had to demote left a constant
the compiler then refused, and one pass refusing takes the whole pack down. The macro is now
read through. Photon writes its fog colours that way, and was refused at load on its blending
pass.
- Blend overrides, target sizes, flips and
endFlashShadowsfollow the pack's own settings.**
shaders.properties lines were read whether or not the #if aroundthem held, so a line the pack had switched off still applied. Photon's two low-resolution
cloud targets took the size of the last of its four choices whichever was picked, and
Complementary's water blend and its weather target's
off held whatever the define or thesetting around them said.
- A pack switching off one of its own programs is obeyed for the world, not only for its
that draw the world went on being drawn whatever the setting said. Where the pack offers a
plainer program behind the one it switched off, that plainer one now draws instead, which is what
the pack is asking for: Bliss draws its translucent entities and blocks through its ordinary
entity and block programs until you turn its translucent entities setting on. Where it offers
none, nothing is drawn: Bliss and BSL stop building a shadow map in the Nether, and Bliss in the
End as well, which is what both of them ask for there.
- A modded dimension is drawn from the folder its pack sends it to.** Both Complementary
continued line per mod in
dimension.properties, and only the first of those lines was read.Everything the rest name, which is Ad Astra's planets and orbits, Prominent's dimensions, The
Bumblezone and half a dozen more, fell through to the pack's catch-all: those worlds were drawn
with the overworld sky, the overworld fog and the overworld full-screen passes instead of the
ones the pack wrote for them. They now get the folder the pack names, as they do under Iris.
- A pack that says it cannot bear anisotropic filtering is believed.** BSL and both
breaksAnisotropy in their shaders.properties, and the line wasread nowhere: with Texture Filtering set to Anisotropic in Video Settings, their terrain showed
a strip of the neighbouring sprite along a block edge seen from low down, where the same packs
under Iris do not. Their terrain and their shadow map now read the block atlas without
anisotropy whatever the setting says, as Iris reads them. Everything the pack does not draw
keeps the player's value, and so does the number the pack itself reads for the setting.
- A pack is told what convention a resource pack draws its material maps in**, as Iris tells it.
MC_TEXTURE_FORMAT_LAB_PBR, and the revision beside it, are what a pack written against thembranches its labPBR decode on, and neither was ever posed here: such a pack read every install as
one where nothing had been declared. Both are posed now, from what
optifine/texture.propertiesnames, and only where a resource pack really declares the format. Changing the resource packs
reads the shader pack again when that changes what is declared, since the symbols decide which
branch was compiled.
- Packs are told the block emission attribute is there**, as Iris tells them. The chunk
tests for it was never posed: Bliss took its path without voxel emission, and Complementary
only kept its two reflection targets at half resolution by the flat read above.
chunkFadeTimeInvreads infinity with Chunk Fade set to none, as it does under Iris.** It read
min(1.0, age * chunkFadeTimeInv) was heldat the start of a fade that never advanced, where under Iris the same expression reads as faded
in. Nothing in the packs that fade chunks changes with it: those read the
mc_chunkFade attributerather than this uniform, and it is a pack written against the uniform that gets the Iris answer
now.
alphaTestRefcarries the alpha reference of the program being drawn**, the pack's own
alphaTest line or the default of the pass, as it does under Iris. It read nought in everypass, so a program fading against it did so at the wrong threshold; a discard against it
was already made at the right one, by the test the translation adds.
- A blend override a pack writes for one target is honoured wherever the program's targets
blend.<program>.<target> line was thrown away whole, one pipeline carryingone blend function for every target it writes, and the log said so. Most such lines are
written for a program that writes that one target and nothing else: the seven programs
Photon draws its translucent layer with, rain, held water, textured pieces, translucent mobs,
blocks and particles, each ask to be laid over that layer premultiplied, its armour glint
asks to add to it, and Complementary's rain writes a droplet's data and asks for it
unblended. Those lines are read now, as Iris reads them: on the target's
rank among the program's draw buffers, for the geometry programs only, a line naming a
target the program does not write dropped as the reference drops it. A program whose
targets would end up blending two ways, which one pipeline cannot carry here, keeps its whole
program function as before, and the log names it at load.
- A buffer a pack asks for starts empty, whatever its size.** Only the small ones were emptied,
that memory. Complementary reads a cell of one before anything has written it and takes a zero
for "no surface here", so at its Ultra profile, which turns World-Space Reflections on and
Advanced Color Tracing up to 16 chunks and asks for 773 MiB on that account, the reflections of
the first seconds could carry scraps of unrelated blocks, and the pack mixes what it reads back
in, which drags them out over several more. Every such buffer is now emptied whole the moment it
is allocated, which is before the pack has drawn anything into it.
- A pack's storage buffers are read and written where the pack put them.** A pack that keeps
bufferObject lines, had that bufferallocated and filled but never handed to the programs that name it: every such program kept the
slot number the pack wrote and read whatever the game had there, which is a buffer of its own.
Reverie keeps the frame's average brightness in one such buffer to set its exposure, read
nothing, and scaled the whole picture to black. Complementary's world-space reflections read
their block data out of another. Both now reach the pack's own bytes. The store of compiled
shader modules is rebuilt once on the first launch, as every module compiled before this
carried the old slot.
- A storage image the graphics card will not give stops the pack instead of drawing it wrong.**
bound under the name, which no driver has to survive. The pack is refused at that screen size
now, and refused for the session with the reason on the settings screen when the image is of a
size the pack chose, since no window size changes that.
- Every target starts from its clear colour when a pack loads or the window resizes**, both
while the shaders were still compiling could keep whatever the driver had left in it, and a
pack that keeps a target from one frame to the next then read that as its history. The
reference clears everything once at that moment, and so does this.
- A colour target read at a lod carries the whole chain OpenGL would have built.** On a
pack reading past that level was clamped to it where Iris had one more. The chain runs to one
texel on the longer side now, on every screen.
- A volume a pack fills for itself is read the same way from every pass.** An image declared
image. line is filtered by its format, smoothly unless it holds whole numbers, whichis the one thing Iris settles on the image and every reader then inherits. Here the answer was
decided in three places and only the geometry programs had it right: a full-screen pass and a
compute pass read every such image unfiltered. So the geometry half of a pack's lighting was
smooth and the full-screen half was not, whatever the settings. Photon's deferred shading and
Bliss's composites interpolate their light volumes, and showed the light in bricks the size of
a voxel with a hard edge; a pack that reads its volume texel by texel never saw it, no filter
reaching that kind of read.
- A texture a pack ships is read by a compute pass as the pack asked for it**, the blurring and
.mcmeta beside the file included, which is how a full-screen passalready read it. A compute naming such a texture found no image behind the name at all: one
spelled like a colour target was answered with the target instead of the pack's own file, and
under any other spelling that one compute did nothing at all, leaving a line in the log while
the pass it belongs to drew on without whatever the compute was there to prepare.
- A pack's depth of field focuses past the item in your hand.** The depth the focus is taken
middle of the screen the focus jumped onto it and everything behind went soft, sharpening again
as the hand swung away. It is now read from the depth kept a step earlier, before the hand is
drawn, which is where Iris takes it, so the focus stays on what you are holding the item in
front of.
- An array handed between a pack's stages arrives whole.** Photon hands its sky harmonics to
that stage read off the wrong slots. An array is now taken apart and put back together the way
a matrix and a struct are.
- A struct handed between a pack's stages arrives whole.** A pack may hand a stage a struct of
That struct reached the other stage wrong, so the fog Photon's reflections computed with it
saturated on every lake past a hundred blocks. A struct handed between stages is now taken
apart and put back together the way a matrix already was.
- The compute programs a pack attaches to its full-screen passes run.** They were named in the
never there: Photon computes its sky lighting in one, and everything in shadow, the hand first,
was black for the lack of it. Those programs now run, right before the pass they belong to. A
compute whose pass the pack ships no fragment program for, and one attached to a setup program,
are still skipped, and the log still names them.
- Photon draws.** Three things stood between its files and its picture. Its atmosphere table
for a volume took one byte a texel and a repeating volume only, so the three deferred passes
reading the table, the sky map, the clouds and the shading itself, were dropped; the atlas now
keeps a blob's channel type and lays a clamped volume out with its edges repeated. Its volumes
are read through macros standing for the sampler's name, which the rewrite of those reads did
not follow; it does. And a volume laid over the name of a colour target for one stage took the
plain
sampler2D reads of that name in the same stage with it, where the reference renamesonly a
sampler3D of that name: Photon's composites read its cloud noise where the scene shouldhave been, and every pixel came out red.
- AstraLex's window panes no longer bloom blue over their walls.** Its glass reflections march
so the ray landed on a pixel it never reached and the pane lit up with it, on some frames and
not others. A lookup through a sampler that carries no mipmap chain is now asked for the base
level of its image outright, which is what the reference's filtering always answered.
- World-space reflections come back after the first launch.** Complementary Unbound on Ultra
pack for the first time that pass ran; on every launch after it, the translation being reused
from the store on disk, the engine stopped recognising the buffer behind the name and dropped
the pass. The reflections went with it, two of the targets the pass writes were read by the
next one as the clear had left them, and the log named the pass as one it would not run. A
pass whose buffer the pack really never declared is still dropped, and still says so.
- A variable a pack reads before writing it reads zero, as it does under Iris.** A shader that
Iris such a variable reads zero in practice, so the picture is right there and nobody notices.
Here it read something else, and what it read changed with the face being drawn: on
Complementary Unbound at its High and Ultra profiles, one face of the held hand was black at
every angle while the others were lit, and the water along far shores carried black lines that
came and went. Every variable a pack can read before writing it now starts at zero, in the
programs of every pack, and both defects are gone. A file
raw-locals in the vitrail folderof the game directory turns the zeroing off, for measuring what it costs. The store of compiled
shader modules is rebuilt once on the first launch, as every module compiled before this carried
the bare variables.
- A pack's own
smooth()accumulators restart with a dimension.** They went on from the
beside them restarted; a world change forgets them with the rest.
- Leaves keep the same self-shadow wherever the camera stands.** The shadow map is drawn
pass and only refills it when the region's sections change or the camera crosses a section
boundary in or next to the region. The camera's draw fills that batch without the faces the
camera cannot see, and where the light and the camera kept the same sections the shadow draw
took the camera's batch as it stood: the faces between the sun and the leaves were missing
from the map, and a canopy's self-shadow came and went region by region as the player walked,
every tree lighter or darker according to where they stood, where Iris showed one shadow. The
shadow draw now keeps filled batches of its own, as Iris does.
- A pack's terrain reads the block atlas unfiltered, as Iris binds it.** The terrain read the
anisotropy, both LINEAR for min and mag, where
Iris throws that sampler away and binds NEAREST for every terrain draw. Both halves now bind
the same sampler Iris does, mipmaps and the player's anisotropy kept. What a
filter can decide on cutout foliage is whether a fragment survives its alpha test, so the two
states can only differ where a leaf's edge falls inside a texel; compared against Iris on one
scene at three camera heights, the two engines shade the trees alike in both states, so this
is parity and not the cure of anything seen so far. Of the Texture Filtering setting, the
anisotropy reaches a pack's terrain as it did; its filter never did, the game's chunk sampler
being LINEAR whatever it says, and it still applies to everything a pack does not draw.
An empty file
vitrail/legacy-terrain-filter in the instance, or-Dvitrail.legacyTerrainFilter=true, puts the game's filtered sampler back on the terrain thecamera sees. The shadow map stays unfiltered either way: what the switch restores is the sampler
the chunk renderer was handed, and the shadow draw hands it one of its own that is unfiltered
already, so a comparison taken with the switch is a comparison of the camera's half alone. The
two states can be compared in one world by reloading the pack with the
Reload Shaders key (R by default) rather than by swapping builds. F3 + T does not read the
pack again and leaves the state as it was. The log names the state once per pack load, at the
first terrain the pack draws.
- A mob standing just past the pack's shadow reach for entities keeps its shadow while any
(Complementary does, at an eighth of its shadow distance) had that reach measured on the
caster's position, so a mob whose body reached back inside the distance lost its whole shadow
where Iris drew it. The reach is measured on the caster's bounding box now, as Iris measures
it: the difference is the caster's half width, under a block for most mobs and a few for the
largest, and the shadow lands as far out as it does there.
- A mob the player cannot see casts no shadow.** With Sodium's entity culling on, which is
first of all, was left out of the shadow map even where its shadow fell in plain sight, and
it came back the moment the player turned towards it. The casters that move are now chosen
after the light's own walk of the world, off what the light sees, as Iris does.
- The shadow map stopped where the camera's fog did.** With Sodium's fog occlusion on, rain
world, so a far hill still casting into the view dropped out of the map. The light's walk is
no longer shortened by the camera's fog.
- A pack can tell water and lava from the blocks around them.** Half of the number a chunk quad
that draws fluid surfaces apart drew them like stone. Both Complementary variants read it to hold
the mip level down on flowing lava, which their own comment says comes out broken without it, and
that guard is compiled in only with Anisotropic Filtering on 8 or 16, not on the 0 they ship nor
on 4: there the guard never fired and the lava kept the broken level. Fluid quads now say what
they are, in the terrain and in the shadow map alike, as they do under Iris, and they say it even
where the pack gave the fluid no number of its own.
- The fire on a burning mob is drawn as fire.** A pack that gives
minecraft:entity_flamea
everything the pack does to that kind of mob was done to its fire as well, and the fire was lit
and fogged like the body under it instead of glowing. Both Complementary builds and Bliss name
that number, and the flames now read it, as they do under Iris. A pack that names no flame now
sees the fire as an entity it never named, as it is under Iris, where before the fire read as
the mob it wraps.
- Name plates, signs and every other text in the world are drawn by the pack, as Iris draws
onto the pack's picture at the spot where the pack blends its water; where a pack keeps
something other than its picture there the letters landed in it and came back as a
half-transparent negative, which under Photon is what a floating name looked like. The pack
now draws them itself, with the program it draws a translucent entity with, with the one it
draws a translucent block entity with for the text of a sign, and with its shadow entity program
from the light. A font that ships as a
.ttf file, which a resource pack may and the game doesnot, is baked into a sheet holding a single channel: the pack is handed that channel in all four,
as Iris hands it, so such a font draws as text and not as solid colour. A pack shipping none of
those programs, and a pack loaded with the entities switched off, keeps the layer and looks as
it did.
- The block outline is drawn by the pack, as Iris draws it.** The thin box around the block
the pack's picture at the spot where the pack blends its water; where a pack keeps something
other than its picture there, the box landed in it and came back as a faint ghost, a bright
refraction of the block behind under Photon. The pack now
draws the lines itself with its
gbuffers_line program, or gbuffers_basic where it shipsnone, under the outline render stage, so a pack's own selection box comes through: the
colour or rainbow Complementary offers for it, the box mode of Photon, the plain dark
outline of the rest.
- A damaged file in the translation cache no longer ends the session.** The cache keeps what a
larger than any translation is, damaged where it lies or carried in from another machine, was
read whole into memory before anything could ask whether it made sense, and running out of
memory reading it stopped the game rather than counting as a miss. Such a file is now refused
before it is read, the program is translated as it would have been anyway, and the log names
what was refused, once.
- Importing settings no longer acts on a screen you have already left.** The window that asks
closed while it is still up. Picking a file at that point queued its values anyway, into a page
nobody was looking at and from the picker's thread rather than the game's, so a pack ended up
carrying settings the player had walked away from. A file picked after leaving the screen is now
dropped, and one picked while the screen is still up is read on the game's own thread. Exporting
was never affected: it copies the settings file of the pack that was open when the button was
pressed, and touches nothing on screen.
- Opening the settings of a pack from the list, then moving on to another pack, no longer
described the pack previewed rather than the one chosen until the options view was opened
again. And the settings file shared with Iris now reads back whole when an editor left a byte
order mark or old Mac line endings in it: either used to turn the first line into a setting no
pack declares, or the whole file into one.
- A Cache Cap slider on the video settings page**, how much compiled-shader disk this
512 MiB is the old hardcodedceiling and the default. Moving it applies at once, with no pack reload: lowering may drop
unused cached shaders. Written in
vitrail/module-cache-ceiling.txt.- A Shadow Map Scale slider under Video Settings**, on the mod's page beside Max Shadow
for, 25 to 100 percent, and the setting outlives whichever pack is chosen. Moving it reloads
the pack, which is what lets the pack be told the smaller number instead of being left to
work against a map it cannot see.
It is a setting of its own rather than something the FSR Render Scale takes along with it,
because of what it does to the picture. The pack works out its shadow blur, its shadow bias
and where it reads the map from the size it was given, so a smaller map is a less defined
shadow, softer where the pack smooths its own and coarser where it does not, and an image
the pack's author never saw. That is a trade worth offering and not worth making on
somebody's behalf, so at 100 percent, which is where it starts, the pack gets exactly the
map it asked for and nothing of the setting runs. The engine says at load when the setting
is in force.
What the render scale reaches and what it leaves alone is now written down, in
docs/render-scale.md.- A switch that fills the shadow map from a box around you rather than the tight
vitrail/box-shadow-cull in the game folder, or-Dvitrail.boxShadowCull=true. The silhouette stays the default, which is what other loadersdraw. The box was tried as the default, to stop leaf blocks popping at the sun's edge as you
move, and measuring it is why it did not stay: on one wooded scene it drew 875 sections where
the silhouette draws 322, and the frame ran twelve to twenty-eight percent slower depending on
how much stood around. It also stops bounding anything at all once Shadow Distance reaches
your render distance, which is where the slider sits at its maximum.
What the box covers up is a defect of this engine and the switch is not its fix: leaves can go
a frame without their shadow while you walk, if you run a mod that narrows what the game
considers visible. That is being fixed at its cause instead.
- A switch that hands every sine and cosine a pack writes back to the graphics driver.** An
vitrail/driver-trig in the game folder, or -Dvitrail.driverTrig=true. They arenormally replaced at load with a helper that keeps its accuracy over a whole world coordinate,
where a driver's own can shed the low bits and show as shimmer. The switch exists so the two
can be compared in one world rather than across two builds, and the log says which of them a
pack load ended up with either way. A pack that defines its own sine keeps it in both states.
### Changed
- Compute shaders now hit the compiled-module cache on a pack reload.** They used to miss
is out of the key. Computes are compiled by this engine, not by the game's shader compiler;
what is kept is the compiled module and its bind table, the same files graphics shaders
already write under
vitrail/modules. Vulkan pipelines are built each load as before.- F3 names the pack the way Iris does.** The profile line is the scanned name or Custom, with
C: a/b D: d without thisengine's own cull dialect.
- The compiling overlay no longer covers F3.** While the debug screen is open, "Compiling
is as it was.
- Video-settings labels tell the truth about reload.** Titles are shorter so they fit the
the pack.
- Loading a pack a second time no longer compiles its shaders again.** The compiled module
vitrail/modules in the game folder and read back when the same shader comes round again, soa warm load does no compiling and no inspecting at all. Editing a shader or moving a pack
setting changes what is asked for, and so does updating the mod, the game or the loader, and
anything that has changed is built from scratch as before. Each release keeps its own folder
and takes the older ones away with it, the whole thing is capped, and the log says how many
shaders came off the disk, how many were built and how much is stored.
- It removes work rather than time.** Measured on one machine: a warm load compiles none of
same to the second. What a pack load really costs sits somewhere neither this nor the log
line is looking.
- Loading a pack again no longer rewrites its shaders from scratch.** Turning a pack's GLSL
is the same answer every time the same pack comes back. What it came to is kept under
vitrail/translations in the game folder and read back instead. Editing a shader, moving apack setting, changing the shadow map scale, updating the mod or the game, or switching one of
the mod's own measurement switches all change what is asked for, and anything that has changed
is rewritten as before. Each version keeps its own folder and takes the older ones away with
it, the whole thing is capped at a quarter of a gigabyte, and the log says how many programs
came off the disk and how many were rewritten. It removes work rather than time: the wait
before a pack draws is the same, and what changes is that none of it is spent here.
- A shadow lookup a pack asks the hardware to compare is now compared by the hardware.** A
sampler2DShadow used to have that comparison rebuilt in shaderarithmetic on every tap, a dozen instructions where a comparison sampler pays one, and a
shadow's blur loop makes many taps per pixel. The comparison now rides the sampler, the pair
Iris binds when a pack asks for its hardware shadow filtering, which every pack that declares
the type does; the picture it computes is the same blend of the same four texels. For a
machine where the sampler road is suspected of a wrong image, a file
vitrail/soft-shadow-compare in the game directory, or -Dvitrail.softShadowCompare=true,puts the arithmetic back in one launch, and removing it again takes a pack reload.
- A patch of this mod that stops fitting the game now refuses to start it, instead of drawing a
moved what they attach to, and what reached the screen was an effect quietly missing or a
surface lit by the wrong program, with nothing in the log pointing at it. The failure now names
itself at launch. The one exception is the line this mod adds to the F3 overlay, which is
allowed to go missing because nothing on screen depends on it.
- A texture's chain of shrunken copies is rebuilt only when its base has changed.** Packs that
that reads one, even when nothing had touched the image in between; two readers in a row now
pay one rebuild instead of two. The copies read are the same ones. Not measured, so this says
work removed and not frames gained.
- Two pieces of per-frame work on the graphics card are gone, and the picture is the same.**
command of its own, which also spares the full stop of the card that such a command carries.
The voxel volumes that follow the camera now copy only the part of themselves that survives
the move, where they used to copy the whole volume. Neither has been measured, so this says
work removed and not frames gained.
- A handful of values handed to shaders are worked out once a frame instead of once for
End's flash, and the two matrices a pack multiplies its vertices by were all rebuilt from
scratch each time a shader asked, which for a large pack is dozens of times a frame out of
numbers that had not moved in between. They are kept and reused until something they are
built from actually changes. The values handed over are the same ones, to the bit, and this
has not been measured either, so again it is work removed rather than frames gained.
- The same picture with less repeated work inside the frame.** A pack's geometry program
drew, where only the two to four that follow the image in hand can change inside one pass;
the rest are now written once, when the pass opens. Beside it: the far terrain's sections are
collected into a list sized from the count Distant Horizons gives rather than grown into one,
and handed on without a copy; a vertex format is searched for this engine's own elements only
until the first one it has not got; and a pass is asked for its name only once everything
cheaper about it has already matched. Whether the frame rate moves is a machine's to measure.
### Fixed
- AstraLex night skies are round again.** A pack that interpolates a 3x3 matrix between
numbers varyings by count, and a matrix occupies several slots. Each matrix is now split into
one vector per column before compile. Complementary never declared one, so it did not show
the oval.
- Turning Distant Horizons on reloads Complementary and then draws it.** The pack used to
outside a block, so the world dropped to vanilla. The machine symbols are now installed
before the pack is opened, so those uniforms enter the block and the reload draws the
pack. The toggle still reloads; it does not keep the pack on without one.
- The button that opens a pack's settings is no longer dead until the pack has been loaded
a fresh install could not be configured at all: the only way in was to load it at whatever
profile its author shipped, which on a small machine is the one launch that hurts. It is now
live for the pack the list has selected, and pressing it reads that pack, which is parsing and
no work on the graphics card, and puts its settings on screen while the loaded pack goes on
drawing. Setting a heavy pack to its low profile before ever loading it now costs one load
instead of two. A pack that lays no settings out says so instead of opening an empty page.
- Breaking a block no longer paints flat black cracks over it.** The overlay that spreads as a
it was landing on an empty layer instead of on the picture, so every crack came out opaque
black from the first stage rather than darkening the face as it broke. It is drawn through the
pack now, on
gbuffers_damagedblock and its fallback onto the terrain, which is what a packexpects to be asked for.
- A pack written with the old shadow lookups could be translated wrong, without a word.**
which could rename one of them or leave a local variable reading a global value instead.
Nothing in the tested packs reached it.
- A pack that changes with how humid a biome is no longer sees a desert everywhere.** The
rainfall value handed to shaders was always nought, so puddles, wetness and fog thatscale with humidity stayed at their driest in a swamp and a jungle alike.
- Changing shaderpack without restarting no longer leaves the buffers of the pack before it
bufferObject blocks were remembered for the wholesession rather than for the pack that wrote them, so a pack loaded after another could have a
block bound to a buffer the earlier one had declared, at whatever size and contents that one
asked for, or keep a program running against a block nothing binds at all. Complementary
Ultra with world-space reflections on is the pack that declares such a block, and quitting
the game between two packs was the only thing that cleared it.
- A shadow compute pass that leaves its size to the engine now covers the screen.** A pack
writes the count out itself was read. A program using any other ran as a single small
tile: it filled a few hundred texels, and everything past them kept whatever the frame
before had left, so the effect showed up in one square at the corner and was stale over
the rest of the picture. Every pack tested here writes the count out, so only packs
outside that set could see it. Two smaller things come with it: a pack asking for no work
at all, which is how one of those forms switches a pass off, now dispatches nothing rather
than one tile, and a program whose size cannot be read at all is left out with a line in
the log naming it, rather than guessed at.
- The log says why a pack is drawing the world with the game's own terrain shader.**
happened: the pack was read and asks for none of the extra vertex data, or its load never
got as far as its chunk programs, or the mesh was built before the pack had been read. All
three used to share one line that named none of them, and the third only showed itself a
world later, as an error about two lists of attributes that said nothing about the order
that made them differ. Each now says which one it was, where it happened.
- The game no longer crashes when AsyncParticles draws its GPU-accelerated particles under a
into the very pass this mod had opened over the pack's colour targets, with pipelines built
for a single target: the frame died on a colour attachment count mismatch a few seconds into
the world. Those draws now take the pack's own particle programs, rebuilt over
AsyncParticles' vertex layout, which is what Iris draws them with as well.
- The link under an empty pack folder opens the CurseForge shader search.** It used to open
### Fixed
- The game no longer crashes when resources reload with a pack loaded.** Moving
and pressing F3 + T all reload every resource, and any of them took a world with a
shaderpack on straight to the crash screen, on "Pipeline is not valid".
The sky is drawn first in the frame and was the piece that fell over, but nothing the pack
draws was safe. The reload now costs what it always should have, a few frames while the
programs compile again.
- A pack swapped while the engine was still warming up could kill the worker that compiles
at the first frame that needed them, which is a stutter where there had been none.
- Mellow draws again.** Since 0.7.5-beta the pack loaded, laid out its settings and then
passes was refused at compile, and a pack one of whose passes does not compile draws
nothing at all. What that pass builds its outline from is a number its own settings fix
before anything is compiled, and the engine was treating it as one that could still
change. Any pack that writes a constant that way was open to the same.
- E-LITE compiles whole.** Twenty of its programs were refused, because one value the
itself. A line that names several values at once is now read to its end, so nothing is
supplied over a name the pack wrote.
- A pack could come up with something wrong smeared across the picture, and stay that way
or noise that is simply there, on a machine where it happens and never on the one next to
it. What was behind it: the images a pack draws into are wiped once when they are built, at
every pack load and again whenever the window changes size, and that wipe was ticked off
the list the moment it was scheduled instead of when it happened. One frame that drew none
of the pack lost it, and the seconds a pack spends compiling are exactly those frames. The
images a pack carries from one frame to the next are never scheduled again after that, so
they kept whatever the graphics driver had left lying in them.
- An FSR Render Scale slider under Video Settings**, on the mod's page beside Max Shadow
finished image is brought back to full size with AMD FidelityFX Super Resolution 1.0 before
the interface is drawn, so menus, chat and the F3 screen stay sharp whatever the scale.
Moving the slider takes effect immediately, the setting outlives whichever pack is chosen,
and at 100 percent, or with shaders off, nothing changes at all.
- A pack's coloured lighting runs.** The storage images, storage buffers and shadow compute
IRIS_FEATURE_CUSTOM_IMAGES is announced, so the voxellighting of Complementary's top profiles, Euphoria Patches' Colored Lighting among them,
draws instead of switching itself off behind a red overlay: lamps and torches colour the
world around them. A pack that requires custom images loads instead of being refused. And
that light holds still as you move: the glow of ores and lava used to flicker at every block
crossed, worst going up, a ring of dark on each jump and a shimmer in upward flight against
nothing at all on the way down, with a placed torch never showing it only because the
ordinary block light covers it over.
- A crash during startup no longer takes the graphics backend with it.** The game resets the
crashed, and nothing of this mod draws off Vulkan, so one crash used to cost a restart to set
it back by hand. A selector under Video Settings picks what to come back to, Vulkan unless
told otherwise.
- A switch that puts the game's own wait back after every render pass.** A pack's passes end on
of memory. That is what makes the frame cheaper, and it is also the kind of thing a driver can
honour by accident: a wrong image on one machine and a right one on another is exactly what a
missing wait looks like. An empty file
vitrail/full-pass-barrier in the instance, or-Dvitrail.fullPassBarrier=true, puts the wide wait back on both roads where one was tradedaway, the close of a pack's pass and the filling of a mip chain. Slower, and it cannot be the
cause of anything, so an image that comes right with it has named the problem.
- The log names the first full frame's GPU stops.** One line per pack load, always on: how many
first. That is the number a Mac trace of queue submits is counting.
- The F3 screen says what the shadow map cost.** Two lines beside the version and the pack:
distance, and what the walk for the light measured against. They are Iris's lines for the same
thing, in the same shape, so a screenshot under one reads against a screenshot under the
other, and nothing has to be switched on for them to appear.
### Changed
- Chloride is no longer required, on either loader.** One thing was behind that requirement:
and the game takes it over instead of making one, so the Vulkan surface was asked for on a
window built for OpenGL. Vitrail now refuses that window itself when the backend is Vulkan,
takes it off FML's hands at the end of mod loading, and closes it once the game has drawn its
first frame. Fabric opens no such window and never needed the help. Chloride remains worth
installing, its settings are still read and reported, and running it alongside changes nothing.
- The odd corners of a pack's properties read the way Iris reads them.** An
alphaTest., a
texture.noise or a dimension.properties line written under a setting's #if now comes andgoes with the setting, a world declared twice keeps the last declaration instead of the first,
a page laid out twice keeps its last line instead of both, and a pack writing
shadow.enabled=false gets what it asked for: nothing is ever drawn from the light. No knownpack is changed by any of this today.
- The settings screen reads a pack's layout the way Iris does.** The
*token now pours out
screen= line getsone page holding everything instead of an empty one; and a name Iris refuses to configure, a
constant off its closed list, a toggle nothing tests or a value without a list of choices,
shows the same blank it shows there instead of becoming a slider or a toggle Iris never had.
- Opening a pack's settings no longer applies it.** Looking at another pack's pages used to
heavy profile in full. The pages now open on the pack that was picked while the loaded one
goes on drawing; Apply is the only thing that costs, and a profile chosen before applying is
the one that lands.
- The shadow walk no longer rotates Sodium's command ring a second time in the same frame.**
next camera walk. Same shadows.
- A pack's frame opens fewer GPU stops.** Clears ride as the first pass's load, leftover
each level, consecutive geometry that writes the same images stays in one pass, ping-pong
targets swap names instead of copying texels back, and our own passes end on a wait naming what
the next one samples and what it writes, rather than on the game's wait for the whole of memory.
Same picture. Written for the extra submits a Mac report was counting; whether the frame rate
moves is still that machine's to measure.
- The frame that rebuilds the pack's programs pays far fewer clears.** A dimension change, a
rebuilt its own copy of the same one-texel constants, one standalone clear per texture: about
ninety full GPU stops on that single frame, felt as the hitch at a portal. The constants are
now built once and shared, and the same frame measures nine.
- Pass uniforms reuse scratch matrices** instead of allocating a model-view-projection and a
still owed one, and the shadow sweep reuses its plane scratch. Same picture, same numbers.
- Improved transparency is turned off while a pack draws**, the same refusal Iris makes. That
writes it is an Immediate draw this engine would otherwise keep as its own GPU stop.
- Leftover Immediate draws and Distant Horizons' GenericObjectRenderer stay in the geometry
never adopted: its viewport and scissor would be whoever opened it.
- Geometry programs compile during the same warm-up as the chain**, before the pack is drawn:
composites and the terrain are in the device cache. From there the leftover families compile
in the background, described under Fixed, and the pulsing mark in the corner carries the
state from the held world to the last word of the closing show.
- The wait for a pack skips the world, not the HUD.** Several programs compile a frame instead
### Fixed
- The freezes on first encounters are gone.** A pack's programs for the entities, the sky, the
drew each of them: around half a second frozen per program on a cold driver cache, over a
hundred programs on a big pack, spread across the first minutes of play and paid again behind
every portal. They are now compiled in the background while you play, several families at
once, and a frame only waits for a program it reached before the background did. While that
work runs, the Vitrail mark pulses in the top-left corner of the screen with "Compiling
shaders..." and the running count beside it, the way the autosave floppy used to blink; when
the work ends, "Shaders compiled!" stands beside the mark for a moment and the corner fades
back to the game. An empty file
vitrail/keep-first-draw-compiles in the instance puts the old path back for a comparison.- A pack's shadow compute is no longer built when the pack switched it off.** A pack turns
was read and handed to the compiler whichever way that setting stood. Switched off, the pack
also takes away the colour tables and the image formats that pass reads, so what reached the
compiler was not a shader at all and it was refused. The refusal came out as a warning, and
there was nothing on screen to say a pass had been meant to run. BSL with its multicoloured
blocklight off, Bliss, and both Complementary outside their coloured lighting profiles were all
in that state.
- A pack's storage images keep the words it wrote around them.** Translation rebuilt those
writeonly, readonly, restrict andcoherent on the way, whichever side of uniform the pack put them. On Vulkan the first ofthose is what makes an image with no declared format legal at all, and it is the one the packs
that ship a voxel volume write.
- Distant Horizons' far water no longer paints over you.** In third person, with far water
followed the part of the far water behind him. Everything drawn between the two halves of the
far terrain was covered the same way: mobs on the ground, particles, and the hand. The far
water is drawn after them and had no idea they were there. It now stands behind whatever the
game drew before it. What a pack reads under
dhDepthTex0 and dhDepthTex1 is still the farterrain and nothing else, with one thing given up: where the near world hides far water
outright, those names answer with the far terrain behind the water rather than with the water,
on a texel where neither is visible.
- Entering a world with Distant Horizons no longer washes the distance out to the sky colour.**
a pack was told how far the far terrain reached in the wrong unit, and the number it got was
sixteen times too small: a dozen blocks or so, rather than the thousands that mod actually
draws. A pack that fogs by that number then fogged out everything past the end of its own nose,
so the whole distance came back as flat sky until the far terrain appeared. Bliss shows it
plainly. The number no longer waits on that first frame.
Two smaller things move with it. Turning that mod's rendering off now gives a pack back the
game's own distance, which is what Iris gives it. And a pack that leaves its shadow planes for
the engine to resolve gets a shadow box sized for whichever terrain is really being drawn. No
pack shipped today asks for that on its default settings.
- Opening a world no longer crashes while leftover families are still being translated.**
ready, which is the same moment the worker is still filling them.
- Keeping consecutive geometry in one pass no longer leaves Sodium's last region scissor on
that copied the top of the screen onto the bottom as chunks streamed.
### Added
- A GPU profile of the frame, per render pass, in the log.** Start the game with
-Dvitrail.passTimings=5among the JVM arguments and every five seconds the log gets a table of where the card's time went, one row per pass label, the game's passes and Sodium's beside the pack's, sorted by cost. Off unless asked for. What a slow pack costs is now a question the log answers instead of a frame counter.
### Fixed
- A pack that declares many textures and samples few of them can compile on Apple Silicon.** Metal only has sixteen sampler slots, numbered by the order the shader first names each texture rather than by how many it actually reads, so a used texture sitting behind unused declarations used to land on slot 17 and the pipeline was refused. The names a program samples are now declared first. A program that samples more than sixteen textures still cannot run there.
- A pack that marks a computed matrix as
constloads instead of falling back to vanilla.** Vulkan will not taketransposeof a literal, or a uniform, as a constant initialiser, and one such pass used to fail the compile and take the whole pack with it. The keyword comes off and the value stays. Seen on Lux v1.2, a BSL derivative.
- Sodium 0.9.2 no longer crashes when a pack extends the chunk mesh.** Its new arena allocator was sized for Sodium's own twenty bytes and refused the wider mesh a pack needs. The allocator now takes the same format the rest of the renderer already asked for. 0.9.1 is unchanged.
- On a backend other than Vulkan, nothing of the pack is drawn any more.** The pack is still
restart, but the game keeps its own image: the passes used to run there and draw a picture that
was credible and wrong. A chat line the first time a world is shown says so and names the setting
to change, Graphics API to "Prefer Vulkan (Experimental)" under Video Settings, beside the error
the log already carried.
### Fixed
- Body Camera's film grain moves again.** The 0.7.3 hash rewrite took the frame time out of
screen. The rewrite now only fires on a constant second argument; BSL's waving is untouched.
- No more dark oval under a mob when the pack draws its own shadows.** The game's flat entity
shading with its shadow map. It now goes away for as long as the pack has a map, which is what
Iris does, and stays under a pack without one. The defect only showed with Entity Shadows on in
the video settings.
- Grass and leaves no longer skip while they sway under BSL.** Packs that hash their waving
taken from the vertex bits instead. Complementary was already smooth; it never wrote that
idiom.
- The hand and the entities no longer stretch into giant triangles after a pack turns on or
was neither: the game's own entity pipelines keep the previous vertex layout until a resource
reload, so anything they drew over the rebuilt mesh, the hand with its switch off, every mob
and hand for the seconds a chain takes to compile, smeared across the screen and stayed that
way for the rest of the session. The engine now takes those pipelines out of the device's cache
the moment the layout moves and compiles them again on the spot; what left the cache is freed
at the next reload, the one safe moment the crash fix established, so the crash stays gone.
- Removing, picking or reloading a shader pack in a running world no longer crashes the game.**
which was two more faults of the same family. A reload freed the pack's images a moment before it
stopped answering for them, so a pass of that very frame could still be handed them; and loading
a pack that draws the entities or the hand emptied the graphics device's whole pipeline cache at
an instant where work already recorded still named what was destroyed. Nothing empties that cache
any more: the game does it itself on every resource reload, which is the one moment it is safe.
What that leaves is cosmetic and brief: after turning a pack on or off in a world, an entity or
the hand drawn by the game's own shader can look wrong for the second or two a pack takes to
finish compiling, and a resource reload clears it. Tried at length on both loaders, turning packs
off and on and switching between four of them, where one to four such gestures used to end the
session.
- Distant Horizons no longer draws its own ambient occlusion and fog while a pack is drawn.**
work was thrown away one pass later, and two of the three ran over the whole screen rather than
leaving it early. Both are on unless the DH menu says otherwise, so an install that changed
nothing was paying for them on every frame. They go back to whatever that menu says the moment a
pack is unloaded.
- Three things taken on every frame are now taken when something reads them.** The search for a
entity that is almost never there; it runs once a tick now, which is the rate the reference
publishes that value at. The count of what the camera saw was taken on every frame for a line
printed once per pack. And the pack's number for an item was spelt out again at every submission,
where the number for a kind of entity had been remembered since it was written.
### Fixed
- Turning the shaders off and back on, or picking another pack, takes the game down far less
was unloaded, while a pass already recorded still held slices of them, and the graphics device was
lost a few seconds later with nothing in the log to say why. They belong to the engine now rather
than to the pack, so a load has nothing to close. It is not the whole of that crash: a second
fault of the same family survives it, and where the pack could not be put back once before, it now
takes somewhere between one and four goes. Issue 111 follows what is left, and until it is closed
a pack changed in game remains a thing that can end the session.
- The same pack now translates to the same text on every start.** Four tables the translator
starts: the varyings a stage is owed, the vertex inputs a mesh has not got, and the volume
helpers a pack's three dimensional textures need. Two launches on the same pack could therefore
produce shaders that differ only in the order of their declarations, which is the same shader to
a reader and a different one to the game, so it compiled pipelines it already had. One warning
line about mesh elements a program computes from and does not get also listed its names in a
different order each run.
- One character no editor should have written no longer costs the player every pack.**
vitrail/options.txt was read as strict UTF-8, so a single byte from another encoding stoppedANY pack from loading, under a message that named neither the file nor the encoding. A byte order
mark, which several editors add on their own, threw nothing and quietly ate the first setting of
the file. Both now cost one character of one value at worst, and
vitrail/pack.txt is read thatway too. That file is also written through a temporary and moved into place, so a crash while it
is being written can no longer leave half a line behind, which read as no pack chosen at all.
- The shadow distance now bounds every chunk it is meant to, and not only the ones weighed one by
everything standing under that group was drawn into the shadow map however far past the distance
it stood. Lowering the distance, from the pack or from the video settings, therefore saved less
than it should have, on the second walk of the world, which is the most expensive thing a frame
does here.
- Distant Horizons' far terrain now casts into the pack's shadow map.** A pack that ships a
dh_shadow program has it drawn, from the light, over the same distant land its dh_terraindraws for the camera, so a far hill lays a shadow on the ground instead of only shading itself
out of its own depth. Packs that write
dhShadow.enabled=false are taken at their word, which ismost of them; the one pack tried here that ships the program keeps it behind a setting of its own
and it has to be switched on. It also follows the two words that govern the near world in the map,
so a pack that keeps the world out of its own shadow map keeps the distant land out with it. What the map holds is the distant land the camera can see, which is
narrower than under Iris: that mod gets a second list of it, built for the light, and there is no
second list to be had here.
### Changed
- Two things taken on every frame are no longer taken for a pack that cannot read them.** The
shadowtex1 is sixty-four mebibytes a frame at a shadow mapof 4096, and the depth kept from before the hand is a full screen image and a draw on every frame
the hand is drawn. Each is now skipped where no file of the pack writes the name that reads it,
which the log says out loud when it happens. Of the eight packs tried here, one skips the shadow
copy and five skip the depth.
- The debug screen names the engine, the pack and its profile**, where Iris has always put those
how" arrives, and until now a Vitrail frame and an Iris frame of the same pack read as the same
picture. A pack that is not being drawn says which of the three reasons it is rather than reading
as none at all: shaders switched off, a pack named that is not in the folder, or a pack the
engine refused, the last of which sends you to the log rather than to the settings screen.
### Changed
- One download for both loaders.** The release now carries a single jar,
vitrail-<version>+mc<minecraft>, that runs on NeoForge and on Fabric alike; each loader readsits own metadata out of it and ignores the rest. It is the same engine the two per-loader jars
carried, in one file, and the per-loader downloads stop being published. Nothing changes in
game, and nothing changes about what has to sit next to it: Sodium, Chloride, and on Fabric the
Fabric API. Upgrading means replacing: delete the old
vitrail-neoforge-* or vitrail-fabric-*jar when this one goes in, because the two carry the same mod and a loader that finds it twice
refuses to start.
### Fixed
- Complementary no longer falls back to its oldest code paths.** The engine told packs it was
it the old way" branch in Complementary Reimagined and Unbound was live. The engine now
announces the Iris release it behaves like, so those branches pick the modern side: rain and
thunder fade over the pack's own timer instead of a hardcoded three seconds, the sun and moon
stop leaning on a workaround for a renderer bug this engine never had, and reflections drop a
workaround for a texture bug fixed before the release this engine mirrors.
- On Fabric, the game no longer throws away every selected resource pack at boot when a slow
the boot's resource reload finished inside that pause the game stitched its atlases before it
had a frame's uniforms to do it with: "Missing uniform Globals", and every resource pack was
deselected. Seen with Distant Horizons installed, whose extra programs made the pack read long
enough to lose the race. The pack is now read once the boot reload is over, which is where
NeoForge always effectively had it.
- Bliss no longer stands its swamp fog over any shoreline.** Biomes were numbered by walking the
Iris hands out, which are the game's own declaration order. Six is swamp there and cold ocean
here, so the green followed you along every coast. The numbering is now taken where Iris takes
it, and a biome the game's own list never declares answers nought, as it does under Iris.
- Distant Horizons terrain stops washing out flat under packs that read the light raw.** The far
(i + 0.5) / 16 and answers the fixed function light matrices with the identity, so a pack reading
that light through the matrix or raw gets the same number either way. BSL and Complementary
multiply the matrix in and were never affected. Bliss reads the pair raw, and from sky level one
upward its light map saturated and its far terrain went flat.
- Under Bliss, the game's sky no longer paints over the far terrain.** The engine fills the
the world's depth holds nothing where an LOD stands, the game never rasterising the far terrain
itself: those pixels read as unanswered and were covered over the colour the Distant Horizons
programs had just written. Only Bliss showed it, its sky pass being the one the translation
cannot hand a coverage mask to, every other pack's sky claiming those pixels itself. The far
terrain's own depth is read now.
- The line printed when the game came up on OpenGL no longer says the pack draws nothing.** The
programs are translated against Vulkan's depth and clip conventions, so a sky cut in two or a
misdrawn hand there is the backend and not the pack. The line owns that now, which is the point
of it, a report filed against the pack being the one thing it exists to prevent.
- A Max Shadow Distance slider in the video settings, under Vitrail.** Pulling it in is the
every frame, and this decides how much of it. It goes from 32 chunks down to none at all. At none
the shadow pass does not run: the shadow depth every pack reads is emptied to its far plane, so
nothing casts a shadow, and the only thing left standing is a
shadowcolor buffer the pack askedto keep between frames, which holds the last one drawn until the setting moves again.
- A pack that fixes its own shadow render distance now gets it.**
shadowDistanceRenderMulwas
asked. Seven of the eight packs tested declare that line, and the shadow walk now stops where they
meant it to: Mellow and Body Camera at 96 blocks, Complementary and Reverie at 192, BSL at 256.
How many of them that changes anything for depends on your render distance, since a shadow walk
asking for more than the world you have loaded is left alone: at 12 chunks it bites on the shorter
three and not on the rest. Those packs decide the distance, so the slider greys out and says so;
it is the packs that stay silent, Sildur's among them, where it is the player's to move.
### Changed
- The shadow map stops being drawn from parts of the world that cannot cast into what you are
you included, which is a second copy of the world drawn every frame for shadows nothing ever
samples. It now walks the camera's own view swept along the sun instead: what stands between the
sun and what you can see is kept, what could only ever shade your back is dropped. Expect more
frames per second wherever shadows are on, and no change to the picture.
The shape is the pack's to choose through
shadow.culling, which is read now where it used to beignored, together with the
voxelDistance distance behind one of its states. A pack asking for abox about the camera instead of that sweep, or for no view frustum at all, gets what it asked for.
The log line the shadow stage prints on the first frame of a pack now names the shape as well as
the two counts, so the gain can be read off it.
### Fixed
- The texture filtering selector in the video settings no longer offers RGSS while a pack draws the
those two draws once the pack's own terrain program does, so the setting read as live and moved
nothing at all. It comes back the moment no pack is drawing the terrain. Anisotropic filtering is
untouched and goes on working under a pack.
- Naming a pack that is not in the Shader Packs folder now says so, in the chat line the reload key
read as if no pack had been asked for at all, so a renamed or deleted pack looked like a choice.
- A Max Shadow Distance slider in the video settings, under Vitrail.** Pulling it in is the
every frame, and this decides how much of it. It goes from 32 chunks down to none at all. At none
the shadow pass does not run: the shadow depth every pack reads is emptied to its far plane, so
nothing casts a shadow, and the only thing left standing is a
shadowcolor buffer the pack askedto keep between frames, which holds the last one drawn until the setting moves again.
- A pack that fixes its own shadow render distance now gets it.**
shadowDistanceRenderMulwas
asked. Seven of the eight packs tested declare that line, and the shadow walk now stops where they
meant it to: Mellow and Body Camera at 96 blocks, Complementary and Reverie at 192, BSL at 256.
How many of them that changes anything for depends on your render distance, since a shadow walk
asking for more than the world you have loaded is left alone: at 12 chunks it bites on the shorter
three and not on the rest. Those packs decide the distance, so the slider greys out and says so;
it is the packs that stay silent, Sildur's among them, where it is the player's to move.
### Changed
- The shadow map stops being drawn from parts of the world that cannot cast into what you are
you included, which is a second copy of the world drawn every frame for shadows nothing ever
samples. It now walks the camera's own view swept along the sun instead: what stands between the
sun and what you can see is kept, what could only ever shade your back is dropped. Expect more
frames per second wherever shadows are on, and no change to the picture.
The shape is the pack's to choose through
shadow.culling, which is read now where it used to beignored, together with the
voxelDistance distance behind one of its states. A pack asking for abox about the camera instead of that sweep, or for no view frustum at all, gets what it asked for.
The log line the shadow stage prints on the first frame of a pack now names the shape as well as
the two counts, so the gain can be read off it.
### Fixed
- The texture filtering selector in the video settings no longer offers RGSS while a pack draws the
those two draws once the pack's own terrain program does, so the setting read as live and moved
nothing at all. It comes back the moment no pack is drawing the terrain. Anisotropic filtering is
untouched and goes on working under a pack.
- Naming a pack that is not in the Shader Packs folder now says so, in the chat line the reload key
read as if no pack had been asked for at all, so a renamed or deleted pack looked like a choice.
- The far terrain of Distant Horizons is drawn by the shader pack itself, lit and fogged like
colour back onto the picture, so no pack ever saw it: no fog on it, a depth of field focused past
it, water that did not know it was behind it. Its geometry is now handed to the pack's own
dh_terrain and dh_water programs, drawn into the pack's own targets, and its depth is servedbeside the world's under the names packs read it by, which is the arrangement they are written
against. The fog, the shadows and the occlusion on the distant land are the pack's own from
there, and the seam where it meets the near terrain closes.
Two limits worth knowing. A pack that ships no
dh_terrain keeps Distant Horizons' own drawing,which no pack effect touches. And the far terrain does not enter the pack's shadow map yet, so
what shades it is what the pack computes from its depth rather than a shadow the map carries.
What this waits on is Distant Horizons and not Vitrail: that mod has to draw on this backend at
all, which the version named in
INSTALL.md does not, and it has to be one whose insides thisengine can read, which the log says when it is not, naming that mod as installed but not in a
shape its far terrain can be served from. The log names Distant Horizons as found when it is,
and names each far terrain pass as the pack's programs take it over.
- A mob and a piece of armour take the relief their resource pack draws for them.** A skin and an
resource pack ships beside them were never read at all and both names came back flat: every mob
stayed matte while the terrain around it had relief. They are now read from whichever texture the
draw is really using, the same way the atlases already were, and the log names each texture that
answers as the skin first comes on screen. A skin downloaded from the skin server rather than
shipped by the resource pack has no maps beside it and is left alone.
- A normal map on a mob, on armour or on a chest is read the right way round.** The two values a
texture runs in over it, were the same constant for every face of every piece: a pack lighting a
mob through them tilted every bump on it the same way, whichever way the face was really turned.
Both are now worked out over each polygon and carried on its corners, on the mobs, on the block
entities, on a held item and on the hand alike. Of the hundred and fifty entity programs the eight
packs tested ship between them, seventy-five read the sprite middle and sixty-one read the
direction. What it changes on screen depends on the resource pack as well: a mob with no normal
map beside its skin has nothing to tilt, and finding that map is the entry above.
- A mob flashes again when it is hurt, and a creeper whitens before it goes off.** The colour the
so a pack that paints the flash itself painted nothing: the red hit, the white of a creeper about
to explode and the tint on a mob standing in fire all went missing the moment the pack took the
mobs over. It is now read off the mesh, one value per vertex, which is where every one of the eight
packs tested expects to find it.
- A pack can tell one kind of mob from another again, and a chest from the block it stands in.**
reaching it as one value for the whole world, because they were handed over per draw and a draw
carries a whole batch of pieces at once. They now ride on the geometry itself, one value per
vertex, out of the pack's own
entity.properties, block.properties and item.properties. Whatit changes on screen is whatever the pack wrote on those numbers: the subsurface scattering some
packs give to living things alone, the treatment of an end crystal and of its beam. Seven of the
eight packs tested read at least one of the three, one of them only in the shadow map; the eighth
declares one and never reads it. The lightning bolt is not among them and stays as it was: the game
draws it with a mesh this engine does not read.
The entity mesh only carries the three while the pack is drawing the entities or the hand, so
turning either switch now rebuilds the world, exactly as the terrain switch already did. It does
not ask for a restart.
- The sky of the End is painted by the pack now**, where the game kept its own shader for it. The
textured pieces of the sky, the one that already drew the sun and the moon. Until now that sky was
the last piece the game still drew itself: a pack's own sky program never ran in the End, and only
its post-processing reached what you saw there. The Nether is the one place left with none of the
pack's sky in it, and there the game opens no sky pass at all.
- Glowing eyes are painted by the pack now**, where the game kept its own shader for them: the eyes
a warden, which the game draws the same way. They go through the program the format keeps for eyes
alone, and they are added onto the mob's skin rather than laid over it, which is what makes an eye
read as a light rather than as a sticker. They are also drawn at full brightness whatever the mob
is standing in, as the game draws them: handed the light of the spot instead, a pack that shades by
that light would have put out the eyes of anything standing in the dark, which is where they matter
most. Six of the eight packs tested ask for that light in the program that serves their eyes, and
one of them looks the game's light map up with it, which is where it shows on screen. They reach
the pack's shadow map as well, where every draw of them used to be dropped, on the light of the
spot rather than at that full brightness. What that puts into the map is colour and not depth, so
an eye lays no shadow of its own; what it changes is what a pack reading the map's colour finds
there.
- The wind a breeze throws and the swirl over a charged creeper are painted by the pack now**,
game's own that scrolls them, and that matrix is answered out of the game's transforms now, so a
breeze scrolls rather than sitting frozen on one frame of its offset and two breezes on screen
keep their own. The swirl writes every image the pack declares for its entities: on five of the
eight packs tested that is between two and four images rather than the single one it would
otherwise have reached.
### Changed
- A chunk vertex only carries what the pack loaded actually reads.** Every vertex of every section
normal, the tangent and a second copy of the colour, whichever of those the pack asked for: forty
four bytes each, whether four of them were read or none. The pack's own chunk programs are now read
first and the mesh is built from what they name, so a vertex costs between twenty four and forty
bytes. Of the eight packs tested, one drops sixteen bytes a vertex, one twelve, one eight and the
other five four. It is video memory and the bandwidth of every chunk draw, so it is paid twice a
frame as soon as a shadow map is being filled. Switching between two packs that read different
names rebuilds the world, as switching the terrain off already did.
- The normal and the tangent of a chunk vertex travel in one word instead of two.** The tangent is
angle and the direction the frame turns in, which is how the engine the packs are written against
has always stored the pair. That is the last four bytes of the paragraph above, on every pack that
lights the terrain by a normal, and it is where the upper bound of forty comes from. A pack reads
the same two directions as before: the normal comes back four times closer than it did, and the
tangent, which every normal map on the terrain is read through, is now exactly perpendicular to it
rather than a few thousandths off, at the price of being up to nine tenths of a degree round the
face from where it was.
- The settings screen is the one pack authors already know.** It is the screen of the engine packs
toggle at its head, the same pages of settings with the value of each in a sunken box beside its
name, the same Cancel, Apply and Done, the same buttons and panels drawn from the same texture. A
right click walks a value backwards, shift and a click give back the value the pack ships, a slider
is dragged and only writes when it is let go, and a setting waiting to be applied is marked in
amber. Hovering a setting brings up the pack's own words about it in a panel at the bottom.
- The settings screen is reached from the video settings now**, under Vitrail in the list of pages
it. Both of those menus lead to the video settings already, so it is the same number of clicks from
either and it is where anything about how the world is drawn is looked for. The
I key and theConfig button of the mod list still open the screen as before.
- Closing the screen applies what you changed**, where it used to leave without writing. Cancel is
- A pack is dropped straight onto the screen**, and a settings file exported and imported through
eight can be looked through without paying for eight loads; Apply and Done are what make a
selection real.
- The eye at the bottom right, and F1, take the screen away** so that the world behind it can be
- The button that reads a pack again is a small circular arrow** at the bottom left of the screen,
word on the button row shown everywhere. Editing a pack's shaders by hand and pressing it is still
the way to see the change without restarting.
Rreads the pack again without opening anything**, which is the key the engine packs are written
it. The game feeds no key while a screen is open, so from inside the settings screen the button is
what reaches it. It says in the chat which of the two happened, and a reading that failed says why,
in red.
- The blur behind the settings screen fades out with the screen** instead of hanging at full width
wide the blur is does not come from the screen in this game, only whether there is one, so the
fade was fading nothing.
- What this engine has to say and the reference has not, a load that failed, how many settings
vitrail/options.txt is holding down and how many passes this backend could not build, is on oneline at the bottom left.
### Fixed
- Mellow draws instead of showing you the game's own picture.** A pass may read a value that the
refusal cost the pass, and a pack cannot lose a pass without losing the whole picture, so what you
saw was the game with no shader on it at all. The value is now handed over rather than the pass
being thrown away. Mellow is the pack it cost, on one of its lighting passes, and it draws now.
- A pass reading its neighbour's value, which showed as a shader that simply looks wrong.** The
next one never asks for used to push everything sent after it one place along, so the pass read
the wrong value under the right name. Nothing was refused and nothing was logged, which is what
made it hard to see. Sixteen passes across Bliss and Mellow were reading at least one value that
way: the enchantment shine under Mellow, and under Bliss the block-breaking crack along with the
post-processing steps that carry the sun's direction and the exposure, in every dimension.
- The far terrain of Distant Horizons is drawn by the shader pack itself, lit and fogged like
colour back onto the picture, so no pack ever saw it: no fog on it, a depth of field focused past
it, water that did not know it was behind it. Its geometry is now handed to the pack's own
dh_terrain and dh_water programs, drawn into the pack's own targets, and its depth is servedbeside the world's under the names packs read it by, which is the arrangement they are written
against. The fog, the shadows and the occlusion on the distant land are the pack's own from
there, and the seam where it meets the near terrain closes.
Two limits worth knowing. A pack that ships no
dh_terrain keeps Distant Horizons' own drawing,which no pack effect touches. And the far terrain does not enter the pack's shadow map yet, so
what shades it is what the pack computes from its depth rather than a shadow the map carries.
What this waits on is Distant Horizons and not Vitrail: that mod has to draw on this backend at
all, which the version named in
INSTALL.md does not, and it has to be one whose insides thisengine can read, which the log says when it is not, naming that mod as installed but not in a
shape its far terrain can be served from. The log names Distant Horizons as found when it is,
and names each far terrain pass as the pack's programs take it over.
- A mob and a piece of armour take the relief their resource pack draws for them.** A skin and an
resource pack ships beside them were never read at all and both names came back flat: every mob
stayed matte while the terrain around it had relief. They are now read from whichever texture the
draw is really using, the same way the atlases already were, and the log names each texture that
answers as the skin first comes on screen. A skin downloaded from the skin server rather than
shipped by the resource pack has no maps beside it and is left alone.
- A normal map on a mob, on armour or on a chest is read the right way round.** The two values a
texture runs in over it, were the same constant for every face of every piece: a pack lighting a
mob through them tilted every bump on it the same way, whichever way the face was really turned.
Both are now worked out over each polygon and carried on its corners, on the mobs, on the block
entities, on a held item and on the hand alike. Of the hundred and fifty entity programs the eight
packs tested ship between them, seventy-five read the sprite middle and sixty-one read the
direction. What it changes on screen depends on the resource pack as well: a mob with no normal
map beside its skin has nothing to tilt, and finding that map is the entry above.
- A mob flashes again when it is hurt, and a creeper whitens before it goes off.** The colour the
so a pack that paints the flash itself painted nothing: the red hit, the white of a creeper about
to explode and the tint on a mob standing in fire all went missing the moment the pack took the
mobs over. It is now read off the mesh, one value per vertex, which is where every one of the eight
packs tested expects to find it.
- A pack can tell one kind of mob from another again, and a chest from the block it stands in.**
reaching it as one value for the whole world, because they were handed over per draw and a draw
carries a whole batch of pieces at once. They now ride on the geometry itself, one value per
vertex, out of the pack's own
entity.properties, block.properties and item.properties. Whatit changes on screen is whatever the pack wrote on those numbers: the subsurface scattering some
packs give to living things alone, the treatment of an end crystal and of its beam. Seven of the
eight packs tested read at least one of the three, one of them only in the shadow map; the eighth
declares one and never reads it. The lightning bolt is not among them and stays as it was: the game
draws it with a mesh this engine does not read.
The entity mesh only carries the three while the pack is drawing the entities or the hand, so
turning either switch now rebuilds the world, exactly as the terrain switch already did. It does
not ask for a restart.
- The sky of the End is painted by the pack now**, where the game kept its own shader for it. The
textured pieces of the sky, the one that already drew the sun and the moon. Until now that sky was
the last piece the game still drew itself: a pack's own sky program never ran in the End, and only
its post-processing reached what you saw there. The Nether is the one place left with none of the
pack's sky in it, and there the game opens no sky pass at all.
- Glowing eyes are painted by the pack now**, where the game kept its own shader for them: the eyes
a warden, which the game draws the same way. They go through the program the format keeps for eyes
alone, and they are added onto the mob's skin rather than laid over it, which is what makes an eye
read as a light rather than as a sticker. They are also drawn at full brightness whatever the mob
is standing in, as the game draws them: handed the light of the spot instead, a pack that shades by
that light would have put out the eyes of anything standing in the dark, which is where they matter
most. Six of the eight packs tested ask for that light in the program that serves their eyes, and
one of them looks the game's light map up with it, which is where it shows on screen. They reach
the pack's shadow map as well, where every draw of them used to be dropped, on the light of the
spot rather than at that full brightness. What that puts into the map is colour and not depth, so
an eye lays no shadow of its own; what it changes is what a pack reading the map's colour finds
there.
- The wind a breeze throws and the swirl over a charged creeper are painted by the pack now**,
game's own that scrolls them, and that matrix is answered out of the game's transforms now, so a
breeze scrolls rather than sitting frozen on one frame of its offset and two breezes on screen
keep their own. The swirl writes every image the pack declares for its entities: on five of the
eight packs tested that is between two and four images rather than the single one it would
otherwise have reached.
### Changed
- A chunk vertex only carries what the pack loaded actually reads.** Every vertex of every section
normal, the tangent and a second copy of the colour, whichever of those the pack asked for: forty
four bytes each, whether four of them were read or none. The pack's own chunk programs are now read
first and the mesh is built from what they name, so a vertex costs between twenty four and forty
bytes. Of the eight packs tested, one drops sixteen bytes a vertex, one twelve, one eight and the
other five four. It is video memory and the bandwidth of every chunk draw, so it is paid twice a
frame as soon as a shadow map is being filled. Switching between two packs that read different
names rebuilds the world, as switching the terrain off already did.
- The normal and the tangent of a chunk vertex travel in one word instead of two.** The tangent is
angle and the direction the frame turns in, which is how the engine the packs are written against
has always stored the pair. That is the last four bytes of the paragraph above, on every pack that
lights the terrain by a normal, and it is where the upper bound of forty comes from. A pack reads
the same two directions as before: the normal comes back four times closer than it did, and the
tangent, which every normal map on the terrain is read through, is now exactly perpendicular to it
rather than a few thousandths off, at the price of being up to nine tenths of a degree round the
face from where it was.
- The settings screen is the one pack authors already know.** It is the screen of the engine packs
toggle at its head, the same pages of settings with the value of each in a sunken box beside its
name, the same Cancel, Apply and Done, the same buttons and panels drawn from the same texture. A
right click walks a value backwards, shift and a click give back the value the pack ships, a slider
is dragged and only writes when it is let go, and a setting waiting to be applied is marked in
amber. Hovering a setting brings up the pack's own words about it in a panel at the bottom.
- The settings screen is reached from the video settings now**, under Vitrail in the list of pages
it. Both of those menus lead to the video settings already, so it is the same number of clicks from
either and it is where anything about how the world is drawn is looked for. The
I key and theConfig button of the mod list still open the screen as before.
- Closing the screen applies what you changed**, where it used to leave without writing. Cancel is
- A pack is dropped straight onto the screen**, and a settings file exported and imported through
eight can be looked through without paying for eight loads; Apply and Done are what make a
selection real.
- The eye at the bottom right, and F1, take the screen away** so that the world behind it can be
- The button that reads a pack again is a small circular arrow** at the bottom left of the screen,
word on the button row shown everywhere. Editing a pack's shaders by hand and pressing it is still
the way to see the change without restarting.
Rreads the pack again without opening anything**, which is the key the engine packs are written
it. The game feeds no key while a screen is open, so from inside the settings screen the button is
what reaches it. It says in the chat which of the two happened, and a reading that failed says why,
in red.
- The blur behind the settings screen fades out with the screen** instead of hanging at full width
wide the blur is does not come from the screen in this game, only whether there is one, so the
fade was fading nothing.
- What this engine has to say and the reference has not, a load that failed, how many settings
vitrail/options.txt is holding down and how many passes this backend could not build, is on oneline at the bottom left.
### Fixed
- Mellow draws instead of showing you the game's own picture.** A pass may read a value that the
refusal cost the pass, and a pack cannot lose a pass without losing the whole picture, so what you
saw was the game with no shader on it at all. The value is now handed over rather than the pass
being thrown away. Mellow is the pack it cost, on one of its lighting passes, and it draws now.
- A pass reading its neighbour's value, which showed as a shader that simply looks wrong.** The
next one never asks for used to push everything sent after it one place along, so the pass read
the wrong value under the right name. Nothing was refused and nothing was logged, which is what
made it hard to see. Sixteen passes across Bliss and Mellow were reading at least one value that
way: the enchantment shine under Mellow, and under Bliss the block-breaking crack along with the
post-processing steps that carry the sun's direction and the exposure, in every dimension.
- Mobs, block entities, the enchantment shine and the player's hand are now painted into the
channel. Packs that pack two values into each channel of a wider image were reading one back in
place of the other: under Bliss an enderman came out lit instead of black.
- The line each program prints at its first draw now names the image it really samples where the
that agrees with it.
### Fixed
- The enchantment shine is no longer dropped by packs that draw it into an image of their own. It
travels through the game.
- Picking None while a pack is drawing no longer leaves the terrain in stretched coloured spikes
vertex the pack needs, over a mesh that had already gone back to the narrower one.
- Your hand no longer turns and stretches along with the screen inside a nether portal or under
screen distortion as the hand's walk bob, and it is the hand's clip position a pack writes
through that. Walking and being hit were already right.
- Mobs, block entities, the enchantment shine and the player's hand are now painted into the
channel. Packs that pack two values into each channel of a wider image were reading one back in
place of the other: under Bliss an enderman came out lit instead of black.
- The line each program prints at its first draw now names the image it really samples where the
that agrees with it.
### Fixed
- The enchantment shine is no longer dropped by packs that draw it into an image of their own. It
travels through the game.
- Picking None while a pack is drawing no longer leaves the terrain in stretched coloured spikes
vertex the pack needs, over a mesh that had already gone back to the narrower one.
- Your hand no longer turns and stretches along with the screen inside a nether portal or under
screen distortion as the hand's walk bob, and it is the hand's clip position a pack writes
through that. Walking and being hit were already right.
- Fabric.** One jar per loader, carrying the same engine. Everything that draws is shared; what
that event is posted from. Fabric API is used for the settings screen and for nothing else.
- The stores now receive both jars, each filed under its own loader, with its own dependencies.
- The mod is on Modrinth beside CurseForge.
### Changed
- The loader-independent half of the mod, which is most of it, moved into a module of its own. No
name once the packages are renamed.
- The ordered work of each stage of the frame is written once, where both loaders call into it,
copies of it would drift.
### Fixed
- An enchanted item held in the hand is drawn by the pack's own program instead of the game's.
- A translucent block held in the hand is served by the water pass, as it is in the reference.
- The view matrix a draw was prepared with is read where the game prepared it, rather than
- Fabric.** One jar per loader, carrying the same engine. Everything that draws is shared; what
that event is posted from. Fabric API is used for the settings screen and for nothing else.
- The stores now receive both jars, each filed under its own loader, with its own dependencies.
- The mod is on Modrinth beside CurseForge.
### Changed
- The loader-independent half of the mod, which is most of it, moved into a module of its own. No
name once the packages are renamed.
- The ordered work of each stage of the frame is written once, where both loaders call into it,
copies of it would drift.
### Fixed
- An enchanted item held in the hand is drawn by the pack's own program instead of the game's.
- A translucent block held in the hand is served by the water pass, as it is in the reference.
- The view matrix a draw was prepared with is read where the game prepared it, rather than