Naprawa błędu tekstu Nova 8K w naszej kompilacji WebGL
14 czerwca 2025 · 6 minut czytania
W skrócie
- Objaw: tekst dłuższy niż około 260 znaków wyświetlał artefakty co kilka glifów, ale tylko w WebGL.
- Przyczyna: awaryjny renderer Nova pakował wierzchołki do jednowymiarowej tekstury RGBA o szerokości przekraczającej limit 8192 pikseli w WebGL.
- Poprawka: podzieliliśmy bufor na wiersze o szerokości 8192 pikseli i ustawiliśmy tę samą szerokość w shaderze.
Błąd: artefakty w długim tekście
Podczas testów okazało się, że okna dialogowe przekraczające około 260 znaków ≈ 1024 glify wyświetlały zniekształcony tekst w WebGL. Znaki znikały lub zamieniały się miejscami mniej więcej co 20 glifów. W edytorze wszystko wyglądało poprawnie, dopóki nie wymusiliśmy SystemSettings.UseFallbackRendering = true. Wtedy błąd pojawił się także tam.
// WebGL console
Texture has out of range width (got 12800 max supported 8192)
Przyczyna: zbyt duże i źle wyrównane bufory awaryjnego renderowania
Gdy SSBO nie są dostępne, jak w WebGL, Nova korzysta z bufora tekstury. Jeden wierzchołek glifu zajmuje 64 bajty, czyli cztery piksele float4. Element <TextBlock> z 3224 wierzchołkami tworzył teksturę o rozmiarze 12896 × 1 pikseli, znacznie przekraczając limit WebGL. Po ograniczeniu szerokości do 8192 pikseli pojawił się kolejny problem: shader nadal zakładał wiersze o szerokości 16384 pikseli. Edycje zapisywały więc dane w jednym wierszu, a GPU odczytywało je z innego.
Poprawka w dwóch commitach
1. Podział bufora tekstury na wiersze
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. Ujednolicenie stałej w shaderze
#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
Poprawiliśmy również SetData(), aby w ścieżkach RGBA uwzględniało shaderBufferStartIndex * 4. Edycje w czasie działania przestały nadpisywać wcześniejsze glify.
Wyniki
Kompilacja WebGL: bez artefaktów i bez awarii. Desktopowe kompilacje korzystające z SSBO o szerokości 16384 pikseli pozostały bez zmian. Edytor nadal wykazuje pewne nietypowe zachowania, ale obecnie nie jest to priorytetem.
Co dalej?
Poprawka jest już w gałęzi develop i powinna trafić do następnej wersji alfa. Jeśli spotkaliście się z podobnym problemem w Nova UI, dajcie znać na Discordzie, Facebooku lub w komentarzach.
