70fb9491de93c58929e7d44cd23e4949690d33cd
[occt.git] / src / Shaders / PhongShading.fs
1 // Created on: 2013-10-10
2 // Created by: Denis BOGOLEPOV
3 // Copyright (c) 2013 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20 //! Direction to the viewer.
21 varying vec3 View;
22
23 //! Vertex normal in view space.
24 varying vec3 Normal;
25
26 //! Vertex position in view space.
27 varying vec4 Position;
28
29
30 //! Ambient contribution of light sources.
31 vec3 Ambient;
32
33 //! Diffuse contribution of light sources.
34 vec3 Diffuse;
35
36 //! Specular contribution of light sources.
37 vec3 Specular;
38
39
40 // =======================================================================
41 // function : AmbientLight
42 // purpose  : Computes contribution of OCCT pure ambient light source
43 // =======================================================================
44 void AmbientLight (in int theIndex)
45 {
46   Ambient += occLightSources[theIndex].Ambient;
47 }
48
49 // =======================================================================
50 // function : PointLight
51 // purpose  : Computes contribution of OCCT isotropic point light source
52 // =======================================================================
53 void PointLight (in int  theIndex,
54                  in vec3 theNormal,
55                  in vec3 theView,
56                  in vec3 thePoint)
57 {
58   vec3 aLight = occLightSources[theIndex].Position;
59   if (occLightSources[theIndex].Head == 0)
60   {
61     aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 1.0));
62   }
63   aLight -= thePoint;
64
65   float aDist = length (aLight);
66   aLight = aLight * (1.0 / aDist);
67   
68   float anAttenuation = 1.0 / (occLightSources[theIndex].ConstAttenuation +
69                                occLightSources[theIndex].LinearAttenuation * aDist);
70
71   vec3 aHalf = normalize (aLight + theView);
72
73   float aNdotL = max (0.0, dot (theNormal, aLight));
74   float aNdotH = max (0.0, dot (theNormal,  aHalf));
75
76   float aSpecl = 0.0;
77   if (aNdotL > 0.0)
78   {
79     aSpecl = pow (aNdotH, occFrontMaterial.Shininess);
80   }
81   
82   Ambient  += occLightSources[theIndex].Ambient * anAttenuation;
83   Diffuse  += occLightSources[theIndex].Diffuse * aNdotL * anAttenuation;
84   Specular += occLightSources[theIndex].Specular * aSpecl * anAttenuation;
85 }
86
87 // =======================================================================
88 // function : DirectionalLight
89 // purpose  : Computes contribution of OCCT directional light source
90 // =======================================================================
91 void DirectionalLight (in int theIndex,
92                        in vec3 theNormal,
93                        in vec3 theView)
94 {
95   vec3 aLight = normalize (occLightSources[theIndex].Position);
96
97   if (occLightSources[theIndex].Head == 0)
98   {
99     aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 0.0));
100   }
101   
102   vec3 aHalf = normalize (aLight + theView);
103   
104   float aNdotL = max (0.0, dot (theNormal, aLight));
105   float aNdotH = max (0.0, dot (theNormal,  aHalf));
106
107   float aSpecl = 0.0;
108   
109   if (aNdotL > 0.0)
110   {
111     aSpecl = pow (aNdotH, occFrontMaterial.Shininess);
112   }
113
114   Ambient  += occLightSources[theIndex].Ambient;
115   Diffuse  += occLightSources[theIndex].Diffuse * aNdotL;
116   Specular += occLightSources[theIndex].Specular * aSpecl;
117 }
118
119 // =======================================================================
120 // function : ComputeLighting
121 // purpose  : Computes illumination from OCCT light sources
122 // =======================================================================
123 vec4 ComputeLighting (in vec3 theNormal,
124                       in vec3 theView,
125                       in vec4 thePoint)
126 {
127   // Clear the light intensity accumulators
128   Ambient  = vec3 (0.0);
129   Diffuse  = vec3 (0.0);
130   Specular = vec3 (0.0);
131
132   vec3 aPoint = thePoint.xyz / thePoint.w;
133         
134   for (int anIndex = 0; anIndex < occLightSourcesCount; ++anIndex)
135   {
136     occLightSource light = occLightSources[anIndex];
137     
138     if (light.Type == occAmbientLight)
139     {
140       AmbientLight (anIndex);
141     }
142     else if (light.Type == occDirectLight)
143           {
144             DirectionalLight (anIndex, theNormal, theView);
145           }
146           else if (light.Type == occPointLight)
147                 {
148       PointLight (anIndex, theNormal, theView, aPoint);
149                 }
150                 else if (light.Type == occSpotLight)
151                 {
152                   /* Not implemented */
153                 }
154   }
155   
156   return vec4 (Ambient,  1.0) * occFrontMaterial.Ambient +
157          vec4 (Diffuse,  1.0) * occFrontMaterial.Diffuse +
158          vec4 (Specular, 1.0) * occFrontMaterial.Specular;
159 }
160
161 // =======================================================================
162 // function : main
163 // purpose  : Entry point to the fragment shader
164 // =======================================================================
165 void main()
166 {
167   gl_FragColor = ComputeLighting (normalize (Normal),
168                                   normalize (View),
169                                   Position);
170 }