
Modern UI
Modern desktop graphics application framework and low-level 3D graphics engine
Обновлён 14 июня 2026 г. · опубликован 11 августа 2023 г.

Modern UI by Icyllis Milica
Description:
Modern UI (by Icyllis Milica) is a desktop application framework designed for standalone 2D and 3D rendering software development. It makes use of modern 3D graphical APIs and technologies to provide real-time rendering with high performance. For good measure, Modern UI improves and optimizes a set of features used by Google Android and its own set of internationalization supporting text engine.
Modern UI for Minecraft, is a Minecraft Mod that is based on Modern UI Core Framework and Modern UI Core Extensions. It provides Modern UI bootstrap program in Minecraft environment and Modding API based on Forge/Fabric, to make powerful Graphical User Interface in Minecraft.
For client, press Ctrl+K or ⌘+K (by default) to open Action Center screen to configure Modern UI. (Note that you can swipe the Preferences screen to configure fonts)
This Mod also includes a powerful text layout engine and text rendering system designed for Minecraft. This engine provides appropriate methods for processing Unicode text and gives you more readable text in any scale, in 2D/3D. In details:
- Real-time preview and reload TrueType/OpenType fonts
- A better font fallback implementation
- Anti-aliasing text and FreeType font hinting
- Use improved SDF text rendering in 2D/3D (also use batch rendering)
- Compute exact font size in device space for native glyph rendering
- Use Google Noto Color Emoji and support all the Unicode 15.1 Emoji (September 12, 2023)
- Configurable bidirectional text heuristic algorithm
- Configurable text shadow and raw font size
- Unicode line breaking and CSS line-break & word-break
- Fast, exact and asynchronous Unicode text layout computation
- Faster and more memory efficient rectangle packing algorithm for glyphs
- Use real grayscale texture (1 byte-per-pixel, whereas Minecraft is 4 bpp)
- Compatible with OptiFine, Sodium (Rubidium), Iris (Oculus) and many mods
- Compatible with Minecraft's JSON font definition (bitmap fonts, TTF fonts)
Additionally, this Mod provides many utilities which improve game performance and gaming experience. Currently, we have:
- Changing screen background color
- Gaussian blur to screen backdrop image
- Fade-in animation to screen background
- More window modes: Fullscreen (borderless), Maximized (borderless)
- Framerate limit and master volume fading on window inactive (out of focus) and minimized
- Pausing single-player game when Inventory is open
- Changing GUI scale option to Slider and providing hint text
- Playing a "Ding" sound when Minecraft loads and reaches the Main Menu
- Enabling smooth scrolling in Vanilla's Selection List and Forge's Scroll Panel
- Pressing "C" to Zoom that is the same as OptiFine
- Undo/Redo (Ctrl+Z/Ctrl+Y) and Unicode grapheme/word iterator for all text fields
- Playing local music, allowing to seek and view spectrum
- Support Discord/Slack/GitHub/IamCal/JoyPixels emoji shortcodes in Chatting
- A fancy tooltip style
- Choose rounded border or normal border (with shadow effect)
- Add title break and control title line spacing
- Auto line wrapping and auto vertical scrolling when out of screen
- Center the title line, support RTL layout direction
- Exactly position the tooltip to pixel grid (smooth movement)
- Change background color and border color (with gradient and animation)
Core Features:
- 2D Graphics Library of Multiple Graphics APIs
- Intermediate Representation and ASTs of Shading Languages
- Symbolic distance function and vector graphics rendering
- Image post-processing effects
- Fast matrix and vector calculation
- Image format conversion
- Animation and transition framework
- Event loop and multi-threading framework
- Text shaping and complex text layout engine
- MVVM and lifecycle handling
- Automatic RTL (right-to-left) UI layout
- Markdown (CommonMark) rendering support
Modern Text Engine for Minecraft:
- Support color Emoji, use Google Noto Color Emoji 15.1, based on Unicode 15.1 Emoji list;
- Support Emoji shortcodes in chat, for example :rofl: to rolling on the floor laughing, support Discord and Slack shortcodes;
- You can use TTF or OTF fonts, configure the font base size, set the baseline shift, and set whether to drop text shadow;
- Scalable vector graphics, automatic switching resolution level (up to 96px), native (non-synthetic) Bold and Italic rendering;
- Supports distance field text rendering in 3D world, but sharpens font atlas in 2D GUI; This enhances a former feature: *Render all characters smoothly on any scale (like when you're away from a sign, or a very small text in GUI)
- Support multilayer text, layout multiple paragraphs together, streaming layout algorithm, and introduce fast layout cache;
- Support fast digit replacement, high-precision layout and alignment, and smoothly draw fast changing digits (fixed width);
- Support mip-mapping, anti-aliasing, linear sampling and supersampling anti-aliasing (SSAA);
- Better and more efficient layout of BiDi text paragraphs (e.g. Arabic, Yiddish); Use sharpen font atlases;
- Configurable BiDi text heuristic algorithm to control text direction more accurately; Support to fix invalid surrogate pairs;
- Use HarfBuzz text shaping, support combining characters rendering, like Thai, Devanagari, Bengali and Tamil;
- Support grapheme cluster break, support Unicode line breaking algorithm;
- Support context-aware and locale-based word break and line break;
- Support pixelated font rendering, support fixed resolution level, support pixel alignment;
- Support bitmap replacement, rendering smoothly for fast changing numbers, support emoji rendering;
- Optimize the layout algorithm, increase your FPS by about 10% when drawing texts in GUI
- Use grayscale pixels to store texture, reduce GPU memory usage
- Reduce unnecessary RAM usage and greatly reduce object creation
Customize Fonts
Press Ctrl+K or ⌘+K (by default) to open Action Center, go to Preferences, swipe the screen to the second page, and you will see Font settings.
- Preferred font family is your most wanted one. It can be either an OS font or a TrueType/OpenType font (collection) file.
- Fallback font families are used when the preferred font family is unavailable.
Modern Text Engine:
Modern UI follows Minecraft's JSON font definition, only glyph provider type 'legacy_unicode' and 'unihex' are ignored. Modern UI font families mentioned above will serve as fallback font families for Minecraft fonts. Default Font Behavior (in Preferences > Text Layout) gives you an option to remove some glyph providers from the Minecraft default font (minecraft:default). To avoid using vanilla ASCII fonts, just set it to Keep Other. Note this option is only valid if you have not turned on Force Unicode Font. If you want to use vanilla Unicode font, just download the OTF version of GNU Unifont.
Additional Features for Minecraft:
- Support setting window mode, such as fullscreen borderless, windowed borderless;
- GUI screen background fade-in animation and 2-pass gaussian convolution blur effect, configurable background gradient color;
- Smooth rounded tooltip style, support RTL layout, configurable background and border color;
- Play a "ding" sound effect when the game is loaded;
- Support pausing the game when your inventory is opened;
- New GUI scale algorithm and slider GUI scale widget (not limited to even numbers, compatible with OptiFine);
- Add smooth scrolling for vanilla and forge scrolling panels;
- Async network handler; Server auto-shutdown;
- All features are configurable in configs or Action Center screen (default shortkey Ctrl+K)
Modern UI for Fabric removed some features (compared to the Forge version):
- OptiFine-like zoom, hide crosshairs in GUI
- Dump more debugging information, crash report extension
Comparison with Caxton text rendering techniques
Caxton mod is known for its MSDF text rendering, you can choose between Caxton and Modern Text Engine.
Similarities:
- Both use HarfBuzz text shaping
- Both support Unicode text processing
- Both support Unicode line breaking and grapheme cluster break
- Both compatible with Iris in raster rendering mode
- Both have an efficient rectangle packing algorithm, further better than Mojang's
Differences:
- Caxton uses a newer HarfBuzz whereas we use a older one (bundled with JDK 17, it's updated in JDK 21)
- Caxton uses multi-channel SDF and renders sharper scaling-up texts, whereas we render over-rounded
- We are compatible with OptiFine, whereas Caxton isn't
- We support color emoji, whereas Caxton doesn't
- We support FreeType font hinting whereas Caxton never support it, font hinting helps on low-res monitor
- We support perfect sampling of native glyph image in screen-space, this is ideal for 2D rendering
- We support single-channel SDF text rendering without additional GPU resources, we always use 1bpp textures
- We have smart SDF sampling method for scaling-down texts, whereas Caxton hasn't
- No need to wait for MSDF texture generation, you can switch fonts in-game with just one click
- We support various text direction heuristics and line break strategies
- We don't use additional native libraries, so Modern UI works on macOS
- We have a slightly higher layout performance than Caxton, and use less RAM
Mod Integration & Compatibility:
Compatible (you should pay attention to):
OptiFine, Sodium, Iris, Create, AoA3
If Shaders are active, Use Modern Text Shaders in 3D is auto disabled, it will cause the outline of glowing text to become invisible.
Mods with similar functions are replaced:
- Blur (ver 1.15 ~ 1.21.8; reason: full functional coverage, better optimization)
- Blur mod claims to use Gaussian blur, but I found it actually uses 2-pass box blur. Whereas Modern UI gives you the true 1-pass Gaussian Blur, which is better than Blur mod.
- Controlling (ver 1.15; reason: another way of implementation)
- TipTheScales (ver 1.15 ~ 1.21.8; reason: another way of implementation)
- Inventory Pause (ver 1.18 ~ 1.21.1; reason: another way of implementation)
- Emojiful (ver 1.18 ~ 1.21.1; reason: we support color emoji rendering since 3.5.0; additionally, Emojiful has really bad code and breaks your game everywhere; you may experience game freezing, high VRAM usage, rendering glitches, and many performance & mod compatibility issues)
- Borderless Window (ver 1.18 ~ 1.21.4; reason: another way of implementation)
- Ding (ver 1.18 ~ 1.21.4; reason: another way of implementation)
- SmoothScrollingEverywhere (ver 1.18 ~ 1.19; reason: another way of implementation)
- FPS Reducer (ver 1.18 ~ 1.21.8; reason: another way of implementation)
Conflict and Solution:
- Emojiful (ver 1.16 ~ 1.21.1; it's not recommended to use Emojiful; if you must use it, disable Modern UI text engine, via config screen or bootstrap properties)
- Legendary Tooltips (ver 1.16 ~ 1.21.4; solution: disable Modern UI tooltip, via config screen)
- FeyTweaks (ver 1.18 ~ 1.21.1; solution: disable TextRendererMixin in FeyTweaks' mixin config)
- SmoothScrollingEverywhere (ver 1.18 ~ 1.19; solution: disable Modern UI smooth scrolling, via config screen)
- Caxton (ver 1.18 ~ 1.21.8; solution: disable Modern UI text engine, via config screen or bootstrap properties)
- ImmediatelyFast (ver 1.18 ~ 1.21.8; solution: for 1.18 ~ 1.21.4: disable ImmediatelyFast's hud_batching, font_atlas_resizing and fast_text_lookup; otherwise, you may experience random game crashes; for 1.21.6 ~ 1.21.8: disable ImmediatelyFast's avoid_redundant_framebuffer_switching)
- Untranslated Items (ver 1.18 ~ 1.21.4; solution: disable Modern UI text component cache, via config screen)
Supported MC versions:
- Actively maintained: 1.21.8, 1.21.7, 1.21.6, 1.21.1, 1.21, 1.20.1, 1.20
- About to be dropped: 1.21.4
- No longer supported: 1.21.3, 1.21.2, 1.20.6, 1.20.4, 1.20.2, 1.19.4, 1.19.2, 1.18.2, 1.18.1, 1.18, 1.17.1, 1.16.5, 1.16.4, 1.16.3, 1.16.2, 1.16.1, 1.15.2, 1.14.4
All descriptions on this page are for Minecraft 1.20.1 and above. Some features may be missing in older versions.
PC Requirements (same as Minecraft Vanilla)
Some people are unwilling to use Modern UI because they believe that Modern UI has a high PC requirements. In fact, as long as you can play Minecraft Vanilla, you can definitely play Modern UI. Unless you forget to update your GPU driver.
- OS: Windows 8.1+, Linux with X11 or Wayland, macOS
- Architecture: x64 or arm64
- GPU: GeForce 210 or better
- GPU Driver: OpenGL 3.3+ or Vulkan 1.1+, higher is better
- Java: Java 17+, higher is better
FAQ:
Q: What is the difference between Default Font Behavior and Force Unicode Font?
A: Firstly, Modern UI always redirects Unicode font to Modern UI default typeface. Default Font Behavior is KEEP ALL in 1.19+, then Minecraft default font is used for ASCII characters. KEEP OTHER means that Minecraft default font is no longer used, but additional fonts, for example, in some minigame maps, are still available. This is the difference from Force Unicode Font (IGNORE ALL).
Q: Does Modern UI have a high overhead? Will Modern UI lower application performance?
A: No, Modern UI does not have a significant impact on CPU, GPU, RAM, and VRAM usage. This is because Modern UI itself has good optimization, but at the same time, Modern UI provides a bunch of new features and effects. Modern UI framework is known to be more efficient than Chromium-based applications. For low-end PCs, screen blur effect may be a performance killer, because Minecraft Vanilla does not allow mipmap generation on render targets. Even so, the blur effect provided by Modern UI is much faster than a mod called 'Blur'.
Q: How to disable all changes to vanilla, I don't want these features.
A: Only GUI scale algorithm and some low-level code are non-configurable, any other features can be disabled in Action Center screen (shortkey Ctrl+K by default), or config files (gameDir/config/ModernUI/), because Modern UI is essentially a framework.
Q: Is this mod a client-only mod? Do I need to install it on the server?
A: Since MC 1.19.2, there is no reason to install this mod on the server anymore. All server features are deprecated and implemented to Forge API and Fabric API.
Q: How to get start to develop my mod based on Modern UI?
A: This project is still in early stages, the specification is still being written. You can view the JavaDoc. Examples include Modern UI itself (Action Center) and Flux Networks. If you have any questions, feel free to join our Discord server.
Issues: All issue reports should go to GitHub issue tracker.
Join my Discord Server for discussion and suggestions.
Версии
| Версия | Канал | Игра | Загрузчики | Дата | Скачать |
|---|---|---|---|---|---|
| 3.13.0.5 | Релиз | 26.1, 26.1.1, 26.1.2 | fabric | 14 июня 2026 г. | .jar (24.5 МБ) |
| 3.13.0.5 | Релиз | 26.1, 26.1.1, 26.1.2 | forge | 14 июня 2026 г. | .jar (24.6 МБ) |
| 3.13.0.5 | Релиз | 26.1, 26.1.1, 26.1.2 | neoforge | 14 июня 2026 г. | .jar (24.5 МБ) |
| 3.13.0.4 | Релиз | 26.1, 26.1.1, 26.1.2 | fabric | 6 июня 2026 г. | .jar (24.5 МБ) |
| 3.13.0.4 | Релиз | 26.1, 26.1.1, 26.1.2 | forge | 6 июня 2026 г. | .jar (24.6 МБ) |
| 3.13.0.4 | Релиз | 26.1, 26.1.1, 26.1.2 | neoforge | 6 июня 2026 г. | .jar (24.5 МБ) |
| 3.13.0.3 | Релиз | 1.21.6, 1.21.7, 1.21.8 | fabric | 6 июня 2026 г. | .jar (24.0 МБ) |
| 3.13.0.3 | Релиз | 1.21.6, 1.21.7, 1.21.8 | forge | 6 июня 2026 г. | .jar (24.1 МБ) |
| 3.13.0.3 | Релиз | 1.21.6, 1.21.7, 1.21.8 | neoforge | 6 июня 2026 г. | .jar (24.1 МБ) |
| 3.13.0.1 | Релиз | 1.21, 1.21.1 | fabric, quilt | 6 июня 2026 г. | .jar (24.0 МБ) |
| 3.13.0.1 | Релиз | 1.21, 1.21.1 | forge | 6 июня 2026 г. | .jar (24.1 МБ) |
| 3.13.0.1 | Релиз | 1.21, 1.21.1 | neoforge | 6 июня 2026 г. | .jar (24.1 МБ) |
| 3.12.0.4 | Релиз | 1.21.6, 1.21.7, 1.21.8 | fabric | 23 сентября 2025 г. | .jar (23.8 МБ) |
| 3.12.0.4 | Релиз | 1.21.6, 1.21.7, 1.21.8 | forge | 23 сентября 2025 г. | .jar (23.9 МБ) |
| 3.12.0.4 | Релиз | 1.21.6, 1.21.7, 1.21.8 | neoforge | 23 сентября 2025 г. | .jar (23.9 МБ) |
Показаны последние 15 из 106 версий. Все версии — на Modrinth.
Ченджлог
3.13.0.5Релиз26.1, 26.1.1, 26.1.2 · 14 июня 2026 г.
Modern UI 3.13.0.5
Changes from
- 3.13.0.4 → 3.13.0.5 for Minecraft 26.1-26.1.2
NeoForge Extension 26.1.2
- Fix compatibility with Beryl
- Fix UI thread loading issue
Forge Extension 26.1.2
- Fix UI thread loading issue, but no Vulkan support
Fabric Extension 26.1.2
- Same as NeoForge version
3.13.0.5Релиз26.1, 26.1.1, 26.1.2 · 14 июня 2026 г.
Modern UI 3.13.0.5
Changes from
- 3.13.0.4 → 3.13.0.5 for Minecraft 26.1-26.1.2
NeoForge Extension 26.1.2
- Fix compatibility with Beryl
- Fix UI thread loading issue
Forge Extension 26.1.2
- Fix UI thread loading issue, but no Vulkan support
Fabric Extension 26.1.2
- Same as NeoForge version
3.13.0.5Релиз26.1, 26.1.1, 26.1.2 · 14 июня 2026 г.
Modern UI 3.13.0.5
Changes from
- 3.13.0.4 → 3.13.0.5 for Minecraft 26.1-26.1.2
NeoForge Extension 26.1.2
- Fix compatibility with Beryl
- Fix UI thread loading issue
Forge Extension 26.1.2
- Fix UI thread loading issue, but no Vulkan support
Fabric Extension 26.1.2
- Same as NeoForge version
3.13.0.4Релиз26.1, 26.1.1, 26.1.2 · 6 июня 2026 г.
Modern UI 3.13.0.4 (3.13.0.3, 3.13.0.1)
Changes from
- 3.13.0.4 → 3.13.0.4 for Minecraft 26.1-26.1.2
- 3.12.0.4 → 3.13.0.3 for Minecraft 1.21.6-1.21.8
- 3.12.0.2 → 3.13.0.1 for Minecraft 1.21-1.21.1
NeoForge Extension 26.1.2 (1.21.8, 1.21.1)
- (26.1+ only) Add Vulkan rendering backend, ModernUI Vulkan will be used when VulkanMod is used
- (26.1+ only) Add "Global Volume Control" option for master volume multiplier
- (1.21.1 only) Fix modern tooltip crash with ImmediatelyFast's hud_batching in HUD
- (1.21.1, Forge and NeoForge only) Fix crash in datagen
- (1.21.6+ only) Change surface origin to upper left to match Arc3D
- Remove modifier restriction on arrow key movement on tooltip
- Add API to register/create additional resources to the ModernUI resource system at runtime
- Fix multiple mixin disable flags not work together
- Add open SimpleScreen and MenuScreen classes to custom ModernUI screens
- Add ImageStore to retrieve Images from Minecraft resources, fix possible threading issues
- Add global "Theme" option for all ModernUI screens
- Add "Linear Metrics" font option for the core framework
- Add "Reset to Default" option to the context menu for all preferences
- Miscellaneous UI improvements
Forge Extension 26.1.2 (1.21.8, 1.21.1)
- Equivalent to NeoForge version, except where noted
Fabric Extension 26.1.2 (1.21.8, 1.21.1)
- Functionally equivalent to NeoForge version, except where noted
Modern Text Engine 26.1.2 (1.21.8, 1.21.1)
- (26.1+ only) Add Vulkan rendering backend
- (26.1+ only) Add support for player head and atlas sprite in text
- (26.1+ only) Remove smart SDF shaders, remove mipmapping for outline fonts
- (1.21.6+ only) Improve compatibility of modern prepared text
- (1.21.1 only) Fix certain EditBox elements from the Create mod erroneously rendered with text shadows
- (1.21.1 only) Add support for Font overriding in EditBox
- (1.21.1 only) Fix EditBox hint text not shown
- Fix line end spaces not stripped when breaking lines, also fix modern tooltip positioning
- Fix color emoji with obfuscated style not render
Core Framework
View
- Add real CONTROL modifier, and update keybinds for macOS
- Fix Toast.cancel()
- Add method to set camera distance explicitly
- Add methods to change ambient/spot shadow color
- Allow shadow casting in reveal animations
- Fix several dirty area accumulation issues that can cause ghosting
Graphics
- Ensure running on LWJGL 3.4.2 and binary-compatible with LWJGL 3.3.1
- Update Vulkan initialization
- Add Bitmap.subImage() to create sub-image view
- Add methods to describe alpha type of Bitmap and Image exactly
- Remove unsupported bitmap formats, deprecate RGBX_8888 (use new setOpaque() instead)
- Add validation to Bitmap.wrap(), and handle 0 rowBytes/stride
- ShapeDrawable's outline no longer relies on stroke opacity
- Migrate everything to wide gamut, extended range colors
- Refactor Drawable's alpha to float type, add wide color setters
- Add dithering to ripple effects
- Remove the RGB space and range restriction on Bitmap.setColorSpace(), this means you can use extended range colors (like extended Display P3) and CIE XYZ colors
- Allow Image.createTextureFromBitmap to be called from non-UI threads
- Fix race between Bitmap.close() and Bitmap.clone()
- Refactor image (GPU) cache; fix thread-safety of Image.clone(); texture-backed image is no longer budgeted
- Add new color packing format, which encodes extended range colors in 16-bit floating-point, in extended color space, using relative colorimetric rendering intent
- Refactor several int color getters to long colors
- Deprecate BMP and TGA support, will be removed in future
- Optimize saving bitmap to path
- Final refactor for ColorSpace-related classes
- Add more Vulkan caps, and add caps dump
- Add option to indicate that zero-to-one depth is used in OpenGL
- Improve error logging
- Simplify builtin color space access, fix some bugs
- Refactor ColorTransform and color space methods
- Introduce separate ChromaticAdaptation class
- Change ColorSpace.Model to int constants
- Update renderer test, Vulkan renderer
- Complete the entire Vulkan rendering backend
- ColorShader now takes original ColorSpace to handle absolute colorimetric intent
- Make computeByteSize() return 0 for invalid row bytes
- Add XYZ D65 space
- Add Oklab support
- Improve color space transformation
- Optimize XYZ<->RGB conversion
- Always uses abs response to handle extended range
- Simplify RGB<->RGB transform computation (skip PCS)
- Fix absolute rendering intent behavior
- Remove references to Unsafe, now Arc3D no longer needs Unsafe
- A8 and BW conversions no longer directly use Unsafe
- Pixmap clear no longer uses Unsafe
- Update usage of image offset=0
- No longer use Unsafe for copyImage()
- Update pixel op and mem tests
- Update low-precision load/store ops
- No longer use LUT for 565 expansion, use only integer arithmetic, add 10-bit store ops
- Change dither method from bayer matrix to R2 sequence
- Replace Unsafe load ops
- Replace Unsafe store ops with separate u and hb versions
- Note that addr for heap is interpreted as byte offset to the first element, without array base offset anymore
- Add validation for pixel memory address
- Add unclamped/extended ColorSpace transformations
- Avoid unnecessary object create for non-strict subset ImageShader
- Relax range check in MathUtil, many checks are too strict, relax to handle unsigned integers
- Add analytic 2D signed distance field generator
- Fix unaligned memory access in building vertices
- Add channel-based IIO stream impl
- Add background compilation executor option
- Workaround macOS OpenGL driver bug on depth-only draw pass
- Add method to wrap backend image for interop
- Use persistent mapping for Vulkan, similar to OpenGL, non-readback and host-visible
- Ensure RenderPassSet is deduplicated and kept alive
- Limit max engine max vertex bindings to 8
- Add option to limit max in-flight command buffers
- Update surface create parameters
- Add support for hairline text
- Switch to Marlin Stroker and deprecate old PathStroker
- Introduce immutable path data, and refactor Path class
- Add Record canvas and BigRecord
- Fix byte offset in Bitmap batch pixel copy operations
- Add command buffer destructor
- Delete many legacy usages of format
- Add Vulkan graphics pipeline
- Fix optimal pixel transfer buffer alignment
- Rework the whole OpenGL texture format table (make it Vulkan-like)
- Add more command buffer parameters
- Add Vulkan queue management
- Finish Vulkan descriptor set management
- Implement Vulkan memory barrier management
- Add RenderPassDesc to pipeline builder
- Migrate to descriptor set layout for pipeline desc
- Add immutable samplers to vkSetLayout
- Sampler are now global objects
- Add Vulkan buffer
- Fix OpenGL readback buffer should not host-coherent or persistently mapped
- Distinguish between BufferBindInfo and BufferSliceInfo
- Add Vulkan sampler
- Add Vulkan command buffer
- Add Vulkan render pass management
- Add Vulkan image view management
- Add Vulkan framebuffers and framebuffer cache
- Introduce consistent way to describe render pass and framebuffer
- Clarify the usage of placeholder attachments and apply them in GL backend.
- Fix some bugs in VulkanRenderPass creation.
- Add full Vulkan render pass creation
- Add definition for Vulkan compatible render passes
- Move actual pipeline destruction to executing thread to ensure thread safety
- Purge framebuffers only when needed instead of every frame
- Refactor FramebufferDesc and RenderPassDesc
- Add engine-level image formats
- Add methods for wide gamut and extended range colors
- Fix all the alignment issues for pixel operations
- Support some new bitmap formats: GRAY_16, GRAY_ALPHA_1616, RGB_161616
- Add method to create Vulkan descriptor pool
- Fix unaligned access in vectorized setPixel/Bitmap.clear()
- Add Vulkan descriptor set pool
- Add descriptor set layout
- Fix ARGB mask swizzle, and reserve SDF mask type
- Implement occlusion culling for the entire Granite Renderer
- Separate paint and style, and use clip stack to handle fullscreen clear
- Cleanup paint key and pipeline construction
- Improve paint color handling and fix
- If step solid color is used, the color of KeyContext will no longer be calculated since it's not used.
- If shader is constant color, reduce to solid color.
- Fix the case where step solid color is not used and the paint is solid color, then it should be in destination space.
- Use a single paint block across multiple draws, by grouping pipeline analysis, pipeline building, and pipeline data gathering together
- Separate image view and image proxy classes
- Fix root of a cubic equation
- Fix fragment textures should come before geometry textures
- The sorting algorithm was changed from TimSort to BM Quicksort
- Improve pipeline descriptor and fixes
- LowerLeft surface origin is now partially supported (mainly for OpenGL backbuffer)
- Add all enum values to ShaderDataType
- Allow RRect effect producing hard edge and coverage AA
- Fix RecordingContext destructor
- Refactor GPU hierarchical clipping (see source code for details)
- Fix Matrix.mapPoints()
- Add more bounds check methods to Rect2*
- Replace small-size zeroing at 4-byte aligned addresses with a custom loop
- Avoid per-pipeline uniform deduplication
- Avoid redundant deduplication while allowing uniform data to be shared across pipelines, simplify the logic.
- Additionally, the size of BindBufferRange is the size of uniform block, not the padded stride.
- Refactor buffer allocator for all kinds of buffers
- All the get*Pointer methods now return BufferSubAllocator, it allows the caller to perform multiple sub-allocations and also allows multiple buffers to be suballocated in parallel (for UBO).
- It also allows specifying an extra alignment offset for the start of each new vertex format, so that buffer binding offsets can be expressed using baseInstance and baseVertex, reducing the number of buffer bindings.
- For mesh draw, we use the concepts of append and static data to simplify. Improvements to UBO allocation, exception handling.
- Rework TextureDataGatherer for new render code
- Fix error shader
- Fix Matrix4 constructor
- Add NullSurface for mock tests
- Remove UByte index type
- Merge geometry definition and remove SimpleShape
- Fix degenerate line stroke and stroke-stroke is not drawn
- Use jacobian matrix to compute device-space gradient for AA-box
- Fix VertexInputLayout masks
- Improve GL error handling
- Switching from JNI to "Java JNI" (FFM) to call GL/GLES functions
- Allow extensions in GLSL codegen, and fix usage of extensions
- Allow creating devices from GL 3.2 contexts; use the reported GLSL version
(Many optimizations and fixes are not listed above)
Resources
This version introduces a brand-new resources system, many APIs have been added, but are not listed below.
- Add Resources.getImage()
- Remove the runtime exception thrown by Resources
- Ensure thread safety for all Resources API classes, fix several thread-safety issues in resources (AOSP bug)
- Add SeekableInputStreamChannel, allow seeking in ZIP instead of stream reading
- Optimize & fix decoding image from buffers
- Optimize image MIME type decoding
- Optimize decoding images from streams and paths
- New methods to declare/add resources at runtime
- Add Asset, AssetsProvider for retrieving assets
- Allow multiple packages and namespaces in Resources
Widget
- Fix TabLayout.setSelectedTabIndicatorColor() behavior
- Add StaggeredGridView
- Fix initial columns of GridView not AUTO_FIT
- Fix ImageView bounds not set when layout unchanged and view detached
- Fix RTL is not resolved in GridView children (AOSP bug)
- Optimize GridView.onMeasure, avoid unnecessary measurement
- Fix some views in AbsListView never get detached (AOSP bug)
Text
- Link clicking on selectable text now checks actual cursor position
- Optimize MeasuredParagraph.buildForStaticLayout in edge cases
- Refactor PrecomputedText, many improvements and bug fixes (AOSP bug)
- Optimize SpannableString.equals()
- Add indexOfSpan map to SpannableStringInternal for performance, also null out reference in removeSpan() to avoid leaks (AOSP bug)
- No longer truncate leading/trailing spaces in TextUtils.ellipsize
- Avoid leaks in TextView's spannable (AOSP bug), also check text object identity to match DynamicLayout
- Refactor BoringLayout
- The legacy BoringLayout only works for LTR only text, now BoringLayout works for bidirectional text. And no longer work for simple Spanned text. It heavily depends on ShapedText API now, so you can think it's a high level wrapper over ShapedText. The bidi, ellipsizer, and text blob building are inlined in the BoringLayout class to improve performance.
- Add method to TextPaint to obtain total advance and per-cluster advances for a bidi run
- Add create flags for text array version of ShapedText
- Add constructor for ShapedText to create layout from icu.Bidi
- Move drawTextRun() from TextUtils to Canvas
- Merge leading/trailing margin in text.Layout, improve performance
- Fix Bidi heuristics being incorrect in some cases
- Move all font options from Paint to TextPaint subclass
- Move TabStops to internal package, and public TextPaint.getInternalPaint()
- Move GetChars and TextRunShaper to graphics package
- Fix concurrency issue of EmojiFont
- Optimize several methods for measuring and shaping text
- Add LineBreakConfig to text.DynamicLayout
- Optimize GraphemeBreak and cursor movement
- Fix cluster advance computation, use font-dependent clusters (HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS), instead of Unicode GCB
- Improve toString(), substring() performance for several classes
- Improve SpannedString and SpannableString constructor performance; always ignore NoCopySpan; never copy PARAGRAPH span if not at paragraph boundary
- Fix SpannableString visibility
Arc3D Shader Compiler
- Keep tracking scope-level symbol table in AST nodes, also make scope level for switch block
Build
- Maven artifact is changed from
icyllis.modernui:ModernUI-Coretodev.icyllis:modernui-core - Update dokka build
- Add junit platform
- Gradle 8.8 -> 9.3.1
- Java 17 -> 25 (for compiler and building, the target JVM is still 17)
- Kotlin 1.9.22 -> 2.3.20 (compiler and stblib)
- Update to Arc3D 2026.2.0 (Arc3D is now modular)
- Use Arc3D from central maven instead of local clone
- Use ModernUI from central maven instead of composite build
3.13.0.4Релиз26.1, 26.1.1, 26.1.2 · 6 июня 2026 г.
Modern UI 3.13.0.4 (3.13.0.3, 3.13.0.1)
Changes from
- 3.13.0.4 → 3.13.0.4 for Minecraft 26.1-26.1.2
- 3.12.0.4 → 3.13.0.3 for Minecraft 1.21.6-1.21.8
- 3.12.0.2 → 3.13.0.1 for Minecraft 1.21-1.21.1
NeoForge Extension 26.1.2 (1.21.8, 1.21.1)
- (26.1+ only) Add Vulkan rendering backend, ModernUI Vulkan will be used when VulkanMod is used
- (26.1+ only) Add "Global Volume Control" option for master volume multiplier
- (1.21.1 only) Fix modern tooltip crash with ImmediatelyFast's hud_batching in HUD
- (1.21.1, Forge and NeoForge only) Fix crash in datagen
- (1.21.6+ only) Change surface origin to upper left to match Arc3D
- Remove modifier restriction on arrow key movement on tooltip
- Add API to register/create additional resources to the ModernUI resource system at runtime
- Fix multiple mixin disable flags not work together
- Add open SimpleScreen and MenuScreen classes to custom ModernUI screens
- Add ImageStore to retrieve Images from Minecraft resources, fix possible threading issues
- Add global "Theme" option for all ModernUI screens
- Add "Linear Metrics" font option for the core framework
- Add "Reset to Default" option to the context menu for all preferences
- Miscellaneous UI improvements
Forge Extension 26.1.2 (1.21.8, 1.21.1)
- Equivalent to NeoForge version, except where noted
Fabric Extension 26.1.2 (1.21.8, 1.21.1)
- Functionally equivalent to NeoForge version, except where noted
Modern Text Engine 26.1.2 (1.21.8, 1.21.1)
- (26.1+ only) Add Vulkan rendering backend
- (26.1+ only) Add support for player head and atlas sprite in text
- (26.1+ only) Remove smart SDF shaders, remove mipmapping for outline fonts
- (1.21.6+ only) Improve compatibility of modern prepared text
- (1.21.1 only) Fix certain EditBox elements from the Create mod erroneously rendered with text shadows
- (1.21.1 only) Add support for Font overriding in EditBox
- (1.21.1 only) Fix EditBox hint text not shown
- Fix line end spaces not stripped when breaking lines, also fix modern tooltip positioning
- Fix color emoji with obfuscated style not render
Core Framework
View
- Add real CONTROL modifier, and update keybinds for macOS
- Fix Toast.cancel()
- Add method to set camera distance explicitly
- Add methods to change ambient/spot shadow color
- Allow shadow casting in reveal animations
- Fix several dirty area accumulation issues that can cause ghosting
Graphics
- Ensure running on LWJGL 3.4.2 and binary-compatible with LWJGL 3.3.1
- Update Vulkan initialization
- Add Bitmap.subImage() to create sub-image view
- Add methods to describe alpha type of Bitmap and Image exactly
- Remove unsupported bitmap formats, deprecate RGBX_8888 (use new setOpaque() instead)
- Add validation to Bitmap.wrap(), and handle 0 rowBytes/stride
- ShapeDrawable's outline no longer relies on stroke opacity
- Migrate everything to wide gamut, extended range colors
- Refactor Drawable's alpha to float type, add wide color setters
- Add dithering to ripple effects
- Remove the RGB space and range restriction on Bitmap.setColorSpace(), this means you can use extended range colors (like extended Display P3) and CIE XYZ colors
- Allow Image.createTextureFromBitmap to be called from non-UI threads
- Fix race between Bitmap.close() and Bitmap.clone()
- Refactor image (GPU) cache; fix thread-safety of Image.clone(); texture-backed image is no longer budgeted
- Add new color packing format, which encodes extended range colors in 16-bit floating-point, in extended color space, using relative colorimetric rendering intent
- Refactor several int color getters to long colors
- Deprecate BMP and TGA support, will be removed in future
- Optimize saving bitmap to path
- Final refactor for ColorSpace-related classes
- Add more Vulkan caps, and add caps dump
- Add option to indicate that zero-to-one depth is used in OpenGL
- Improve error logging
- Simplify builtin color space access, fix some bugs
- Refactor ColorTransform and color space methods
- Introduce separate ChromaticAdaptation class
- Change ColorSpace.Model to int constants
- Update renderer test, Vulkan renderer
- Complete the entire Vulkan rendering backend
- ColorShader now takes original ColorSpace to handle absolute colorimetric intent
- Make computeByteSize() return 0 for invalid row bytes
- Add XYZ D65 space
- Add Oklab support
- Improve color space transformation
- Optimize XYZ<->RGB conversion
- Always uses abs response to handle extended range
- Simplify RGB<->RGB transform computation (skip PCS)
- Fix absolute rendering intent behavior
- Remove references to Unsafe, now Arc3D no longer needs Unsafe
- A8 and BW conversions no longer directly use Unsafe
- Pixmap clear no longer uses Unsafe
- Update usage of image offset=0
- No longer use Unsafe for copyImage()
- Update pixel op and mem tests
- Update low-precision load/store ops
- No longer use LUT for 565 expansion, use only integer arithmetic, add 10-bit store ops
- Change dither method from bayer matrix to R2 sequence
- Replace Unsafe load ops
- Replace Unsafe store ops with separate u and hb versions
- Note that addr for heap is interpreted as byte offset to the first element, without array base offset anymore
- Add validation for pixel memory address
- Add unclamped/extended ColorSpace transformations
- Avoid unnecessary object create for non-strict subset ImageShader
- Relax range check in MathUtil, many checks are too strict, relax to handle unsigned integers
- Add analytic 2D signed distance field generator
- Fix unaligned memory access in building vertices
- Add channel-based IIO stream impl
- Add background compilation executor option
- Workaround macOS OpenGL driver bug on depth-only draw pass
- Add method to wrap backend image for interop
- Use persistent mapping for Vulkan, similar to OpenGL, non-readback and host-visible
- Ensure RenderPassSet is deduplicated and kept alive
- Limit max engine max vertex bindings to 8
- Add option to limit max in-flight command buffers
- Update surface create parameters
- Add support for hairline text
- Switch to Marlin Stroker and deprecate old PathStroker
- Introduce immutable path data, and refactor Path class
- Add Record canvas and BigRecord
- Fix byte offset in Bitmap batch pixel copy operations
- Add command buffer destructor
- Delete many legacy usages of format
- Add Vulkan graphics pipeline
- Fix optimal pixel transfer buffer alignment
- Rework the whole OpenGL texture format table (make it Vulkan-like)
- Add more command buffer parameters
- Add Vulkan queue management
- Finish Vulkan descriptor set management
- Implement Vulkan memory barrier management
- Add RenderPassDesc to pipeline builder
- Migrate to descriptor set layout for pipeline desc
- Add immutable samplers to vkSetLayout
- Sampler are now global objects
- Add Vulkan buffer
- Fix OpenGL readback buffer should not host-coherent or persistently mapped
- Distinguish between BufferBindInfo and BufferSliceInfo
- Add Vulkan sampler
- Add Vulkan command buffer
- Add Vulkan render pass management
- Add Vulkan image view management
- Add Vulkan framebuffers and framebuffer cache
- Introduce consistent way to describe render pass and framebuffer
- Clarify the usage of placeholder attachments and apply them in GL backend.
- Fix some bugs in VulkanRenderPass creation.
- Add full Vulkan render pass creation
- Add definition for Vulkan compatible render passes
- Move actual pipeline destruction to executing thread to ensure thread safety
- Purge framebuffers only when needed instead of every frame
- Refactor FramebufferDesc and RenderPassDesc
- Add engine-level image formats
- Add methods for wide gamut and extended range colors
- Fix all the alignment issues for pixel operations
- Support some new bitmap formats: GRAY_16, GRAY_ALPHA_1616, RGB_161616
- Add method to create Vulkan descriptor pool
- Fix unaligned access in vectorized setPixel/Bitmap.clear()
- Add Vulkan descriptor set pool
- Add descriptor set layout
- Fix ARGB mask swizzle, and reserve SDF mask type
- Implement occlusion culling for the entire Granite Renderer
- Separate paint and style, and use clip stack to handle fullscreen clear
- Cleanup paint key and pipeline construction
- Improve paint color handling and fix
- If step solid color is used, the color of KeyContext will no longer be calculated since it's not used.
- If shader is constant color, reduce to solid color.
- Fix the case where step solid color is not used and the paint is solid color, then it should be in destination space.
- Use a single paint block across multiple draws, by grouping pipeline analysis, pipeline building, and pipeline data gathering together
- Separate image view and image proxy classes
- Fix root of a cubic equation
- Fix fragment textures should come before geometry textures
- The sorting algorithm was changed from TimSort to BM Quicksort
- Improve pipeline descriptor and fixes
- LowerLeft surface origin is now partially supported (mainly for OpenGL backbuffer)
- Add all enum values to ShaderDataType
- Allow RRect effect producing hard edge and coverage AA
- Fix RecordingContext destructor
- Refactor GPU hierarchical clipping (see source code for details)
- Fix Matrix.mapPoints()
- Add more bounds check methods to Rect2*
- Replace small-size zeroing at 4-byte aligned addresses with a custom loop
- Avoid per-pipeline uniform deduplication
- Avoid redundant deduplication while allowing uniform data to be shared across pipelines, simplify the logic.
- Additionally, the size of BindBufferRange is the size of uniform block, not the padded stride.
- Refactor buffer allocator for all kinds of buffers
- All the get*Pointer methods now return BufferSubAllocator, it allows the caller to perform multiple sub-allocations and also allows multiple buffers to be suballocated in parallel (for UBO).
- It also allows specifying an extra alignment offset for the start of each new vertex format, so that buffer binding offsets can be expressed using baseInstance and baseVertex, reducing the number of buffer bindings.
- For mesh draw, we use the concepts of append and static data to simplify. Improvements to UBO allocation, exception handling.
- Rework TextureDataGatherer for new render code
- Fix error shader
- Fix Matrix4 constructor
- Add NullSurface for mock tests
- Remove UByte index type
- Merge geometry definition and remove SimpleShape
- Fix degenerate line stroke and stroke-stroke is not drawn
- Use jacobian matrix to compute device-space gradient for AA-box
- Fix VertexInputLayout masks
- Improve GL error handling
- Switching from JNI to "Java JNI" (FFM) to call GL/GLES functions
- Allow extensions in GLSL codegen, and fix usage of extensions
- Allow creating devices from GL 3.2 contexts; use the reported GLSL version
(Many optimizations and fixes are not listed above)
Resources
This version introduces a brand-new resources system, many APIs have been added, but are not listed below.
- Add Resources.getImage()
- Remove the runtime exception thrown by Resources
- Ensure thread safety for all Resources API classes, fix several thread-safety issues in resources (AOSP bug)
- Add SeekableInputStreamChannel, allow seeking in ZIP instead of stream reading
- Optimize & fix decoding image from buffers
- Optimize image MIME type decoding
- Optimize decoding images from streams and paths
- New methods to declare/add resources at runtime
- Add Asset, AssetsProvider for retrieving assets
- Allow multiple packages and namespaces in Resources
Widget
- Fix TabLayout.setSelectedTabIndicatorColor() behavior
- Add StaggeredGridView
- Fix initial columns of GridView not AUTO_FIT
- Fix ImageView bounds not set when layout unchanged and view detached
- Fix RTL is not resolved in GridView children (AOSP bug)
- Optimize GridView.onMeasure, avoid unnecessary measurement
- Fix some views in AbsListView never get detached (AOSP bug)
Text
- Link clicking on selectable text now checks actual cursor position
- Optimize MeasuredParagraph.buildForStaticLayout in edge cases
- Refactor PrecomputedText, many improvements and bug fixes (AOSP bug)
- Optimize SpannableString.equals()
- Add indexOfSpan map to SpannableStringInternal for performance, also null out reference in removeSpan() to avoid leaks (AOSP bug)
- No longer truncate leading/trailing spaces in TextUtils.ellipsize
- Avoid leaks in TextView's spannable (AOSP bug), also check text object identity to match DynamicLayout
- Refactor BoringLayout
- The legacy BoringLayout only works for LTR only text, now BoringLayout works for bidirectional text. And no longer work for simple Spanned text. It heavily depends on ShapedText API now, so you can think it's a high level wrapper over ShapedText. The bidi, ellipsizer, and text blob building are inlined in the BoringLayout class to improve performance.
- Add method to TextPaint to obtain total advance and per-cluster advances for a bidi run
- Add create flags for text array version of ShapedText
- Add constructor for ShapedText to create layout from icu.Bidi
- Move drawTextRun() from TextUtils to Canvas
- Merge leading/trailing margin in text.Layout, improve performance
- Fix Bidi heuristics being incorrect in some cases
- Move all font options from Paint to TextPaint subclass
- Move TabStops to internal package, and public TextPaint.getInternalPaint()
- Move GetChars and TextRunShaper to graphics package
- Fix concurrency issue of EmojiFont
- Optimize several methods for measuring and shaping text
- Add LineBreakConfig to text.DynamicLayout
- Optimize GraphemeBreak and cursor movement
- Fix cluster advance computation, use font-dependent clusters (HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS), instead of Unicode GCB
- Improve toString(), substring() performance for several classes
- Improve SpannedString and SpannableString constructor performance; always ignore NoCopySpan; never copy PARAGRAPH span if not at paragraph boundary
- Fix SpannableString visibility
Arc3D Shader Compiler
- Keep tracking scope-level symbol table in AST nodes, also make scope level for switch block
Build
- Maven artifact is changed from
icyllis.modernui:ModernUI-Coretodev.icyllis:modernui-core - Update dokka build
- Add junit platform
- Gradle 8.8 -> 9.3.1
- Java 17 -> 25 (for compiler and building, the target JVM is still 17)
- Kotlin 1.9.22 -> 2.3.20 (compiler and stblib)
- Update to Arc3D 2026.2.0 (Arc3D is now modular)
- Use Arc3D from central maven instead of local clone
- Use ModernUI from central maven instead of composite build
3.13.0.4Релиз26.1, 26.1.1, 26.1.2 · 6 июня 2026 г.
Modern UI 3.13.0.4 (3.13.0.3, 3.13.0.1)
Changes from
- 3.13.0.4 → 3.13.0.4 for Minecraft 26.1-26.1.2
- 3.12.0.4 → 3.13.0.3 for Minecraft 1.21.6-1.21.8
- 3.12.0.2 → 3.13.0.1 for Minecraft 1.21-1.21.1
NeoForge Extension 26.1.2 (1.21.8, 1.21.1)
- (26.1+ only) Add Vulkan rendering backend, ModernUI Vulkan will be used when VulkanMod is used
- (26.1+ only) Add "Global Volume Control" option for master volume multiplier
- (1.21.1 only) Fix modern tooltip crash with ImmediatelyFast's hud_batching in HUD
- (1.21.1, Forge and NeoForge only) Fix crash in datagen
- (1.21.6+ only) Change surface origin to upper left to match Arc3D
- Remove modifier restriction on arrow key movement on tooltip
- Add API to register/create additional resources to the ModernUI resource system at runtime
- Fix multiple mixin disable flags not work together
- Add open SimpleScreen and MenuScreen classes to custom ModernUI screens
- Add ImageStore to retrieve Images from Minecraft resources, fix possible threading issues
- Add global "Theme" option for all ModernUI screens
- Add "Linear Metrics" font option for the core framework
- Add "Reset to Default" option to the context menu for all preferences
- Miscellaneous UI improvements
Forge Extension 26.1.2 (1.21.8, 1.21.1)
- Equivalent to NeoForge version, except where noted
Fabric Extension 26.1.2 (1.21.8, 1.21.1)
- Functionally equivalent to NeoForge version, except where noted
Modern Text Engine 26.1.2 (1.21.8, 1.21.1)
- (26.1+ only) Add Vulkan rendering backend
- (26.1+ only) Add support for player head and atlas sprite in text
- (26.1+ only) Remove smart SDF shaders, remove mipmapping for outline fonts
- (1.21.6+ only) Improve compatibility of modern prepared text
- (1.21.1 only) Fix certain EditBox elements from the Create mod erroneously rendered with text shadows
- (1.21.1 only) Add support for Font overriding in EditBox
- (1.21.1 only) Fix EditBox hint text not shown
- Fix line end spaces not stripped when breaking lines, also fix modern tooltip positioning
- Fix color emoji with obfuscated style not render
Core Framework
View
- Add real CONTROL modifier, and update keybinds for macOS
- Fix Toast.cancel()
- Add method to set camera distance explicitly
- Add methods to change ambient/spot shadow color
- Allow shadow casting in reveal animations
- Fix several dirty area accumulation issues that can cause ghosting
Graphics
- Ensure running on LWJGL 3.4.2 and binary-compatible with LWJGL 3.3.1
- Update Vulkan initialization
- Add Bitmap.subImage() to create sub-image view
- Add methods to describe alpha type of Bitmap and Image exactly
- Remove unsupported bitmap formats, deprecate RGBX_8888 (use new setOpaque() instead)
- Add validation to Bitmap.wrap(), and handle 0 rowBytes/stride
- ShapeDrawable's outline no longer relies on stroke opacity
- Migrate everything to wide gamut, extended range colors
- Refactor Drawable's alpha to float type, add wide color setters
- Add dithering to ripple effects
- Remove the RGB space and range restriction on Bitmap.setColorSpace(), this means you can use extended range colors (like extended Display P3) and CIE XYZ colors
- Allow Image.createTextureFromBitmap to be called from non-UI threads
- Fix race between Bitmap.close() and Bitmap.clone()
- Refactor image (GPU) cache; fix thread-safety of Image.clone(); texture-backed image is no longer budgeted
- Add new color packing format, which encodes extended range colors in 16-bit floating-point, in extended color space, using relative colorimetric rendering intent
- Refactor several int color getters to long colors
- Deprecate BMP and TGA support, will be removed in future
- Optimize saving bitmap to path
- Final refactor for ColorSpace-related classes
- Add more Vulkan caps, and add caps dump
- Add option to indicate that zero-to-one depth is used in OpenGL
- Improve error logging
- Simplify builtin color space access, fix some bugs
- Refactor ColorTransform and color space methods
- Introduce separate ChromaticAdaptation class
- Change ColorSpace.Model to int constants
- Update renderer test, Vulkan renderer
- Complete the entire Vulkan rendering backend
- ColorShader now takes original ColorSpace to handle absolute colorimetric intent
- Make computeByteSize() return 0 for invalid row bytes
- Add XYZ D65 space
- Add Oklab support
- Improve color space transformation
- Optimize XYZ<->RGB conversion
- Always uses abs response to handle extended range
- Simplify RGB<->RGB transform computation (skip PCS)
- Fix absolute rendering intent behavior
- Remove references to Unsafe, now Arc3D no longer needs Unsafe
- A8 and BW conversions no longer directly use Unsafe
- Pixmap clear no longer uses Unsafe
- Update usage of image offset=0
- No longer use Unsafe for copyImage()
- Update pixel op and mem tests
- Update low-precision load/store ops
- No longer use LUT for 565 expansion, use only integer arithmetic, add 10-bit store ops
- Change dither method from bayer matrix to R2 sequence
- Replace Unsafe load ops
- Replace Unsafe store ops with separate u and hb versions
- Note that addr for heap is interpreted as byte offset to the first element, without array base offset anymore
- Add validation for pixel memory address
- Add unclamped/extended ColorSpace transformations
- Avoid unnecessary object create for non-strict subset ImageShader
- Relax range check in MathUtil, many checks are too strict, relax to handle unsigned integers
- Add analytic 2D signed distance field generator
- Fix unaligned memory access in building vertices
- Add channel-based IIO stream impl
- Add background compilation executor option
- Workaround macOS OpenGL driver bug on depth-only draw pass
- Add method to wrap backend image for interop
- Use persistent mapping for Vulkan, similar to OpenGL, non-readback and host-visible
- Ensure RenderPassSet is deduplicated and kept alive
- Limit max engine max vertex bindings to 8
- Add option to limit max in-flight command buffers
- Update surface create parameters
- Add support for hairline text
- Switch to Marlin Stroker and deprecate old PathStroker
- Introduce immutable path data, and refactor Path class
- Add Record canvas and BigRecord
- Fix byte offset in Bitmap batch pixel copy operations
- Add command buffer destructor
- Delete many legacy usages of format
- Add Vulkan graphics pipeline
- Fix optimal pixel transfer buffer alignment
- Rework the whole OpenGL texture format table (make it Vulkan-like)
- Add more command buffer parameters
- Add Vulkan queue management
- Finish Vulkan descriptor set management
- Implement Vulkan memory barrier management
- Add RenderPassDesc to pipeline builder
- Migrate to descriptor set layout for pipeline desc
- Add immutable samplers to vkSetLayout
- Sampler are now global objects
- Add Vulkan buffer
- Fix OpenGL readback buffer should not host-coherent or persistently mapped
- Distinguish between BufferBindInfo and BufferSliceInfo
- Add Vulkan sampler
- Add Vulkan command buffer
- Add Vulkan render pass management
- Add Vulkan image view management
- Add Vulkan framebuffers and framebuffer cache
- Introduce consistent way to describe render pass and framebuffer
- Clarify the usage of placeholder attachments and apply them in GL backend.
- Fix some bugs in VulkanRenderPass creation.
- Add full Vulkan render pass creation
- Add definition for Vulkan compatible render passes
- Move actual pipeline destruction to executing thread to ensure thread safety
- Purge framebuffers only when needed instead of every frame
- Refactor FramebufferDesc and RenderPassDesc
- Add engine-level image formats
- Add methods for wide gamut and extended range colors
- Fix all the alignment issues for pixel operations
- Support some new bitmap formats: GRAY_16, GRAY_ALPHA_1616, RGB_161616
- Add method to create Vulkan descriptor pool
- Fix unaligned access in vectorized setPixel/Bitmap.clear()
- Add Vulkan descriptor set pool
- Add descriptor set layout
- Fix ARGB mask swizzle, and reserve SDF mask type
- Implement occlusion culling for the entire Granite Renderer
- Separate paint and style, and use clip stack to handle fullscreen clear
- Cleanup paint key and pipeline construction
- Improve paint color handling and fix
- If step solid color is used, the color of KeyContext will no longer be calculated since it's not used.
- If shader is constant color, reduce to solid color.
- Fix the case where step solid color is not used and the paint is solid color, then it should be in destination space.
- Use a single paint block across multiple draws, by grouping pipeline analysis, pipeline building, and pipeline data gathering together
- Separate image view and image proxy classes
- Fix root of a cubic equation
- Fix fragment textures should come before geometry textures
- The sorting algorithm was changed from TimSort to BM Quicksort
- Improve pipeline descriptor and fixes
- LowerLeft surface origin is now partially supported (mainly for OpenGL backbuffer)
- Add all enum values to ShaderDataType
- Allow RRect effect producing hard edge and coverage AA
- Fix RecordingContext destructor
- Refactor GPU hierarchical clipping (see source code for details)
- Fix Matrix.mapPoints()
- Add more bounds check methods to Rect2*
- Replace small-size zeroing at 4-byte aligned addresses with a custom loop
- Avoid per-pipeline uniform deduplication
- Avoid redundant deduplication while allowing uniform data to be shared across pipelines, simplify the logic.
- Additionally, the size of BindBufferRange is the size of uniform block, not the padded stride.
- Refactor buffer allocator for all kinds of buffers
- All the get*Pointer methods now return BufferSubAllocator, it allows the caller to perform multiple sub-allocations and also allows multiple buffers to be suballocated in parallel (for UBO).
- It also allows specifying an extra alignment offset for the start of each new vertex format, so that buffer binding offsets can be expressed using baseInstance and baseVertex, reducing the number of buffer bindings.
- For mesh draw, we use the concepts of append and static data to simplify. Improvements to UBO allocation, exception handling.
- Rework TextureDataGatherer for new render code
- Fix error shader
- Fix Matrix4 constructor
- Add NullSurface for mock tests
- Remove UByte index type
- Merge geometry definition and remove SimpleShape
- Fix degenerate line stroke and stroke-stroke is not drawn
- Use jacobian matrix to compute device-space gradient for AA-box
- Fix VertexInputLayout masks
- Improve GL error handling
- Switching from JNI to "Java JNI" (FFM) to call GL/GLES functions
- Allow extensions in GLSL codegen, and fix usage of extensions
- Allow creating devices from GL 3.2 contexts; use the reported GLSL version
(Many optimizations and fixes are not listed above)
Resources
This version introduces a brand-new resources system, many APIs have been added, but are not listed below.
- Add Resources.getImage()
- Remove the runtime exception thrown by Resources
- Ensure thread safety for all Resources API classes, fix several thread-safety issues in resources (AOSP bug)
- Add SeekableInputStreamChannel, allow seeking in ZIP instead of stream reading
- Optimize & fix decoding image from buffers
- Optimize image MIME type decoding
- Optimize decoding images from streams and paths
- New methods to declare/add resources at runtime
- Add Asset, AssetsProvider for retrieving assets
- Allow multiple packages and namespaces in Resources
Widget
- Fix TabLayout.setSelectedTabIndicatorColor() behavior
- Add StaggeredGridView
- Fix initial columns of GridView not AUTO_FIT
- Fix ImageView bounds not set when layout unchanged and view detached
- Fix RTL is not resolved in GridView children (AOSP bug)
- Optimize GridView.onMeasure, avoid unnecessary measurement
- Fix some views in AbsListView never get detached (AOSP bug)
Text
- Link clicking on selectable text now checks actual cursor position
- Optimize MeasuredParagraph.buildForStaticLayout in edge cases
- Refactor PrecomputedText, many improvements and bug fixes (AOSP bug)
- Optimize SpannableString.equals()
- Add indexOfSpan map to SpannableStringInternal for performance, also null out reference in removeSpan() to avoid leaks (AOSP bug)
- No longer truncate leading/trailing spaces in TextUtils.ellipsize
- Avoid leaks in TextView's spannable (AOSP bug), also check text object identity to match DynamicLayout
- Refactor BoringLayout
- The legacy BoringLayout only works for LTR only text, now BoringLayout works for bidirectional text. And no longer work for simple Spanned text. It heavily depends on ShapedText API now, so you can think it's a high level wrapper over ShapedText. The bidi, ellipsizer, and text blob building are inlined in the BoringLayout class to improve performance.
- Add method to TextPaint to obtain total advance and per-cluster advances for a bidi run
- Add create flags for text array version of ShapedText
- Add constructor for ShapedText to create layout from icu.Bidi
- Move drawTextRun() from TextUtils to Canvas
- Merge leading/trailing margin in text.Layout, improve performance
- Fix Bidi heuristics being incorrect in some cases
- Move all font options from Paint to TextPaint subclass
- Move TabStops to internal package, and public TextPaint.getInternalPaint()
- Move GetChars and TextRunShaper to graphics package
- Fix concurrency issue of EmojiFont
- Optimize several methods for measuring and shaping text
- Add LineBreakConfig to text.DynamicLayout
- Optimize GraphemeBreak and cursor movement
- Fix cluster advance computation, use font-dependent clusters (HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS), instead of Unicode GCB
- Improve toString(), substring() performance for several classes
- Improve SpannedString and SpannableString constructor performance; always ignore NoCopySpan; never copy PARAGRAPH span if not at paragraph boundary
- Fix SpannableString visibility
Arc3D Shader Compiler
- Keep tracking scope-level symbol table in AST nodes, also make scope level for switch block
Build
- Maven artifact is changed from
icyllis.modernui:ModernUI-Coretodev.icyllis:modernui-core - Update dokka build
- Add junit platform
- Gradle 8.8 -> 9.3.1
- Java 17 -> 25 (for compiler and building, the target JVM is still 17)
- Kotlin 1.9.22 -> 2.3.20 (compiler and stblib)
- Update to Arc3D 2026.2.0 (Arc3D is now modular)
- Use Arc3D from central maven instead of local clone
- Use ModernUI from central maven instead of composite build
3.13.0.3Релиз1.21.6, 1.21.7, 1.21.8 · 6 июня 2026 г.
Modern UI 3.13.0.3
NeoForge Extension 1.21.8
- (26.1+ only) Add Vulkan rendering backend, ModernUI Vulkan will be used when VulkanMod is used
- (26.1+ only) Add "Global Volume Control" option for master volume multiplier
- (1.21.1 only) Fix modern tooltip crash with ImmediatelyFast's hud_batching in HUD
- (1.21.1, Forge and NeoForge only) Fix crash in datagen
- (1.21.6+ only) Change surface origin to upper left to match Arc3D
- Remove modifier restriction on arrow key movement on tooltip
- Add API to register/create additional resources to the ModernUI resource system at runtime
- Fix multiple mixin disable flags not work together
- Add open SimpleScreen and MenuScreen classes to custom ModernUI screens
- Add ImageStore to retrieve Images from Minecraft resources, fix possible threading issues
- Add global "Theme" option for all ModernUI screens
- Add "Linear Metrics" font option for the core framework
- Add "Reset to Default" option to the context menu for all preferences
- Miscellaneous UI improvements
Forge Extension 1.21.8
- Equivalent to NeoForge version, except where noted
Fabric Extension 1.21.8
- Functionally equivalent to NeoForge version, except where noted
Modern Text Engine 1.21.8
- (26.1+ only) Add Vulkan rendering backend
- (26.1+ only) Add support for player head and atlas sprite in text
- (26.1+ only) Remove smart SDF shaders, remove mipmapping for outline fonts
- (1.21.6+ only) Improve compatibility of modern prepared text
- (1.21.1 only) Fix certain EditBox elements from the Create mod erroneously rendered with text shadows
- (1.21.1 only) Add support for Font overriding in EditBox
- (1.21.1 only) Fix EditBox hint text not shown
- Fix line end spaces not stripped when breaking lines, also fix modern tooltip positioning
- Fix color emoji with obfuscated style not render
Core Framework
View
- Add real CONTROL modifier, and update keybinds for macOS
- Fix Toast.cancel()
- Add method to set camera distance explicitly
- Add methods to change ambient/spot shadow color
- Allow shadow casting in reveal animations
- Fix several dirty area accumulation issues that can cause ghosting
Graphics
- Ensure running on LWJGL 3.4.2 and binary-compatible with LWJGL 3.3.1
- Update Vulkan initialization
- Add Bitmap.subImage() to create sub-image view
- Add methods to describe alpha type of Bitmap and Image exactly
- Remove unsupported bitmap formats, deprecate RGBX_8888 (use new setOpaque() instead)
- Add validation to Bitmap.wrap(), and handle 0 rowBytes/stride
- ShapeDrawable's outline no longer relies on stroke opacity
- Migrate everything to wide gamut, extended range colors
- Refactor Drawable's alpha to float type, add wide color setters
- Add dithering to ripple effects
- Remove the RGB space and range restriction on Bitmap.setColorSpace(), this means you can use extended range colors (like extended Display P3) and CIE XYZ colors
- Allow Image.createTextureFromBitmap to be called from non-UI threads
- Fix race between Bitmap.close() and Bitmap.clone()
- Refactor image (GPU) cache; fix thread-safety of Image.clone(); texture-backed image is no longer budgeted
- Add new color packing format, which encodes extended range colors in 16-bit floating-point, in extended color space, using relative colorimetric rendering intent
- Refactor several int color getters to long colors
- Deprecate BMP and TGA support, will be removed in future
- Optimize saving bitmap to path
- Final refactor for ColorSpace-related classes
- Add more Vulkan caps, and add caps dump
- Add option to indicate that zero-to-one depth is used in OpenGL
- Improve error logging
- Simplify builtin color space access, fix some bugs
- Refactor ColorTransform and color space methods
- Introduce separate ChromaticAdaptation class
- Change ColorSpace.Model to int constants
- Update renderer test, Vulkan renderer
- Complete the entire Vulkan rendering backend
- ColorShader now takes original ColorSpace to handle absolute colorimetric intent
- Make computeByteSize() return 0 for invalid row bytes
- Add XYZ D65 space
- Add Oklab support
- Improve color space transformation
- Optimize XYZ<->RGB conversion
- Always uses abs response to handle extended range
- Simplify RGB<->RGB transform computation (skip PCS)
- Fix absolute rendering intent behavior
- Remove references to Unsafe, now Arc3D no longer needs Unsafe
- A8 and BW conversions no longer directly use Unsafe
- Pixmap clear no longer uses Unsafe
- Update usage of image offset=0
- No longer use Unsafe for copyImage()
- Update pixel op and mem tests
- Update low-precision load/store ops
- No longer use LUT for 565 expansion, use only integer arithmetic, add 10-bit store ops
- Change dither method from bayer matrix to R2 sequence
- Replace Unsafe load ops
- Replace Unsafe store ops with separate u and hb versions
- Note that addr for heap is interpreted as byte offset to the first element, without array base offset anymore
- Add validation for pixel memory address
- Add unclamped/extended ColorSpace transformations
- Avoid unnecessary object create for non-strict subset ImageShader
- Relax range check in MathUtil, many checks are too strict, relax to handle unsigned integers
- Add analytic 2D signed distance field generator
- Fix unaligned memory access in building vertices
- Add channel-based IIO stream impl
- Add background compilation executor option
- Workaround macOS OpenGL driver bug on depth-only draw pass
- Add method to wrap backend image for interop
- Use persistent mapping for Vulkan, similar to OpenGL, non-readback and host-visible
- Ensure RenderPassSet is deduplicated and kept alive
- Limit max engine max vertex bindings to 8
- Add option to limit max in-flight command buffers
- Update surface create parameters
- Add support for hairline text
- Switch to Marlin Stroker and deprecate old PathStroker
- Introduce immutable path data, and refactor Path class
- Add Record canvas and BigRecord
- Fix byte offset in Bitmap batch pixel copy operations
- Add command buffer destructor
- Delete many legacy usages of format
- Add Vulkan graphics pipeline
- Fix optimal pixel transfer buffer alignment
- Rework the whole OpenGL texture format table (make it Vulkan-like)
- Add more command buffer parameters
- Add Vulkan queue management
- Finish Vulkan descriptor set management
- Implement Vulkan memory barrier management
- Add RenderPassDesc to pipeline builder
- Migrate to descriptor set layout for pipeline desc
- Add immutable samplers to vkSetLayout
- Sampler are now global objects
- Add Vulkan buffer
- Fix OpenGL readback buffer should not host-coherent or persistently mapped
- Distinguish between BufferBindInfo and BufferSliceInfo
- Add Vulkan sampler
- Add Vulkan command buffer
- Add Vulkan render pass management
- Add Vulkan image view management
- Add Vulkan framebuffers and framebuffer cache
- Introduce consistent way to describe render pass and framebuffer
- Clarify the usage of placeholder attachments and apply them in GL backend.
- Fix some bugs in VulkanRenderPass creation.
- Add full Vulkan render pass creation
- Add definition for Vulkan compatible render passes
- Move actual pipeline destruction to executing thread to ensure thread safety
- Purge framebuffers only when needed instead of every frame
- Refactor FramebufferDesc and RenderPassDesc
- Add engine-level image formats
- Add methods for wide gamut and extended range colors
- Fix all the alignment issues for pixel operations
- Support some new bitmap formats: GRAY_16, GRAY_ALPHA_1616, RGB_161616
- Add method to create Vulkan descriptor pool
- Fix unaligned access in vectorized setPixel/Bitmap.clear()
- Add Vulkan descriptor set pool
- Add descriptor set layout
- Fix ARGB mask swizzle, and reserve SDF mask type
- Implement occlusion culling for the entire Granite Renderer
- Separate paint and style, and use clip stack to handle fullscreen clear
- Cleanup paint key and pipeline construction
- Improve paint color handling and fix
- If step solid color is used, the color of KeyContext will no longer be calculated since it's not used.
- If shader is constant color, reduce to solid color.
- Fix the case where step solid color is not used and the paint is solid color, then it should be in destination space.
- Use a single paint block across multiple draws, by grouping pipeline analysis, pipeline building, and pipeline data gathering together
- Separate image view and image proxy classes
- Fix root of a cubic equation
- Fix fragment textures should come before geometry textures
- The sorting algorithm was changed from TimSort to BM Quicksort
- Improve pipeline descriptor and fixes
- LowerLeft surface origin is now partially supported (mainly for OpenGL backbuffer)
- Add all enum values to ShaderDataType
- Allow RRect effect producing hard edge and coverage AA
- Fix RecordingContext destructor
- Refactor GPU hierarchical clipping (see source code for details)
- Fix Matrix.mapPoints()
- Add more bounds check methods to Rect2*
- Replace small-size zeroing at 4-byte aligned addresses with a custom loop
- Avoid per-pipeline uniform deduplication
- Avoid redundant deduplication while allowing uniform data to be shared across pipelines, simplify the logic.
- Additionally, the size of BindBufferRange is the size of uniform block, not the padded stride.
- Refactor buffer allocator for all kinds of buffers
- All the get*Pointer methods now return BufferSubAllocator, it allows the caller to perform multiple sub-allocations and also allows multiple buffers to be suballocated in parallel (for UBO).
- It also allows specifying an extra alignment offset for the start of each new vertex format, so that buffer binding offsets can be expressed using baseInstance and baseVertex, reducing the number of buffer bindings.
- For mesh draw, we use the concepts of append and static data to simplify. Improvements to UBO allocation, exception handling.
- Rework TextureDataGatherer for new render code
- Fix error shader
- Fix Matrix4 constructor
- Add NullSurface for mock tests
- Remove UByte index type
- Merge geometry definition and remove SimpleShape
- Fix degenerate line stroke and stroke-stroke is not drawn
- Use jacobian matrix to compute device-space gradient for AA-box
- Fix VertexInputLayout masks
- Improve GL error handling
- Switching from JNI to "Java JNI" (FFM) to call GL/GLES functions
- Allow extensions in GLSL codegen, and fix usage of extensions
- Allow creating devices from GL 3.2 contexts; use the reported GLSL version
(Many optimizations and fixes are not listed above)
Resources
This version introduces a brand-new resources system, many APIs have been added, but are not listed below.
- Add Resources.getImage()
- Remove the runtime exception thrown by Resources
- Ensure thread safety for all Resources API classes, fix several thread-safety issues in resources (AOSP bug)
- Add SeekableInputStreamChannel, allow seeking in ZIP instead of stream reading
- Optimize & fix decoding image from buffers
- Optimize image MIME type decoding
- Optimize decoding images from streams and paths
- New methods to declare/add resources at runtime
- Add Asset, AssetsProvider for retrieving assets
- Allow multiple packages and namespaces in Resources
Widget
- Fix TabLayout.setSelectedTabIndicatorColor() behavior
- Add StaggeredGridView
- Fix initial columns of GridView not AUTO_FIT
- Fix ImageView bounds not set when layout unchanged and view detached
- Fix RTL is not resolved in GridView children (AOSP bug)
- Optimize GridView.onMeasure, avoid unnecessary measurement
- Fix some views in AbsListView never get detached (AOSP bug)
Text
- Link clicking on selectable text now checks actual cursor position
- Optimize MeasuredParagraph.buildForStaticLayout in edge cases
- Refactor PrecomputedText, many improvements and bug fixes (AOSP bug)
- Optimize SpannableString.equals()
- Add indexOfSpan map to SpannableStringInternal for performance, also null out reference in removeSpan() to avoid leaks (AOSP bug)
- No longer truncate leading/trailing spaces in TextUtils.ellipsize
- Avoid leaks in TextView's spannable (AOSP bug), also check text object identity to match DynamicLayout
- Refactor BoringLayout
- The legacy BoringLayout only works for LTR only text, now BoringLayout works for bidirectional text. And no longer work for simple Spanned text. It heavily depends on ShapedText API now, so you can think it's a high level wrapper over ShapedText. The bidi, ellipsizer, and text blob building are inlined in the BoringLayout class to improve performance.
- Add method to TextPaint to obtain total advance and per-cluster advances for a bidi run
- Add create flags for text array version of ShapedText
- Add constructor for ShapedText to create layout from icu.Bidi
- Move drawTextRun() from TextUtils to Canvas
- Merge leading/trailing margin in text.Layout, improve performance
- Fix Bidi heuristics being incorrect in some cases
- Move all font options from Paint to TextPaint subclass
- Move TabStops to internal package, and public TextPaint.getInternalPaint()
- Move GetChars and TextRunShaper to graphics package
- Fix concurrency issue of EmojiFont
- Optimize several methods for measuring and shaping text
- Add LineBreakConfig to text.DynamicLayout
- Optimize GraphemeBreak and cursor movement
- Fix cluster advance computation, use font-dependent clusters (HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS), instead of Unicode GCB
- Improve toString(), substring() performance for several classes
- Improve SpannedString and SpannableString constructor performance; always ignore NoCopySpan; never copy PARAGRAPH span if not at paragraph boundary
- Fix SpannableString visibility
Arc3D Shader Compiler
- Keep tracking scope-level symbol table in AST nodes, also make scope level for switch block
Build
- Maven artifact is changed from
icyllis.modernui:ModernUI-Coretodev.icyllis:modernui-core - Update dokka build
- Add junit platform
- Gradle 8.8 -> 9.3.1
- Java 17 -> 25 (for compiler and building, the target JVM is still 17)
- Kotlin 1.9.22 -> 2.3.20 (compiler and stblib)
- Update to Arc3D 2026.2.0 (Arc3D is now modular)
- Use Arc3D from central maven instead of local clone
- Use ModernUI from central maven instead of composite build
3.13.0.3Релиз1.21.6, 1.21.7, 1.21.8 · 6 июня 2026 г.
Modern UI 3.13.0.3
NeoForge Extension 1.21.8
- (26.1+ only) Add Vulkan rendering backend, ModernUI Vulkan will be used when VulkanMod is used
- (26.1+ only) Add "Global Volume Control" option for master volume multiplier
- (1.21.1 only) Fix modern tooltip crash with ImmediatelyFast's hud_batching in HUD
- (1.21.1, Forge and NeoForge only) Fix crash in datagen
- (1.21.6+ only) Change surface origin to upper left to match Arc3D
- Remove modifier restriction on arrow key movement on tooltip
- Add API to register/create additional resources to the ModernUI resource system at runtime
- Fix multiple mixin disable flags not work together
- Add open SimpleScreen and MenuScreen classes to custom ModernUI screens
- Add ImageStore to retrieve Images from Minecraft resources, fix possible threading issues
- Add global "Theme" option for all ModernUI screens
- Add "Linear Metrics" font option for the core framework
- Add "Reset to Default" option to the context menu for all preferences
- Miscellaneous UI improvements
Forge Extension 1.21.8
- Equivalent to NeoForge version, except where noted
Fabric Extension 1.21.8
- Functionally equivalent to NeoForge version, except where noted
Modern Text Engine 1.21.8
- (26.1+ only) Add Vulkan rendering backend
- (26.1+ only) Add support for player head and atlas sprite in text
- (26.1+ only) Remove smart SDF shaders, remove mipmapping for outline fonts
- (1.21.6+ only) Improve compatibility of modern prepared text
- (1.21.1 only) Fix certain EditBox elements from the Create mod erroneously rendered with text shadows
- (1.21.1 only) Add support for Font overriding in EditBox
- (1.21.1 only) Fix EditBox hint text not shown
- Fix line end spaces not stripped when breaking lines, also fix modern tooltip positioning
- Fix color emoji with obfuscated style not render
Core Framework
View
- Add real CONTROL modifier, and update keybinds for macOS
- Fix Toast.cancel()
- Add method to set camera distance explicitly
- Add methods to change ambient/spot shadow color
- Allow shadow casting in reveal animations
- Fix several dirty area accumulation issues that can cause ghosting
Graphics
- Ensure running on LWJGL 3.4.2 and binary-compatible with LWJGL 3.3.1
- Update Vulkan initialization
- Add Bitmap.subImage() to create sub-image view
- Add methods to describe alpha type of Bitmap and Image exactly
- Remove unsupported bitmap formats, deprecate RGBX_8888 (use new setOpaque() instead)
- Add validation to Bitmap.wrap(), and handle 0 rowBytes/stride
- ShapeDrawable's outline no longer relies on stroke opacity
- Migrate everything to wide gamut, extended range colors
- Refactor Drawable's alpha to float type, add wide color setters
- Add dithering to ripple effects
- Remove the RGB space and range restriction on Bitmap.setColorSpace(), this means you can use extended range colors (like extended Display P3) and CIE XYZ colors
- Allow Image.createTextureFromBitmap to be called from non-UI threads
- Fix race between Bitmap.close() and Bitmap.clone()
- Refactor image (GPU) cache; fix thread-safety of Image.clone(); texture-backed image is no longer budgeted
- Add new color packing format, which encodes extended range colors in 16-bit floating-point, in extended color space, using relative colorimetric rendering intent
- Refactor several int color getters to long colors
- Deprecate BMP and TGA support, will be removed in future
- Optimize saving bitmap to path
- Final refactor for ColorSpace-related classes
- Add more Vulkan caps, and add caps dump
- Add option to indicate that zero-to-one depth is used in OpenGL
- Improve error logging
- Simplify builtin color space access, fix some bugs
- Refactor ColorTransform and color space methods
- Introduce separate ChromaticAdaptation class
- Change ColorSpace.Model to int constants
- Update renderer test, Vulkan renderer
- Complete the entire Vulkan rendering backend
- ColorShader now takes original ColorSpace to handle absolute colorimetric intent
- Make computeByteSize() return 0 for invalid row bytes
- Add XYZ D65 space
- Add Oklab support
- Improve color space transformation
- Optimize XYZ<->RGB conversion
- Always uses abs response to handle extended range
- Simplify RGB<->RGB transform computation (skip PCS)
- Fix absolute rendering intent behavior
- Remove references to Unsafe, now Arc3D no longer needs Unsafe
- A8 and BW conversions no longer directly use Unsafe
- Pixmap clear no longer uses Unsafe
- Update usage of image offset=0
- No longer use Unsafe for copyImage()
- Update pixel op and mem tests
- Update low-precision load/store ops
- No longer use LUT for 565 expansion, use only integer arithmetic, add 10-bit store ops
- Change dither method from bayer matrix to R2 sequence
- Replace Unsafe load ops
- Replace Unsafe store ops with separate u and hb versions
- Note that addr for heap is interpreted as byte offset to the first element, without array base offset anymore
- Add validation for pixel memory address
- Add unclamped/extended ColorSpace transformations
- Avoid unnecessary object create for non-strict subset ImageShader
- Relax range check in MathUtil, many checks are too strict, relax to handle unsigned integers
- Add analytic 2D signed distance field generator
- Fix unaligned memory access in building vertices
- Add channel-based IIO stream impl
- Add background compilation executor option
- Workaround macOS OpenGL driver bug on depth-only draw pass
- Add method to wrap backend image for interop
- Use persistent mapping for Vulkan, similar to OpenGL, non-readback and host-visible
- Ensure RenderPassSet is deduplicated and kept alive
- Limit max engine max vertex bindings to 8
- Add option to limit max in-flight command buffers
- Update surface create parameters
- Add support for hairline text
- Switch to Marlin Stroker and deprecate old PathStroker
- Introduce immutable path data, and refactor Path class
- Add Record canvas and BigRecord
- Fix byte offset in Bitmap batch pixel copy operations
- Add command buffer destructor
- Delete many legacy usages of format
- Add Vulkan graphics pipeline
- Fix optimal pixel transfer buffer alignment
- Rework the whole OpenGL texture format table (make it Vulkan-like)
- Add more command buffer parameters
- Add Vulkan queue management
- Finish Vulkan descriptor set management
- Implement Vulkan memory barrier management
- Add RenderPassDesc to pipeline builder
- Migrate to descriptor set layout for pipeline desc
- Add immutable samplers to vkSetLayout
- Sampler are now global objects
- Add Vulkan buffer
- Fix OpenGL readback buffer should not host-coherent or persistently mapped
- Distinguish between BufferBindInfo and BufferSliceInfo
- Add Vulkan sampler
- Add Vulkan command buffer
- Add Vulkan render pass management
- Add Vulkan image view management
- Add Vulkan framebuffers and framebuffer cache
- Introduce consistent way to describe render pass and framebuffer
- Clarify the usage of placeholder attachments and apply them in GL backend.
- Fix some bugs in VulkanRenderPass creation.
- Add full Vulkan render pass creation
- Add definition for Vulkan compatible render passes
- Move actual pipeline destruction to executing thread to ensure thread safety
- Purge framebuffers only when needed instead of every frame
- Refactor FramebufferDesc and RenderPassDesc
- Add engine-level image formats
- Add methods for wide gamut and extended range colors
- Fix all the alignment issues for pixel operations
- Support some new bitmap formats: GRAY_16, GRAY_ALPHA_1616, RGB_161616
- Add method to create Vulkan descriptor pool
- Fix unaligned access in vectorized setPixel/Bitmap.clear()
- Add Vulkan descriptor set pool
- Add descriptor set layout
- Fix ARGB mask swizzle, and reserve SDF mask type
- Implement occlusion culling for the entire Granite Renderer
- Separate paint and style, and use clip stack to handle fullscreen clear
- Cleanup paint key and pipeline construction
- Improve paint color handling and fix
- If step solid color is used, the color of KeyContext will no longer be calculated since it's not used.
- If shader is constant color, reduce to solid color.
- Fix the case where step solid color is not used and the paint is solid color, then it should be in destination space.
- Use a single paint block across multiple draws, by grouping pipeline analysis, pipeline building, and pipeline data gathering together
- Separate image view and image proxy classes
- Fix root of a cubic equation
- Fix fragment textures should come before geometry textures
- The sorting algorithm was changed from TimSort to BM Quicksort
- Improve pipeline descriptor and fixes
- LowerLeft surface origin is now partially supported (mainly for OpenGL backbuffer)
- Add all enum values to ShaderDataType
- Allow RRect effect producing hard edge and coverage AA
- Fix RecordingContext destructor
- Refactor GPU hierarchical clipping (see source code for details)
- Fix Matrix.mapPoints()
- Add more bounds check methods to Rect2*
- Replace small-size zeroing at 4-byte aligned addresses with a custom loop
- Avoid per-pipeline uniform deduplication
- Avoid redundant deduplication while allowing uniform data to be shared across pipelines, simplify the logic.
- Additionally, the size of BindBufferRange is the size of uniform block, not the padded stride.
- Refactor buffer allocator for all kinds of buffers
- All the get*Pointer methods now return BufferSubAllocator, it allows the caller to perform multiple sub-allocations and also allows multiple buffers to be suballocated in parallel (for UBO).
- It also allows specifying an extra alignment offset for the start of each new vertex format, so that buffer binding offsets can be expressed using baseInstance and baseVertex, reducing the number of buffer bindings.
- For mesh draw, we use the concepts of append and static data to simplify. Improvements to UBO allocation, exception handling.
- Rework TextureDataGatherer for new render code
- Fix error shader
- Fix Matrix4 constructor
- Add NullSurface for mock tests
- Remove UByte index type
- Merge geometry definition and remove SimpleShape
- Fix degenerate line stroke and stroke-stroke is not drawn
- Use jacobian matrix to compute device-space gradient for AA-box
- Fix VertexInputLayout masks
- Improve GL error handling
- Switching from JNI to "Java JNI" (FFM) to call GL/GLES functions
- Allow extensions in GLSL codegen, and fix usage of extensions
- Allow creating devices from GL 3.2 contexts; use the reported GLSL version
(Many optimizations and fixes are not listed above)
Resources
This version introduces a brand-new resources system, many APIs have been added, but are not listed below.
- Add Resources.getImage()
- Remove the runtime exception thrown by Resources
- Ensure thread safety for all Resources API classes, fix several thread-safety issues in resources (AOSP bug)
- Add SeekableInputStreamChannel, allow seeking in ZIP instead of stream reading
- Optimize & fix decoding image from buffers
- Optimize image MIME type decoding
- Optimize decoding images from streams and paths
- New methods to declare/add resources at runtime
- Add Asset, AssetsProvider for retrieving assets
- Allow multiple packages and namespaces in Resources
Widget
- Fix TabLayout.setSelectedTabIndicatorColor() behavior
- Add StaggeredGridView
- Fix initial columns of GridView not AUTO_FIT
- Fix ImageView bounds not set when layout unchanged and view detached
- Fix RTL is not resolved in GridView children (AOSP bug)
- Optimize GridView.onMeasure, avoid unnecessary measurement
- Fix some views in AbsListView never get detached (AOSP bug)
Text
- Link clicking on selectable text now checks actual cursor position
- Optimize MeasuredParagraph.buildForStaticLayout in edge cases
- Refactor PrecomputedText, many improvements and bug fixes (AOSP bug)
- Optimize SpannableString.equals()
- Add indexOfSpan map to SpannableStringInternal for performance, also null out reference in removeSpan() to avoid leaks (AOSP bug)
- No longer truncate leading/trailing spaces in TextUtils.ellipsize
- Avoid leaks in TextView's spannable (AOSP bug), also check text object identity to match DynamicLayout
- Refactor BoringLayout
- The legacy BoringLayout only works for LTR only text, now BoringLayout works for bidirectional text. And no longer work for simple Spanned text. It heavily depends on ShapedText API now, so you can think it's a high level wrapper over ShapedText. The bidi, ellipsizer, and text blob building are inlined in the BoringLayout class to improve performance.
- Add method to TextPaint to obtain total advance and per-cluster advances for a bidi run
- Add create flags for text array version of ShapedText
- Add constructor for ShapedText to create layout from icu.Bidi
- Move drawTextRun() from TextUtils to Canvas
- Merge leading/trailing margin in text.Layout, improve performance
- Fix Bidi heuristics being incorrect in some cases
- Move all font options from Paint to TextPaint subclass
- Move TabStops to internal package, and public TextPaint.getInternalPaint()
- Move GetChars and TextRunShaper to graphics package
- Fix concurrency issue of EmojiFont
- Optimize several methods for measuring and shaping text
- Add LineBreakConfig to text.DynamicLayout
- Optimize GraphemeBreak and cursor movement
- Fix cluster advance computation, use font-dependent clusters (HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS), instead of Unicode GCB
- Improve toString(), substring() performance for several classes
- Improve SpannedString and SpannableString constructor performance; always ignore NoCopySpan; never copy PARAGRAPH span if not at paragraph boundary
- Fix SpannableString visibility
Arc3D Shader Compiler
- Keep tracking scope-level symbol table in AST nodes, also make scope level for switch block
Build
- Maven artifact is changed from
icyllis.modernui:ModernUI-Coretodev.icyllis:modernui-core - Update dokka build
- Add junit platform
- Gradle 8.8 -> 9.3.1
- Java 17 -> 25 (for compiler and building, the target JVM is still 17)
- Kotlin 1.9.22 -> 2.3.20 (compiler and stblib)
- Update to Arc3D 2026.2.0 (Arc3D is now modular)
- Use Arc3D from central maven instead of local clone
- Use ModernUI from central maven instead of composite build
Полная история изменений — на Modrinth.
Комментарии
Загружаем…





