| 1 | /* Bump mapping with Parallax offset vertex program |
|---|
| 2 | In this program, we want to calculate the tangent space light end eye vectors |
|---|
| 3 | which will get passed to the fragment program to produce the per-pixel bump map |
|---|
| 4 | with parallax offset effect. |
|---|
| 5 | */ |
|---|
| 6 | |
|---|
| 7 | #include "Common.cg" |
|---|
| 8 | |
|---|
| 9 | float4 lightPosition; |
|---|
| 10 | float3 eyePosition; |
|---|
| 11 | float4x4 worldViewProj; |
|---|
| 12 | |
|---|
| 13 | float3 lightDiffuse; |
|---|
| 14 | float3 lightSpecular; |
|---|
| 15 | float4 scaleBias; |
|---|
| 16 | sampler2D normalHeightMap; |
|---|
| 17 | sampler2D diffuseMap; |
|---|
| 18 | |
|---|
| 19 | struct app2vertOffsetMapping |
|---|
| 20 | { |
|---|
| 21 | float4 position : POSITION; |
|---|
| 22 | float3 normal : NORMAL; |
|---|
| 23 | float2 uv : TEXCOORD0; |
|---|
| 24 | float3 tangent : TANGENT; |
|---|
| 25 | }; |
|---|
| 26 | |
|---|
| 27 | struct vert2fragOffsetMapping |
|---|
| 28 | { |
|---|
| 29 | float4 position : POSITION; |
|---|
| 30 | float2 uv : TEXCOORD0; |
|---|
| 31 | float3 lightDir : TEXCOORD1; |
|---|
| 32 | float3 eyeDir : TEXCOORD2; |
|---|
| 33 | float3 halfAngle : TEXCOORD3; |
|---|
| 34 | }; |
|---|
| 35 | |
|---|
| 36 | /* Vertex program that moves light and eye vectors into texture tangent space at vertex */ |
|---|
| 37 | |
|---|
| 38 | vert2fragOffsetMapping main_vp(app2vertOffsetMapping IN) |
|---|
| 39 | { |
|---|
| 40 | vert2fragOffsetMapping OUT; |
|---|
| 41 | |
|---|
| 42 | // calculate output position |
|---|
| 43 | OUT.position = mul(worldViewProj, IN.position); |
|---|
| 44 | |
|---|
| 45 | // pass the main uvs straight through unchanged |
|---|
| 46 | OUT.uv = IN.uv; |
|---|
| 47 | |
|---|
| 48 | half3 lightDir = getLightDirection(lightPosition, IN.position); |
|---|
| 49 | half3 eyeDir = getEyeDirection(eyePosition, IN.position); |
|---|
| 50 | |
|---|
| 51 | // Form a rotation matrix out of the vectors |
|---|
| 52 | half3x3 TBN = getTBNMatrix(IN.tangent, IN.normal); |
|---|
| 53 | |
|---|
| 54 | // Transform the light vector according to this matrix |
|---|
| 55 | OUT.lightDir = normalize(mul(TBN, lightDir)); |
|---|
| 56 | OUT.eyeDir = normalize(mul(TBN, eyeDir)); |
|---|
| 57 | |
|---|
| 58 | OUT.halfAngle = normalize(OUT.eyeDir + OUT.lightDir); |
|---|
| 59 | |
|---|
| 60 | return OUT; |
|---|
| 61 | } |
|---|
| 62 | |
|---|
| 63 | outPixel main_fp(vert2fragOffsetMapping IN) |
|---|
| 64 | { |
|---|
| 65 | outPixel OUT; |
|---|
| 66 | |
|---|
| 67 | half displacement = getDisplacement(normalHeightMap, IN.uv, scaleBias.x, scaleBias.y); |
|---|
| 68 | |
|---|
| 69 | float3 uv2 = float3(IN.uv, 1); |
|---|
| 70 | |
|---|
| 71 | // calculate the new tex coord to use for normal and diffuse |
|---|
| 72 | float2 newTexCoord = ((IN.eyeDir * displacement) + uv2).xy; |
|---|
| 73 | |
|---|
| 74 | // get the new normal and diffuse values |
|---|
| 75 | half3 normal = getNormalMapVector(normalHeightMap, newTexCoord); |
|---|
| 76 | half3 diffuse = tex2D(diffuseMap, newTexCoord).xyz; |
|---|
| 77 | |
|---|
| 78 | half3 specular = getSpecularComponent(normal, IN.halfAngle, lightSpecular, 32); |
|---|
| 79 | half3 col = diffuse * getLightingComponent(normal, IN.lightDir, lightDiffuse) + specular; |
|---|
| 80 | |
|---|
| 81 | OUT.colour = float4(col, 1); |
|---|
| 82 | |
|---|
| 83 | return OUT; |
|---|
| 84 | } |
|---|