Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: data/data_extern/programs/Cg/Example_BumpMapping.cg @ 12408

Last change on this file since 12408 was 12115, checked in by wiesep, 6 years ago

Changed folder structure, deletet some unused files and cleaned up code

File size: 6.9 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                         float4 tangent     : TANGENT,
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
44#if TANGENTS_HAVE_PARITY
45        float3 binormal = cross(tangent.xyz, normal) * tangent.www;
46#else
47        // fixed handedness
48        float3 binormal = cross(tangent.xyz, normal);
49#endif
50       
51        // Form a rotation matrix out of the vectors
52        float3x3 rotation = float3x3(tangent.xyz, binormal, normal);
53       
54        // Transform the light vector according to this matrix
55        oTSLightDir = mul(rotation, lightDir);
56       
57       
58}
59
60/* Bump mapping vertex program for shadow receiving
61   In this program, we want to calculate the tangent space light vector
62   on a per-vertex level which will get passed to the fragment program,
63   or to the fixed function dot3 operation, to produce the per-pixel
64   lighting effect.
65*/
66void main_shadowreceiver_vp(float4 position     : POSITION,
67                         float3 normal          : NORMAL,
68                         float2 uv                      : TEXCOORD0,
69                         float3 tangent     : TANGENT,
70                         
71                         // outputs
72                         out float4 oPosition    : POSITION,
73                         out float4 uvproj               : TEXCOORD0,
74                         out float2 oUv                  : TEXCOORD1,
75                         out float3 oTSLightDir  : TEXCOORD2,
76                         
77                         // parameters
78                         uniform float4 lightPosition, // object space
79                         uniform float4x4 worldViewProj,
80                         uniform float4x4 worldMatrix,
81                         uniform float4x4 texViewProj)
82{
83        // calculate output position
84        oPosition = mul(worldViewProj, position);
85
86        // pass the main uvs straight through unchanged
87        oUv = uv;
88
89        // calculate tangent space light vector
90        // Get object space light direction
91        // Non-normalised since we'll do that in the fragment program anyway
92        float3 lightDir = lightPosition.xyz -  (position * lightPosition.w);
93
94        // Calculate the binormal (NB we assume both normal and tangent are
95        // already normalised)
96        // NB looks like nvidia cross params are BACKWARDS to what you'd expect
97        // this equates to NxT, not TxN
98        float3 binormal = cross(tangent, normal);
99       
100        // Form a rotation matrix out of the vectors
101        float3x3 rotation = float3x3(tangent.xyz, binormal, normal);
102       
103        // Transform the light vector according to this matrix
104        oTSLightDir = mul(rotation, lightDir);
105
106        // Projection
107    uvproj = mul(worldMatrix, position);
108        uvproj = mul(texViewProj, uvproj);
109       
110}
111
112
113void main_fp( float4 position   : POSITION,
114        float2 uv                       : TEXCOORD0,
115                          float3 TSlightDir : TEXCOORD1,
116
117                          out float4 colour     : COLOR,
118
119                          uniform float4 lightDiffuse,
120                          uniform sampler2D   normalMap : register(s0))
121{
122        // retrieve normalised light vector, expand from range-compressed
123        float3 lightVec = normalize(TSlightDir).xyz;
124
125        // get bump map vector, again expand from range-compressed
126        float3 bumpVec = expand(tex2D(normalMap, uv).xyz);
127
128        // Calculate dot product
129        colour = lightDiffuse * dot(bumpVec, lightVec);
130       
131}
132
133void main_shadowreceiver_fp( float4 position    : POSITION,
134                          float4 uvproj         : TEXCOORD0,
135                          float2 uv                     : TEXCOORD1,
136                          float3 TSlightDir : TEXCOORD2,
137
138                          out float4 colour     : COLOR,
139
140                          uniform float4 lightDiffuse,
141                          uniform sampler2D   shadowMap : register(s0),
142                          uniform sampler2D   normalMap : register(s1))
143{
144
145
146        // retrieve normalised light vector, expand from range-compressed
147        float3 lightVec = expand(normalize(TSlightDir).xyz);
148
149        // get bump map vector, again expand from range-compressed
150        float3 bumpVec = expand(tex2D(normalMap, uv).xyz);
151
152        // get shadow value
153        float3 shadow = tex2Dproj(shadowMap, uvproj).xyz;
154
155        // Calculate dot product
156        colour = float4(shadow * lightDiffuse * dot(bumpVec, lightVec), 1.0f);
157       
158}
159
160/* Vertex program which includes specular component */
161void specular_vp(float4 position        : POSITION,
162                                 float3 normal          : NORMAL,
163                                 float2 uv                      : TEXCOORD0,
164                                 float3 tangent     : TANGENT,
165                                 // outputs
166                                 out float4 oPosition    : POSITION,
167                                 out float2 oUv                  : TEXCOORD0,
168                                 out float3 oTSLightDir  : TEXCOORD1,
169                                 out float3 oTSHalfAngle : TEXCOORD2,
170                                 // parameters
171                                 uniform float4 lightPosition, // object space
172                                 uniform float3 eyePosition,   // object space
173                                 uniform float4x4 worldViewProj)
174{
175        // calculate output position
176        oPosition = mul(worldViewProj, position);
177
178        // pass the main uvs straight through unchanged
179        oUv = uv;
180
181        // calculate tangent space light vector
182        // Get object space light direction
183        float3 lightDir = normalize(lightPosition.xyz -  (position * lightPosition.w));
184
185        // Calculate the binormal (NB we assume both normal and tangent are
186        // already normalised)
187        // NB looks like nvidia cross params are BACKWARDS to what you'd expect
188        // this equates to NxT, not TxN
189        float3 binormal = cross(tangent, normal);
190       
191        // Form a rotation matrix out of the vectors
192        float3x3 rotation = float3x3(tangent, binormal, normal);
193       
194        // Transform the light vector according to this matrix
195        oTSLightDir = mul(rotation, lightDir);
196
197        // Calculate half-angle in tangent space
198        float3 eyeDir = normalize(eyePosition - position.xyz);
199        float3 halfAngle = normalize(eyeDir + lightDir);
200        oTSHalfAngle = mul(rotation, halfAngle);
201       
202       
203}
204
205/* Fragment program which supports specular component */
206void specular_fp( float4 position       : POSITION,
207        float2 uv                       : TEXCOORD0,
208                          float3 TSlightDir : TEXCOORD1,
209                          float3 TShalfAngle: TEXCOORD2,
210
211                          out float4 colour     : COLOR,
212
213                          uniform float4 lightDiffuse,
214                          uniform float4 lightSpecular,
215                          uniform sampler2D   normalMap : register(s0))
216{
217        // retrieve normalised light vector
218        float3 lightVec = normalize(TSlightDir);
219
220        // retrieve half angle and normalise
221        float3 halfAngle = normalize(TShalfAngle);
222
223        // get bump map vector, again expand from range-compressed
224        float3 bumpVec = expand(tex2D(normalMap, uv).xyz);
225
226        // Pre-raise the specular exponent to the eight power
227        float specFactor = pow(saturate(dot(bumpVec, halfAngle)), 4);
228       
229
230        // Calculate dot product for diffuse
231        colour = (lightDiffuse * saturate(dot(bumpVec, lightVec))) +
232                        (lightSpecular * specFactor);
233       
234}
235                         
Note: See TracBrowser for help on using the repository browser.