Table of Contents

Class TexturePixels

Namespace
Stride.CommunityToolkit.Rendering
Assembly
Stride.CommunityToolkit.dll

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

baseLevel Color[]

The largest level, prepared for its role: premultiplied, flipped.

width int

Its width.

height int

Its height.

role TextureRole

What 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

pixels Span<Color>

The pixels.

LinearToSrgb(float)

Encodes a linear value, clamped to 0 to 1, as an sRGB channel byte.

public static byte LinearToSrgb(float value)

Parameters

value float

The linear value.

Returns

byte

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

width int

The width of the largest level.

height int

The height of the largest level.

Returns

int

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

pixels Span<Color>

The pixels, sRGB, straight alpha.

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

value byte

The stored byte.

Returns

float

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)

Parameters

pixels Span<Color>

The pixels.