RGB into a single float16

A place for Ogre users to discuss non-Ogre subjects with friends from the community.
Post Reply
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 116

RGB into a single float16

Post by mkultra333 »

I considered putting this in the "Ogre in Practice" forum, but it's more a shader thing than a strictly Ogre thing.

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) ;
The deferred code reconstructs the colour like this:

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 ;
	///////////////////////////////////////////////////////////
Seems to work as intended on my Nvidia GT7950. I'm a little worried though, because I wonder how stable and reliable float16 numbers are across graphics cards and drivers. Any floating point noise would seriously mess up the above.

What do you think? Should it hold up ok, or are float16s, drivers and cards so variable that it'd probably break?
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
Post Reply