For a long time I was using [Normal Map Online](https://cpetry.github.io/NormalMap-Online/) to generate normal textures from my colour textures. One day I was curious how it worked, and discovered it was just a shader under the covers. So rather than shipping normal textures (large files) with Sector's Edge, I deleted them all and used the shader to generate them on startup. It currently only supports converting [[AbstractPalettedTextureArray]] to an array of `RG8i` textures, which store 8-bit pitch and yaw values, which are converted to vec3 directions using the `GetVector(ivec2 value)` function in [[ConversionUniforms]] ## Examples See `GlobalTextureManager.cs` in the `voxel` project. ## Usage ```cs PalettedTextureArray texArray; void Startup() { // Load a paletted RGBA texture array from disk texArray = new PalettedTextureArray(...); // Enqueue it for normal generation NormalManager.Enqueue(texArray); } void Render() { ModelShader.UseProgram(); // Check if normals have been generated if (NormalManager.readyPaletted.TryGetValue(texArray, out var normalArray)) { // Bind it to a ShaderUniformISampler2D shader uniform ShaderUniformISampler2D normalTex = ModelShader.uniforms.normalTex; normalTex.Set(normalArray); } // Render a model ... } ```