[12115] | 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 | } |
---|