1 // Created on: 2013-10-10
2 // Created by: Denis BOGOLEPOV
3 // Copyright (c) 2013-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 varying vec3 View; //!< Direction to the viewer
17 varying vec3 Normal; //!< Vertex normal in view space
18 varying vec4 Position; //!< Vertex position in view space.
19 varying vec4 PositionWorld; //!< Vertex position in world space
21 vec3 Ambient; //!< Ambient contribution of light sources
22 vec3 Diffuse; //!< Diffuse contribution of light sources
23 vec3 Specular; //!< Specular contribution of light sources
25 //! Computes contribution of isotropic point light source
26 void pointLight (in int theId,
31 vec3 aLight = occLight_Position (theId).xyz;
32 if (!occLight_IsHeadlight (theId))
34 aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 1.0));
38 float aDist = length (aLight);
39 aLight = aLight * (1.0 / aDist);
41 float anAtten = 1.0 / (occLight_ConstAttenuation (theId)
42 + occLight_LinearAttenuation (theId) * aDist);
44 vec3 aHalf = normalize (aLight + theView);
46 vec3 aFaceSideNormal = gl_FrontFacing ? theNormal : -theNormal;
47 float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));
48 float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));
53 aSpecl = pow (aNdotH, gl_FrontFacing ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());
56 Diffuse += occLight_Diffuse (theId).rgb * aNdotL * anAtten;
57 Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;
60 //! Computes contribution of spotlight source
61 void spotLight (in int theId,
66 vec3 aLight = occLight_Position (theId).xyz;
67 vec3 aSpotDir = occLight_SpotDirection (theId).xyz;
68 if (occLight_IsHeadlight (theId) == 0)
70 aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 1.0));
71 aSpotDir = vec3 (occWorldViewMatrix * vec4 (aSpotDir, 0.0));
75 float aDist = length (aLight);
76 aLight = aLight * (1.0 / aDist);
78 aSpotDir = normalize (aSpotDir);
81 float aCosA = dot (aSpotDir, -aLight);
82 if (aCosA >= 1.0 || aCosA < cos (occLight_SpotCutOff (theId)))
87 float anExponent = occLight_SpotExponent (theId);
88 float anAtten = 1.0 / (occLight_ConstAttenuation (theId)
89 + occLight_LinearAttenuation (theId) * aDist);
92 anAtten *= pow (aCosA, anExponent * 128.0);
95 vec3 aHalf = normalize (aLight + theView);
97 vec3 aFaceSideNormal = gl_FrontFacing ? theNormal : -theNormal;
98 float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));
99 float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));
104 aSpecl = pow (aNdotH, gl_FrontFacing ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());
107 Diffuse += occLight_Diffuse (theId).rgb * aNdotL * anAtten;
108 Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;
111 //! Computes contribution of directional light source
112 void directionalLight (in int theId,
116 vec3 aLight = normalize (occLight_Position (theId).xyz);
117 if (occLight_IsHeadlight (theId) == 0)
119 aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 0.0));
122 vec3 aHalf = normalize (aLight + theView);
124 vec3 aFaceSideNormal = gl_FrontFacing ? theNormal : -theNormal;
125 float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));
126 float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));
131 aSpecl = pow (aNdotH, gl_FrontFacing ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());
134 Diffuse += occLight_Diffuse (theId).rgb * aNdotL;
135 Specular += occLight_Specular (theId).rgb * aSpecl;
138 //! Computes illumination from light sources
139 vec4 computeLighting (in vec3 theNormal,
143 // Clear the light intensity accumulators
144 Ambient = occLightAmbient.rgb;
145 Diffuse = vec3 (0.0);
146 Specular = vec3 (0.0);
147 vec3 aPoint = thePoint.xyz / thePoint.w;
148 for (int anIndex = 0; anIndex < occLightSourcesCount; ++anIndex)
150 int aType = occLight_Type (anIndex);
151 if (aType == OccLightType_Direct)
153 directionalLight (anIndex, theNormal, theView);
155 else if (aType == OccLightType_Point)
157 pointLight (anIndex, theNormal, theView, aPoint);
159 else if (aType == OccLightType_Spot)
161 spotLight (anIndex, theNormal, theView, aPoint);
165 vec4 aMaterialAmbient = gl_FrontFacing ? occFrontMaterial_Ambient() : occBackMaterial_Ambient();
166 vec4 aMaterialDiffuse = gl_FrontFacing ? occFrontMaterial_Diffuse() : occBackMaterial_Diffuse();
167 vec4 aMaterialSpecular = gl_FrontFacing ? occFrontMaterial_Specular() : occBackMaterial_Specular();
168 vec4 aMaterialEmission = gl_FrontFacing ? occFrontMaterial_Emission() : occBackMaterial_Emission();
169 vec3 aColor = Ambient * aMaterialAmbient.rgb
170 + Diffuse * aMaterialDiffuse.rgb
171 + Specular * aMaterialSpecular.rgb
172 + aMaterialEmission.rgb;
173 return vec4 (aColor, aMaterialDiffuse.a);
176 //! Entry point to the Fragment Shader
179 // process clipping planes
180 for (int anIndex = 0; anIndex < occClipPlaneCount; ++anIndex)
182 vec4 aClipEquation = occClipPlaneEquations[anIndex];
183 if (dot (aClipEquation.xyz, PositionWorld.xyz / PositionWorld.w) + aClipEquation.w < 0.0)
189 vec4 aColor = computeLighting (normalize (Normal), normalize (View), Position);
190 occSetFragColor (aColor);