1+ /*
2+ Part of the Processing project - http://processing.org
3+
4+ Copyright (c) 2011-13 Ben Fry and Casey Reas
5+
6+ This library is free software; you can redistribute it and/or
7+ modify it under the terms of the GNU Lesser General Public
8+ License version 2.1 as published by the Free Software Foundation.
9+
10+ This library is distributed in the hope that it will be useful,
11+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+ Lesser General Public License for more details.
14+
15+ You should have received a copy of the GNU Lesser General
16+ Public License along with this library; if not, write to the
17+ Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18+ Boston, MA 02111-1307 USA
19+ */
20+
21+ #define PROCESSING_LIGHT_SHADER
22+
23+ uniform mat4 modelviewMatrix;
24+ uniform mat4 transformMatrix;
25+ uniform mat3 normalMatrix;
26+
27+ uniform int lightCount;
28+ uniform vec4 lightPosition[8 ];
29+ uniform vec3 lightNormal[8 ];
30+ uniform vec3 lightAmbient[8 ];
31+ uniform vec3 lightDiffuse[8 ];
32+ uniform vec3 lightSpecular[8 ];
33+ uniform vec3 lightFalloff[8 ];
34+ uniform vec2 lightSpot[8 ];
35+
36+ attribute vec4 position;
37+ attribute vec4 color;
38+ attribute vec3 normal;
39+
40+ attribute vec4 ambient;
41+ attribute vec4 specular;
42+ attribute vec4 emissive;
43+ attribute float shininess;
44+
45+ varying vec4 vertColor;
46+ varying vec4 backVertColor;
47+
48+ const float zero_float = 0.0 ;
49+ const float one_float = 1.0 ;
50+ const vec3 zero_vec3 = vec3 (0 );
51+
52+ float falloffFactor(vec3 lightPos, vec3 vertPos, vec3 coeff) {
53+ vec3 lpv = lightPos - vertPos;
54+ vec3 dist = vec3 (one_float);
55+ dist.z = dot (lpv, lpv);
56+ dist.y = sqrt (dist.z);
57+ return one_float / dot (dist, coeff);
58+ }
59+
60+ float spotFactor(vec3 lightPos, vec3 vertPos, vec3 lightNorm, float minCos, float spotExp) {
61+ vec3 lpv = normalize (lightPos - vertPos);
62+ vec3 nln = - one_float * lightNorm;
63+ float spotCos = dot (nln, lpv);
64+ return spotCos <= minCos ? zero_float : pow (spotCos, spotExp);
65+ }
66+
67+ float lambertFactor(vec3 lightDir, vec3 vecNormal) {
68+ return max (zero_float, dot (lightDir, vecNormal));
69+ }
70+
71+ float blinnPhongFactor(vec3 lightDir, vec3 vertPos, vec3 vecNormal, float shine) {
72+ vec3 np = normalize (vertPos);
73+ vec3 ldp = normalize (lightDir - np);
74+ return pow (max (zero_float, dot (ldp, vecNormal)), shine);
75+ }
76+
77+ void main() {
78+ // Vertex in clip coordinates
79+ gl_Position = transformMatrix * position;
80+
81+ // Vertex in eye coordinates
82+ vec3 ecVertex = vec3 (modelviewMatrix * position);
83+
84+ // Normal vector in eye coordinates
85+ vec3 ecNormal = normalize (normalMatrix * normal);
86+ vec3 ecNormalInv = ecNormal * - one_float;
87+
88+ // Light calculations
89+ vec3 totalAmbient = vec3 (0 , 0 , 0 );
90+
91+ vec3 totalFrontDiffuse = vec3 (0 , 0 , 0 );
92+ vec3 totalFrontSpecular = vec3 (0 , 0 , 0 );
93+
94+ vec3 totalBackDiffuse = vec3 (0 , 0 , 0 );
95+ vec3 totalBackSpecular = vec3 (0 , 0 , 0 );
96+
97+ // prevent register allocation failure by limiting ourselves to
98+ // two lights for now
99+ for (int i = 0 ; i < 2 ; i++ ) {
100+ if (lightCount == i) break ;
101+
102+ vec3 lightPos = lightPosition[i].xyz;
103+ bool isDir = zero_float < lightPosition[i].w;
104+ float spotCos = lightSpot[i].x;
105+ float spotExp = lightSpot[i].y;
106+
107+ vec3 lightDir;
108+ float falloff;
109+ float spotf;
110+
111+ if (isDir) {
112+ falloff = one_float;
113+ lightDir = - one_float * lightNormal[i];
114+ } else {
115+ falloff = falloffFactor(lightPos, ecVertex, lightFalloff[i]);
116+ lightDir = normalize (lightPos - ecVertex);
117+ }
118+
119+ spotf = spotExp > zero_float ? spotFactor(lightPos, ecVertex, lightNormal[i],
120+ spotCos, spotExp)
121+ : one_float;
122+
123+ if (any (greaterThan (lightAmbient[i], zero_vec3))) {
124+ totalAmbient += lightAmbient[i] * falloff;
125+ }
126+
127+ if (any (greaterThan (lightDiffuse[i], zero_vec3))) {
128+ totalFrontDiffuse += lightDiffuse[i] * falloff * spotf *
129+ lambertFactor(lightDir, ecNormal);
130+ totalBackDiffuse += lightDiffuse[i] * falloff * spotf *
131+ lambertFactor(lightDir, ecNormalInv);
132+ }
133+
134+ if (any (greaterThan (lightSpecular[i], zero_vec3))) {
135+ totalFrontSpecular += lightSpecular[i] * falloff * spotf *
136+ blinnPhongFactor(lightDir, ecVertex, ecNormal, shininess);
137+ totalBackSpecular += lightSpecular[i] * falloff * spotf *
138+ blinnPhongFactor(lightDir, ecVertex, ecNormalInv, shininess);
139+ }
140+ }
141+
142+ // Calculating final color as result of all lights (plus emissive term).
143+ // Transparency is determined exclusively by the diffuse component.
144+ vertColor = vec4 (totalAmbient, 0 ) * ambient +
145+ vec4 (totalFrontDiffuse, 1 ) * color +
146+ vec4 (totalFrontSpecular, 0 ) * specular +
147+ vec4 (emissive.rgb, 0 );
148+
149+ backVertColor = vec4 (totalAmbient, 0 ) * ambient +
150+ vec4 (totalBackDiffuse, 1 ) * color +
151+ vec4 (totalBackSpecular, 0 ) * specular +
152+ vec4 (emissive.rgb, 0 );
153+ }
0 commit comments