392ac980 |
1 | // Created on: 2013-10-10 |
2 | // Created by: Denis BOGOLEPOV |
d5f74e42 |
3 | // Copyright (c) 2013-2014 OPEN CASCADE SAS |
392ac980 |
4 | // |
973c2be1 |
5 | // This file is part of Open CASCADE Technology software library. |
392ac980 |
6 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
392ac980 |
12 | // |
973c2be1 |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
392ac980 |
15 | |
5495fa7e |
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 |
392ac980 |
20 | |
12381341 |
21 | vec3 Ambient; //!< Ambient contribution of light sources |
22 | vec3 Diffuse; //!< Diffuse contribution of light sources |
23 | vec3 Specular; //!< Specular contribution of light sources |
392ac980 |
24 | |
12381341 |
25 | //! Computes contribution of isotropic point light source |
26 | void pointLight (in int theId, |
392ac980 |
27 | in vec3 theNormal, |
28 | in vec3 theView, |
29 | in vec3 thePoint) |
30 | { |
12381341 |
31 | vec3 aLight = occLight_Position (theId).xyz; |
32 | if (occLight_IsHeadlight (theId) == 0) |
392ac980 |
33 | { |
5f4bd4d4 |
34 | aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 1.0)); |
392ac980 |
35 | } |
36 | aLight -= thePoint; |
37 | |
38 | float aDist = length (aLight); |
39 | aLight = aLight * (1.0 / aDist); |
12381341 |
40 | |
41 | float anAtten = 1.0 / (occLight_ConstAttenuation (theId) |
42 | + occLight_LinearAttenuation (theId) * aDist); |
392ac980 |
43 | |
44 | vec3 aHalf = normalize (aLight + theView); |
45 | |
c90e941f |
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 )); |
392ac980 |
49 | |
50 | float aSpecl = 0.0; |
51 | if (aNdotL > 0.0) |
52 | { |
c90e941f |
53 | aSpecl = pow (aNdotH, gl_FrontFacing ? occFrontMaterial_Shininess() : occBackMaterial_Shininess()); |
392ac980 |
54 | } |
12381341 |
55 | |
56 | Diffuse += occLight_Diffuse (theId).rgb * aNdotL * anAtten; |
57 | Specular += occLight_Specular (theId).rgb * aSpecl * anAtten; |
392ac980 |
58 | } |
59 | |
816d03ee |
60 | //! Computes contribution of spotlight source |
61 | void spotLight (in int theId, |
62 | in vec3 theNormal, |
63 | in vec3 theView, |
64 | in vec3 thePoint) |
65 | { |
66 | vec3 aLight = occLight_Position (theId).xyz; |
67 | vec3 aSpotDir = occLight_SpotDirection (theId).xyz; |
68 | if (occLight_IsHeadlight (theId) == 0) |
69 | { |
5f4bd4d4 |
70 | aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 1.0)); |
71 | aSpotDir = vec3 (occWorldViewMatrix * vec4 (aSpotDir, 0.0)); |
816d03ee |
72 | } |
73 | aLight -= thePoint; |
74 | |
75 | float aDist = length (aLight); |
76 | aLight = aLight * (1.0 / aDist); |
77 | |
78 | aSpotDir = normalize (aSpotDir); |
79 | |
80 | // light cone |
81 | float aCosA = dot (aSpotDir, -aLight); |
82 | if (aCosA >= 1.0 || aCosA < cos (occLight_SpotCutOff (theId))) |
83 | { |
84 | return; |
85 | } |
86 | |
87 | float anExponent = occLight_SpotExponent (theId); |
88 | float anAtten = 1.0 / (occLight_ConstAttenuation (theId) |
89 | + occLight_LinearAttenuation (theId) * aDist); |
90 | if (anExponent > 0.0) |
91 | { |
92 | anAtten *= pow (aCosA, anExponent * 128.0); |
93 | } |
94 | |
95 | vec3 aHalf = normalize (aLight + theView); |
96 | |
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 )); |
100 | |
101 | float aSpecl = 0.0; |
102 | if (aNdotL > 0.0) |
103 | { |
104 | aSpecl = pow (aNdotH, gl_FrontFacing ? occFrontMaterial_Shininess() : occBackMaterial_Shininess()); |
105 | } |
106 | |
107 | Diffuse += occLight_Diffuse (theId).rgb * aNdotL * anAtten; |
108 | Specular += occLight_Specular (theId).rgb * aSpecl * anAtten; |
109 | } |
110 | |
12381341 |
111 | //! Computes contribution of directional light source |
112 | void directionalLight (in int theId, |
392ac980 |
113 | in vec3 theNormal, |
114 | in vec3 theView) |
115 | { |
12381341 |
116 | vec3 aLight = normalize (occLight_Position (theId).xyz); |
117 | if (occLight_IsHeadlight (theId) == 0) |
392ac980 |
118 | { |
5f4bd4d4 |
119 | aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 0.0)); |
392ac980 |
120 | } |
12381341 |
121 | |
392ac980 |
122 | vec3 aHalf = normalize (aLight + theView); |
c90e941f |
123 | |
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 )); |
392ac980 |
127 | |
128 | float aSpecl = 0.0; |
392ac980 |
129 | if (aNdotL > 0.0) |
130 | { |
c90e941f |
131 | aSpecl = pow (aNdotH, gl_FrontFacing ? occFrontMaterial_Shininess() : occBackMaterial_Shininess()); |
392ac980 |
132 | } |
133 | |
12381341 |
134 | Diffuse += occLight_Diffuse (theId).rgb * aNdotL; |
135 | Specular += occLight_Specular (theId).rgb * aSpecl; |
392ac980 |
136 | } |
137 | |
12381341 |
138 | //! Computes illumination from light sources |
139 | vec4 computeLighting (in vec3 theNormal, |
392ac980 |
140 | in vec3 theView, |
141 | in vec4 thePoint) |
142 | { |
143 | // Clear the light intensity accumulators |
12381341 |
144 | Ambient = occLightAmbient.rgb; |
392ac980 |
145 | Diffuse = vec3 (0.0); |
146 | Specular = vec3 (0.0); |
392ac980 |
147 | vec3 aPoint = thePoint.xyz / thePoint.w; |
816d03ee |
148 | for (int anIndex = 0; anIndex < occLightSourcesCount; ++anIndex) |
392ac980 |
149 | { |
12381341 |
150 | int aType = occLight_Type (anIndex); |
151 | if (aType == OccLightType_Direct) |
392ac980 |
152 | { |
12381341 |
153 | directionalLight (anIndex, theNormal, theView); |
154 | } |
155 | else if (aType == OccLightType_Point) |
156 | { |
157 | pointLight (anIndex, theNormal, theView, aPoint); |
158 | } |
159 | else if (aType == OccLightType_Spot) |
160 | { |
816d03ee |
161 | spotLight (anIndex, theNormal, theView, aPoint); |
392ac980 |
162 | } |
392ac980 |
163 | } |
12381341 |
164 | |
c90e941f |
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(); |
0e330c8c |
168 | vec4 aMaterialEmission = gl_FrontFacing ? occFrontMaterial_Emission() : occBackMaterial_Emission(); |
a1073ae2 |
169 | vec3 aColor = Ambient * aMaterialAmbient.rgb |
170 | + Diffuse * aMaterialDiffuse.rgb |
171 | + Specular * aMaterialSpecular.rgb |
172 | + aMaterialEmission.rgb; |
173 | return vec4 (aColor, aMaterialDiffuse.a); |
392ac980 |
174 | } |
175 | |
12381341 |
176 | //! Entry point to the Fragment Shader |
392ac980 |
177 | void main() |
178 | { |
5495fa7e |
179 | // process clipping planes |
180 | for (int anIndex = 0; anIndex < occClipPlaneCount; ++anIndex) |
181 | { |
182 | vec4 aClipEquation = occClipPlaneEquations[anIndex]; |
89a929ea |
183 | if (dot (aClipEquation.xyz, PositionWorld.xyz / PositionWorld.w) + aClipEquation.w < 0.0) |
5495fa7e |
184 | { |
89a929ea |
185 | discard; |
5495fa7e |
186 | } |
187 | } |
188 | |
b17e5bae |
189 | vec4 aColor = computeLighting (normalize (Normal), normalize (View), Position); |
190 | occSetFragColor (aColor); |
392ac980 |
191 | } |