I needed two more slots in my GBuffer but it was already packed tight, so something had to give. I decided that instead of a full 3 float16 RGB specular I'd squeeze the whole specular into a single float16. There's also another float16 for specular exponent with remains untouched.
AFAIK a float16 gives you 12 bits of mantissa accuracy (technically 11 plus 1 implied bit that's always there unless the float is zero.) So I figure I can get roughly 12 bit colour accuracy, which is 16 levels each for red, green and blue. While that wouldn't do for diffuse, I figure I can get away with it on specular.
I use the following code to write the colour to the GBuffer.
Code: Select all
// we compress the specular colour into a single float16, so it's equivalent to 12 bit colour.
float4 Specular=tex2D(SpecularMap,IN.uv.xy).rgba ;
float2 SpecComp ;
SpecComp.y=Specular.a ;
SpecComp.x= floor(Specular.r*15.99)*256.0 + floor(Specular.g*15.99)*16.0 + floor(Specular.b*15.99) ;
colour3=float4(0,0,SpecComp) ;
Code: Select all
/////////////////////////////////////////////////////////////
// convert single float16 RGB (12bit-ish) to float3 (24bit-ish) RGB
float4 SpecTemp = tex2D(SpecularMap,screenUV.xy).rgba ;
float4 SpecColor ;
SpecColor.a=SpecTemp.a ;
SpecColor.r=floor(SpecTemp.z/256.0f) ;
SpecColor.g=floor((SpecTemp.z-SpecColor.r*256.0f)/16.0f) ;
SpecColor.b=floor(SpecTemp.z-SpecColor.r*256.0f-SpecColor.g*16.0f) ;
SpecColor.rgb/=16.0f ;
///////////////////////////////////////////////////////////
What do you think? Should it hold up ok, or are float16s, drivers and cards so variable that it'd probably break?
