Several threads here and on beyond3d forums inspired me to do some tests on data compression. I implemented a simple shader using the shader designer (superb tool!) that show how to use bump-mapping without that annoying tangent attribute per vertex The tangent space is calculated per-fragment and is used to transform the bump-map normal to the camera space. Below is the fragment shader (the vertex shader just transforms light, position and normal to camera space, so I left it out)

```
varying vec2 texCoord;
varying vec3 g_normal;
varying vec3 g_light;
varying vec3 g_pos;
void main()
{
vec3 color = texture2D(ColorMap, texCoord).rgb;
vec3 normal = texture2D(BumpMap, texCoord).rgb*2.0 - 1.0;
// compute tangent T and bitangent B
vec3 Q1 = dFdx(g_pos);
vec3 Q2 = dFdy(g_pos);
vec2 st1 = dFdx(texCoord);
vec2 st2 = dFdy(texCoord);
vec3 T = normalize(Q1*st2.t - Q2*st1.t);
vec3 B = normalize(-Q1*st2.s + Q2*st1.s);
// the transpose of texture-to-eye space matrix
mat3 TBN = mat3(T, B, g_normal);
// transform the normal to eye space
normal = normal*TBN;
// diffuse term
float diffuse = dot(g_light, normal);
// and the color...
gl_FragColor.rgb = diffuse*color;
}
```

As said, I only tried it out with the Shader Designer, and there is no noticeable difference to standard approach (using the precomputed vertex attributes). The question is, of course, the performance. Unfortunately, I have no â€śrealâ€ť bump-mapping code at hand to benchmark it have , so I thought, maybe someone here who already does camera-space bump-mapping can give it a try

Just a side note: I did some tests with YCoCg color space and S3tc compression, being able to store a RGB+height texture at 4:1 compression rate, without any visible quality loss. The normal can be generated from height (this is pretty cheap too, only three texture fetches and some basic math). This is 1024*1024 color+bump map in 1Mb! I am not sure if it is still too early for per-pixel bump-map computation, but YCoCg color decompression is almost free.