I want to have an R8G8B8A8 texture where 2 channels hold IDs and i want the last 2 channels to hold a weight. How do i do that?
Storing value across two texture channels?
You can sort of think of it as two base-256 digits. So if you wanted to store the value 1000 there, you would have:
B: (1000 / 256 ) A: (1000 - 1000 / 256 * 256) // (integer math)
B: 3 A: 232
And then to reconstruct:
weight = B * (256 ^ 1) + A * (256 ^ 0)
weight = 3 * 256 + 232 * 1
weight = 1000
Of course, if it's a weight, you're probably expecting normalized [0-1] values. (Splitting it across 2 channels gives you 65536 separate weights between 0 and 1 instead of 256). In this case, multiply the weight by 256 and use the fractional and non fractional values.
So, in HLSL for instance:
float weightTemp = weight * 256;
float bValue = floor(weightTemp) / 256; // bring it back to [0-1] so it fits in B
float aValue = frac(weightTemp);
Then to reconstruct:
float4 weightTemp; // Assume this is the texture sample
float weight = weightTemp.b + weightTemp.a / 256;
Note that texture filtering doesn't make sense anymore if you're storing a value across two channels. So you'll have to use point sampling.
Cascade Quest - IceFall Games - Dev blog - twitter - youtube
You an use 1000 % 256 to get the remainder instead of doing A = (1000 - 1000 / 256 * 256)
And if you want to encode values in the interval [0, 1] into a byte you multiply or divide by 255 instead of 256.