Dark Bit Factory & Gravity

GENERAL => Challenges & Competitions => Topic started by: Jim on May 11, 2008

Title: [PROCEDURAL] Spider!
Post by: Jim on May 11, 2008
Here's my entry - my first real go at glsl shaders!  It has perlin noise via a 3D texture, and a 1d texture for the marble and wood.  It also has per-pixel specular lighting.  Hope it runs on everyone's kit because debugging glsl isn't that much fun :)  I have an 8600GT.

Jim
Title: Re: [PROCEDURAL] Spider!
Post by: energy on May 11, 2008
Very good...
Runs fine here XPSP2
Nvidea quadro nvs 110m

Cheers eNeRGy
Title: Re: [PROCEDURAL] Spider!
Post by: Shockwave on May 11, 2008
On ati x1650 cards you get the objects but no textures, basically the shapes are there but they are grey.
Title: Re: [PROCEDURAL] Spider!
Post by: Optimus on May 11, 2008
It looks great on the screenshot but doesn't even start on my Ati Radeon 9600 Pro. I just click on it and it does nothing. It doesn't need any d3dx dll or anything else, does it?
Title: Re: [PROCEDURAL] Spider!
Post by: Jim on May 11, 2008
It needs d3dx, an oldish one, but it would tell you about that.
The ATI problem is that it doesn't like the pixel shader - how is anyone supposed to debug this?!

I'll have to make a debug version...

Jim
PS. Here are my shader programs if anyone has any ideas.
Code: [Select]
//setup for per-pixel lighting
const char *Spider::vsh=
"varying vec4 t;"\
"varying vec4 u;"\
"varying vec3 v;"\
"varying vec4 diffuse, ambient;"\
"varying vec3 normal,lightDir,halfVector;"\
"void main() {"\
"normal = normalize(gl_NormalMatrix * gl_Normal);"\
"lightDir = normalize(vec3(gl_LightSource[0].position));"\
"halfVector = normalize(gl_LightSource[0].halfVector.xyz);"\
"diffuse = gl_LightSource[0].diffuse;"\
"ambient = gl_LightSource[0].ambient;"\
"gl_TexCoord[0] = gl_MultiTexCoord0;"\
"u = gl_Vertex;"\
"v = gl_Vertex.xyz;"\
"gl_Position = t = ftransform();"\
"}";

//marble
const char *Spider::fsh_marble=
"varying vec4 u;"\
"varying vec3 v;"\
"uniform sampler1D tex2;"\
"uniform sampler3D tex3;"\
"uniform float scale;"\
"varying vec4 diffuse,ambient;"\
"varying vec3 normal,lightDir,halfVector;"\
"void main() {"\
"vec3 r = v*scale;"\
"vec3 n0 = texture3D(tex3,r)*0.9;"\
"vec3 n1 = texture3D(tex3,r*2)*0.5;"\
"vec3 n2 = texture3D(tex3,r*4)*0.2;"\
"vec3 n3 = texture3D(tex3,r*8)*0.1;"\
"vec3 q = cos(r+n0+n1+n2+n3);"\
"vec3 n,halfV;"\
"float NdotL,NdotHV;"\
"vec4 color = ambient;"\
"n = normalize(normal);"\
"NdotL = max(dot(n,lightDir),0.0);"\
"if (NdotL > 0.0) {"\
"color += diffuse * NdotL;"\
"halfV = normalize(halfVector);"\
"NdotHV = max(dot(n,halfV),0.0);"\
"color += "\
"gl_LightSource[0].specular * "\
"pow(NdotHV, 10.0);}"\
"gl_FragColor = texture1D(tex2,q.x)*color;"\
"}";

