//Vertex program for bump reflection void main( float4 Position : POSITION, //in object space float2 TexCoord : TEXCOORD0, float3 T : TEXCOORD1, //in object space float3 B : TEXCOORD2, //in object space float3 N : TEXCOORD3, //in object space out float4 oPosition : POSITION, //in projection space out float4 oTexCoord : TEXCOORD0, out float4 oTangentToCubeSpace0 : TEXCOORD1, //first row of the 3x3 transform from tangent to cube space out float4 oTangentToCubeSpace1 : TEXCOORD2, //second row of the 3x3 transform from tangent to cube space out float4 oTangentToCubeSpace2 : TEXCOORD3, //third row of the 3x3 transform from tangent to cube space uniform float4x4 WorldViewProj, uniform float3x4 ObjToCubeSpace, uniform float3 EyePosition, // in cube space uniform float BumpScale) { // pass texture coordinates for fetching the normal map oTexCoord.xy = TexCoord.xy; // compute the 3x3 tranform from tangent space to object space float3x3 objToTangentSpace; // first rows are the tangent and binormal scaled by the bump scale objToTangentSpace[0] = BumpScale * T; objToTangentSpace[1] = BumpScale * B; objToTangentSpace[2] = N; // compute the 3x3 transform from tangent space to cube space: // TangentToCubeSpace = object2cube * tangent2object // = object2cube * transpose(objToTangentSpace) (since the inverse of a rotation is its transpose) // so a row of TangentToCubeSpace is the transform by objToTangentSpace of the corresponding row of ObjToCubeSpace oTangentToCubeSpace0.xyz = mul(objToTangentSpace, ObjToCubeSpace[0].xyz); oTangentToCubeSpace1.xyz = mul(objToTangentSpace, ObjToCubeSpace[1].xyz); oTangentToCubeSpace2.xyz = mul(objToTangentSpace, ObjToCubeSpace[2].xyz); // compute the eye vector (going from shaded point to eye) in cube space float3 eyeVector = EyePosition - mul(ObjToCubeSpace, Position); oTangentToCubeSpace0.w = eyeVector.x; oTangentToCubeSpace1.w = eyeVector.y; oTangentToCubeSpace2.w = eyeVector.z; // transform position to projection space oPosition = mul(WorldViewProj, Position); } ----------------------------------------------------- //fragment program for bump reflection void main( float4 Position : POSITION, //in projection space float4 TexCoord : TEXCOORD0, float4 TangentToCubeSpace0 : TEXCOORD1, //first row of the 3x3 transform from tangent to cube space float4 TangentToCubeSpace1 : TEXCOORD2, //second row of the 3x3 transform from tangent to cube space float4 TangentToCubeSpace2 : TEXCOORD3, //third row of the 3x3 transform from tangent to cube space out float4 Color : COLOR, uniform sampler2D NormalMap, uniform samplerCUBE EnvironmentMap) { // fetch the bump normal from the normal map float4 normal = tex2D(NormalMap); // transform the bump normal into cube space // then use the transformed normal and eye vector to compute a reflection vector // used to fetch the cube map // (we multiply by 2 only to increase brightness) Color = 2 * texCUBE_reflect_dp3x3(EnvironmentMap, TangentToCubeSpace0, TangentToCubeSpace1, normal); }