/* Bump mapping with Parallax offset vertex program In this program, we want to calculate the tangent space light end eye vectors which will get passed to the fragment program to produce the per-pixel bump map with parallax offset effect. */ #include "Common.cg" float4 lightPosition; float3 eyePosition; float4x4 worldViewProj; float3 lightDiffuse; float3 lightSpecular; float4 scaleBias; sampler2D normalHeightMap; sampler2D diffuseMap; struct app2vertOffsetMapping { float4 position : POSITION; float3 normal : NORMAL; float2 uv : TEXCOORD0; float3 tangent : TANGENT; }; struct vert2fragOffsetMapping { float4 position : POSITION; float2 uv : TEXCOORD0; float3 lightDir : TEXCOORD1; float3 eyeDir : TEXCOORD2; float3 halfAngle : TEXCOORD3; }; /* Vertex program that moves light and eye vectors into texture tangent space at vertex */ vert2fragOffsetMapping main_vp(app2vertOffsetMapping IN) { vert2fragOffsetMapping OUT; // calculate output position OUT.position = mul(worldViewProj, IN.position); // pass the main uvs straight through unchanged OUT.uv = IN.uv; half3 lightDir = getLightDirection(lightPosition, IN.position); half3 eyeDir = getEyeDirection(eyePosition, IN.position); // Form a rotation matrix out of the vectors half3x3 TBN = getTBNMatrix(IN.tangent, IN.normal); // Transform the light vector according to this matrix OUT.lightDir = normalize(mul(TBN, lightDir)); OUT.eyeDir = normalize(mul(TBN, eyeDir)); OUT.halfAngle = normalize(OUT.eyeDir + OUT.lightDir); return OUT; } outPixel main_fp(vert2fragOffsetMapping IN) { outPixel OUT; half displacement = getDisplacement(normalHeightMap, IN.uv, scaleBias.x, scaleBias.y); float3 uv2 = float3(IN.uv, 1); // calculate the new tex coord to use for normal and diffuse float2 newTexCoord = ((IN.eyeDir * displacement) + uv2).xy; // get the new normal and diffuse values half3 normal = getNormalMapVector(normalHeightMap, newTexCoord); half3 diffuse = tex2D(diffuseMap, newTexCoord).xyz; half3 specular = getSpecularComponent(normal, IN.halfAngle, lightSpecular, 32); half3 col = diffuse * getLightingComponent(normal, IN.lightDir, lightDiffuse) + specular; OUT.colour = float4(col, 1); return OUT; }