normalproj.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 uniform sampler2D Texture2;
00086 
00087 uniform int vShadowCount;
00088 varying vec4 vProjected;
00089 
00090 #define KERNEL_SIZE   3.0
00091 #define KERNEL_AREA  16.0
00092 #define BLUR        0.003
00093 
00094 void main() 
00095 {
00096     // Get the ambient colour as a base
00097     vec4 vBase = vec4( 0.0, 0.0, 0.0, 1.0 );
00098     vec4 vLight = vec4( 0.0, 0.0, 0.0, 1.0 );
00099     
00100     // Normalize the projected vector
00101     vec3 tmp = vProjected.xyz / vProjected.w;
00102 
00103     // If it's not in range, set depth to zero anyway
00104     if ( tmp.x >= 0.0 && tmp.x <= 1.0 && tmp.y >= 0.0 && tmp.y <= 1.0 )
00105     {
00106         // If we have a shadow...
00107         if ( vShadowCount > 0 )
00108         {
00109             // Mark is totally in shadow
00110             // vBase += shadow2D( Texture1, tmp );
00111             for ( float x = -KERNEL_SIZE + 1.0; x < KERNEL_SIZE; x += 1.0 )
00112             {
00113                 for ( float y = -KERNEL_SIZE + 1.0; y < KERNEL_SIZE; y += 1.0 )
00114                 {
00115                     vBase += shadow2D( Texture1, tmp + vec3( BLUR * x, BLUR * y, 0 ) );
00116                 }
00117             }
00118             vBase /= KERNEL_AREA;
00119         }
00120 
00121         // Modulate with the projected texture
00122         vBase *= texture2D( Texture2, vec2( tmp.x, 1.0 - tmp.y ) );
00123     }
00124 
00125     // Get the bump vector
00126     vec3 vN = normalize( texture2D( Texture0, gl_TexCoord[0].xy ).xyz * 2.0 - 1.0 );
00127     vN.y = -vN.y;
00128 
00129     // Get the light vector
00130     vec3 vL = normalize( vLightDir );
00131 
00132     // Get NdotL and make sure it's +ve before getting the specular
00133     float NdotL = dot( vN, vL );
00134 
00135     // Get the attenuation
00136     float att = 0.0;
00137 
00138     // Do we do specular?
00139     if ( NdotL > 0.0 )
00140     {
00141         // Get the spot direction
00142         vec3 vS = normalize( vSpot );
00143 
00144         // Get the effected area of the spotlight
00145         float effect = dot( vS, -vL );
00146 
00147         // If it's in range...
00148         if ( effect > gl_LightSource[0].spotCosCutoff )
00149         {
00150             // Boost the effect
00151             effect = pow( effect, gl_LightSource[0].spotExponent );
00152 
00153             // Get the attenuation
00154             att = effect / ( gl_LightSource[0].constantAttenuation +
00155                     gl_LightSource[0].linearAttenuation * vDist +
00156                     gl_LightSource[0].quadraticAttenuation * vDist * vDist );
00157 
00158             // Add the diffuse component of the light
00159             vLight = att * NdotL * gl_LightSource[0].diffuse;
00160 
00161             // Get the half vector
00162             vec3 vH = normalize( vHalf );
00163 
00164             // Dot it with the eye
00165             NdotL = max( dot( vN, vH ), 0.0 ); 
00166 
00167             // Now add the specular component
00168             vLight +=   att * 
00169                         pow( NdotL, gl_FrontMaterial.shininess ) *      // Power
00170                         gl_FrontMaterial.specular *                     // Material Specular
00171                         gl_LightSource[0].specular;                     // Light Specular
00172         }
00173     }
00174 
00175     // Output the fragment colour
00176     gl_FragColor = vec4( vBase.xyz, 1 ) * vLight;
00177 }

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