normalspot.shader

00001 
00002 varying vec4 vColour;
00003 varying vec3 vEye;
00004 varying vec3 vLightDir;
00005 varying vec3 vHalf;
00006 varying vec3 vSpot;
00007 varying float vDist;
00008 
00009 attribute vec3 tangent;
00010 
00011 uniform int vShadowCount;
00012 varying vec4 vProjected;
00013 
00014 void main() 
00015 {
00016     //Put the color in a varying variable
00017     vColour = gl_Color * gl_FrontMaterial.diffuse;
00018 
00019     //Use the first set of texture coordinates in the fragment shader 
00020     gl_TexCoord[0] = gl_MultiTexCoord0;
00021 
00022     // Get the normal and normalize
00023     vec3 vN = normalize( gl_NormalMatrix * gl_Normal );
00024 
00025     // Get this fragment's position
00026     vec4 vPos = gl_ModelViewMatrix * gl_Vertex;
00027 
00028     // Get the light's direction
00029     vec3 vTmp = gl_LightSource[0].position.xyz - vPos.xyz;
00030 
00031     // Get the distance
00032     vDist = length( vTmp );
00033 
00034 ///// Normal mapping specific:
00035 
00036     // Get the tangent and normalise
00037     vec3 vT = normalize( gl_NormalMatrix * tangent );
00038 
00039     // Get the binormal
00040     vec3 vB = cross( vN, vT );
00041 
00042     // Get the light's direction
00043     vLightDir.x = dot( vTmp, vT );
00044     vLightDir.y = dot( vTmp, vB );
00045     vLightDir.z = dot( vTmp, vN );
00046 
00047     // Get the half vector
00048     vTmp = gl_LightSource[0].halfVector.xyz;
00049     vHalf.x = dot( vTmp, vT );
00050     vHalf.y = dot( vTmp, vB );
00051     vHalf.z = dot( vTmp, vN );
00052 
00053     // Get the spot direction
00054     vTmp = gl_LightSource[0].spotDirection;
00055     vSpot.x = dot( vTmp, vT );
00056     vSpot.y = dot( vTmp, vB );
00057     vSpot.z = dot( vTmp, vN );
00058 
00059     // Get the eye vector
00060     vTmp = -vPos.xyz;
00061     vEye.x = dot( vTmp, vT );
00062     vEye.y = dot( vTmp, vB );
00063     vEye.z = dot( vTmp, vN );
00064 
00065 ///// Shadow specific:
00066 
00067     // Get the projected position
00068     vProjected = gl_TextureMatrix[1] * vPos;
00069 
00070     // Transform the position to screen space
00071     gl_Position = ftransform(); 
00072 }
00073 
00074 ~~~~~
00075 
00076 varying vec4 vColour;
00077 varying vec3 vEye;
00078 varying vec3 vLightDir;
00079 varying vec3 vHalf;
00080 varying vec3 vSpot;
00081 varying float vDist;
00082 
00083 uniform sampler2D Texture0;
00084 uniform sampler2DShadow Texture1;
00085 
00086 uniform int vShadowCount;
00087 varying vec4 vProjected;
00088 
00089 #define KERNEL_SIZE   3.0
00090 #define KERNEL_AREA  16.0
00091 #define BLUR        0.003
00092 
00093 void main() 
00094 {
00095     // Get the ambient colour as a base
00096     vec4 vBase  = vec4( 0.0, 0.0, 0.0, 1.0 );
00097     vec4 vLight = vec4( 0.0, 0.0, 0.0, 1.0 );
00098 
00099     // If we have a shadow...
00100     if ( vShadowCount > 0 )
00101     {
00102         // Normalize the projected vector
00103         vec3 tmp = vProjected.xyz / vProjected.w;
00104     
00105         // If it's not in range, set depth to zero anyway
00106         if ( tmp.x >= 0.0 && tmp.x <= 1.0 && tmp.y >= 0.0 && tmp.y <= 1.0 )
00107         {
00108             // Mark as in shadow or not, depending on the map
00109             // vBase += shadow2D( Texture1, tmp );
00110             for ( float x = -KERNEL_SIZE + 1.0; x < KERNEL_SIZE; x += 1.0 )
00111             {
00112                 for ( float y = -KERNEL_SIZE + 1.0; y < KERNEL_SIZE; y += 1.0 )
00113                 {
00114                     vBase += shadow2D( Texture1, tmp + vec3( BLUR * x, BLUR * y, 0 ) );
00115                 }
00116             }
00117             vBase /= KERNEL_AREA;
00118         }
00119     }
00120 
00121     // Get the bump vector
00122     vec3 vN = normalize( texture2D( Texture0, gl_TexCoord[0].xy ).xyz * 2.0 - 1.0 );
00123     vN.y = -vN.y;
00124 
00125     // Get the light vector
00126     vec3 vL = normalize( vLightDir );
00127 
00128     // Get NdotL and make sure it's +ve before getting the specular
00129     float NdotL = dot( vN, vL );
00130 
00131     // Get the attenuation
00132     float att = 0.0;
00133 
00134     // Do we do specular?
00135     if ( NdotL > 0.0 )
00136     {
00137         // Get the spot direction
00138         vec3 vS = normalize( vSpot );
00139 
00140         // Get the effected area of the spotlight
00141         float effect = dot( vS, -vL );
00142 
00143         // If it's in range...
00144         if ( effect > gl_LightSource[0].spotCosCutoff )
00145         {
00146             // Boost the effect
00147             effect = pow( effect, gl_LightSource[0].spotExponent );
00148 
00149             // Get the attenuation
00150             att = effect / ( gl_LightSource[0].constantAttenuation +
00151                     gl_LightSource[0].linearAttenuation * vDist +
00152                     gl_LightSource[0].quadraticAttenuation * vDist * vDist );
00153 
00154             // Add the diffuse component of the light
00155             vLight = att * NdotL * gl_LightSource[0].diffuse;
00156 
00157             // Get the half vector
00158             vec3 vH = normalize( vHalf );
00159 
00160             // Dot it with the eye
00161             NdotL = max( dot( vN, vH ), 0.0 ); 
00162 
00163             // Now add the specular component
00164             vLight +=   att * 
00165                         pow( NdotL, gl_FrontMaterial.shininess ) *      // Power
00166                         gl_FrontMaterial.specular *                     // Material Specular
00167                         gl_LightSource[0].specular;                     // Light Specular
00168         }
00169     }
00170 
00171     // Output the fragment colour
00172     gl_FragColor = vec4( vBase.xyz, 1 ) * vLight;
00173 }

Generated on Fri Mar 23 12:55:03 2007 for glsldemo by  doxygen 1.5.1-p1