Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: data/pool/programs/BumpMapping.cg @ 9286

Last change on this file since 9286 was 7708, checked in by dafrick, 14 years ago

Merging cleanup branch. You will need to update your data repository as well as your local copy of the code.

  • Property svn:eol-style set to native
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.