// Bump Mapping FX // [FullArbTechnique] // // Profile: ARBVP1 // Options: position invariant // Copyright 2003 by Marco Jez struct Vertex_data { float4 Position : POSITION; // vertex position float4 Normal : NORMAL; // vertex normal float2 TexCoordC : TEXCOORD0; // color map texture coordinates float2 TexCoordN : TEXCOORD1; // normal map texture coordinates float3 T : ATTR3; // tangent vector float3 B : ATTR4; // binormal vector float3 N : ATTR5; // normal vector }; struct Fragment_data { float4 Position : POSITION; // homogeneous position float4 LightVector : COLOR0; // tangent space; component w is the diffuse shadowing term float4 HalfWayVector : COLOR1; // tangent space; component w is the specular shadowing term float4 TexCoordC : TEXCOORD0; // color map texture coordinates, components zw are red/green of specular color float4 TexCoordN : TEXCOORD1; // normal map texture coordinates, components zw are blue/alpha of specular color float4 AmbientAndShininess : TEXCOORD2; // ambient color; component w is the specular exponent }; Fragment_data main(Vertex_data input, uniform float4x4 VI) { // compute model matrix float4x4 M = mul(VI, glstate.matrix.modelview[0]); // compute rotational model transform float3x3 RotOnlyModel; RotOnlyModel[0] = M[0].xyz; RotOnlyModel[1] = M[1].xyz; RotOnlyModel[2] = M[2].xyz; Fragment_data output; // pass ambient color output.AmbientAndShininess.xyz = glstate.lightprod[0].ambient.xyz; // pass specular exponent output.AmbientAndShininess.w = glstate.material.shininess.x; // pass specular color output.TexCoordC.zw = glstate.lightprod[0].specular.xy; output.TexCoordN.zw = glstate.lightprod[0].specular.zw; // pass texture coordinates for fetching the color map output.TexCoordC.xy = input.TexCoordC; // pass texture coordinates for fetching the normal map output.TexCoordN.xy = input.TexCoordN; // compute the 3x3 tranform from object space to tangent space float3x3 objToTangentSpace; objToTangentSpace[0] = mul(RotOnlyModel, input.T); objToTangentSpace[1] = mul(RotOnlyModel, input.B); objToTangentSpace[2] = mul(RotOnlyModel, input.N); // compute view point float3 viewPoint = mul(VI, float4(0, 0, 0, 1)).xyz; // compute view vector using world-space vertex position float3 viewVector = normalize(viewPoint - mul(M, input.Position).xyz); // compute world-space normal float3 worldNormal = normalize(mul(RotOnlyModel, input.Normal.xyz)); // compute world-space light vector float3 worldLight = normalize(mul(VI, glstate.light[0].position).xyz); // compute half angle vector in object space float3 HalfWayVector = normalize(worldLight + viewVector); // transform half angle vector from object space to tangent space and pass it as a color output.HalfWayVector.xyz = 0.5 * mul(objToTangentSpace, HalfWayVector) + 0.5.xxx; // compute specular shadowing term output.HalfWayVector.w = 4 * dot(worldNormal, HalfWayVector); // transform light vector from object space to tangent space and pass it as a color output.LightVector.xyz = 0.5 * mul(objToTangentSpace, worldLight) + 0.5.xxx; // compute diffuse shadowing term output.LightVector.w = 4 * dot(worldNormal, worldLight); // transform position to projection space output.Position = mul(glstate.matrix.mvp, input.Position); return output; }