1 //////////////////////////////////////////////////////////////////////
2 //
3 //                             Pixie
4 //
5 // Copyright � 1999 - 2003, Okan Arikan
6 //
7 // Contact: okan@cs.utexas.edu
8 //
9 //	This library is free software; you can redistribute it and/or
10 //	modify it under the terms of the GNU Lesser General Public
11 //	License as published by the Free Software Foundation; either
12 //	version 2.1 of the License, or (at your option) any later version.
13 //
14 //	This library is distributed in the hope that it will be useful,
15 //	but WITHOUT ANY WARRANTY; without even the implied warranty of
16 //	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 //	Lesser General Public License for more details.
18 //
19 //	You should have received a copy of the GNU Lesser General Public
20 //	License along with this library; if not, write to the Free Software
21 //	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 //
23 ///////////////////////////////////////////////////////////////////////
24 ///////////////////////////////////////////////////////////////////////
25 //
26 //  File				:	hcshader.cpp
27 //  Classes				:	-
28 //  Description			:	This file holds the hardcoded shaders
29 //
30 ////////////////////////////////////////////////////////////////////////
31 #include <math.h>
32 
33 #include "common/os.h"
34 #include "hcshader.h"
35 #include "shading.h"
36 #include "memory.h"
37 #include "attributes.h"
38 #include "object.h"
39 #include "renderer.h"
40 #include "ri_config.h"
41 
42 
43 ///////////////////////////////////////////////////////////////////////
44 // Class				:	CSphereLight
45 // Method				:	CSphereLight
46 // Description			:	Ctor
47 // Return Value			:	-
48 // Comments				:
CSphereLight(CAttributes * a,CXform * x)49 CSphereLight::CSphereLight(CAttributes *a,CXform *x) : CShaderInstance(a,x) {
50 	vector	P;
51 
52 	initv(P,0,0,0);
53 	mulmp(from,xform->from,P);
54 	initv(lightColor,1,1,1);
55 	intensity	=	1;
56 	radius		=	0;
57 	numSamples	=	1;
58 	flags		=	SHADERFLAGS_NONAMBIENT;
59 }
60 
61 ///////////////////////////////////////////////////////////////////////
62 // Class				:	CSphereLight
63 // Method				:	~CSphereLight
64 // Description			:	Dtor
65 // Return Value			:	-
66 // Comments				:
~CSphereLight()67 CSphereLight::~CSphereLight() {
68 }
69 
70 
71 ///////////////////////////////////////////////////////////////////////
72 // Class				:	CSphereLight
73 // Method				:	illuminate
74 // Description			:	Called when we need to illuminate a point
75 // Return Value			:	-
76 // Comments				:
illuminate(CShadingContext * context,float ** locals)77 void					CSphereLight::illuminate(CShadingContext *context,float **locals) {
78 	CShadingState	*currentShadingState	=	context->currentShadingState;
79 
80 #define sampleSphere(cP)								\
81 	while(TRUE) {										\
82 		cP[COMP_X]	=	2*context->urand()-1;			\
83 		cP[COMP_Y]	=	2*context->urand()-1;			\
84 		cP[COMP_Z]	=	2*context->urand()-1;			\
85 														\
86 		if (dotvv(cP,cP) < 1)	break;					\
87 	}
88 
89 
90 	if (CRenderer::hiderFlags & HIDER_ILLUMINATIONHOOK) {
91 		const int	numVertices	=	currentShadingState->numVertices;
92 		float		*Pf			=	(float *) alloca(numVertices*3*sizeof(float));
93 		float		*Nf			=	(float *) alloca(numVertices*3*sizeof(float));
94 		float		*thetaf		=	(float *) alloca(numVertices*sizeof(float));
95 		int			i;
96 		float		*cP			=	Pf;
97 		float		*cN			=	Nf;
98 		float		*L;
99 		float		*CL;
100 
101 		// Generate points on the surface
102 		for (i=numVertices;i>0;i--,cP+=3,cN+=3) {
103 			sampleSphere(cP);
104 			normalizev(cP);
105 			movvv(cN,cP);
106 			mulvf(cP,radius);
107 			addvv(cP,from);
108 		}
109 
110 		// Call the hook handle
111 		context->illuminateBegin(Pf,Nf,thetaf);
112 
113 		// Compute the intensity
114 		L			=	currentShadingState->varying[VARIABLE_L];
115 		CL			=	currentShadingState->varying[VARIABLE_CL];
116 		for (i=numVertices;i>0;i--,L+=3,CL+=3,Nf+=3) {
117 			// The L must be unit vector
118 			assert((dotvv(L,L) - 1)*(dotvv(L,L) - 1) < 0.00001);
119 			assert(dotvv(Nf,L) >= 0);
120 
121 			mulvf(CL,lightColor,intensity);
122 			mulvf(CL,dotvv(Nf,L));
123 		}
124 
125 		// Call the hook handle
126 		context->illuminateEnd();
127 	} else {
128 		CShadedLight	**lights				=	&currentShadingState->lights;
129 		const int		*tags					=	currentShadingState->tags;
130 		float			*Ps						=	currentShadingState->varying[VARIABLE_PS];
131 		int				j;
132 		CRay			ray;
133 		const float		bias					=	currentShadingState->currentObject->attributes->bias;
134 		int				numVertices				=	currentShadingState->numRealVertices;
135 		CShadedLight	*cLight;
136 
137 		if (currentShadingState->numActive == 0)
138 			return;
139 
140 		cLight						=	(CShadedLight*) ralloc(sizeof(CShadedLight),context->threadMemory);
141 		cLight->lightTags			=	(int*)			ralloc(sizeof(int)*numVertices,context->threadMemory);
142 		cLight->savedState			=	(float**)		ralloc(2*sizeof(float*),context->threadMemory);
143 		cLight->savedState[0]		=	(float*)		ralloc(3*sizeof(float)*numVertices,context->threadMemory);
144 		cLight->savedState[1]		=	(float*)		ralloc(3*sizeof(float)*numVertices,context->threadMemory);
145 		cLight->instance			=	this;
146 		cLight->next				=	*lights;
147 		*lights						=	cLight;
148 		memcpy(cLight->lightTags,tags,sizeof(int)*numVertices);
149 		float		*L				=	cLight->savedState[0];
150 		float		*Cl				=	cLight->savedState[1];
151 		const float	*time			=	currentShadingState->varying[VARIABLE_TIME];
152 
153 		for (int i=numVertices;i>0;i--,Ps+=3,time++){
154 			if (*tags++ == 0) {
155 				vector			P;
156 				float			visibility	=	0;
157 
158 				for (j=numSamples;j>0;j--) {
159 					sampleSphere(P);
160 					normalizev(P);
161 					mulvf(P,radius);
162 					addvv(P,from);
163 
164 					// Evaluate visibility between P and Ps
165 					movvv(ray.from,Ps);
166 					subvv(ray.dir,P,Ps);
167 					const float	len	=	lengthv(ray.dir);
168 					mulvf(ray.dir,1 / len);
169 
170 					ray.flags				=	ATTRIBUTES_FLAGS_TRANSMISSION_VISIBLE;
171 					ray.tmin				=	bias;
172 					ray.t					=	len - bias;
173 					ray.time				=	*time;
174 
175 					// Figure out the ray differential
176 					const float	sina		=	radius / len;
177 					const float	cosa		=	sqrtf(1 - sina*sina);
178 					const float	da			=	sina / (cosa + C_EPSILON);
179 					ray.da					=	min(DEFAULT_RAY_DA,da);
180 					ray.db					=	DEFAULT_RAY_DB;
181 
182 					context->trace(&ray);
183 
184 					if (ray.object == NULL) {
185 						subvv(P,Ps);
186 						visibility			+=	intensity / dotvv(P,P);
187 					}
188 				}
189 
190 				visibility	/=	(float) numSamples;
191 
192 				subvv(L,from,Ps);
193 				normalizev(L);
194 				mulvf(Cl,lightColor,visibility);
195 			}
196 			L	+=	3;
197 			Cl	+=	3;
198 		}
199 	}
200 #undef sampleSphere
201 }
202 
203 ///////////////////////////////////////////////////////////////////////
204 // Class				:	CSphereLight
205 // Method				:	setParameters
206 // Description			:	Set shader parameters
207 // Return Value			:	-
208 // Comments				:
setParameters(int n,const char ** params,const void ** vals)209 void					CSphereLight::setParameters(int n,const char **params,const void **vals) {
210 	int	i;
211 
212 	for (i=0;i<n;i++) {
213 		if (strcmp(params[i],"from") == 0) {
214 			const float	*val	=	(const float *) vals[i];
215 
216 			mulmp(from,xform->from,val);
217 		} else if (strcmp(params[i],"radius") == 0) {
218 			const float	*val	=	(const float *) vals[i];
219 
220 			radius	=	val[0]*powf(determinantm(xform->from),1.0f / 3.0f);
221 		} else if (strcmp(params[i],"lightcolor") == 0) {
222 			const float	*val	=	(const float *) vals[i];
223 
224 			movvv(lightColor,val);
225 		} else if (strcmp(params[i],"intensity") == 0) {
226 			const float	*val	=	(const float *) vals[i];
227 
228 			intensity	=	val[0];
229 		} else if (strcmp(params[i],"numSamples") == 0) {
230 			const float	*val	=	(const float *) vals[i];
231 
232 			numSamples	=	(int) val[0];
233 		}
234 	}
235 }
236 
237 ///////////////////////////////////////////////////////////////////////
238 // Class				:	CSphereLight
239 // Method				:	getParameter
240 // Description			:	Query a shader parameter
241 // Return Value			:	-
242 // Comments				:
getParameter(const char * param,void * val,CVariable **,int *)243 int						CSphereLight::getParameter(const char *param,void *val,CVariable**,int*) {
244 	if (strcmp(param,"from") == 0) {
245 		float	*cval	=	(float *) val;
246 
247 		movvv(cval,from);
248 		return TRUE;
249 	} else if (strcmp(param,"radius") == 0) {
250 		float	*cval	=	(float *) val;
251 
252 		cval[0]	=	radius;
253 		return TRUE;
254 	} else if (strcmp(param,"lightcolor") == 0) {
255 		float	*cval	=	(float *) val;
256 
257 		movvv(cval,lightColor);
258 		return TRUE;
259 	} else if (strcmp(param,"intensity") == 0) {
260 		float	*cval	=	(float *) val;
261 
262 		cval[0]	=	intensity;
263 		return TRUE;
264 	} else if (strcmp(param,"numSamples") == 0) {
265 		float	*cval	=	(float *) val;
266 
267 		cval[0]	=	(float) numSamples;
268 		return TRUE;
269 	}
270 
271 	return FALSE;
272 }
273 
274 ///////////////////////////////////////////////////////////////////////
275 // Class				:	CSphereLight
276 // Method				:	execute
277 // Description			:	Execute the shader
278 // Return Value			:	-
279 // Comments				:	Should never be called
execute(CShadingContext * context,float ** locals)280 void					CSphereLight::execute(CShadingContext *context,float **locals) {
281 	// Should never be called
282 	assert(FALSE);
283 }
284 
285 ///////////////////////////////////////////////////////////////////////
286 // Class				:	CSphereLight
287 // Method				:	requiredParameters
288 // Description			:	Get the required parameters
289 // Return Value			:	-
290 // Comments				:
requiredParameters()291 unsigned int			CSphereLight::requiredParameters() {
292 	return 0;
293 }
294 
295 ///////////////////////////////////////////////////////////////////////
296 // Class				:	CSphereLight
297 // Method				:	getName
298 // Description			:	Get the name of the shader
299 // Return Value			:	-
300 // Comments				:
getName()301 const char				*CSphereLight::getName() {
302 	return "spherelight";
303 }
304 
305 
306 
307 
308 
309 
310 
311 
312 
313 
314 
315 
316 
317 
318 
319 
320 
321 
322 
323 
324 
325 
326 
327 
328 ///////////////////////////////////////////////////////////////////////
329 // Class				:	CQuadLight
330 // Method				:	CQuadLight
331 // Description			:	Ctor
332 // Return Value			:	-
333 // Comments				:
CQuadLight(CAttributes * a,CXform * x)334 CQuadLight::CQuadLight(CAttributes *a,CXform *x) : CShaderInstance(a,x) {
335 	vector	P;
336 	vector	D0,D1;
337 
338 	initv(P,-1,-1,0);
339 	mulmp(corners[0],xform->from,P);
340 	initv(P,1,-1,0);
341 	mulmp(corners[1],xform->from,P);
342 	initv(P,-1,1,0);
343 	mulmp(corners[2],xform->from,P);
344 	initv(P,1,1,0);
345 	mulmp(corners[3],xform->from,P);
346 
347 	initv(lightColor,1,1,1);
348 	intensity	=	1;
349 	numSamples	=	1;
350 	reverse		=	(a->flags & ATTRIBUTES_FLAGS_INSIDE);
351 	flags		=	SHADERFLAGS_NONAMBIENT;
352 
353 	subvv(D0,corners[1],corners[0]);
354 	subvv(D1,corners[2],corners[0]);
355 	crossvv(N,D0,D1);
356 	normalizev(N);
357 
358 	if (reverse)	mulvf(N,-1);
359 
360 	// Find the center point of the light
361 	addvv(center,corners[0],corners[1]);
362 	addvv(center,corners[2]);
363 	addvv(center,corners[3]);
364 	mulvf(center,1 / (float) 4);
365 
366 	// Find the radius of the light
367 	vector	tmp;
368 	subvv(tmp,corners[0],center);
369 	r	=	lengthv(tmp);
370 	subvv(tmp,corners[1],center);
371 	r	+=	lengthv(tmp);
372 	subvv(tmp,corners[2],center);
373 	r	+=	lengthv(tmp);
374 	subvv(tmp,corners[3],center);
375 	r	+=	lengthv(tmp);
376 	r	*=	0.25f;
377 }
378 
379 ///////////////////////////////////////////////////////////////////////
380 // Class				:	CQuadLight
381 // Method				:	~CQuadLight
382 // Description			:	Dtor
383 // Return Value			:	-
384 // Comments				:
~CQuadLight()385 CQuadLight::~CQuadLight() {
386 }
387 
388 
389 ///////////////////////////////////////////////////////////////////////
390 // Class				:	CQuadLight
391 // Method				:	illuminate
392 // Description			:	Called chen we need to illuminate a point
393 // Return Value			:	-
394 // Comments				:
illuminate(CShadingContext * context,float ** locals)395 void					CQuadLight::illuminate(CShadingContext *context,float **locals) {
396 	CShadingState	*currentShadingState	=	context->currentShadingState;
397 
398 	if (CRenderer::hiderFlags & HIDER_ILLUMINATIONHOOK) {
399 		const int	numVertices	=	currentShadingState->numVertices;
400 		float		*Pf			=	(float *) alloca(numVertices*3*sizeof(float));
401 		float		*Nf			=	(float *) alloca(numVertices*3*sizeof(float));
402 		float		*thetaf		=	(float *) alloca(numVertices*sizeof(float));
403 		int			i;
404 		float		*cP			=	Pf;
405 		float		*cN			=	Nf;
406 		float		*cTheta		=	thetaf;
407 		float		*L;
408 		float		*CL;
409 
410 		// Generate points on the surface
411 		for (i=numVertices;i>0;i--,cP+=3,cN+=3) {
412 			vector			P0,P1;
413 			const float		u	=	context->urand();
414 			const float		v	=	context->urand();
415 
416 			interpolatev(P0,corners[0],corners[1],u);
417 			interpolatev(P1,corners[2],corners[3],u);
418 			interpolatev(cP,P0,P1,v);
419 
420 			movvv(cN,N);
421 
422 			*cTheta++	=	(float) (C_PI / 2.0);
423 		}
424 
425 		// Call the hook handle
426 		context->illuminateBegin(Pf,Nf,thetaf);
427 
428 		// Compute the intensity
429 		L			=	currentShadingState->varying[VARIABLE_L];
430 		CL			=	currentShadingState->varying[VARIABLE_CL];
431 		for (i=numVertices;i>0;i--,L+=3,CL+=3) {
432 			// The L must be unit vector
433 			assert((dotvv(L,L) - 1)*(dotvv(L,L) - 1) < 0.00001);
434 			assert(dotvv(N,L) >= 0);
435 
436 			mulvf(CL,lightColor,intensity);
437 			mulvf(CL,dotvv(N,L));
438 		}
439 
440 		// Call the hook handle
441 		context->illuminateEnd();
442 	} else {
443 		CShadedLight	**lights				=	&currentShadingState->lights;
444 		CShadedLight	**freeLights			=	&currentShadingState->freeLights;
445 		const int		*tags					=	currentShadingState->tags;
446 		float			*Ps						=	currentShadingState->varying[VARIABLE_PS];
447 		CRay			ray;
448 		const float		bias					=	currentShadingState->currentObject->attributes->bias;
449 		vector			D;
450 		int				j;
451 		int				numVertices				=	currentShadingState->numRealVertices;
452 		int				numLitPoints			=	0;
453 		CShadedLight	*cLight;
454 		int				*lightTags;
455 
456 		if (currentShadingState->numActive == 0)
457 			return;
458 
459 		cLight						=	(CShadedLight*) ralloc(sizeof(CShadedLight),context->threadMemory);
460 		cLight->lightTags			=	(int*)			ralloc(sizeof(int)*numVertices,context->threadMemory);
461 		cLight->savedState			=	(float**)		ralloc(2*sizeof(float*),context->threadMemory);
462 		cLight->savedState[0]		=	(float*)		ralloc(3*sizeof(float)*numVertices,context->threadMemory);
463 		cLight->savedState[1]		=	(float*)		ralloc(3*sizeof(float)*numVertices,context->threadMemory);
464 		cLight->instance			=	this;
465 		memcpy(cLight->lightTags,tags,sizeof(int)*numVertices);
466 		float		*L					=	cLight->savedState[0];
467 		float		*Cl					=	cLight->savedState[1];
468 		const float	*time				=	currentShadingState->varying[VARIABLE_TIME];
469 
470 		// GSHTODO: do something to check Ps vs N angle before allocating light
471 
472 
473 
474 
475 		lightTags = cLight->lightTags;
476 		for (int i=currentShadingState->numRealVertices;i>0;i--,Ps+=3,time++) {
477 			if (*lightTags == 0) {
478 				subvv(D,Ps,center);
479 				if (dotvv(D,N) > 0) {
480 					vector			P,P0,P1;
481 					float			visibility	=	0;
482 
483 					for (j=numSamples;j>0;j--) {
484 						const float	u	=	context->urand();
485 
486 						interpolatev(P0,corners[0],corners[1],u);
487 						interpolatev(P1,corners[2],corners[3],u);
488 						interpolatev(P,P0,P1,context->urand());
489 
490 						// Evaluate visibility between P and Ps
491 						movvv(ray.from,Ps);
492 						subvv(ray.dir,P,Ps);
493 						const float	len	=	lengthv(ray.dir);
494 						mulvf(ray.dir,1 / len);
495 
496 						ray.flags				=	ATTRIBUTES_FLAGS_TRANSMISSION_VISIBLE;
497 						ray.tmin				=	bias;
498 						ray.t					=	len - bias;
499 						ray.time				=	*time;
500 
501 						// Figure out the ray differential
502 						const float	sina		=	r / len;
503 						const float	cosa		=	sqrtf(1 - sina*sina);
504 						const float	da			=	sina / (cosa + C_EPSILON);
505 						ray.da					=	min(DEFAULT_RAY_DA,da);
506 						ray.db					=	DEFAULT_RAY_DB;
507 
508 						context->trace(&ray);
509 
510 						if (ray.object == NULL) {
511 							visibility++;
512 						}
513 					}
514 
515 					visibility			/=	(float) numSamples;
516 					subvv(L,center,Ps);
517 					visibility			/=	dotvv(L,L);
518 					normalizev(L);
519 					visibility			*=	-dotvv(N,L)*intensity;
520 					mulvf(Cl,lightColor,visibility);
521 					numLitPoints++;
522 				} else {
523 					(*lightTags)++;
524 				}
525 				lightTags++;
526 				L	+=	3;
527 				Cl	+=	3;
528 			}
529 		}
530 
531 		if (numLitPoints > 0) {
532 			// Only save the light if it has active points
533 			cLight->next				=	*lights;
534 			*lights						=	cLight;
535 		} else {
536 			// Otherwise put it on the free list
537 			cLight->next				=	*freeLights;
538 			*freeLights					=	cLight;
539 		}
540 	}
541 }
542 
543 ///////////////////////////////////////////////////////////////////////
544 // Class				:	CQuadLight
545 // Method				:	setParameters
546 // Description			:	Set shader parameters
547 // Return Value			:	-
548 // Comments				:
setParameters(int n,const char ** params,const void ** vals)549 void					CQuadLight::setParameters(int n,const char **params,const void **vals) {
550 	int	i;
551 
552 	for (i=0;i<n;i++) {
553 		if (strcmp(params[i],"P0") == 0) {
554 			const float	*val	=	(const float *) vals[i];
555 
556 			mulmp(corners[0],xform->from,val);
557 		} else if (strcmp(params[i],"P1") == 0) {
558 			const float	*val	=	(const float *) vals[i];
559 
560 			mulmp(corners[1],xform->from,val);
561 		} else if (strcmp(params[i],"P2") == 0) {
562 			const float	*val	=	(const float *) vals[i];
563 
564 			mulmp(corners[2],xform->from,val);
565 		} else if (strcmp(params[i],"P3") == 0) {
566 			const float	*val	=	(const float *) vals[i];
567 
568 			mulmp(corners[3],xform->from,val);
569 		} else if (strcmp(params[i],"direction") == 0) {
570 			const float	*val	=	(const float *) vals[i];
571 
572 			mulmn(N,xform->to,val);
573 		} else if (strcmp(params[i],"lightcolor") == 0) {
574 			const float	*val	=	(const float *) vals[i];
575 
576 			movvv(lightColor,val);
577 		} else if (strcmp(params[i],"intensity") == 0) {
578 			const float	*val	=	(const float *) vals[i];
579 
580 			intensity	=	val[0];
581 		} else if (strcmp(params[i],"numSamples") == 0) {
582 			const float	*val	=	(const float *) vals[i];
583 
584 			numSamples	=	(int) val[0];
585 		}
586 	}
587 }
588 
589 ///////////////////////////////////////////////////////////////////////
590 // Class				:	CQuadLight
591 // Method				:	getParameter
592 // Description			:	Query a shader parameter
593 // Return Value			:	-
594 // Comments				:
getParameter(const char * param,void * val,CVariable **,int *)595 int						CQuadLight::getParameter(const char *param,void *val,CVariable**,int*) {
596 	if (strcmp(param,"P0") == 0) {
597 		float	*cval	=	(float *) val;
598 
599 		movvv(cval,corners[0]);
600 		return TRUE;
601 	} else if (strcmp(param,"P1") == 0) {
602 		float	*cval	=	(float *) val;
603 
604 		movvv(cval,corners[1]);
605 		return TRUE;
606 	} else if (strcmp(param,"P2") == 0) {
607 		float	*cval	=	(float *) val;
608 
609 		movvv(cval,corners[1]);
610 		return TRUE;
611 	} else if (strcmp(param,"P3") == 0) {
612 		float	*cval	=	(float *) val;
613 
614 		movvv(cval,corners[1]);
615 		return TRUE;
616 	} else if (strcmp(param,"direction") == 0) {
617 		float	*cval	=	(float *) val;
618 
619 		movvv(cval,N);
620 		return TRUE;
621 	} else if (strcmp(param,"lightColor") == 0) {
622 		float	*cval	=	(float *) val;
623 
624 		movvv(cval,lightColor);
625 		return TRUE;
626 	} else if (strcmp(param,"intensity") == 0) {
627 		float	*cval	=	(float *) val;
628 
629 		cval[0]	=	intensity;
630 		return TRUE;
631 	} else if (strcmp(param,"numSamples") == 0) {
632 		float	*cval	=	(float *) val;
633 
634 		cval[0]	=	(float) numSamples;
635 		return TRUE;
636 	}
637 
638 	return FALSE;
639 }
640 
641 ///////////////////////////////////////////////////////////////////////
642 // Class				:	CQuadLight
643 // Method				:	execute
644 // Description			:	Execute the shader
645 // Return Value			:	-
646 // Comments				:	Should never be called
execute(CShadingContext * context,float ** locals)647 void					CQuadLight::execute(CShadingContext *context,float **locals) {
648 	// Should never be called
649 	assert(FALSE);
650 }
651 
652 ///////////////////////////////////////////////////////////////////////
653 // Class				:	CQuadLight
654 // Method				:	requiredParameters
655 // Description			:	Get the required parameters
656 // Return Value			:	-
657 // Comments				:
requiredParameters()658 unsigned int			CQuadLight::requiredParameters() {
659 	return 0;
660 }
661 
662 ///////////////////////////////////////////////////////////////////////
663 // Class				:	CQuadLight
664 // Method				:	getName
665 // Description			:	Get the name of the shader
666 // Return Value			:	-
667 // Comments				:
getName()668 const char				*CQuadLight::getName() {
669 	return "quadlight";
670 }
671 
672