source: OGRE/trunk/ogrenew/Samples/Media/materials/programs/Example_BumpMapping.cg @ 692

Revision 692, 7.1 KB checked in by mattausch, 19 years ago (diff)

adding ogre 1.2 and dependencies

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