There is something I've been wanting to do for quite some time, I have an RSM that is stored in 3 textures:
one R32F, and two RGBA8.
- R32F : depth in meters (from camera that rendered the RSM)
- RGBA8 : normal storage in classical shifted to color space with " * 0.5 + 0.5 "
- RGBA8 : albedo
For optimisation, because 3 RT can be very heavy for some cards, I thought about compacting ALL of that, into ONE RGBA16F texture.
- R : depth, part 1
- G : depth, part 2 (+ sign bit for normal)
- B : normal
- A : color
I thought of for the depth, a simple range splitting should do the trick.
we decide of some multiple of a distance that the "MSB" will store, and the LSB will store the rest.
R = floor(truedepth / 100) * 100; G = truedepth - R;
for the normal, we could store the x in the first 8 MSbits using the same trick, and the y in the 8 LSB.
the z can be reconstructed using the sign stored in the depth. knowing we are on a sphere there is just a square root to evaluate.
(and when reading depth we just always think of doing abs(tex2d(depth).r))
for the color, it would be a 16 bits color, stored in HLS with the same trick, again, of "floor" and "modulo" to park the values in 6/5/5 bits.
knowing we have 16 bits IEEE754 half floats per channel here.
checking wikipedia, the precision is at least integer until 1024,
therefore should be increasing by steps of 32 between 32k and 65k.
and by steps of 0.00098 max between 0 and 1.
the issue is, what space slices should we use for the depth divisor ??
and would it be better stored if using a logarithmic depth ?
but in that case it would still need slicing since we need to store the depth in 32bits, so on two components, I suppose in that case the slicing will be logarithmic too ?
about the normal, I feel that there is a danger storing them like this, because some direction will have more precision than others.
the color is not really an issue, RSM don't need precise albedo.
what do you think ?
thanks in advance !