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 | } |
---|