Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: data/trunk/Media/materials/programs/BumpMapping.cg @ 5246

Last change on this file since 5246 was 5180, checked in by dafrick, 16 years ago
File size: 4.6 KB
Line 
1// General functions
2
3// Expand a range-compressed vector
4float3 expand(float3 v)
5{
6        return (v - 0.5) * 2;
7}
8
9
10/* Bump mapping vertex program
11   In this program, we want to calculate the tangent space light vector
12   on a per-vertex level which will get passed to the fragment program,
13   or to the fixed function dot3 operation, to produce the per-pixel
14   lighting effect.
15*/
16void main_vp(float4 position    : POSITION,
17                         float3 normal          : NORMAL,
18                         float2 uv                      : TEXCOORD0,
19                         float3 tangent     : TANGENT0,
20                         // outputs
21                         out float4 oPosition    : POSITION,
22                         out float2 oUv                  : TEXCOORD0,
23                         out float3 oTSLightDir  : TEXCOORD1,
24                         // parameters
25                         uniform float4 lightPosition, // object space
26                         uniform float4x4 worldViewProj)
27{
28        // calculate output position
29        oPosition = mul(worldViewProj, position);
30
31        // pass the main uvs straight through unchanged
32        oUv = uv;
33
34        // calculate tangent space light vector
35        // Get object space light direction
36        // Non-normalised since we'll do that in the fragment program anyway
37        float3 lightDir = lightPosition.xyz -  (position * lightPosition.w);
38
39        // Calculate the binormal (NB we assume both normal and tangent are
40        // already normalised)
41        // NB looks like nvidia cross params are BACKWARDS to what you'd expect
42        // this equates to NxT, not TxN
43        float3 binormal = cross(tangent, normal);
44
45        // Form a rotation matrix out of the vectors
46        float3x3 rotation = float3x3(tangent, binormal, normal);
47
48        // Transform the light vector according to this matrix
49        oTSLightDir = mul(rotation, lightDir);
50
51
52}
53
54void main_fp( float2 uv                 : TEXCOORD0,
55                          float3 TSlightDir : TEXCOORD1,
56
57                          out float4 colour     : COLOR,
58
59                          uniform float4 lightDiffuse,
60                          uniform sampler2D   normalMap : register(s0),
61                          uniform samplerCUBE normalCubeMap : register(s1) )
62{
63        // retrieve normalised light vector, expand from range-compressed
64        float3 lightVec = expand(texCUBE(normalCubeMap, TSlightDir).xyz);
65
66        // get bump map vector, again expand from range-compressed
67        float3 bumpVec = expand(tex2D(normalMap, uv).xyz);
68
69        // Calculate dot product
70        colour = lightDiffuse * dot(bumpVec, lightVec);
71
72}
73
74/* Vertex program which includes specular component */
75void specular_vp(float4 position        : POSITION,
76                                 float3 normal          : NORMAL,
77                                 float2 uv                      : TEXCOORD0,
78                                 float3 tangent     : TANGENT0,
79                                 // outputs
80                                 out float4 oPosition    : POSITION,
81                                 out float2 oUv                  : TEXCOORD0,
82                                 out float3 oTSLightDir  : TEXCOORD1,
83                                 out float3 oTSHalfAngle : TEXCOORD2,
84                                 // parameters
85                                 uniform float4 lightPosition, // object space
86                                 uniform float3 eyePosition,   // object space
87                                 uniform float4x4 worldViewProj)
88{
89        // calculate output position
90        oPosition = mul(worldViewProj, position);
91
92        // pass the main uvs straight through unchanged
93        oUv = uv;
94
95        // calculate tangent space light vector
96        // Get object space light direction
97        float3 lightDir = normalize(lightPosition.xyz -  (position * lightPosition.w));
98
99        // Calculate the binormal (NB we assume both normal and tangent are
100        // already normalised)
101        // NB looks like nvidia cross params are BACKWARDS to what you'd expect
102        // this equates to NxT, not TxN
103        float3 binormal = cross(tangent, normal);
104
105        // Form a rotation matrix out of the vectors
106        float3x3 rotation = float3x3(tangent, binormal, normal);
107
108        // Transform the light vector according to this matrix
109        oTSLightDir = mul(rotation, lightDir);
110
111        // Calculate half-angle in tangent space
112        float3 eyeDir = normalize(eyePosition - position.xyz);
113        float3 halfAngle = normalize(eyeDir + lightDir);
114        oTSHalfAngle = mul(rotation, halfAngle);
115
116
117}
118
119/* Fragment program which supports specular component */
120void specular_fp( float2 uv                     : TEXCOORD0,
121                          float3 TSlightDir : TEXCOORD1,
122                          float3 TShalfAngle: TEXCOORD2,
123
124                          out float4 colour     : COLOR,
125
126                          uniform float4 lightDiffuse,
127                          uniform float4 lightSpecular,
128                          uniform float shine,
129                          uniform sampler2D   normalMap : register(s0),
130                          uniform samplerCUBE normalCubeMap : register(s1),
131                          uniform samplerCUBE normalCubeMap2 : register(s2)) // we need this second binding to be compatible with ps_1_1, ps_2_0 could reuse the other
132{
133        // retrieve normalised light vector, expand from range-compressed
134        float3 lightVec = expand(texCUBE(normalCubeMap, TSlightDir).xyz);
135
136        // retrieve half angle and normalise through cube map
137        float3 halfAngle = expand(texCUBE(normalCubeMap2, TShalfAngle).xyz);
138
139        // get bump map vector, again expand from range-compressed
140        float3 bumpVec = expand(tex2D(normalMap, uv).xyz);
141
142
143        float specFactor = pow(dot(bumpVec, halfAngle),shine);
144
145
146
147        // Calculate dot product for diffuse
148        colour = (lightDiffuse * saturate(dot(bumpVec, lightVec))) +
149                        (lightSpecular * specFactor);
150
151}
152
Note: See TracBrowser for help on using the repository browser.