0024344: TKOpenGl - only front side is lighted within Phong GLSL program
[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 varying vec3 View;     //!< Direction to the viewer
21 varying vec3 Normal;   //!< Vertex normal in view space
22 varying vec4 Position; //!< Vertex position in view space.
23
24 vec3 Ambient;  //!< Ambient  contribution of light sources
25 vec3 Diffuse;  //!< Diffuse  contribution of light sources
26 vec3 Specular; //!< Specular contribution of light sources
27
28 //! Computes contribution of isotropic point light source
29 void pointLight (in int  theId,
30                  in vec3 theNormal,
31                  in vec3 theView,
32                  in vec3 thePoint)
33 {
34   vec3 aLight = occLight_Position (theId).xyz;
35   if (occLight_IsHeadlight (theId) == 0)
36   {
37     aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 1.0));
38   }
39   aLight -= thePoint;
40
41   float aDist = length (aLight);
42   aLight = aLight * (1.0 / aDist);
43
44   float anAtten = 1.0 / (occLight_ConstAttenuation  (theId)
45                        + occLight_LinearAttenuation (theId) * aDist);
46
47   vec3 aHalf = normalize (aLight + theView);
48
49   vec3  aFaceSideNormal = gl_FrontFacing ? theNormal : -theNormal;
50   float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));
51   float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));
52
53   float aSpecl = 0.0;
54   if (aNdotL > 0.0)
55   {
56     aSpecl = pow (aNdotH, gl_FrontFacing ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());
57   }
58
59   Diffuse  += occLight_Diffuse  (theId).rgb * aNdotL * anAtten;
60   Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;
61 }
62
63 //! Computes contribution of directional light source
64 void directionalLight (in int  theId,
65                        in vec3 theNormal,
66                        in vec3 theView)
67 {
68   vec3 aLight = normalize (occLight_Position (theId).xyz);
69   if (occLight_IsHeadlight (theId) == 0)
70   {
71     aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 0.0));
72   }
73
74   vec3 aHalf = normalize (aLight + theView);
75
76   vec3  aFaceSideNormal = gl_FrontFacing ? theNormal : -theNormal;
77   float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));
78   float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));
79
80   float aSpecl = 0.0;
81   if (aNdotL > 0.0)
82   {
83     aSpecl = pow (aNdotH, gl_FrontFacing ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());
84   }
85
86   Diffuse  += occLight_Diffuse  (theId).rgb * aNdotL;
87   Specular += occLight_Specular (theId).rgb * aSpecl;
88 }
89
90 //! Computes illumination from light sources
91 vec4 computeLighting (in vec3 theNormal,
92                       in vec3 theView,
93                       in vec4 thePoint)
94 {
95   // Clear the light intensity accumulators
96   Ambient  = occLightAmbient.rgb;
97   Diffuse  = vec3 (0.0);
98   Specular = vec3 (0.0);
99   vec3 aPoint = thePoint.xyz / thePoint.w;
100   for (int anIndex = 0; anIndex < occLightSourcesCount; ++anIndex)
101   {
102     int aType = occLight_Type (anIndex);
103     if (aType == OccLightType_Direct)
104     {
105       directionalLight (anIndex, theNormal, theView);
106     }
107     else if (aType == OccLightType_Point)
108     {
109       pointLight (anIndex, theNormal, theView, aPoint);
110     }
111     else if (aType == OccLightType_Spot)
112     {
113       // Not implemented
114     }
115   }
116
117   vec4 aMaterialAmbient  = gl_FrontFacing ? occFrontMaterial_Ambient()  : occBackMaterial_Ambient();
118   vec4 aMaterialDiffuse  = gl_FrontFacing ? occFrontMaterial_Diffuse()  : occBackMaterial_Diffuse();
119   vec4 aMaterialSpecular = gl_FrontFacing ? occFrontMaterial_Specular() : occBackMaterial_Specular();
120   return vec4 (Ambient,  1.0) * aMaterialAmbient
121        + vec4 (Diffuse,  1.0) * aMaterialDiffuse
122        + vec4 (Specular, 1.0) * aMaterialSpecular;
123 }
124
125 //! Entry point to the Fragment Shader
126 void main()
127 {
128   gl_FragColor = computeLighting (normalize (Normal),
129                                   normalize (View),
130                                   Position);
131 }