| [390] | 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 | /* Vertex program that moves light and eye vectors into texture tangent space at vertex */  | 
|---|
 | 8 |  | 
|---|
 | 9 | void main_vp(float4 position   : POSITION,  | 
|---|
 | 10 |               float3 normal      : NORMAL,  | 
|---|
 | 11 |               float2 uv         : TEXCOORD0,  | 
|---|
 | 12 |               float3 tangent     : TANGENT0,  | 
|---|
 | 13 |               // outputs  | 
|---|
 | 14 |               out float4 oPosition    : POSITION,  | 
|---|
 | 15 |               out float2 oUv          : TEXCOORD0,  | 
|---|
 | 16 |               out float3 oLightDir    : TEXCOORD1, // tangent space  | 
|---|
 | 17 |              out float3 oEyeDir       : TEXCOORD2, // tangent space  | 
|---|
 | 18 |              out float3 oHalfAngle    : TEXCOORD3, //  | 
|---|
 | 19 |               // parameters  | 
|---|
 | 20 |               uniform float4 lightPosition, // object space  | 
|---|
 | 21 |               uniform float3 eyePosition,   // object space  | 
|---|
 | 22 |               uniform float4x4 worldViewProj)  | 
|---|
 | 23 | {   | 
|---|
 | 24 |    // calculate output position  | 
|---|
 | 25 |    oPosition = mul(worldViewProj, position);  | 
|---|
 | 26 |  | 
|---|
 | 27 |    // pass the main uvs straight through unchanged  | 
|---|
 | 28 |    oUv = uv;  | 
|---|
 | 29 |  | 
|---|
 | 30 |    // calculate tangent space light vector  | 
|---|
 | 31 |    // Get object space light direction  | 
|---|
 | 32 |    float3 lightDir = normalize(lightPosition.xyz -  (position * lightPosition.w)); | 
|---|
 | 33 |    float3 eyeDir = eyePosition - position.xyz;  | 
|---|
 | 34 |      | 
|---|
 | 35 |    // Calculate the binormal (NB we assume both normal and tangent are  | 
|---|
 | 36 |    // already normalised)  | 
|---|
 | 37 |    // NB looks like nvidia cross params are BACKWARDS to what you'd expect  | 
|---|
 | 38 |    // this equates to NxT, not TxN  | 
|---|
 | 39 |    float3 binormal = cross(tangent, normal);  | 
|---|
 | 40 |      | 
|---|
 | 41 |    // Form a rotation matrix out of the vectors  | 
|---|
 | 42 |    float3x3 rotation = float3x3(tangent, binormal, normal);  | 
|---|
 | 43 |      | 
|---|
 | 44 |    // Transform the light vector according to this matrix  | 
|---|
 | 45 |    lightDir = normalize(mul(rotation, lightDir));  | 
|---|
 | 46 |    eyeDir = normalize(mul(rotation, eyeDir));  | 
|---|
 | 47 |  | 
|---|
 | 48 |    oLightDir = lightDir;  | 
|---|
 | 49 |    oEyeDir = eyeDir;  | 
|---|
 | 50 |    oHalfAngle = normalize(eyeDir + lightDir);  | 
|---|
 | 51 | } | 
|---|
 | 52 |  | 
|---|
 | 53 | // General functions | 
|---|
 | 54 |  | 
|---|
 | 55 | // Expand a range-compressed vector | 
|---|
 | 56 | float3 expand(float3 v) | 
|---|
 | 57 | { | 
|---|
 | 58 |         return (v - 0.5) * 2; | 
|---|
 | 59 | } | 
|---|
 | 60 |  | 
|---|
 | 61 | void main_fp(float2 uv : TEXCOORD0, | 
|---|
 | 62 |         float3 lightDir : TEXCOORD1, | 
|---|
 | 63 |         float3 eyeDir : TEXCOORD2, | 
|---|
 | 64 |         float3 halfAngle : TEXCOORD3, | 
|---|
 | 65 |         uniform float3 lightDiffuse, | 
|---|
 | 66 |         uniform float3 lightSpecular, | 
|---|
 | 67 |         uniform float4 scaleBias, | 
|---|
 | 68 |         uniform sampler2D normalHeightMap, | 
|---|
 | 69 |         uniform sampler2D diffuseMap, | 
|---|
 | 70 |         out float4 oColor : COLOR) | 
|---|
 | 71 | { | 
|---|
 | 72 |         // get the height using the tex coords | 
|---|
 | 73 |         float height = tex2D(normalHeightMap, uv).a; | 
|---|
 | 74 |  | 
|---|
 | 75 |         // scale and bias factors        | 
|---|
 | 76 |         float scale = scaleBias.x; | 
|---|
 | 77 |         float bias = scaleBias.y; | 
|---|
 | 78 |  | 
|---|
 | 79 |         // calculate displacement        | 
|---|
 | 80 |         float displacement = (height * scale) + bias; | 
|---|
 | 81 |          | 
|---|
 | 82 |         float3 uv2 = float3(uv, 1); | 
|---|
 | 83 |          | 
|---|
 | 84 |         // calculate the new tex coord to use for normal and diffuse | 
|---|
 | 85 |         float2 newTexCoord = ((eyeDir * displacement) + uv2).xy; | 
|---|
 | 86 |          | 
|---|
 | 87 |         // get the new normal and diffuse values | 
|---|
 | 88 |         float3 normal = expand(tex2D(normalHeightMap, newTexCoord).xyz); | 
|---|
 | 89 |         float3 diffuse = tex2D(diffuseMap, newTexCoord).xyz; | 
|---|
 | 90 |          | 
|---|
 | 91 |         float3 specular = pow(saturate(dot(normal, halfAngle)), 32) * lightSpecular; | 
|---|
 | 92 |         float3 col = diffuse * saturate(dot(normal, lightDir)) * lightDiffuse + specular; | 
|---|
 | 93 |                  | 
|---|
 | 94 |         oColor = float4(col, 1); | 
|---|
 | 95 | } | 
|---|
 | 96 |  | 
|---|
 | 97 |  | 
|---|