Algorithm for the left hand texture. It's just a 1d texture (a scanline of 1024 pixels)
unsigned int blend(unsigned int c0, unsigned int c1)
{
unsigned int r0,g0,b0,a0;
unsigned int r1,g1,b1,a1;
unsigned int r,g,b,a;
a0 = (c0>>24)&0xff;
r0 = (c0>>16)&0xff;
g0 = (c0>>8)&0xff;
b0 = (c0>>0)&0xff;
a1 = (c1>>24)&0xff;
r1 = (c1>>16)&0xff;
g1 = (c1>>8)&0xff;
b1 = (c1>>0)&0xff;
a = (a0+a1)>>1;
r = (r0+r1)>>1;
g = (g0+g1)>>1;
b = (b0+b1)>>1;
return (a<<24)|(r<<16)|(g<<8)|b;
}
void make_marble1d(void)
{
unsigned int marble[1024];
for (int x = 0; x < 1024; x++)
marble[x] = (x/64)*7*0x00010101+0xff7f7f7f;
for (int x = 100; x < 200; x++)
{
double p=0.5*(1.0+sin((x-100.0)*M_PI/100.0));
unsigned int c = 0xff7f7f7f+(unsigned int)(p*0x7f);
marble[x] = blend(marble[x],c);
}
for (int x = 500; x < 700; x++)
{
double p=0.5*(1.0+sin((x-500.0)*M_PI/200.0));
unsigned int c = 0xff7f3f3f+(unsigned int)(p*0x7f);
marble[x] = blend(marble[x],c);
}
for (int x = 600; x < 800; x++)
{
double p=0.5*(1.0+sin((x-600.0)*M_PI/200.0));
unsigned int c = 0xff3f3f3f+((unsigned int)(p*0x5f)<<16);
marble[x] = blend(marble[x],c);
}
for (int x = 900; x < 950; x++)
{
marble[x] = 0xff000000;
}
...
So, it's a 50% grey to 100% gray gradient over 1024 pixels with a pinky red bit added at 100-200pixels, a blue bit between 500-700, a red bit between 600 and 800 and a black bit between 900 and 950. The bilinear filtering deals with the discontinuities in this texture, which is cool.
The really cool bit is in the 3D texture where dozens of blends you'd need to do this on the CPU are replaced by a trilinear filter. Awesome stuff!
Jim