1 /*
  2   Copyright (c) 2008 Seneca College
  3   Licenced under the MIT License (http://www.c3dl.org/index.php/mit-license/)
  4 */
  5 
  6 //
  7 c3dl.light_vs = 
  8 
  9 
 10 
 11 // We need to create our own light structure since we can't access 
 12 // the light() function in the 2.0 context.
 13 "struct Light" +
 14 "{" +
 15 
 16 // figure out culling/light bug
 17 //"	int isOn;" +
 18 "	bool isOn;" +
 19 "	int type;" +
 20 
 21 "	vec3 ambient;" +
 22 "	vec3 diffuse;" +
 23 "	vec3 specular;" +
 24 "	vec4 position;" +
 25 
 26 	// Used if the light is a spotlight
 27 "	vec3 spotDirection;" +
 28 "	float spotExponent;" +
 29 "	float spotCutoff;" +
 30 
 31 	// Not used in calculations if the light is directional, since directional
 32 	// lights do not attenuate.
 33 "	float attenuation1;" +
 34 "	float attenuation2;" +
 35 "	float attenuation3;" +
 36 "};" +
 37 
 38 "uniform vec3 ambientLightColor;" +
 39 
 40 // global lighting state, if this is off, no light calculations 
 41 // are computed.
 42 "uniform bool lightingOn;" +
 43 
 44 //
 45 "const int C3DL_MAX_LIGHTS = 7;" +
 46 
 47 // custom light structures needed, we can't access opengl light states.
 48 "uniform Light lights[C3DL_MAX_LIGHTS];" +
 49 
 50 
 51 /*
 52 	A Spotlight is a positional light with a constraint which prevents light from radiating from
 53 	all directions from the point light.  Instead a cone of light is created which lights up objects.
 54 
 55 	Light light - the light in viewspace
 56 	vec3 normal - transformed normal
 57 	vec3 eye - 
 58 	vec3 ecPos - vertex in eye coordinate space. 
 59 	vec3 ambient - 
 60 	vec3 diffuse - 
 61 	vec3 specular - 	
 62 	float shininess - 
 63 */
 64 "void c3dl_SpotLight(	in Light light, in vec3 normal, in vec3 eye, in vec3 ecPos, " + 
 65 "						inout vec3 ambient, inout vec3 diffuse, inout vec3 specular, " +
 66 "						float shininess)" +
 67 "{" +
 68 "	float nDotVP; " + 
 69 "	float nDotHV; " +
 70 "	float spotDot; " + 
 71 "	float spotAttenuation;" +
 72 "	float attenuation;" + 
 73 "	float d;" +
 74 "	vec3 VP;" +
 75 "	float pf;" +
 76 "	vec3 halfVector;" +
 77 
 78 	// calculate the vector from the current vertex to the light.
 79 "	VP = vec3(light.position) - ecPos; " + 
 80 
 81 "	vec3 ldir = normalize(light.spotDirection);" +
 82 
 83 "	d = length(VP);" +
 84 "	VP = normalize(VP);" + 
 85 
 86 "	attenuation = 1.0 / (light.attenuation1 + (light.attenuation2 * d) + (light.attenuation3 * d * d));" +
 87 
 88 	// dot product of the vector from vertex to light and light direction.
 89 "	spotDot = dot(-VP, ldir);" +
 90 
 91 	// if the vertex falls inside the cone
 92 "	if(spotDot > cos(radians(light.spotCutoff)))" +
 93 "	{" +
 94 "		spotAttenuation = pow(spotDot, light.spotExponent);" +
 95 "	}" +
 96 "	else{" +
 97 "		spotAttenuation = 0.0;" +
 98 "	}" +
 99 
100 
101 "	attenuation *= spotAttenuation;" +
102 
103 "	halfVector = normalize(VP + eye);" +
104 
105 "	nDotVP = max(0.0, dot(normal, VP));" + 
106 "	nDotHV = max(0.0, dot(normal, halfVector));" +
107 
108 	//
109 "	if(nDotVP == 0.0){" +
110 "		pf = 0.0;" +
111 "	}" +
112 "	else{"+
113 "		pf = pow(nDotHV, shininess);" +
114 "	}" +
115 
116 "	ambient += light.ambient * attenuation;" +
117 "	diffuse += light.diffuse * nDotVP * attenuation; " +
118 "	specular += light.specular * pf * attenuation;" +
119 "}" +
120 
121 
122 
123  
124  /*
125 	A point light is similar to a lightbulb in that light rays radiate out in all directions.
126 	Unlike directional lights, point lights attenuate with distance.
127 
128 	Light light - the light in view space
129 	vec3 normal - 
130 	vec3 eye - 
131 	vec3 ecPos - 
132 	vec3 ambient - 
133 	vec3 diffuse -
134 	vec3 specular -  
135 	float shininess - 
136  */
137 "void c3dl_PointLight(	in Light light, in vec3 normal, in vec3 eye, in vec3 ecPos, " +
138 "						inout vec3 ambient, inout vec3 diffuse, inout vec3 specular, " +
139 "						float shininess)" +
140 "{" +
141 	// get the vector from the current vertex to the light's position.
142 "	vec3 VP = vec3(light.position) - ecPos;" +
143 
144 	// amount of shininess
145 "	float pf;" +	
146 
147 	// vector midway between VP and eye
148 "	vec3 halfVector = normalize(VP + eye);" +
149 
150 	// get the distance from the current vector to the light position
151 "	float d = length(VP); " + 
152 
153 	// normalize the light so it can be used in the dot product operation.
154 "	VP = normalize(VP);" + 
155 
156 	// calculate the attenuation
157 "	float attenuation = 1.0 / (light.attenuation1 + (light.attenuation2 * d) + (light.attenuation3 * d * d));" + 
158 
159 "	float nDotVP = max(0.0, dot(normal, VP));"+ 
160 "	float nDotHV = max(0.0, dot(normal, halfVector));" +
161 
162 	//
163 "	if(nDotVP == 0.0){" +
164 "		pf = 0.0;" +
165 "	}" +
166 "	else{"+
167 "		pf = pow(nDotHV, shininess);" +
168 "	}" +
169 
170 	// similar to the directional light, except we apply attenuation.
171 "	ambient += light.ambient * attenuation;" + 
172 "	diffuse += light.diffuse * nDotVP * attenuation;" + 
173 "	specular += light.specular * pf * attenuation;" +
174 "}" +
175 
176 
177 /*
178 	Light light - the light in view space
179 	vec3 normal - 
180 	vec3 ambient - 
181 	vec3 diffuse - 
182 	vec3 specular - 
183 	float shininess - 
184 */
185 "void c3dl_DirectionalLight(in Light light, in vec3 normal, " +
186 "							inout vec3 ambient, inout vec3 diffuse, inout vec3 specular," +
187 "							float shininess)" +
188 "{" +
189 
190 	// we have to flip the direction because the script tells the shader 
191 	// where the light is coming FROM. We have to specify what direction the light
192 	// is infinately towards.
193 "	vec3 VP = normalize(vec3(-light.position));" +
194 
195 "	float powerfactor;" +
196 
197 "	float nDotVP = max(0.0, dot(normal, VP));" + 
198 "	float nDotHV = nDotVP;" +
199 
200 "	if(nDotVP == 0.0){" +
201 "		powerfactor = 0.0;" +
202 "	}" +
203 "	else{"+
204 "		powerfactor = pow(nDotHV, shininess);" +
205 "	}" +
206 
207 "	ambient += light.ambient;" + 
208 "	diffuse += light.diffuse * nDotVP;" +
209 "	specular += light.specular * powerfactor;" +
210 "} ";
211