Исправление ошибки текста 8K в нашей сборке WebGL
14 июня 2025 · 6 минут чтения
Кратко
- Симптом: текст длиннее примерно 260 символов отображался с артефактами через каждые несколько глифов, но только в WebGL.
- Причина: резервный рендерер Nova упаковывал вершины в одномерную текстуру RGBA шире предела WebGL в 8192 пикселя.
- Исправление: разбить буфер на строки шириной 8192 пикселя и использовать ту же ширину в шейдере.
Ошибка: артефакты в длинном тексте
При тестировании обнаружилось, что диалоги длиннее 260 символов ≈ 1024 глифов искажались в WebGL: символы исчезали или менялись местами примерно через каждые 20 глифов. В редакторе все выглядело нормально, пока мы не включили SystemSettings.UseFallbackRendering = true. Тогда ошибка появилась и там.
// WebGL console
Texture has out of range width (got 12800 max supported 8192)
Причина: слишком большие и неправильно выровненные буферы резервного рендеринга
Когда SSBO недоступны, как в WebGL, Nova использует текстурный буфер. Одна вершина глифа занимает 64 байта, то есть четыре пикселя float4. Элемент <TextBlock> с 3224 вершинами создавал текстуру 12896 × 1 пиксель, значительно превышая предел WebGL. После ограничения ширины до 8192 пикселей проявилась еще одна ошибка: шейдер по-прежнему считал ширину строки равной 16384 пикселям. Изменения записывались в одну строку, а GPU считывал другую.
Исправление в двух коммитах
1. Разбить текстурный буфер на строки
int maxEdge = 8192;
int width = Mathf.Min(numPixels, maxEdge);
int height = Mathf.CeilToInt((float)numPixels / width);
texture = new Texture2D(width, height, TextureFormat.RGBAFloat, false, true);
2. Синхронизировать константу шейдера
#if defined(NOVA_FALLBACK_RENDERING)
#if defined(UNITY_WEBGL) || defined(UNITY_EDITOR)
#define MAX_TEXTURE_DIMENSION 8192u
#else
#define MAX_TEXTURE_DIMENSION 16384u
#endif
#endif
Мы также исправили SetData(), чтобы в путях RGBA учитывалось shaderBufferStartIndex * 4. Изменения во время выполнения больше не перезаписывают предыдущие глифы.
Результаты
Сборка WebGL: без артефактов и сбоев. Настольные сборки с SSBO шириной 16384 пикселя остались без изменений. В редакторе еще встречается необычное поведение, но сейчас это не приоритет.
Что дальше?
Исправление уже в ветке develop и должно появиться в следующей альфа-версии. Если вы сталкивались с похожими проблемами Nova UI, расскажите о них в Discord, Facebook или комментариях.
