PDA

View Full Version : Strange Pixel Shader



DudeMiester
04-16-2005, 12:05 AM
I made this woot! It was done with Nvidia's CG, and only tested on a 6800 GT. The whole program follows.


struct Vert2Frag// : vertex2fragment
{
float4 Position : POSITION;
float2 TexCoord : TEXCOORD0;
float3 PixelPos : TEXCOORD1;
float3 Normal : TEXCOORD2;
float3 LightPos : TEXCOORD3;
};

struct Fragout
{
float4 Colour : COLOR;
};

float4 BlurSample(sampler2D Texture, float2 Coord, float Radius, float numSamples)
{
float Step=Radius/sqrt(numSamples)*2;
float4 Result={0, 0, 0, 0};

for(float x=-Radius; x<Radius; x+=Step)
for(float y=-Radius; y<Radius; y+=Step)
Result+=tex2D(Texture, Coord+float2(x, y));

return Result/numSamples;
}

Fragout PixelMain(Vert2Frag IN,
//Texture
uniform sampler2D Texture,
//Material Properties: X=Reflection Curvature
// Y=Diffusion Curvature
uniform float2 MaterialProp,
//Light Properties: XYZ=Light Colour (RGB)
// W=Light Intensity
uniform float4 LightProp)
{

Fragout OUT;

//Get the pixel colour from the texture with some blurring
float4 TexCol=BlurSample(Texture, IN.TexCoord, 0.01, 8);

//Create a normal pointing from the pixel to the light source
float3 LightRay=normalize(IN.LightPos-IN.PixelPos);

//Create a normal pointing from the pixel to the eye
float3 EyeDirection=normalize(-IN.PixelPos);

//Calculate the direction of the reflected light off the pixel
float3 ReflectRay=IN.Normal*dot(IN.Normal, LightRay)*2-LightRay;

//Calculate the reflected light by finding how close the central reflected ray is
//to being directly pointing to the eye, then modulate that value by the reflection
//curvature of the material, then amplifing it by the light intesity
float ReflectLight=LightProp.w*pow(max(dot(ReflectRay, EyeDirection), 0), 1);

//Calculate the absorbed light by finding how directly the light hits the pixel, and
//modulate that by the absorbtion curvature, and amplifing it by the light intesity
float AbsorbLight=LightProp.w*pow(abs(dot(LightRay, IN.Normal)), MaterialProp.y)+0.4;

//Crazy wave that consisted of many rings around the center of the screen
float Wave1=cos(sin(dot(IN.PixelPos, IN.PixelPos)*10));
//Even crazier wave that consists of horizontal bands that use the texture as an offset
float Wave2=cos((IN.PixelPos.y+TexCol.x/2)*20)*0.5+1;
float Fog=min(1+(IN.Position.z+3)/5, 1);

//Put it all together, taking into account the light's colour, and layering the reflected
//light on top of the brightness of the pixel
OUT.Colour.rgb=(AbsorbLight.xxx*TexCol.rgb-ReflectLight.xxx*Wave1)*LightProp.rgb*Wave2*Fog;

//Add the alpha
OUT.Colour.a=TexCol.a;

//And send the final colour off on its merry way
return OUT;
}

http://ca.geocities.com/dudemiester@rogers.com/SimpleProg.zip

I could post the source code, but I don't think it currently will compile. It's C++ btw.

masterofpuppets
04-18-2005, 12:06 PM
Some screenies would be nice for Linux users. ATi's driver's won't let me run pixel shaders :(