Class TexturePixels
The pixel work a TextureLoader does between decoding a file and creating the texture,
on plain RGBA arrays: the sRGB transfer function, premultiplication, the green flip of a normal map,
and a mipmap chain filtered the right way for each role. Public so a texture made in code can take
the same steps before Texture.New2D.
public static class TexturePixels
- Inheritance
-
TexturePixels
Methods
BuildMipChain(Color[], int, int, TextureRole)
Builds the mipmap levels below a prepared base level, each half the size of the one above, by averaging two by two texels in the space that is right for the role: linear light for a colour, the stored values for data, unit vectors for a normal map.
public static IReadOnlyList<Color[]> BuildMipChain(Color[] baseLevel, int width, int height, TextureRole role)
Parameters
baseLevelColor[]The largest level, prepared for its role: premultiplied, flipped.
widthintIts width.
heightintIts height.
roleTextureRoleWhat the texture is for.
Returns
- IReadOnlyList<Color[]>
Every level including the base, largest first.
Remarks
Averaging sRGB bytes directly, the easy way, darkens every mipmap of a contrasted colour texture: black and white average to a byte of 128, which the GPU decodes as 0.22, not 0.5. A normal map averaged without renormalising grows shorter and flatter in the distance. An odd size repeats its last row or column, so the chain works for any size, power of two or not.
InvertGreen(Span<Color>)
Inverts the green channel in place: a normal map's Y from one convention to the other.
public static void InvertGreen(Span<Color> pixels)
Parameters
LinearToSrgb(float)
Encodes a linear value, clamped to 0 to 1, as an sRGB channel byte.
public static byte LinearToSrgb(float value)
Parameters
valuefloatThe linear value.
Returns
MipCount(int, int)
How many levels a full mipmap chain of a texture this size has, down to one texel.
public static int MipCount(int width, int height)
Parameters
Returns
PremultiplyAlpha(Span<Color>)
Premultiplies sRGB-encoded colours by their alpha, in linear light, in place: decoded, scaled, encoded again. An opaque pixel is left exactly as it was; a transparent one becomes black, whatever colour the file kept under it.
public static void PremultiplyAlpha(Span<Color> pixels)
Parameters
Remarks
The content pipeline scales the stored bytes instead, which is the same for an opaque pixel and slightly darker at a half-transparent edge; scaling in linear light is what the GPU undoes when it decodes the sRGB texture, so the edge blends to exactly the colour the file meant.
SrgbToLinear(byte)
Decodes one sRGB channel value to linear light, 0 to 1.
public static float SrgbToLinear(byte value)
Parameters
valuebyteThe stored byte.
Returns
SwapRedBlue(Span<Color>)
Swaps the red and blue channels in place: the engine's decoder hands back BGRA, a texture made from Color is RGBA.
public static void SwapRedBlue(Span<Color> pixels)