View Full Version : Real world example where 24-bits isn't enough for graphics.
bloodbob
20-Nov-2003, 14:04
Well not really doing any shader stuff till today ( was fiddling with the shaders in humus' latest demo ) I really didn't expect to hit the 24-bit limit so soon.
Where I hit the 24-bit limit for reference was converting a texture into HSV modifing the hue value and converting back to RGB. There is conditional code based on the hue value but with the lack of precision certain textures ( such as enivorment maps in humus' demo ) end up following the incorrect branching.
Can anyone else give me some real world examples where 24-bits just isn't enough.
The shader 23 (water colour like rendering) in ShaderMark v2.0 is a real simple shader(summed area tables), but if you run it at high resolutions (1600x1200) you will see some wrong coloured pixel on the r3xx. With the refrast. they are gone, I think because of the 32 bit prec. per component.
Thomas
HSV to RGB and back should work just fine with 24bit. Heck, I implemented that using 3D texture lookups in 8bit/channel when I was at ATI, and the results were virtually identical to those using full math. The full math example is included in the latest RenderMonkey if you want to take a look at it.
bloodbob
21-Nov-2003, 01:39
My water.shd try it out and notice the pink stuff. Then remove the line of code as mentioned in the comments. I have you a nicer way for me to wrap the range please feel free to tell me.
By the way normal its a range 0-360 but for obvious reasons I've worked with 0-6.
[Vertex shader]
float4x4 view_proj_matrix;
float3 camPos;
struct VS_OUTPUT {
float4 Pos: POSITION;
float2 texCoord: TEXCOORD0;
float3 viewVec: TEXCOORD1;
};
VS_OUTPUT main(float4 pos: POSITION, float2 texCoord: TEXCOORD0){
VS_OUTPUT Out;
Out.Pos = mul(view_proj_matrix, pos);
Out.texCoord = texCoord;
Out.viewVec = pos - camPos;
return Out;
}
[Fragment shader]
sampler Tex: register(s0);
sampler Env: register(s1);
float off;
float4 main(float2 texCoord: TEXCOORD0, float3 viewVec: TEXCOORD1) : COLOR {
float4 texy = texCUBE(Env, float3( texCoord , 0.5 ));
float min = min( min (texy.x, texy.y), texy.z );
float maxy = max( max(texy.x, texy.y), texy.z );
float delta = maxy-min;
float s = delta / maxy;
float h= ( texy.y - texy.z ) / delta;
if( texy.x == maxy )
{
}
else if( texy.y == maxy )
{
h = 2 + ( texy.z - texy.x ) / delta;
}
else
{
h = 4 + ( texy.x - texy.y ) / delta;
}
if( h < 0.0 ) h+=6.0;
h=clamp(h, 0, 6.0);//(h,6.0);
h=frac(h/6.0)*6.0; /// THE PROBLEM LIES HERE WHEN I DO MODIFICATION HERE
// AND THEN USE FRAC TO WRAP THE VALUES TO THE RANGE [0,6] I LOOSE TO MUCH PRECESSION
// NO MODIFICATION IS BEING DONE IN THIS CODE REMOVE THIS LINE AND NOTICE THE ARTIFACTS ARE GONE
int i = floor (h);
float r,g,b;
float f = h - i;
float p = maxy * ( 1 - s );
float q = maxy * ( 1 - s * f );
float t = maxy * ( 1 - s * ( 1 - f ) );
if( i == 0 )
{
r = maxy;
g = t;
b = p;
}
else if( i == 1 )
{
r = q;
g = maxy;
b = p;
}
else if( i == 2 )
{
r = p;
g = maxy;
b = t;
}else if( i == 3 )
{
r = p;
g = q;
b = maxy;
}else if( i == 4 )
{
r = t;
g = p;
b = maxy;
}
else{
r = maxy;
g = p;
b = q;
}
return float4( r,g,b,0);
}
Well, the == operator is always sensitive to precision. Especially since DX9 HLSL implements floor(x) as x - frac(x). So you should be using < instead. Like this:
if( h < 1 )
{
r = maxy;
g = t;
b = p;
}
else if( h < 2 )
{
r = q;
g = maxy;
b = p;
}
...
bloodbob
22-Nov-2003, 02:19
Spanks humus very nice still I guess this is where we need true integer support I assumed incorrectly that it would return the closest float representation of the integer.
vBulletin® v3.8.6, Copyright ©2000-2013, Jelsoft Enterprises Ltd.