//wood
const char *Spider::fsh_wood=
"varying vec4 u;"\
"varying vec3 v;"\
"uniform sampler1D tex2;"\
"uniform sampler3D tex3;"\
"uniform float scale;"\
"varying vec4 diffuse,ambient;"\
"varying vec3 normal,lightDir,halfVector;"\
"void main() {"\
"vec3 r = v*scale;"\
"vec3 n0 = texture3D(tex3,r)*0.9;"\
"vec3 n1 = texture3D(tex3,r*2)*0.5;"\
"vec3 n2 = texture3D(tex3,r*4)*0.2;"\
"vec3 n3 = texture3D(tex3,r*8)*0.1;"\
"vec3 g = (n0+n1+n2+n3)*20;"\
"g = fract(g);"\
"r.xy*=500;"\
"r.z*=200;"\
"n0 = texture3D(tex3,r)*0.5;"\
"n1 = texture3D(tex3,r*2)*0.3;"\
"n2 = texture3D(tex3,r*4)*0.15;"\
"n3 = texture3D(tex3,r*8)*0.05;"\
"vec3 h=n0+n1+n2+n3+0.5;"\
"h=floor(h)*0.1+1;"\
"vec3 n,halfV;"\
"float NdotL,NdotHV;"\
"vec4 color = ambient;"\
"n = normalize(normal);"\
"NdotL = max(dot(n,lightDir),0.0);"\
"if (NdotL > 0.0) {"\
"color += diffuse * NdotL;"\
"halfV = normalize(halfVector);"\
"NdotHV = max(dot(n,halfV),0.0);"\
"color += "\
"gl_LightSource[0].specular * "\
"pow(NdotHV, 10.0);}"\
"gl_FragColor = texture1D(tex2,g.x)*vec4(h,1)*color;"\
"}";
Thanks to lighthouse3d.com (http://lighthouse3d.com) for the lighting tutorials!
Title: Re: [PROCEDURAL] Spider!
Post by: hellfire on May 12, 2008
Hi Jim,

a texture-lookup returns a vec4 (rgba). when you assign it to a vec3, the ati-shader-compiler wets its' pants while the nvidia-compiler drops the 4th component silently.
Just add a cast:
Code: [Select]
vec3 n0 = vec3(texture3D(tex3,r)*0.9);
vec3 n1 = vec3(texture3D(tex3,r*2)*0.5);
vec3 n2 = vec3(texture3D(tex3,r*4)*0.2);
vec3 n3 = vec3(texture3D(tex3,r*8)*0.1);

Title: Re: [PROCEDURAL] Spider!
Post by: rain_storm on May 12, 2008
It runs here just like the screenies but at a very low frame rate maybe 4 fps
Title: Re: [PROCEDURAL] Spider!
Post by: Clyde on May 12, 2008
Nice one Jim :)
Title: Re: [PROCEDURAL] Spider!
Post by: Jim on May 12, 2008
Thanks to Hellfire (cheers mate!), I've udpated the texture3D calls to use vec3 and replaced the zip file on the OP.
I've also added a MessageBox to the compiler if it comes up with an error.

Jim
Title: Re: [PROCEDURAL] Spider!
Post by: hellfire on May 12, 2008
Now works perfectly on my Radeon 9600.
I especially like the left material.
But i'm wondering why you need d3dx when using glsl ???
Title: Re: [PROCEDURAL] Spider!
Post by: Jim on May 13, 2008
Thanks for testing!
The code sits in my framework which has an image loader in it based on d3dx.  I should make it more modular so I can take chunks out - there's a whole sprite/font engine in there too!

Jim
Title: Re: [PROCEDURAL] Spider!
Post by: Rbz on May 13, 2008
Works like a charm here Jim, congrats for your first shader program!
Title: Re: [PROCEDURAL] Spider!
Post by: hellfire on May 13, 2008
If no d3dx9_32.dll is found, the application exits without further information.
Just so you know.
Title: Re: [PROCEDURAL] Spider!
Post by: benny! on May 13, 2008
Good one, Jim!
Title: Re: [PROCEDURAL] Spider!
Post by: Jim on May 13, 2008
d3dx9_32.dll is ancient history (Dec 06?), so anyone with a well maintained Windows box should have it.  If not go here... http://www.microsoft.com/downloads/details.aspx?FamilyID=2da43d38-db71-4c1b-bc6a-9b6652cd92a3&DisplayLang=en (http://www.microsoft.com/downloads/details.aspx?FamilyID=2da43d38-db71-4c1b-bc6a-9b6652cd92a3&DisplayLang=en)...and it will very intelligently work out what you do and don't have, DirectX-wise, and just download a few Mb of updates.
Sorry about the requirement, but any up-to-date games machine will have all these dlls.

Thanks again to Hellfire for helping me fix my PS and thanks to everyone else for the great comments!

Jim
Title: Re: [PROCEDURAL] Spider!
Post by: Jim on May 13, 2008
Algorithm for the left hand texture.  It's just a 1d texture (a scanline of 1024 pixels)
Code: [Select]
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
Title: Re: [PROCEDURAL] Spider!
Post by: Shockwave on May 13, 2008
It is working like a charm here now :)