source: GTP/trunk/App/Demos/Geom/OgreStuff/media/materials/programs/Example_BumpMapping.cg @ 1092

Revision 1092, 5.0 KB checked in by gumbau, 18 years ago (diff)

LodStrips? and LODTrees demos

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
53void main_fp( float2 uv                 : TEXCOORD0,
54                          float3 TSlightDir : TEXCOORD1,
55
56                          out float4 colour     : COLOR,
57
58                          uniform float4 lightDiffuse,
59                          uniform sampler2D   normalMap,
60                          uniform samplerCUBE normalCubeMap)
61{
62        // retrieve normalised light vector, expand from range-compressed
63        float3 lightVec = expand(texCUBE(normalCubeMap, TSlightDir).xyz);
64
65        // get bump map vector, again expand from range-compressed
66        float3 bumpVec = expand(tex2D(normalMap, uv).xyz);
67
68        // Calculate dot product
69        colour = lightDiffuse * dot(bumpVec, lightVec);
70       
71}
72
73/* Vertex program which includes specular component */
74void specular_vp(float4 position        : POSITION,
75                                 float3 normal          : NORMAL,
76                                 float2 uv                      : TEXCOORD0,
77                                 float3 tangent     : TEXCOORD1,
78                                 // outputs
79                                 out float4 oPosition    : POSITION,
80                                 out float2 oUv                  : TEXCOORD0,
81                                 out float3 oTSLightDir  : TEXCOORD1,
82                                 out float3 oTSHalfAngle : TEXCOORD2,
83                                 // parameters
84                                 uniform float4 lightPosition, // object space
85                                 uniform float3 eyePosition,   // object space
86                                 uniform float4x4 worldViewProj)
87{
88        // calculate output position
89        oPosition = mul(worldViewProj, position);
90
91        // pass the main uvs straight through unchanged
92        oUv = uv;
93
94        // calculate tangent space light vector
95        // Get object space light direction
96        float3 lightDir = normalize(lightPosition.xyz -  (position * lightPosition.w));
97
98        // Calculate the binormal (NB we assume both normal and tangent are
99        // already normalised)
100        // NB looks like nvidia cross params are BACKWARDS to what you'd expect
101        // this equates to NxT, not TxN
102        float3 binormal = cross(tangent, normal);
103       
104        // Form a rotation matrix out of the vectors
105        float3x3 rotation = float3x3(tangent, binormal, normal);
106       
107        // Transform the light vector according to this matrix
108        oTSLightDir = normalize(mul(rotation, lightDir));
109
110        // Calculate half-angle in tangent space
111        float3 eyeDir = eyePosition - position.xyz;
112        float3 halfAngle = normalize(eyeDir + lightDir);
113        oTSHalfAngle = mul(rotation, halfAngle);
114       
115       
116}
117
118/* Fragment program which supports specular component */
119void specular_fp( float2 uv                     : TEXCOORD0,
120                          float3 TSlightDir : TEXCOORD1,
121                          float3 TShalfAngle: TEXCOORD2,
122
123                          out float4 colour     : COLOR,
124
125                          uniform float4 lightDiffuse,
126                          uniform float4 lightSpecular,
127                          uniform sampler2D   normalMap,
128                          uniform samplerCUBE normalCubeMap,
129                          uniform samplerCUBE normalCubeMap2) // we need this second binding to be compatible with ps_1_1, ps_2_0 could reuse the other
130{
131        // retrieve normalised light vector, expand from range-compressed
132        float3 lightVec = expand(texCUBE(normalCubeMap, TSlightDir).xyz);
133
134        // retrieve half angle and normalise through cube map
135        float3 halfAngle = expand(texCUBE(normalCubeMap2, TShalfAngle).xyz);
136
137        // get bump map vector, again expand from range-compressed
138        float3 bumpVec = expand(tex2D(normalMap, uv).xyz);
139
140        // Pre-raise the specular exponent to the eight power
141        // Note we have no 'pow' function in basic fragment programs, if we were willing to accept compatibility
142        // with ps_2_0 / arbfp1 and above, we could have a variable shininess parameter
143        // This is equivalent to
144        float specFactor = dot(bumpVec, halfAngle);
145        for (int i = 0; i < 3; ++i)
146                specFactor *= specFactor;
147       
148
149        // Calculate dot product for diffuse
150        colour = (lightDiffuse * saturate(dot(bumpVec, lightVec))) +
151                        (lightSpecular * specFactor);
152       
153}
154                         
Note: See TracBrowser for help on using the repository browser.