Carefully went over all scanline updating while rendering, to ensure only
[blender-staging.git] / source / blender / render / intern / source / rendercore.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributors: Hos, Robert Wenzlaff.
24  * Contributors: 2004/2005/2006 Blender Foundation, full recode
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 /* system includes */
30 #include <stdio.h>
31 #include <math.h>
32 #include <string.h>
33 #include <stdlib.h>
34
35 /* External modules: */
36 #include "MTC_matrixops.h"
37
38 #include "BLI_arithb.h"
39 #include "BLI_blenlib.h"
40 #include "BLI_jitter.h"
41 #include "BLI_rand.h"
42 #include "BLI_threads.h"
43
44 #include "BKE_utildefines.h"
45
46 #include "DNA_group_types.h"
47 #include "DNA_image_types.h"
48 #include "DNA_lamp_types.h"
49 #include "DNA_material_types.h"
50 #include "DNA_mesh_types.h"
51 #include "DNA_meshdata_types.h"
52 #include "DNA_object_types.h"
53 #include "DNA_texture_types.h"
54
55 #include "BKE_global.h"
56 #include "BKE_material.h"
57 #include "BKE_node.h"
58 #include "BKE_texture.h"
59
60 /* local include */
61 #include "renderpipeline.h"
62 #include "render_types.h"
63 #include "renderdatabase.h"
64 #include "pixelblending.h"
65 #include "pixelshading.h"
66 #include "gammaCorrectionTables.h"
67 #include "shadbuf.h"
68 #include "zbuf.h"
69
70 #include "texture.h"
71
72 /* own include */
73 #include "rendercore.h"
74
75
76 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
77 /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
78 /* only to be used here in this file, it's for speed */
79 extern struct Render R;
80 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
81
82 /* x and y are current pixels in rect to be rendered */
83 /* do not normalize! */
84 void calc_view_vector(float *view, float x, float y)
85 {
86
87         if(R.r.mode & R_ORTHO) {
88                 view[0]= view[1]= 0.0;
89         }
90         else {
91                 /* move x and y to real viewplane coords */
92                 x= (x/(float)R.winx);
93                 view[0]= R.viewplane.xmin + x*(R.viewplane.xmax - R.viewplane.xmin);
94                 
95                 y= (y/(float)R.winy);
96                 view[1]= R.viewplane.ymin + y*(R.viewplane.ymax - R.viewplane.ymin);
97                 
98 //              if(R.flag & R_SEC_FIELD) {
99 //                      if(R.r.mode & R_ODDFIELD) view[1]= (y+R.ystart)*R.ycor;
100 //                      else view[1]= (y+R.ystart+1.0)*R.ycor;
101 //              }
102 //              else view[1]= (y+R.ystart+R.bluroffsy+0.5)*R.ycor;
103         }
104         
105         view[2]= -R.clipsta;
106         
107         if(R.r.mode & R_PANORAMA) {
108                 float u= view[0]; float v= view[2];
109                 view[0]= R.panoco*u + R.panosi*v;
110                 view[2]= -R.panosi*u + R.panoco*v;
111         }
112
113 }
114
115 #if 0
116 static void fogcolor(float *colf, float *rco, float *view)
117 {
118         float alpha, stepsize, startdist, dist, hor[4], zen[3], vec[3], dview[3];
119         float div=0.0f, distfac;
120         
121         hor[0]= R.wrld.horr; hor[1]= R.wrld.horg; hor[2]= R.wrld.horb;
122         zen[0]= R.wrld.zenr; zen[1]= R.wrld.zeng; zen[2]= R.wrld.zenb;
123         
124         VECCOPY(vec, rco);
125         
126         /* we loop from cur coord to mist start in steps */
127         stepsize= 1.0f;
128         
129         div= ABS(view[2]);
130         dview[0]= view[0]/(stepsize*div);
131         dview[1]= view[1]/(stepsize*div);
132         dview[2]= -stepsize;
133
134         startdist= -rco[2] + BLI_frand();
135         for(dist= startdist; dist>R.wrld.miststa; dist-= stepsize) {
136                 
137                 hor[0]= R.wrld.horr; hor[1]= R.wrld.horg; hor[2]= R.wrld.horb;
138                 alpha= 1.0f;
139                 do_sky_tex(vec, vec, NULL, hor, zen, &alpha);
140                 
141                 distfac= (dist-R.wrld.miststa)/R.wrld.mistdist;
142                 
143                 hor[3]= hor[0]*distfac*distfac;
144                 
145                 /* premul! */
146                 alpha= hor[3];
147                 hor[0]= hor[0]*alpha;
148                 hor[1]= hor[1]*alpha;
149                 hor[2]= hor[2]*alpha;
150                 addAlphaOverFloat(colf, hor);
151                 
152                 VECSUB(vec, vec, dview);
153         }       
154 }
155 #endif
156
157 float mistfactor(float zcor, float *co) /* dist en height, return alpha */
158 {
159         float fac, hi;
160         
161         fac= zcor - R.wrld.miststa;     /* zcor is calculated per pixel */
162
163         /* fac= -co[2]-R.wrld.miststa; */
164
165         if(fac>0.0) {
166                 if(fac< R.wrld.mistdist) {
167                         
168                         fac= (fac/(R.wrld.mistdist));
169                         
170                         if(R.wrld.mistype==0) fac*= fac;
171                         else if(R.wrld.mistype==1);
172                         else fac= sqrt(fac);
173                 }
174                 else fac= 1.0;
175         }
176         else fac= 0.0;
177         
178         /* height switched off mist */
179         if(R.wrld.misthi!=0.0 && fac!=0.0) {
180                 /* at height misthi the mist is completely gone */
181
182                 hi= R.viewinv[0][2]*co[0]+R.viewinv[1][2]*co[1]+R.viewinv[2][2]*co[2]+R.viewinv[3][2];
183                 
184                 if(hi>R.wrld.misthi) fac= 0.0;
185                 else if(hi>0.0) {
186                         hi= (R.wrld.misthi-hi)/R.wrld.misthi;
187                         fac*= hi*hi;
188                 }
189         }
190
191         return (1.0-fac)* (1.0-R.wrld.misi);    
192 }
193
194 static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens)
195 {
196         double a, b, c, disc, nray[3], npos[3];
197         float t0, t1 = 0.0, t2= 0.0, t3, haint;
198         float p1[3], p2[3], ladist, maxz = 0.0, maxy = 0.0;
199         int snijp, doclip=1, use_yco=0;
200         int ok1=0, ok2=0;
201         
202         *intens= 0.0;
203         haint= lar->haint;
204         
205         if(R.r.mode & R_ORTHO) {
206                 /* camera pos (view vector) cannot be used... */
207                 /* camera position (cox,coy,0) rotate around lamp */
208                 p1[0]= shi->co[0]-lar->co[0];
209                 p1[1]= shi->co[1]-lar->co[1];
210                 p1[2]= -lar->co[2];
211                 MTC_Mat3MulVecfl(lar->imat, p1);
212                 VECCOPY(npos, p1);      // npos is double!
213         }
214         else {
215                 VECCOPY(npos, lar->sh_invcampos);       /* in initlamp calculated */
216         }
217         
218         /* rotate view */
219         VECCOPY(nray, shi->view);
220         MTC_Mat3MulVecd(lar->imat, nray);
221         
222         if(R.wrld.mode & WO_MIST) {
223                 /* patchy... */
224                 haint *= mistfactor(-lar->co[2], lar->co);
225                 if(haint==0.0) {
226                         return;
227                 }
228         }
229
230
231         /* rotate maxz */
232         if(shi->co[2]==0.0) doclip= 0;  /* for when halo at sky */
233         else {
234                 p1[0]= shi->co[0]-lar->co[0];
235                 p1[1]= shi->co[1]-lar->co[1];
236                 p1[2]= shi->co[2]-lar->co[2];
237         
238                 maxz= lar->imat[0][2]*p1[0]+lar->imat[1][2]*p1[1]+lar->imat[2][2]*p1[2];
239                 maxz*= lar->sh_zfac;
240                 maxy= lar->imat[0][1]*p1[0]+lar->imat[1][1]*p1[1]+lar->imat[2][1]*p1[2];
241
242                 if( fabs(nray[2]) <0.000001 ) use_yco= 1;
243         }
244         
245         /* scale z to make sure volume is normalized */ 
246         nray[2]*= lar->sh_zfac;
247         /* nray does not need normalization */
248         
249         ladist= lar->sh_zfac*lar->dist;
250         
251         /* solve */
252         a = nray[0] * nray[0] + nray[1] * nray[1] - nray[2]*nray[2];
253         b = nray[0] * npos[0] + nray[1] * npos[1] - nray[2]*npos[2];
254         c = npos[0] * npos[0] + npos[1] * npos[1] - npos[2]*npos[2];
255
256         snijp= 0;
257         if (fabs(a) < 0.00000001) {
258                 /*
259                  * Only one intersection point...
260                  */
261                 return;
262         }
263         else {
264                 disc = b*b - a*c;
265                 
266                 if(disc==0.0) {
267                         t1=t2= (-b)/ a;
268                         snijp= 2;
269                 }
270                 else if (disc > 0.0) {
271                         disc = sqrt(disc);
272                         t1 = (-b + disc) / a;
273                         t2 = (-b - disc) / a;
274                         snijp= 2;
275                 }
276         }
277         if(snijp==2) {
278                 /* sort */
279                 if(t1>t2) {
280                         a= t1; t1= t2; t2= a;
281                 }
282
283                 /* z of intersection points with diabolo */
284                 p1[2]= npos[2] + t1*nray[2];
285                 p2[2]= npos[2] + t2*nray[2];
286
287                 /* evaluate both points */
288                 if(p1[2]<=0.0) ok1= 1;
289                 if(p2[2]<=0.0 && t1!=t2) ok2= 1;
290                 
291                 /* at least 1 point with negative z */
292                 if(ok1==0 && ok2==0) return;
293                 
294                 /* intersction point with -ladist, the bottom of the cone */
295                 if(use_yco==0) {
296                         t3= (-ladist-npos[2])/nray[2];
297                                 
298                         /* de we have to replace one of the intersection points? */
299                         if(ok1) {
300                                 if(p1[2]<-ladist) t1= t3;
301                         }
302                         else {
303                                 ok1= 1;
304                                 t1= t3;
305                         }
306                         if(ok2) {
307                                 if(p2[2]<-ladist) t2= t3;
308                         }
309                         else {
310                                 ok2= 1;
311                                 t2= t3;
312                         }
313                 }
314                 else if(ok1==0 || ok2==0) return;
315                 
316                 /* at least 1 visible interesction point */
317                 if(t1<0.0 && t2<0.0) return;
318                 
319                 if(t1<0.0) t1= 0.0;
320                 if(t2<0.0) t2= 0.0;
321                 
322                 if(t1==t2) return;
323                 
324                 /* sort again to be sure */
325                 if(t1>t2) {
326                         a= t1; t1= t2; t2= a;
327                 }
328                 
329                 /* calculate t0: is the maximum visible z (when halo is intersected by face) */ 
330                 if(doclip) {
331                         if(use_yco==0) t0= (maxz-npos[2])/nray[2];
332                         else t0= (maxy-npos[1])/nray[1];
333
334                         if(t0<t1) return;
335                         if(t0<t2) t2= t0;
336                 }
337
338                 /* calc points */
339                 p1[0]= npos[0] + t1*nray[0];
340                 p1[1]= npos[1] + t1*nray[1];
341                 p1[2]= npos[2] + t1*nray[2];
342                 p2[0]= npos[0] + t2*nray[0];
343                 p2[1]= npos[1] + t2*nray[1];
344                 p2[2]= npos[2] + t2*nray[2];
345                 
346                         
347                 /* now we have 2 points, make three lengths with it */
348                 
349                 a= sqrt(p1[0]*p1[0]+p1[1]*p1[1]+p1[2]*p1[2]);
350                 b= sqrt(p2[0]*p2[0]+p2[1]*p2[1]+p2[2]*p2[2]);
351                 c= VecLenf(p1, p2);
352                 
353                 a/= ladist;
354                 a= sqrt(a);
355                 b/= ladist; 
356                 b= sqrt(b);
357                 c/= ladist;
358                 
359                 *intens= c*( (1.0-a)+(1.0-b) );
360
361                 /* WATCH IT: do not clip a,b en c at 1.0, this gives nasty little overflows
362                         at the edges (especially with narrow halos) */
363                 if(*intens<=0.0) return;
364
365                 /* soft area */
366                 /* not needed because t0 has been used for p1/p2 as well */
367                 /* if(doclip && t0<t2) { */
368                 /*      *intens *= (t0-t1)/(t2-t1); */
369                 /* } */
370                 
371                 *intens *= haint;
372                 
373                 if(lar->shb && lar->shb->shadhalostep) {
374                         *intens *= shadow_halo(lar, p1, p2);
375                 }
376                 
377         }
378 }
379
380 static void renderspothalo(ShadeInput *shi, float *col, float alpha)
381 {
382         GroupObject *go;
383         LampRen *lar;
384         float i;
385         
386         if(alpha==0.0f) return;
387
388         for(go=R.lights.first; go; go= go->next) {
389                 lar= go->lampren;
390                 
391                 if(lar->type==LA_SPOT && (lar->mode & LA_HALO) && lar->haint>0) {
392         
393                         spothalo(lar, shi, &i);
394                         if(i>0.0) {
395                                 col[3]+= i*alpha;                       // all premul
396                                 col[0]+= i*lar->r*alpha;
397                                 col[1]+= i*lar->g*alpha;
398                                 col[2]+= i*lar->b*alpha;        
399                         }
400                 }
401         }
402         /* clip alpha, is needed for unified 'alpha threshold' (vanillaRenderPipe.c) */
403         if(col[3]>1.0) col[3]= 1.0;
404 }
405
406
407
408 /* also used in zbuf.c */
409 int count_mask(unsigned short mask)
410 {
411         if(R.samples)
412                 return (R.samples->cmask[mask & 255]+R.samples->cmask[mask>>8]);
413         return 0;
414 }
415
416 static int calchalo_z(HaloRen *har, int zz)
417 {
418         
419         if(har->type & HA_ONLYSKY) {
420                 if(zz!=0x7FFFFFFF) zz= - 0x7FFFFF;
421         }
422         else {
423                 zz= (zz>>8);
424         }
425         return zz;
426 }
427
428 static void halo_pixelstruct(HaloRen *har, float *rb, float dist, float xn, float yn, PixStr *ps)
429 {
430         float col[4], accol[4];
431         int amount, amountm, zz, flarec;
432         
433         amount= 0;
434         accol[0]=accol[1]=accol[2]=accol[3]= 0.0;
435         flarec= har->flarec;
436         
437         while(ps) {
438                 amountm= count_mask(ps->mask);
439                 amount+= amountm;
440                 
441                 zz= calchalo_z(har, ps->z);
442                 if(zz> har->zs) {
443                         float fac;
444                         
445                         shadeHaloFloat(har, col, zz, dist, xn, yn, flarec);
446                         fac= ((float)amountm)/(float)R.osa;
447                         accol[0]+= fac*col[0];
448                         accol[1]+= fac*col[1];
449                         accol[2]+= fac*col[2];
450                         accol[3]+= fac*col[3];
451                         flarec= 0;
452                 }
453                 
454                 ps= ps->next;
455         }
456         /* now do the sky sub-pixels */
457         amount= R.osa-amount;
458         if(amount) {
459                 float fac;
460
461                 shadeHaloFloat(har, col, 0x7FFFFF, dist, xn, yn, flarec);
462                 fac= ((float)amount)/(float)R.osa;
463                 accol[0]+= fac*col[0];
464                 accol[1]+= fac*col[1];
465                 accol[2]+= fac*col[2];
466                 accol[3]+= fac*col[3];
467         }
468         col[0]= accol[0];
469         col[1]= accol[1];
470         col[2]= accol[2];
471         col[3]= accol[3];
472         
473         addalphaAddfacFloat(rb, col, har->add);
474         
475 }
476
477 static void halo_tile(RenderPart *pa, float *pass, unsigned int lay)
478 {
479         HaloRen *har = NULL;
480         rcti disprect= pa->disprect;
481         float dist, xsq, ysq, xn, yn, *rb;
482         float col[4];
483         long *rd= NULL;
484         int a, *rz, zz, y;
485         short minx, maxx, miny, maxy, x;
486
487         for(a=0; a<R.tothalo; a++) {
488                 if((a & 255)==0) {
489                         if(R.test_break() ) break; 
490                         har= R.bloha[a>>8];
491                 }
492                 else har++;
493
494                 /* layer test, clip halo with y */
495                 if((har->lay & lay)==0);
496                 else if(disprect.ymin > har->maxy);
497                 else if(disprect.ymax < har->miny);
498                 else {
499                         
500                         minx= floor(har->xs-har->rad);
501                         maxx= ceil(har->xs+har->rad);
502                         
503                         if(disprect.xmin > maxx);
504                         else if(disprect.xmax < minx);
505                         else {
506                                 
507                                 minx= MAX2(minx, disprect.xmin);
508                                 maxx= MIN2(maxx, disprect.xmax);
509                         
510                                 miny= MAX2(har->miny, disprect.ymin);
511                                 maxy= MIN2(har->maxy, disprect.ymax);
512                         
513                                 for(y=miny; y<maxy; y++) {
514                                         int rectofs= (y-disprect.ymin)*pa->rectx + (minx - disprect.xmin);
515                                         rb= pass + 4*rectofs;
516                                         rz= pa->rectz + rectofs;
517                                         
518                                         if(pa->rectdaps)
519                                                 rd= pa->rectdaps + rectofs;
520                                         
521                                         yn= (y-har->ys)*R.ycor;
522                                         ysq= yn*yn;
523                                         
524                                         for(x=minx; x<maxx; x++, rb+=4, rz++) {
525                                                 xn= x- har->xs;
526                                                 xsq= xn*xn;
527                                                 dist= xsq+ysq;
528                                                 if(dist<har->radsq) {
529                                                         if(rd && *rd) {
530                                                                 halo_pixelstruct(har, rb, dist, xn, yn, (PixStr *)*rd);
531                                                         }
532                                                         else {
533                                                                 zz= calchalo_z(har, *rz);
534                                                                 if(zz> har->zs) {
535                                                                         shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec);
536                                                                         addalphaAddfacFloat(rb, col, har->add);
537                                                                 }
538                                                         }
539                                                 }
540                                                 if(rd) rd++;
541                                         }
542                                 }
543                         }
544                 }
545         }
546 }
547
548 static void lamphalo_tile(RenderPart *pa, float *pass, unsigned int lay)
549 {
550         ShadeInput shi;
551         float zco, fac;
552         long *rd= pa->rectdaps;
553         int x, y, *rz= pa->rectz;
554         
555         for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
556                 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, pass+=4) {
557                         
558                         calc_view_vector(shi.view, x, y);
559                         
560                         if(rd && *rd) {
561                                 PixStr *ps= (PixStr *)*rd;
562                                 int samp, totsamp= 0;
563                                 
564                                 while(ps) {
565                                         /* inverse of zbuf calc: zbuf = MAXZ*hoco_z/hoco_w */
566                                         zco= ((float)ps->z)/2147483647.0f;
567                                         shi.co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] );
568                                         
569                                         fac= shi.co[2]/shi.view[2];
570                                         shi.co[0]= fac*shi.view[0];
571                                         shi.co[1]= fac*shi.view[1];
572                                         
573                                         totsamp+= samp= count_mask(ps->mask);
574                                         fac= ((float)samp)/(float)R.osa;
575                                         renderspothalo(&shi, pass, fac);
576                                         ps= ps->next;
577                                 }
578                                 if(totsamp<R.osa) {
579                                         fac= ((float)R.osa-totsamp)/(float)R.osa;
580                                         shi.co[2]= 0.0f;
581                                         renderspothalo(&shi, pass, fac);
582                                 }
583                                 
584                         }
585                         else {
586                                 /* inverse of zbuf calc: zbuf = MAXZ*hoco_z/hoco_w */
587                                 zco= ((float)*rz)/2147483647.0f;
588                                 zco= shi.co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] );
589                                 fac= shi.co[2]/shi.view[2];
590                                 shi.co[0]= fac*shi.view[0];
591                                 shi.co[1]= fac*shi.view[1];
592                                 
593                                 renderspothalo(&shi, pass, 1.0);
594                         }
595                         
596                         if(rd) rd++;
597                 }
598                 if(y&1)
599                         if(R.test_break()) break; 
600         }
601 }                               
602
603 /* ---------------- shaders ----------------------- */
604
605 static double Normalise_d(double *n)
606 {
607         double d;
608         
609         d= n[0]*n[0]+n[1]*n[1]+n[2]*n[2];
610
611         if(d>0.00000000000000001) {
612                 d= sqrt(d);
613
614                 n[0]/=d; 
615                 n[1]/=d; 
616                 n[2]/=d;
617         } else {
618                 n[0]=n[1]=n[2]= 0.0;
619                 d= 0.0;
620         }
621         return d;
622 }
623
624 /* mix of 'real' fresnel and allowing control. grad defines blending gradient */
625 float fresnel_fac(float *view, float *vn, float grad, float fac)
626 {
627         float t1, t2;
628         
629         if(fac==0.0) return 1.0;
630         
631         t1= (view[0]*vn[0] + view[1]*vn[1] + view[2]*vn[2]);
632         if(t1>0.0)  t2= 1.0+t1;
633         else t2= 1.0-t1;
634         
635         t2= grad + (1.0-grad)*pow(t2, fac);
636         
637         if(t2<0.0) return 0.0;
638         else if(t2>1.0) return 1.0;
639         return t2;
640 }
641
642 static double saacos_d(double fac)
643 {
644         if(fac<= -1.0f) return M_PI;
645         else if(fac>=1.0f) return 0.0;
646         else return acos(fac);
647 }
648
649 /* Stoke's form factor. Need doubles here for extreme small area sizes */
650 static float area_lamp_energy(float *co, float *vn, LampRen *lar)
651 {
652         double fac;
653         double vec[4][3];       /* vectors of rendered co to vertices lamp */
654         double cross[4][3];     /* cross products of this */
655         double rad[4];          /* angles between vecs */
656
657         VECSUB(vec[0], co, lar->area[0]);
658         VECSUB(vec[1], co, lar->area[1]);
659         VECSUB(vec[2], co, lar->area[2]);
660         VECSUB(vec[3], co, lar->area[3]);
661         
662         Normalise_d(vec[0]);
663         Normalise_d(vec[1]);
664         Normalise_d(vec[2]);
665         Normalise_d(vec[3]);
666
667         /* cross product */
668         CROSS(cross[0], vec[0], vec[1]);
669         CROSS(cross[1], vec[1], vec[2]);
670         CROSS(cross[2], vec[2], vec[3]);
671         CROSS(cross[3], vec[3], vec[0]);
672
673         Normalise_d(cross[0]);
674         Normalise_d(cross[1]);
675         Normalise_d(cross[2]);
676         Normalise_d(cross[3]);
677
678         /* angles */
679         rad[0]= vec[0][0]*vec[1][0]+ vec[0][1]*vec[1][1]+ vec[0][2]*vec[1][2];
680         rad[1]= vec[1][0]*vec[2][0]+ vec[1][1]*vec[2][1]+ vec[1][2]*vec[2][2];
681         rad[2]= vec[2][0]*vec[3][0]+ vec[2][1]*vec[3][1]+ vec[2][2]*vec[3][2];
682         rad[3]= vec[3][0]*vec[0][0]+ vec[3][1]*vec[0][1]+ vec[3][2]*vec[0][2];
683
684         rad[0]= saacos_d(rad[0]);
685         rad[1]= saacos_d(rad[1]);
686         rad[2]= saacos_d(rad[2]);
687         rad[3]= saacos_d(rad[3]);
688
689         /* Stoke formula */
690         fac=  rad[0]*(vn[0]*cross[0][0]+ vn[1]*cross[0][1]+ vn[2]*cross[0][2]);
691         fac+= rad[1]*(vn[0]*cross[1][0]+ vn[1]*cross[1][1]+ vn[2]*cross[1][2]);
692         fac+= rad[2]*(vn[0]*cross[2][0]+ vn[1]*cross[2][1]+ vn[2]*cross[2][2]);
693         fac+= rad[3]*(vn[0]*cross[3][0]+ vn[1]*cross[3][1]+ vn[2]*cross[3][2]);
694
695         if(fac<=0.0) return 0.0;
696         return pow(fac*lar->areasize, lar->k);  // corrected for buttons size and lar->dist^2
697 }
698
699 static float spec(float inp, int hard)  
700 {
701         float b1;
702         
703         if(inp>=1.0) return 1.0;
704         else if (inp<=0.0) return 0.0;
705         
706         b1= inp*inp;
707         /* avoid FPE */
708         if(b1<0.01) b1= 0.01;   
709         
710         if((hard & 1)==0)  inp= 1.0;
711         if(hard & 2)  inp*= b1;
712         b1*= b1;
713         if(hard & 4)  inp*= b1;
714         b1*= b1;
715         if(hard & 8)  inp*= b1;
716         b1*= b1;
717         if(hard & 16) inp*= b1;
718         b1*= b1;
719
720         /* avoid FPE */
721         if(b1<0.001) b1= 0.0;   
722
723         if(hard & 32) inp*= b1;
724         b1*= b1;
725         if(hard & 64) inp*=b1;
726         b1*= b1;
727         if(hard & 128) inp*=b1;
728
729         if(b1<0.001) b1= 0.0;   
730
731         if(hard & 256) {
732                 b1*= b1;
733                 inp*=b1;
734         }
735
736         return inp;
737 }
738
739 static float Phong_Spec( float *n, float *l, float *v, int hard, int tangent )
740 {
741         float h[3];
742         float rslt;
743         
744         h[0] = l[0] + v[0];
745         h[1] = l[1] + v[1];
746         h[2] = l[2] + v[2];
747         Normalise(h);
748         
749         rslt = h[0]*n[0] + h[1]*n[1] + h[2]*n[2];
750         if(tangent) rslt= sasqrt(1.0 - rslt*rslt);
751                 
752         if( rslt > 0.0 ) rslt= spec(rslt, hard);
753         else rslt = 0.0;
754         
755         return rslt;
756 }
757
758
759 /* reduced cook torrance spec (for off-specular peak) */
760 static float CookTorr_Spec(float *n, float *l, float *v, int hard, int tangent)
761 {
762         float i, nh, nv, h[3];
763
764         h[0]= v[0]+l[0];
765         h[1]= v[1]+l[1];
766         h[2]= v[2]+l[2];
767         Normalise(h);
768
769         nh= n[0]*h[0]+n[1]*h[1]+n[2]*h[2];
770         if(tangent) nh= sasqrt(1.0 - nh*nh);
771         else if(nh<0.0) return 0.0;
772         
773         nv= n[0]*v[0]+n[1]*v[1]+n[2]*v[2];
774         if(tangent) nv= sasqrt(1.0 - nv*nv);
775         else if(nv<0.0) nv= 0.0;
776
777         i= spec(nh, hard);
778
779         i= i/(0.1+nv);
780         return i;
781 }
782
783 /* Blinn spec */
784 static float Blinn_Spec(float *n, float *l, float *v, float refrac, float spec_power, int tangent)
785 {
786         float i, nh, nv, nl, vh, h[3];
787         float a, b, c, g=0.0, p, f, ang;
788
789         if(refrac < 1.0) return 0.0;
790         if(spec_power == 0.0) return 0.0;
791         
792         /* conversion from 'hardness' (1-255) to 'spec_power' (50 maps at 0.1) */
793         if(spec_power<100.0)
794                 spec_power= sqrt(1.0/spec_power);
795         else spec_power= 10.0/spec_power;
796         
797         h[0]= v[0]+l[0];
798         h[1]= v[1]+l[1];
799         h[2]= v[2]+l[2];
800         Normalise(h);
801
802         nh= n[0]*h[0]+n[1]*h[1]+n[2]*h[2]; /* Dot product between surface normal and half-way vector */
803         if(tangent) nh= sasqrt(1.0f - nh*nh);
804         else if(nh<0.0) return 0.0;
805
806         nv= n[0]*v[0]+n[1]*v[1]+n[2]*v[2]; /* Dot product between surface normal and view vector */
807         if(tangent) nv= sasqrt(1.0f - nv*nv);
808         if(nv<=0.0) nv= 0.01;                           /* hrms... */
809
810         nl= n[0]*l[0]+n[1]*l[1]+n[2]*l[2]; /* Dot product between surface normal and light vector */
811         if(tangent) nl= sasqrt(1.0f - nl*nl);
812         if(nl<=0.0) {
813                 return 0.0;
814         }
815
816         vh= v[0]*h[0]+v[1]*h[1]+v[2]*h[2]; /* Dot product between view vector and half-way vector */
817         if(vh<=0.0) vh= 0.01;
818
819         a = 1.0;
820         b = (2.0*nh*nv)/vh;
821         c = (2.0*nh*nl)/vh;
822
823         if( a < b && a < c ) g = a;
824         else if( b < a && b < c ) g = b;
825         else if( c < a && c < b ) g = c;
826
827         p = sqrt( (double)((refrac * refrac)+(vh*vh)-1.0) );
828         f = (((p-vh)*(p-vh))/((p+vh)*(p+vh)))*(1+((((vh*(p+vh))-1.0)*((vh*(p+vh))-1.0))/(((vh*(p-vh))+1.0)*((vh*(p-vh))+1.0))));
829         ang = saacos(nh);
830
831         i= f * g * exp((double)(-(ang*ang) / (2.0*spec_power*spec_power)));
832         if(i<0.0) i= 0.0;
833         
834         return i;
835 }
836
837 /* cartoon render spec */
838 static float Toon_Spec( float *n, float *l, float *v, float size, float smooth, int tangent)
839 {
840         float h[3];
841         float ang;
842         float rslt;
843         
844         h[0] = l[0] + v[0];
845         h[1] = l[1] + v[1];
846         h[2] = l[2] + v[2];
847         Normalise(h);
848         
849         rslt = h[0]*n[0] + h[1]*n[1] + h[2]*n[2];
850         if(tangent) rslt = sasqrt(1.0f - rslt*rslt);
851         
852         ang = saacos( rslt ); 
853         
854         if( ang < size ) rslt = 1.0;
855         else if( ang >= (size + smooth) || smooth == 0.0 ) rslt = 0.0;
856         else rslt = 1.0 - ((ang - size) / smooth);
857         
858         return rslt;
859 }
860
861 /* Ward isotropic gaussian spec */
862 static float WardIso_Spec( float *n, float *l, float *v, float rms, int tangent)
863 {
864         float i, nh, nv, nl, h[3], angle, alpha;
865
866
867         /* half-way vector */
868         h[0] = l[0] + v[0];
869         h[1] = l[1] + v[1];
870         h[2] = l[2] + v[2];
871         Normalise(h);
872
873         nh = n[0]*h[0]+n[1]*h[1]+n[2]*h[2]; /* Dot product between surface normal and half-way vector */
874         if(tangent) nh = sasqrt(1.0f - nh*nh);
875         if(nh<=0.0) nh = 0.001f;
876         
877         nv = n[0]*v[0]+n[1]*v[1]+n[2]*v[2]; /* Dot product between surface normal and view vector */
878         if(tangent) nv = sasqrt(1.0f - nv*nv);
879         if(nv<=0.0) nv = 0.001f;
880
881         nl = n[0]*l[0]+n[1]*l[1]+n[2]*l[2]; /* Dot product between surface normal and light vector */
882         if(tangent) nl = sasqrt(1.0f - nl*nl);
883         if(nl<=0.0) nl = 0.001;
884
885         angle = tan(saacos(nh));
886         alpha = MAX2(rms,0.001);
887
888         i= nl * (1.0/(4*M_PI*alpha*alpha)) * (exp( -(angle*angle)/(alpha*alpha))/(sqrt(nv*nl)));
889
890         return i;
891 }
892
893 /* cartoon render diffuse */
894 static float Toon_Diff( float *n, float *l, float *v, float size, float smooth )
895 {
896         float rslt, ang;
897
898         rslt = n[0]*l[0] + n[1]*l[1] + n[2]*l[2];
899
900         ang = saacos( (double)(rslt) );
901
902         if( ang < size ) rslt = 1.0;
903         else if( ang >= (size + smooth) || smooth == 0.0 ) rslt = 0.0;
904         else rslt = 1.0 - ((ang - size) / smooth);
905
906         return rslt;
907 }
908
909 /* Oren Nayar diffuse */
910
911 /* 'nl' is either dot product, or return value of area light */
912 /* in latter case, only last multiplication uses 'nl' */
913 static float OrenNayar_Diff(float nl, float *n, float *l, float *v, float rough )
914 {
915         float i, nh, nv, vh, realnl, h[3];
916         float a, b, t, A, B;
917         float Lit_A, View_A, Lit_B[3], View_B[3];
918         
919         h[0]= v[0]+l[0];
920         h[1]= v[1]+l[1];
921         h[2]= v[2]+l[2];
922         Normalise(h);
923         
924         nh= n[0]*h[0]+n[1]*h[1]+n[2]*h[2]; /* Dot product between surface normal and half-way vector */
925         if(nh<0.0) nh = 0.0;
926         
927         nv= n[0]*v[0]+n[1]*v[1]+n[2]*v[2]; /* Dot product between surface normal and view vector */
928         if(nv<=0.0) nv= 0.0;
929         
930         realnl= n[0]*l[0]+n[1]*l[1]+n[2]*l[2]; /* Dot product between surface normal and light vector */
931         if(realnl<=0.0) return 0.0;
932         if(nl<0.0) return 0.0;          /* value from area light */
933         
934         vh= v[0]*h[0]+v[1]*h[1]+v[2]*h[2]; /* Dot product between view vector and halfway vector */
935         if(vh<=0.0) vh= 0.0;
936         
937         Lit_A = saacos(realnl);
938         View_A = saacos( nv );
939         
940         Lit_B[0] = l[0] - (realnl * n[0]);
941         Lit_B[1] = l[1] - (realnl * n[1]);
942         Lit_B[2] = l[2] - (realnl * n[2]);
943         Normalise( Lit_B );
944         
945         View_B[0] = v[0] - (nv * n[0]);
946         View_B[1] = v[1] - (nv * n[1]);
947         View_B[2] = v[2] - (nv * n[2]);
948         Normalise( View_B );
949         
950         t = Lit_B[0]*View_B[0] + Lit_B[1]*View_B[1] + Lit_B[2]*View_B[2];
951         if( t < 0 ) t = 0;
952         
953         if( Lit_A > View_A ) {
954                 a = Lit_A;
955                 b = View_A;
956         }
957         else {
958                 a = View_A;
959                 b = Lit_A;
960         }
961         
962         A = 1 - (0.5 * ((rough * rough) / ((rough * rough) + 0.33)));
963         B = 0.45 * ((rough * rough) / ((rough * rough) + 0.09));
964         
965         b*= 0.95;       /* prevent tangens from shooting to inf, 'nl' can be not a dot product here. */
966                                 /* overflow only happens with extreme size area light, and higher roughness */
967         i = nl * ( A + ( B * t * sin(a) * tan(b) ) );
968         
969         return i;
970 }
971
972 /* Minnaert diffuse */
973 static float Minnaert_Diff(float nl, float *n, float *v, float darkness)
974 {
975
976         float i, nv;
977
978         /* nl = dot product between surface normal and light vector */
979         if (nl <= 0.0)
980                 return 0;
981
982         /* nv = dot product between surface normal and view vector */
983         nv = n[0]*v[0]+n[1]*v[1]+n[2]*v[2];
984         if (nv < 0.0)
985                 nv = 0;
986
987         if (darkness <= 1)
988                 i = nl * pow(MAX2(nv*nl, 0.1), (darkness - 1) ); /*The Real model*/
989         else
990                 i = nl * pow( (1.001 - nv), (darkness  - 1) ); /*Nvidia model*/
991
992         return i;
993 }
994
995 static float Fresnel_Diff(float *vn, float *lv, float *view, float fac_i, float fac)
996 {
997         return fresnel_fac(lv, vn, fac_i, fac);
998 }
999
1000 /* --------------------------------------------- */
1001 /* also called from texture.c */
1002 void calc_R_ref(ShadeInput *shi)
1003 {
1004         float i;
1005
1006         /* shi->vn dot shi->view */
1007         i= -2*(shi->vn[0]*shi->view[0]+shi->vn[1]*shi->view[1]+shi->vn[2]*shi->view[2]);
1008
1009         shi->ref[0]= (shi->view[0]+i*shi->vn[0]);
1010         shi->ref[1]= (shi->view[1]+i*shi->vn[1]);
1011         shi->ref[2]= (shi->view[2]+i*shi->vn[2]);
1012         if(shi->osatex) {
1013                 if(shi->vlr->flag & R_SMOOTH) {
1014                         i= -2*( (shi->vn[0]+shi->dxno[0])*(shi->view[0]+shi->dxview) +
1015                                 (shi->vn[1]+shi->dxno[1])*shi->view[1]+ (shi->vn[2]+shi->dxno[2])*shi->view[2] );
1016
1017                         shi->dxref[0]= shi->ref[0]- ( shi->view[0]+shi->dxview+i*(shi->vn[0]+shi->dxno[0]));
1018                         shi->dxref[1]= shi->ref[1]- (shi->view[1]+ i*(shi->vn[1]+shi->dxno[1]));
1019                         shi->dxref[2]= shi->ref[2]- (shi->view[2]+ i*(shi->vn[2]+shi->dxno[2]));
1020
1021                         i= -2*( (shi->vn[0]+shi->dyno[0])*shi->view[0]+
1022                                 (shi->vn[1]+shi->dyno[1])*(shi->view[1]+shi->dyview)+ (shi->vn[2]+shi->dyno[2])*shi->view[2] );
1023
1024                         shi->dyref[0]= shi->ref[0]- (shi->view[0]+ i*(shi->vn[0]+shi->dyno[0]));
1025                         shi->dyref[1]= shi->ref[1]- (shi->view[1]+shi->dyview+i*(shi->vn[1]+shi->dyno[1]));
1026                         shi->dyref[2]= shi->ref[2]- (shi->view[2]+ i*(shi->vn[2]+shi->dyno[2]));
1027
1028                 }
1029                 else {
1030
1031                         i= -2*( shi->vn[0]*(shi->view[0]+shi->dxview) +
1032                                 shi->vn[1]*shi->view[1]+ shi->vn[2]*shi->view[2] );
1033
1034                         shi->dxref[0]= shi->ref[0]- (shi->view[0]+shi->dxview+i*shi->vn[0]);
1035                         shi->dxref[1]= shi->ref[1]- (shi->view[1]+ i*shi->vn[1]);
1036                         shi->dxref[2]= shi->ref[2]- (shi->view[2]+ i*shi->vn[2]);
1037
1038                         i= -2*( shi->vn[0]*shi->view[0]+
1039                                 shi->vn[1]*(shi->view[1]+shi->dyview)+ shi->vn[2]*shi->view[2] );
1040
1041                         shi->dyref[0]= shi->ref[0]- (shi->view[0]+ i*shi->vn[0]);
1042                         shi->dyref[1]= shi->ref[1]- (shi->view[1]+shi->dyview+i*shi->vn[1]);
1043                         shi->dyref[2]= shi->ref[2]- (shi->view[2]+ i*shi->vn[2]);
1044                 }
1045         }
1046
1047 }
1048
1049 /* called from ray.c */
1050 void shade_color(ShadeInput *shi, ShadeResult *shr)
1051 {
1052         Material *ma= shi->mat;
1053
1054         if(ma->mode & (MA_VERTEXCOLP|MA_FACETEXTURE)) {
1055                 shi->r= shi->vcol[0];
1056                 shi->g= shi->vcol[1];
1057                 shi->b= shi->vcol[2];
1058         }
1059         
1060         if(ma->texco) {
1061                 if(ma->mode & (MA_VERTEXCOLP|MA_FACETEXTURE)) {
1062                         shi->r= shi->vcol[0];
1063                         shi->g= shi->vcol[1];
1064                         shi->b= shi->vcol[2];
1065                 }
1066                 do_material_tex(shi);
1067         }
1068
1069         if(ma->mode & (MA_ZTRA|MA_RAYTRANSP)) {
1070                 if(ma->fresnel_tra!=0.0) 
1071                         shi->alpha*= fresnel_fac(shi->view, shi->vn, ma->fresnel_tra_i, ma->fresnel_tra);
1072         }
1073
1074         shr->diff[0]= shi->r;
1075         shr->diff[1]= shi->g;
1076         shr->diff[2]= shi->b;
1077         shr->alpha= shi->alpha;
1078 }
1079
1080 /* ramp for at end of shade */
1081 static void ramp_diffuse_result(float *diff, ShadeInput *shi)
1082 {
1083         Material *ma= shi->mat;
1084         float col[4], fac=0;
1085
1086         if(ma->ramp_col) {
1087                 if(ma->rampin_col==MA_RAMP_IN_RESULT) {
1088                         
1089                         fac= 0.3*diff[0] + 0.58*diff[1] + 0.12*diff[2];
1090                         do_colorband(ma->ramp_col, fac, col);
1091                         
1092                         /* blending method */
1093                         fac= col[3]*ma->rampfac_col;
1094                         
1095                         ramp_blend(ma->rampblend_col, diff, diff+1, diff+2, fac, col);
1096                 }
1097         }
1098 }
1099
1100 /* r,g,b denote energy, ramp is used with different values to make new material color */
1101 static void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, float g, float b)
1102 {
1103         Material *ma= shi->mat;
1104         float col[4], colt[3], fac=0;
1105         
1106         if(ma->ramp_col && (ma->mode & MA_RAMP_COL)) {
1107                 
1108                 /* MA_RAMP_IN_RESULT is exceptional */
1109                 if(ma->rampin_col==MA_RAMP_IN_RESULT) {
1110                         // normal add
1111                         diff[0] += r * shi->r;
1112                         diff[1] += g * shi->g;
1113                         diff[2] += b * shi->b;
1114                 }
1115                 else {
1116                         /* input */
1117                         switch(ma->rampin_col) {
1118                         case MA_RAMP_IN_ENERGY:
1119                                 fac= 0.3*r + 0.58*g + 0.12*b;
1120                                 break;
1121                         case MA_RAMP_IN_SHADER:
1122                                 fac= is;
1123                                 break;
1124                         case MA_RAMP_IN_NOR:
1125                                 fac= shi->view[0]*shi->vn[0] + shi->view[1]*shi->vn[1] + shi->view[2]*shi->vn[2];
1126                                 break;
1127                         }
1128         
1129                         do_colorband(ma->ramp_col, fac, col);
1130                         
1131                         /* blending method */
1132                         fac= col[3]*ma->rampfac_col;
1133                         colt[0]= shi->r;
1134                         colt[1]= shi->g;
1135                         colt[2]= shi->b;
1136
1137                         ramp_blend(ma->rampblend_col, colt, colt+1, colt+2, fac, col);
1138
1139                         /* output to */
1140                         diff[0] += r * colt[0];
1141                         diff[1] += g * colt[1];
1142                         diff[2] += b * colt[2];
1143                 }
1144         }
1145         else {
1146                 diff[0] += r * shi->r;
1147                 diff[1] += g * shi->g;
1148                 diff[2] += b * shi->b;
1149         }
1150 }
1151
1152 static void ramp_spec_result(float *specr, float *specg, float *specb, ShadeInput *shi)
1153 {
1154         Material *ma= shi->mat;
1155         float col[4];
1156         float fac;
1157         
1158         if(ma->ramp_spec && (ma->rampin_spec==MA_RAMP_IN_RESULT)) {
1159                 fac= 0.3*(*specr) + 0.58*(*specg) + 0.12*(*specb);
1160                 do_colorband(ma->ramp_spec, fac, col);
1161                 
1162                 /* blending method */
1163                 fac= col[3]*ma->rampfac_spec;
1164                 
1165                 ramp_blend(ma->rampblend_spec, specr, specg, specb, fac, col);
1166                 
1167         }
1168 }
1169
1170 /* is = dot product shade, t = spec energy */
1171 static void do_specular_ramp(ShadeInput *shi, float is, float t, float *spec)
1172 {
1173         Material *ma= shi->mat;
1174         float col[4];
1175         float fac=0.0;
1176         
1177         spec[0]= shi->specr;
1178         spec[1]= shi->specg;
1179         spec[2]= shi->specb;
1180
1181         /* MA_RAMP_IN_RESULT is exception */
1182         if(ma->ramp_spec && (ma->rampin_spec!=MA_RAMP_IN_RESULT)) {
1183                 
1184                 /* input */
1185                 switch(ma->rampin_spec) {
1186                 case MA_RAMP_IN_ENERGY:
1187                         fac= t;
1188                         break;
1189                 case MA_RAMP_IN_SHADER:
1190                         fac= is;
1191                         break;
1192                 case MA_RAMP_IN_NOR:
1193                         fac= shi->view[0]*shi->vn[0] + shi->view[1]*shi->vn[1] + shi->view[2]*shi->vn[2];
1194                         break;
1195                 }
1196                 
1197                 do_colorband(ma->ramp_spec, fac, col);
1198                 
1199                 /* blending method */
1200                 fac= col[3]*ma->rampfac_spec;
1201                 
1202                 ramp_blend(ma->rampblend_spec, spec, spec+1, spec+2, fac, col);
1203         }
1204 }
1205
1206
1207
1208 static void ambient_occlusion(ShadeInput *shi, ShadeResult *shr)
1209 {
1210         float f, shadfac[4];
1211         
1212         if((R.wrld.mode & WO_AMB_OCC) && (R.r.mode & R_RAYTRACE) && shi->amb!=0.0) {
1213                 ray_ao(shi, shadfac);
1214
1215                 if(R.wrld.aocolor==WO_AOPLAIN) {
1216                         if (R.wrld.aomix==WO_AOADDSUB) shadfac[3] = 2.0*shadfac[3]-1.0;
1217                         else if (R.wrld.aomix==WO_AOSUB) shadfac[3] = shadfac[3]-1.0;
1218
1219                         f= R.wrld.aoenergy*shadfac[3]*shi->amb;
1220                         shr->ao[0]+= f;
1221                         shr->ao[1]+= f;
1222                         shr->ao[2]+= f;
1223                 }
1224                 else {
1225                         if (R.wrld.aomix==WO_AOADDSUB) {
1226                                 shadfac[0] = 2.0*shadfac[0]-1.0;
1227                                 shadfac[1] = 2.0*shadfac[1]-1.0;
1228                                 shadfac[2] = 2.0*shadfac[2]-1.0;
1229                         }
1230                         else if (R.wrld.aomix==WO_AOSUB) {
1231                                 shadfac[0] = shadfac[0]-1.0;
1232                                 shadfac[1] = shadfac[1]-1.0;
1233                                 shadfac[2] = shadfac[2]-1.0;
1234                         }
1235                         f= R.wrld.aoenergy*shi->amb;
1236                         shr->ao[0]+= f*shadfac[0];
1237                         shr->ao[1]+= f*shadfac[1];
1238                         shr->ao[2]+= f*shadfac[2];
1239                 }
1240         }
1241 }
1242
1243 /* function returns diff, spec and optional shadow */
1244 /* if passrender it returns shadow color, otherwise it applies it to diffuse and spec */
1245 static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int passrender)
1246 {
1247         Material *ma= shi->mat;
1248         VlakRen *vlr= shi->vlr;
1249         float lv[3], lampdist, ld= 1.0f, lacol[3], shadfac[4];
1250         float i, is, inp, i_noshad, *vn, *view, vnor[3], phongcorr;
1251         
1252         vn= shi->vn;
1253         view= shi->view;
1254         
1255         /* lampdist calculation */
1256         if(lar->type==LA_SUN || lar->type==LA_HEMI) {
1257                 VECCOPY(lv, lar->vec);
1258                 lampdist= 1.0;
1259         }
1260         else {
1261                 lv[0]= shi->co[0]-lar->co[0];
1262                 lv[1]= shi->co[1]-lar->co[1];
1263                 lv[2]= shi->co[2]-lar->co[2];
1264                 ld= sqrt(lv[0]*lv[0]+lv[1]*lv[1]+lv[2]*lv[2]);
1265                 lv[0]/= ld;
1266                 lv[1]/= ld;
1267                 lv[2]/= ld;
1268                 
1269                 /* ld is re-used further on (texco's) */
1270                 if(lar->type==LA_AREA) {
1271                         lampdist= 1.0;
1272                 }
1273                 else {
1274                         if(lar->mode & LA_QUAD) {
1275                                 float t= 1.0;
1276                                 if(lar->ld1>0.0)
1277                                         t= lar->dist/(lar->dist+lar->ld1*ld);
1278                                 if(lar->ld2>0.0)
1279                                         t*= lar->distkw/(lar->distkw+lar->ld2*ld*ld);
1280                                 
1281                                 lampdist= t;
1282                         }
1283                         else {
1284                                 lampdist= (lar->dist/(lar->dist+ld));
1285                         }
1286                         
1287                         if(lar->mode & LA_SPHERE) {
1288                                 float t= lar->dist - ld;
1289                                 if(t<0.0) return;
1290                                 
1291                                 t/= lar->dist;
1292                                 lampdist*= (t);
1293                         }
1294                 }
1295         }
1296         
1297         lacol[0]= lar->r;
1298         lacol[1]= lar->g;
1299         lacol[2]= lar->b;
1300         
1301         if(lar->type==LA_SPOT) {
1302                 float t, inpr;
1303                 
1304                 if(lar->mode & LA_SQUARE) {
1305                         if(lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]>0.0) {
1306                                 float lvrot[3], x;
1307                                 
1308                                 /* rotate view to lampspace */
1309                                 VECCOPY(lvrot, lv);
1310                                 MTC_Mat3MulVecfl(lar->imat, lvrot);
1311                                 
1312                                 x= MAX2(fabs(lvrot[0]/lvrot[2]) , fabs(lvrot[1]/lvrot[2]));
1313                                 /* 1.0/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */
1314                                 
1315                                 inpr= 1.0f/(sqrt(1.0f+x*x));
1316                         }
1317                         else inpr= 0.0;
1318                 }
1319                 else {
1320                         inpr= lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2];
1321                 }
1322                 
1323                 t= lar->spotsi;
1324                 if(inpr<t) return;
1325                 else {
1326                         t= inpr-t;
1327                         i= 1.0;
1328                         if(t<lar->spotbl && lar->spotbl!=0.0) {
1329                                 /* soft area */
1330                                 i= t/lar->spotbl;
1331                                 t= i*i;
1332                                 inpr*= (3.0*t-2.0*t*i);
1333                         }
1334                         lampdist*=inpr;
1335                 }
1336                 
1337                 if(lar->mode & LA_OSATEX) {
1338                         shi->osatex= 1; /* signal for multitex() */
1339                         
1340                         shi->dxlv[0]= lv[0] - (shi->co[0]-lar->co[0]+shi->dxco[0])/ld;
1341                         shi->dxlv[1]= lv[1] - (shi->co[1]-lar->co[1]+shi->dxco[1])/ld;
1342                         shi->dxlv[2]= lv[2] - (shi->co[2]-lar->co[2]+shi->dxco[2])/ld;
1343                         
1344                         shi->dylv[0]= lv[0] - (shi->co[0]-lar->co[0]+shi->dyco[0])/ld;
1345                         shi->dylv[1]= lv[1] - (shi->co[1]-lar->co[1]+shi->dyco[1])/ld;
1346                         shi->dylv[2]= lv[2] - (shi->co[2]-lar->co[2]+shi->dyco[2])/ld;
1347                 }
1348                 
1349         }
1350         
1351         if(lar->mode & LA_TEXTURE)  do_lamp_tex(lar, lv, shi, lacol);
1352         
1353         /* dot product and reflectivity */
1354         /* inp = dotproduct, is = shader result, i = lamp energy (with shadow) */
1355         
1356         /* tangent case; calculate fake face normal, aligned with lampvector */
1357         if(vlr->flag & R_TANGENT) {
1358                 float cross[3];
1359                 Crossf(cross, lv, vn);
1360                 Crossf(vnor, cross, vn);
1361                 vnor[0]= -vnor[0];vnor[1]= -vnor[1];vnor[2]= -vnor[2];
1362                 vn= vnor;
1363         }
1364         else if(ma->mode & MA_TANGENT_V) {
1365                 float cross[3];
1366                 Crossf(cross, lv, shi->tang);
1367                 Crossf(vnor, cross, shi->tang);
1368                 vnor[0]= -vnor[0];vnor[1]= -vnor[1];vnor[2]= -vnor[2];
1369                 vn= vnor;
1370         }
1371         
1372         inp= vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2];
1373         
1374         /* phong threshold to prevent backfacing faces having artefacts on ray shadow (terminator problem) */
1375         if((ma->mode & MA_RAYBIAS) && (lar->mode & LA_SHAD_RAY) && (vlr->flag & R_SMOOTH)) {
1376                 float thresh= vlr->ob->smoothresh;
1377                 if(inp>thresh)
1378                         phongcorr= (inp-thresh)/(inp*(1.0-thresh));
1379                 else
1380                         phongcorr= 0.0;
1381         }
1382         else if(ma->sbias!=0.0f) {
1383                 if(inp>ma->sbias)
1384                         phongcorr= (inp-ma->sbias)/(inp*(1.0-ma->sbias));
1385                 else
1386                         phongcorr= 0.0;
1387         }
1388         else phongcorr= 1.0;
1389         
1390         /* diffuse shaders */
1391         if(lar->mode & LA_NO_DIFF) {
1392                 is= 0.0;        // skip shaders
1393         }
1394         else if(lar->type==LA_HEMI) {
1395                 is= 0.5*inp + 0.5;
1396         }
1397         else {
1398                 
1399                 if(lar->type==LA_AREA) {
1400                         /* single sided */
1401                         if(lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]>0.0) {
1402                                 inp= area_lamp_energy(shi->co, vn, lar);
1403                         }
1404                         else inp= 0.0;
1405                 }
1406                 
1407                 /* diffuse shaders (oren nayer gets inp from area light) */
1408                 if(ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(inp, vn, lv, view, ma->roughness);
1409                 else if(ma->diff_shader==MA_DIFF_TOON) is= Toon_Diff(vn, lv, view, ma->param[0], ma->param[1]);
1410                 else if(ma->diff_shader==MA_DIFF_MINNAERT) is= Minnaert_Diff(inp, vn, view, ma->darkness);
1411                 else if(ma->diff_shader==MA_DIFF_FRESNEL) is= Fresnel_Diff(vn, lv, view, ma->param[0], ma->param[1]);
1412                 else is= inp;   // Lambert
1413         }
1414         
1415         i= is*phongcorr;
1416         
1417         if(i>0.0) {
1418                 i*= lampdist*shi->refl;
1419         }
1420         i_noshad= i;
1421         
1422         vn= shi->vn;    // bring back original vector, we use special specular shaders for tangent
1423         if(ma->mode & MA_TANGENT_V)
1424                 vn= shi->tang;
1425         
1426         /* init transp shadow */
1427         shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 1.0;
1428         
1429         /* shadow and spec, (lampdist==0 outside spot) */
1430         if(lampdist> 0.0) {
1431                 
1432                 if(i>0.0 && (R.r.mode & R_SHADOW)) {
1433                         if(ma->mode & MA_SHADOW) {
1434                                 if(lar->type==LA_HEMI); // no shadow
1435                                 else {
1436                                         if(lar->shb) {
1437                                                 shadfac[3] = testshadowbuf(lar->shb, shi->co, shi->dxco, shi->dyco, inp);
1438                                         }
1439                                         else if(lar->mode & LA_SHAD_RAY) {
1440                                                 ray_shadow(shi, lar, shadfac);
1441                                         }
1442                                         
1443                                         /* warning, here it skips the loop */
1444                                         if(lar->mode & LA_ONLYSHADOW) {
1445                                                 
1446                                                 shadfac[3]= i*lar->energy*(1.0-shadfac[3]);
1447                                                 shr->diff[0] -= shadfac[3]*shi->r;
1448                                                 shr->diff[1] -= shadfac[3]*shi->g;
1449                                                 shr->diff[2] -= shadfac[3]*shi->b;
1450                                                 return;
1451                                         }
1452                                         
1453                                         if(passrender==0)
1454                                                 if(shadfac[3]==0.0) return;
1455                                         
1456                                         i*= shadfac[3];
1457                                 }
1458                         }
1459                 }
1460                 
1461                 /* in case 'no diffuse' we still do most calculus, spec can be in shadow */
1462                 if(i>0.0 && !(lar->mode & LA_NO_DIFF)) {
1463                         if(ma->mode & MA_SHADOW_TRA)
1464                                 add_to_diffuse(shr->diff, shi, is, i*shadfac[0]*lacol[0], i*shadfac[1]*lacol[1], i*shadfac[2]*lacol[2]);
1465                         else
1466                                 add_to_diffuse(shr->diff, shi, is, i*lacol[0], i*lacol[1], i*lacol[2]);
1467                 }
1468                 if(passrender && i_noshad>0.0 && !(lar->mode & LA_NO_DIFF)) {
1469                         /* while passrender we store shadowless diffuse in shr->shad, so we can subtract */
1470                         if(ma->mode & MA_SHADOW_TRA)
1471                                 add_to_diffuse(shr->shad, shi, is, i_noshad*shadfac[0]*lacol[0], i_noshad*shadfac[1]*lacol[1], i_noshad*shadfac[2]*lacol[2]);
1472                         else
1473                                 add_to_diffuse(shr->shad, shi, is, i_noshad*lacol[0], i_noshad*lacol[1], i_noshad*lacol[2]);
1474                 }
1475                 
1476                 /* specularity */
1477                 if(shadfac[3]>0.0 && shi->spec!=0.0 && !(lar->mode & LA_NO_SPEC)) {
1478                         
1479                         if(lar->type==LA_HEMI) {
1480                                 float t;
1481                                 /* hemi uses no spec shaders (yet) */
1482                                 
1483                                 lv[0]+= view[0];
1484                                 lv[1]+= view[1];
1485                                 lv[2]+= view[2];
1486                                 
1487                                 Normalise(lv);
1488                                 
1489                                 t= vn[0]*lv[0]+vn[1]*lv[1]+vn[2]*lv[2];
1490                                 
1491                                 if(lar->type==LA_HEMI) {
1492                                         t= 0.5*t+0.5;
1493                                 }
1494                                 
1495                                 t= shadfac[3]*shi->spec*spec(t, shi->har);
1496                                 
1497                                 shr->spec[0]+= t*(lacol[0] * shi->specr);
1498                                 shr->spec[1]+= t*(lacol[1] * shi->specg);
1499                                 shr->spec[2]+= t*(lacol[2] * shi->specb);
1500                         }
1501                         else {
1502                                 /* specular shaders */
1503                                 float specfac, t;
1504                                 
1505                                 if(ma->spec_shader==MA_SPEC_PHONG) 
1506                                         specfac= Phong_Spec(vn, lv, view, shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
1507                                 else if(ma->spec_shader==MA_SPEC_COOKTORR) 
1508                                         specfac= CookTorr_Spec(vn, lv, view, shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
1509                                 else if(ma->spec_shader==MA_SPEC_BLINN) 
1510                                         specfac= Blinn_Spec(vn, lv, view, ma->refrac, (float)shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
1511                                 else if(ma->spec_shader==MA_SPEC_WARDISO)
1512                                         specfac= WardIso_Spec( vn, lv, view, ma->rms, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
1513                                 else 
1514                                         specfac= Toon_Spec(vn, lv, view, ma->param[2], ma->param[3], (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
1515                                 
1516                                 /* area lamp correction */
1517                                 if(lar->type==LA_AREA) specfac*= inp;
1518                                 
1519                                 t= shadfac[3]*shi->spec*lampdist*specfac;
1520                                 
1521                                 if(ma->mode & MA_RAMP_SPEC) {
1522                                         float spec[3];
1523                                         do_specular_ramp(shi, specfac, t, spec);
1524                                         shr->spec[0]+= t*(lacol[0] * spec[0]);
1525                                         shr->spec[1]+= t*(lacol[1] * spec[1]);
1526                                         shr->spec[2]+= t*(lacol[2] * spec[2]);
1527                                 }
1528                                 else {
1529                                         shr->spec[0]+= t*(lacol[0] * shi->specr);
1530                                         shr->spec[1]+= t*(lacol[1] * shi->specg);
1531                                         shr->spec[2]+= t*(lacol[2] * shi->specb);
1532                                 }
1533                         }
1534                 }
1535         }
1536         
1537 }
1538
1539 #if 0
1540 static void shade_lamp_loop_pass(ShadeInput *shi, ShadeResult *shr, int passflag)
1541 {
1542         Material *ma= shi->mat;
1543         VlakRen *vlr= shi->vlr;
1544         
1545         memset(shr, 0, sizeof(ShadeResult));
1546         
1547         /* envmap hack, always reset */
1548         shi->refcol[0]= shi->refcol[1]= shi->refcol[2]= shi->refcol[3]= 0.0f;
1549         
1550         /* material color itself */
1551         if(passflag & (SCE_PASS_COMBINED|SCE_PASS_RGBA)) {
1552                 if(ma->mode & (MA_VERTEXCOLP|MA_FACETEXTURE)) {
1553                         shi->r= shi->vcol[0];
1554                         shi->g= shi->vcol[1];
1555                         shi->b= shi->vcol[2];
1556                 }
1557                 if(ma->texco)
1558                         do_material_tex(shi);
1559                 
1560                 shr->col[0]= shi->r;
1561                 shr->col[1]= shi->g;
1562                 shr->col[2]= shi->b;
1563         }
1564         
1565         if(ma->mode & MA_SHLESS) {
1566                 shr->diff[0]= shi->r;
1567                 shr->diff[1]= shi->g;
1568                 shr->diff[2]= shi->b;
1569                 shr->alpha= shi->alpha;
1570                 return;
1571         }
1572
1573         if( (ma->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))== MA_VERTEXCOL ) {        // vertexcolor light
1574                 shr->diff[0]= shi->r*(shi->emit+shi->vcol[0]);
1575                 shr->diff[1]= shi->g*(shi->emit+shi->vcol[1]);
1576                 shr->diff[2]= shi->b*(shi->emit+shi->vcol[2]);
1577         }
1578         else {
1579                 shr->diff[0]= shi->r*shi->emit;
1580                 shr->diff[1]= shi->g*shi->emit;
1581                 shr->diff[2]= shi->b*shi->emit;
1582         }
1583         
1584         /* AO pass */
1585         if(passflag & (SCE_PASS_COMBINED|SCE_PASS_AO)) {
1586                 ambient_occlusion(shi, shr);
1587         }
1588                 
1589         /* lighting pass */
1590         if(passflag & (SCE_PASS_COMBINED|SCE_PASS_DIFFUSE|SCE_PASS_SPEC|SCE_PASS_SHADOW)) {
1591                 GroupObject *go;
1592                 ListBase *lights;
1593                 LampRen *lar;
1594                 float diff[3];
1595                 
1596                 /* lights */
1597                 if(ma->group)
1598                         lights= &ma->group->gobject;
1599                 else
1600                         lights= &R.lights;
1601                 
1602                 for(go=lights->first; go; go= go->next) {
1603                         lar= go->lampren;
1604                         if(lar==NULL) continue;
1605                         
1606                         /* yafray: ignore shading by photonlights, not used in Blender */
1607                         if (lar->type==LA_YF_PHOTON) continue;
1608                         
1609                         /* test for lamp layer */
1610                         if(lar->mode & LA_LAYER) if((lar->lay & vlr->lay)==0) continue;
1611                         if((lar->lay & shi->lay)==0) continue;
1612
1613                         /* accumulates in shr->diff and shr->spec and shr->shad */
1614                         shade_one_light(lar, shi, shr, passflag);
1615                 }
1616                 
1617                 /* calculate shadow */
1618                 VECCOPY(diff, shr->shad);
1619                 VECSUB(shr->shad, shr->shad, shr->diff);
1620                 VECCOPY(shr->diff, diff);
1621         }
1622         
1623         /* alpha in end, spec can influence it */
1624         if(passflag & (SCE_PASS_COMBINED|SCE_PASS_RGBA)) {
1625                 if(ma->mode & (MA_ZTRA|MA_RAYTRANSP)) {
1626                         if(ma->fresnel_tra!=0.0) 
1627                                 shi->alpha*= fresnel_fac(shi->view, shi->vn, ma->fresnel_tra_i, ma->fresnel_tra);
1628                         
1629                         if(shi->spectra!=0.0) {
1630                                 float t = MAX3(shr->spec[0], shr->spec[1], shr->spec[2]);
1631                                 t *= shi->spectra;
1632                                 if(t>1.0) t= 1.0;
1633                                 shi->alpha= (1.0-t)*shi->alpha+t;
1634                         }
1635                 }
1636                 shr->col[3]= shi->alpha;
1637         }
1638         shr->alpha= shi->alpha;
1639         
1640         shr->diff[0]+= shi->ambr + shi->r*shi->amb*shi->rad[0];
1641         shr->diff[1]+= shi->ambg + shi->g*shi->amb*shi->rad[1];
1642         shr->diff[2]+= shi->ambb + shi->b*shi->amb*shi->rad[2];
1643         
1644         if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(shr->diff, shi);
1645         if(ma->mode & MA_RAMP_SPEC) ramp_spec_result(shr->spec, shr->spec+1, shr->spec+2, shi);
1646         
1647         /* refcol is for envmap only */
1648         if(shi->refcol[0]!=0.0) {
1649                 shr->diff[0]= shi->mirr*shi->refcol[1] + (1.0 - shi->mirr*shi->refcol[0])*shr->diff[0];
1650                 shr->diff[1]= shi->mirg*shi->refcol[2] + (1.0 - shi->mirg*shi->refcol[0])*shr->diff[1];
1651                 shr->diff[2]= shi->mirb*shi->refcol[3] + (1.0 - shi->mirb*shi->refcol[0])*shr->diff[2];
1652         }
1653         
1654         if(passflag & SCE_PASS_COMBINED) {
1655                 shr->combined[0]= shr->diff[0]+(shr->ao[0])*shr->col[0] + shr->spec[0];
1656                 shr->combined[1]= shr->diff[1]+(shr->ao[1])*shr->col[1] + shr->spec[1];
1657                 shr->combined[2]= shr->diff[2]+(shr->ao[2])*shr->col[2] + shr->spec[2];
1658                 shr->combined[3]= shr->alpha;
1659         }
1660         
1661         if(R.r.mode & R_RAYTRACE) {
1662                 
1663                 if((ma->mode & MA_RAYMIRROR)==0) shi->ray_mirror= 0.0;
1664                 
1665                 if(shi->ray_mirror!=0.0 || ((shi->mat->mode & MA_RAYTRANSP) && shr->alpha!=1.0)) {
1666                         float diff[3];
1667                         
1668                         VECCOPY(diff, shr->diff);
1669                         
1670                         ray_trace(shi, shr);
1671                         
1672                         VECSUB(shr->ray, shr->diff, diff);
1673                         VECCOPY(shr->diff, diff);
1674                         VECADD(shr->combined, shr->combined, shr->ray);
1675                 }
1676         }
1677         else {
1678                 /* doesnt look 'correct', but is better for preview, plus envmaps dont raytrace this */
1679                 if(shi->mat->mode & MA_RAYTRANSP) shr->alpha= 1.0;
1680         }       
1681 }
1682 #endif
1683
1684 void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
1685 {
1686         LampRen *lar;
1687         GroupObject *go;
1688         Material *ma= shi->mat;
1689         VlakRen *vlr= shi->vlr;
1690         ListBase *lights;
1691         
1692         memset(shr, 0, sizeof(ShadeResult));
1693         
1694         if((ma->mode & MA_RAYMIRROR)==0) shi->ray_mirror= 0.0;
1695         
1696         /* lights */
1697         if(ma->group)
1698                 lights= &ma->group->gobject;
1699         else
1700                 lights= &R.lights;
1701         
1702         /* separate loop */
1703         if(ma->mode & MA_ONLYSHADOW) {
1704                 float i, inp, inpr, lv[3];
1705                 float *vn, *view, shadfac[4];
1706                 float t, ir;
1707                 
1708                 vn= shi->vn;
1709                 view= shi->view;
1710                 
1711                 if(R.r.mode & R_SHADOW) {
1712                         
1713                         shadfac[3]= ir= 0.0;
1714                         for(go=lights->first; go; go= go->next) {
1715                                 lar= go->lampren;
1716                                 if(lar==NULL) continue;
1717                                 
1718                                 /* yafray: ignore shading by photonlights, not used in Blender */
1719                                 if (lar->type==LA_YF_PHOTON) continue;
1720                                 
1721                                 if(lar->mode & LA_LAYER) if((lar->lay & vlr->lay)==0) continue;
1722                                 if((lar->lay & shi->lay)==0) continue;
1723                                 
1724                                 lv[0]= shi->co[0]-lar->co[0];
1725                                 lv[1]= shi->co[1]-lar->co[1];
1726                                 lv[2]= shi->co[2]-lar->co[2];
1727
1728                                 if(lar->type==LA_SPOT) {
1729                                         /* only test within spotbundel */
1730                                         if(lar->shb || (lar->mode & LA_SHAD_RAY)) {
1731
1732                                                 Normalise(lv);
1733                                                 inpr= lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2];
1734                                                 if(inpr>lar->spotsi) {
1735                                                         
1736                                                         inp= vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2];
1737                                                         
1738                                                         if(lar->shb) i = testshadowbuf(lar->shb, shi->co, shi->dxco, shi->dyco, inp);
1739                                                         else {
1740                                                                 float shad[4];
1741                                                                 ray_shadow(shi, lar, shad);
1742                                                                 i= shad[3];
1743                                                         }
1744                                                         
1745                                                         t= inpr - lar->spotsi;
1746                                                         if(t<lar->spotbl && lar->spotbl!=0.0) {
1747                                                                 t/= lar->spotbl;
1748                                                                 t*= t;
1749                                                                 i= t*i+(1.0-t);
1750                                                         }
1751                                                         
1752                                                         shadfac[3]+= i;
1753                                                         ir+= 1.0;
1754                                                 }
1755                                                 else {
1756                                                         shadfac[3]+= 1.0;
1757                                                         ir+= 1.0;
1758                                                 }
1759                                         }
1760                                 }
1761                                 else if(lar->mode & LA_SHAD_RAY) {
1762                                         float shad[4];
1763                                         
1764                                         /* single sided? */
1765                                         if( shi->facenor[0]*lv[0] + shi->facenor[1]*lv[1] + shi->facenor[2]*lv[2] > -0.01) {
1766                                                 ray_shadow(shi, lar, shad);
1767                                                 shadfac[3]+= shad[3];
1768                                                 ir+= 1.0;
1769                                         }
1770                                 }
1771
1772                         }
1773                         if(ir>0.0) {
1774                                 shadfac[3]/= ir;
1775                                 shr->alpha= (shi->alpha)*(1.0-shadfac[3]);
1776                         }
1777                 }
1778                 
1779                 if((R.wrld.mode & WO_AMB_OCC) && (R.r.mode & R_RAYTRACE) && shi->amb!=0.0) {
1780                         float f;
1781
1782                         ray_ao(shi, shadfac);   // shadfac==0: full light
1783                         shadfac[3]= 1.0-shadfac[3];
1784                         
1785                         f= R.wrld.aoenergy*shadfac[3]*shi->amb;
1786                         
1787                         if(R.wrld.aomix==WO_AOADD) {
1788                                 shr->alpha += f;
1789                                 shr->alpha *= f;
1790                         }
1791                         else if(R.wrld.aomix==WO_AOSUB) {
1792                                 shr->alpha += f;
1793                         }
1794                         else {
1795                                 shr->alpha *= f;
1796                                 shr->alpha += f;
1797                         }
1798                 }
1799                 
1800                 return;
1801         }
1802                 
1803         if(ma->mode & (MA_VERTEXCOLP|MA_FACETEXTURE)) {
1804                 shi->r= shi->vcol[0];
1805                 shi->g= shi->vcol[1];
1806                 shi->b= shi->vcol[2];
1807         }
1808         
1809         /* envmap hack, always reset */
1810         shi->refcol[0]= shi->refcol[1]= shi->refcol[2]= shi->refcol[3]= 0.0;
1811
1812         if(ma->texco) {
1813                 if(ma->mode & (MA_VERTEXCOLP|MA_FACETEXTURE)) {
1814                         shi->r= shi->vcol[0];
1815                         shi->g= shi->vcol[1];
1816                         shi->b= shi->vcol[2];
1817                 }
1818                 do_material_tex(shi);
1819         }
1820         
1821         if(ma->mode & MA_SHLESS) {
1822                 shr->diff[0]= shi->r;
1823                 shr->diff[1]= shi->g;
1824                 shr->diff[2]= shi->b;
1825                 shr->alpha= shi->alpha;
1826                 return;
1827         }
1828
1829         if( (ma->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))== MA_VERTEXCOL ) {        // vertexcolor light
1830                 shr->diff[0]= shi->r*(shi->emit+shi->vcol[0]);
1831                 shr->diff[1]= shi->g*(shi->emit+shi->vcol[1]);
1832                 shr->diff[2]= shi->b*(shi->emit+shi->vcol[2]);
1833         }
1834         else {
1835                 shr->diff[0]= shi->r*shi->emit;
1836                 shr->diff[1]= shi->g*shi->emit;
1837                 shr->diff[2]= shi->b*shi->emit;
1838         }
1839         
1840         if(R.wrld.mode & WO_AMB_OCC) {
1841                 ambient_occlusion(shi, shr);
1842                 VECADD(shr->diff, shr->diff, shr->ao);
1843         }
1844         
1845         for(go=lights->first; go; go= go->next) {
1846                 lar= go->lampren;
1847                 if(lar==NULL) continue;
1848                 
1849                 /* yafray: ignore shading by photonlights, not used in Blender */
1850                 if (lar->type==LA_YF_PHOTON) continue;
1851
1852                 /* test for lamp layer */
1853                 if(lar->mode & LA_LAYER) if((lar->lay & vlr->lay)==0) continue;
1854                 if((lar->lay & shi->lay)==0) continue;
1855                 
1856                 /* accumulates in shr->diff and shr->spec, 0= no passrender */
1857                 shade_one_light(lar, shi, shr, 0);
1858         }
1859
1860         if(ma->mode & (MA_ZTRA|MA_RAYTRANSP)) {
1861                 if(ma->fresnel_tra!=0.0) 
1862                         shi->alpha*= fresnel_fac(shi->view, shi->vn, ma->fresnel_tra_i, ma->fresnel_tra);
1863
1864                 if(shi->spectra!=0.0) {
1865                         float t = MAX3(shr->spec[0], shr->spec[1], shr->spec[2]);
1866                         t *= shi->spectra;
1867                         if(t>1.0) t= 1.0;
1868                         shi->alpha= (1.0-t)*shi->alpha+t;
1869                 }
1870         }
1871
1872         shr->alpha= shi->alpha;
1873
1874         shr->diff[0]+= shi->r*shi->amb*shi->rad[0];
1875         shr->diff[0]+= shi->ambr;
1876         
1877         shr->diff[1]+= shi->g*shi->amb*shi->rad[1];
1878         shr->diff[1]+= shi->ambg;
1879         
1880         shr->diff[2]+= shi->b*shi->amb*shi->rad[2];
1881         shr->diff[2]+= shi->ambb;
1882         
1883         if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(shr->diff, shi);
1884         if(ma->mode & MA_RAMP_SPEC) ramp_spec_result(shr->spec, shr->spec+1, shr->spec+2, shi);
1885         
1886         /* refcol is for envmap only */
1887         if(shi->refcol[0]!=0.0) {
1888                 shr->diff[0]= shi->mirr*shi->refcol[1] + (1.0 - shi->mirr*shi->refcol[0])*shr->diff[0];
1889                 shr->diff[1]= shi->mirg*shi->refcol[2] + (1.0 - shi->mirg*shi->refcol[0])*shr->diff[1];
1890                 shr->diff[2]= shi->mirb*shi->refcol[3] + (1.0 - shi->mirb*shi->refcol[0])*shr->diff[2];
1891         }
1892
1893 }
1894
1895 /* this function sets all coords for render (shared with raytracer) */
1896 /* warning; exception for ortho render is here, can be done better! */
1897 void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, int i3)
1898 {
1899         VertRen *v1, *v2, *v3;
1900         VlakRen *vlr= shi->vlr;
1901         float l, dl;
1902         short texco= shi->mat->texco;
1903         int mode= shi->mat->mode_l;             /* or-ed result for all layers */
1904         char p1, p2, p3;
1905         
1906         /* for rendering of quads, the following values are used to denote vertices:
1907            0 1 2        scanline tria & first half quad, and ray tria
1908            0 2 3    scanline 2nd half quad
1909            0 1 3    raytracer first half quad
1910            2 1 3    raytracer 2nd half quad
1911         */
1912
1913         if(i1==0) {
1914                 v1= vlr->v1;
1915                 p1= ME_FLIPV1;
1916         } else {
1917                 v1= vlr->v3;
1918                 p1= ME_FLIPV3;
1919         }
1920
1921         if(i2==1) {
1922                 v2= vlr->v2;
1923                 p2= ME_FLIPV2;
1924         } else {
1925                 v2= vlr->v3;
1926                 p2= ME_FLIPV3;
1927         }
1928         
1929         if(i3==2) {
1930                 v3= vlr->v3;
1931                 p3= ME_FLIPV3;
1932         } else {
1933                 v3= vlr->v4;
1934                 p3= ME_FLIPV4;
1935         }
1936
1937         /* calculate U and V, for scanline (normal u and v are -1 to 0) */
1938         if(u==1.0) {
1939                 if( (vlr->flag & R_SMOOTH) || (texco & NEED_UV) ) {
1940                         /* exception case for wire render of edge */
1941                         if(vlr->v2==vlr->v3) {
1942                                 float lend, lenc;
1943                                 
1944                                 lend= VecLenf(v2->co, v1->co);
1945                                 lenc= VecLenf(shi->co, v1->co);
1946                                 
1947                                 if(lend==0.0f) {
1948                                         u=v= 0.0f;
1949                                 }
1950                                 else {
1951                                         u= - (1.0f - lenc/lend);
1952                                         v= 0.0f;
1953                                 }
1954                                 
1955                                 if(shi->osatex) {
1956                                         shi->dxuv[0]=  0.0f;
1957                                         shi->dxuv[1]=  0.0f;
1958                                         shi->dyuv[0]=  0.0f;
1959                                         shi->dyuv[1]=  0.0f;
1960                                 }
1961                         }
1962                         else {
1963                                 float detsh, t00, t10, t01, t11;
1964                                 
1965                                 if(vlr->snproj==0) {
1966                                         t00= v3->co[0]-v1->co[0]; t01= v3->co[1]-v1->co[1];
1967                                         t10= v3->co[0]-v2->co[0]; t11= v3->co[1]-v2->co[1];
1968                                 }
1969                                 else if(vlr->snproj==1) {
1970                                         t00= v3->co[0]-v1->co[0]; t01= v3->co[2]-v1->co[2];
1971                                         t10= v3->co[0]-v2->co[0]; t11= v3->co[2]-v2->co[2];
1972                                 }
1973                                 else {
1974                                         t00= v3->co[1]-v1->co[1]; t01= v3->co[2]-v1->co[2];
1975                                         t10= v3->co[1]-v2->co[1]; t11= v3->co[2]-v2->co[2];
1976                                 }
1977                                 
1978                                 detsh= 1.0/(t00*t11-t10*t01);
1979                                 t00*= detsh; t01*=detsh; 
1980                                 t10*=detsh; t11*=detsh;
1981                         
1982                                 if(vlr->snproj==0) {
1983                                         u= (shi->co[0]-v3->co[0])*t11-(shi->co[1]-v3->co[1])*t10;
1984                                         v= (shi->co[1]-v3->co[1])*t00-(shi->co[0]-v3->co[0])*t01;
1985                                         if(shi->osatex) {
1986                                                 shi->dxuv[0]=  shi->dxco[0]*t11- shi->dxco[1]*t10;
1987                                                 shi->dxuv[1]=  shi->dxco[1]*t00- shi->dxco[0]*t01;
1988                                                 shi->dyuv[0]=  shi->dyco[0]*t11- shi->dyco[1]*t10;
1989                                                 shi->dyuv[1]=  shi->dyco[1]*t00- shi->dyco[0]*t01;
1990                                         }
1991                                 }
1992                                 else if(vlr->snproj==1) {
1993                                         u= (shi->co[0]-v3->co[0])*t11-(shi->co[2]-v3->co[2])*t10;
1994                                         v= (shi->co[2]-v3->co[2])*t00-(shi->co[0]-v3->co[0])*t01;
1995                                         if(shi->osatex) {
1996                                                 shi->dxuv[0]=  shi->dxco[0]*t11- shi->dxco[2]*t10;
1997                                                 shi->dxuv[1]=  shi->dxco[2]*t00- shi->dxco[0]*t01;
1998                                                 shi->dyuv[0]=  shi->dyco[0]*t11- shi->dyco[2]*t10;
1999                                                 shi->dyuv[1]=  shi->dyco[2]*t00- shi->dyco[0]*t01;
2000                                         }
2001                                 }
2002                                 else {
2003                                         u= (shi->co[1]-v3->co[1])*t11-(shi->co[2]-v3->co[2])*t10;
2004                                         v= (shi->co[2]-v3->co[2])*t00-(shi->co[1]-v3->co[1])*t01;
2005                                         if(shi->osatex) {
2006                                                 shi->dxuv[0]=  shi->dxco[1]*t11- shi->dxco[2]*t10;
2007                                                 shi->dxuv[1]=  shi->dxco[2]*t00- shi->dxco[1]*t01;
2008                                                 shi->dyuv[0]=  shi->dyco[1]*t11- shi->dyco[2]*t10;
2009                                                 shi->dyuv[1]=  shi->dyco[2]*t00- shi->dyco[1]*t01;
2010                                         }
2011                                 }
2012                         }
2013                 }       
2014         }
2015         l= 1.0+u+v;
2016         
2017         /* calculate punos (vertexnormals) */
2018         if(vlr->flag & R_SMOOTH) { 
2019                 float n1[3], n2[3], n3[3];
2020                 
2021                 if(shi->puno & p1) {
2022                         n1[0]= -v1->n[0]; n1[1]= -v1->n[1]; n1[2]= -v1->n[2];
2023                 } else {
2024                         n1[0]= v1->n[0]; n1[1]= v1->n[1]; n1[2]= v1->n[2];
2025                 }
2026                 if(shi->puno & p2) {
2027                         n2[0]= -v2->n[0]; n2[1]= -v2->n[1]; n2[2]= -v2->n[2];
2028                 } else {
2029                         n2[0]= v2->n[0]; n2[1]= v2->n[1]; n2[2]= v2->n[2];
2030                 }
2031                 
2032                 if(shi->puno & p3) {
2033                         n3[0]= -v3->n[0]; n3[1]= -v3->n[1]; n3[2]= -v3->n[2];
2034                 } else {
2035                         n3[0]= v3->n[0]; n3[1]= v3->n[1]; n3[2]= v3->n[2];
2036                 }
2037
2038                 shi->vn[0]= l*n3[0]-u*n1[0]-v*n2[0];
2039                 shi->vn[1]= l*n3[1]-u*n1[1]-v*n2[1];
2040                 shi->vn[2]= l*n3[2]-u*n1[2]-v*n2[2];
2041
2042                 Normalise(shi->vn);
2043
2044                 if(shi->osatex && (texco & (TEXCO_NORM|TEXCO_REFL)) ) {
2045                         dl= shi->dxuv[0]+shi->dxuv[1];
2046                         shi->dxno[0]= dl*n3[0]-shi->dxuv[0]*n1[0]-shi->dxuv[1]*n2[0];
2047                         shi->dxno[1]= dl*n3[1]-shi->dxuv[0]*n1[1]-shi->dxuv[1]*n2[1];
2048                         shi->dxno[2]= dl*n3[2]-shi->dxuv[0]*n1[2]-shi->dxuv[1]*n2[2];
2049                         dl= shi->dyuv[0]+shi->dyuv[1];
2050                         shi->dyno[0]= dl*n3[0]-shi->dyuv[0]*n1[0]-shi->dyuv[1]*n2[0];
2051                         shi->dyno[1]= dl*n3[1]-shi->dyuv[0]*n1[1]-shi->dyuv[1]*n2[1];
2052                         shi->dyno[2]= dl*n3[2]-shi->dyuv[0]*n1[2]-shi->dyuv[1]*n2[2];
2053
2054                 }
2055                 
2056                 if(mode & MA_TANGENT_V) {
2057                         float *s1, *s2, *s3;
2058                         
2059                         s1= RE_vertren_get_tangent(&R, v1, 0);
2060                         s2= RE_vertren_get_tangent(&R, v2, 0);
2061                         s3= RE_vertren_get_tangent(&R, v3, 0);
2062                         if(s1 && s2 && s3) {
2063                                 shi->tang[0]= (l*s3[0] - u*s1[0] - v*s2[0]);
2064                                 shi->tang[1]= (l*s3[1] - u*s1[1] - v*s2[1]);
2065                                 shi->tang[2]= (l*s3[2] - u*s1[2] - v*s2[2]);
2066                         }
2067                         else shi->tang[0]= shi->tang[1]= shi->tang[2]= 0.0f;
2068                 }               
2069         }
2070         else {
2071                 VECCOPY(shi->vn, shi->facenor);
2072                 if(mode & MA_TANGENT_V) 
2073                         shi->tang[0]= shi->tang[1]= shi->tang[2]= 0.0f;
2074         }
2075         
2076         if(R.r.mode & R_SPEED) {
2077                 float *s1, *s2, *s3;
2078                 
2079                 s1= RE_vertren_get_winspeed(&R, v1, 0);
2080                 s2= RE_vertren_get_winspeed(&R, v2, 0);
2081                 s3= RE_vertren_get_winspeed(&R, v3, 0);
2082                 if(s1 && s2 && s3) {
2083                         shi->winspeed[0]= (l*s3[0] - u*s1[0] - v*s2[0]);
2084                         shi->winspeed[1]= (l*s3[1] - u*s1[1] - v*s2[1]);
2085                         shi->winspeed[2]= (l*s3[2] - u*s1[2] - v*s2[2]);
2086                         shi->winspeed[3]= (l*s3[3] - u*s1[3] - v*s2[3]);
2087                 }
2088                 else {
2089                         shi->winspeed[0]= shi->winspeed[1]= shi->winspeed[2]= shi->winspeed[3]= 0.0f;
2090                 }
2091         }
2092         
2093         /* texture coordinates. shi->dxuv shi->dyuv have been set */
2094         if(texco & NEED_UV) {
2095                 if(texco & TEXCO_ORCO) {
2096                         if(v1->orco) {
2097                                 float *o1, *o2, *o3;
2098                                 
2099                                 o1= v1->orco;
2100                                 o2= v2->orco;
2101                                 o3= v3->orco;
2102                                 
2103                                 shi->lo[0]= l*o3[0]-u*o1[0]-v*o2[0];
2104                                 shi->lo[1]= l*o3[1]-u*o1[1]-v*o2[1];
2105                                 shi->lo[2]= l*o3[2]-u*o1[2]-v*o2[2];
2106         
2107                                 if(shi->osatex) {
2108                                         dl= shi->dxuv[0]+shi->dxuv[1];
2109                                         shi->dxlo[0]= dl*o3[0]-shi->dxuv[0]*o1[0]-shi->dxuv[1]*o2[0];
2110                                         shi->dxlo[1]= dl*o3[1]-shi->dxuv[0]*o1[1]-shi->dxuv[1]*o2[1];
2111                                         shi->dxlo[2]= dl*o3[2]-shi->dxuv[0]*o1[2]-shi->dxuv[1]*o2[2];
2112                                         dl= shi->dyuv[0]+shi->dyuv[1];
2113                                         shi->dylo[0]= dl*o3[0]-shi->dyuv[0]*o1[0]-shi->dyuv[1]*o2[0];
2114                                         shi->dylo[1]= dl*o3[1]-shi->dyuv[0]*o1[1]-shi->dyuv[1]*o2[1];
2115                                         shi->dylo[2]= dl*o3[2]-shi->dyuv[0]*o1[2]-shi->dyuv[1]*o2[2];
2116                                 }
2117                         }
2118                 }
2119                 
2120                 if(texco & TEXCO_GLOB) {
2121                         VECCOPY(shi->gl, shi->co);
2122                         MTC_Mat4MulVecfl(R.viewinv, shi->gl);
2123                         if(shi->osatex) {
2124                                 VECCOPY(shi->dxgl, shi->dxco);
2125                                 MTC_Mat3MulVecfl(R.imat, shi->dxco);
2126                                 VECCOPY(shi->dygl, shi->dyco);
2127                                 MTC_Mat3MulVecfl(R.imat, shi->dyco);
2128                         }
2129                 }
2130                 if(texco & TEXCO_STRAND) {
2131                         shi->strand= (l*v3->accum - u*v1->accum - v*v2->accum);
2132                         if(shi->osatex) {
2133                                 dl= shi->dxuv[0]+shi->dxuv[1];
2134                                 shi->dxstrand= dl*v3->accum-shi->dxuv[0]*v1->accum-shi->dxuv[1]*v2->accum;
2135                                 dl= shi->dyuv[0]+shi->dyuv[1];
2136                                 shi->dystrand= dl*v3->accum-shi->dyuv[0]*v1->accum-shi->dyuv[1]*v2->accum;
2137                         }
2138                 }
2139                 if((texco & TEXCO_UV) || (mode & (MA_VERTEXCOL|MA_VERTEXCOLP|MA_FACETEXTURE)))  {
2140                         int j1=i1, j2=i2, j3=i3;
2141                         
2142                         /* to prevent storing new tfaces or vcols, we check a split runtime */
2143                         /*              4---3           4---3 */
2144                         /*              |\ 1|   or  |1 /| */
2145                         /*              |0\ |           |/ 0| */
2146                         /*              1---2           1---2   0 = orig face, 1 = new face */
2147                         
2148                         /* Update vert nums to point to correct verts of original face */
2149                         if(vlr->flag & R_DIVIDE_24) {  
2150                                 if(vlr->flag & R_FACE_SPLIT) {
2151                                         j1++; j2++; j3++;
2152                                 }
2153                                 else {
2154                                         j3++;
2155                                 }
2156                         }
2157                         else if(vlr->flag & R_FACE_SPLIT) {
2158                                 j2++; j3++; 
2159                         }
2160                         
2161                         if(mode & (MA_VERTEXCOL|MA_VERTEXCOLP)) {
2162                                 
2163                                 if(vlr->vcol) {
2164                                         char *cp1, *cp2, *cp3;
2165                                         
2166                                         cp1= (char *)(vlr->vcol+j1);
2167                                         cp2= (char *)(vlr->vcol+j2);
2168                                         cp3= (char *)(vlr->vcol+j3);
2169
2170                                         shi->vcol[0]= (l*((float)cp3[3]) - u*((float)cp1[3]) - v*((float)cp2[3]))/255.0;
2171                                         shi->vcol[1]= (l*((float)cp3[2]) - u*((float)cp1[2]) - v*((float)cp2[2]))/255.0;
2172                                         shi->vcol[2]= (l*((float)cp3[1]) - u*((float)cp1[1]) - v*((float)cp2[1]))/255.0;
2173                                 }
2174                                 else {
2175                                         shi->vcol[0]= 0.0;
2176                                         shi->vcol[1]= 0.0;
2177                                         shi->vcol[2]= 0.0;
2178                                 }
2179                         }
2180                         if(vlr->tface) {
2181                                 float *uv1, *uv2, *uv3;
2182                                 
2183                                 uv1= vlr->tface->uv[j1];
2184                                 uv2= vlr->tface->uv[j2];
2185                                 uv3= vlr->tface->uv[j3];
2186                                 
2187                                 shi->uv[0]= -1.0 + 2.0*(l*uv3[0]-u*uv1[0]-v*uv2[0]);
2188                                 shi->uv[1]= -1.0 + 2.0*(l*uv3[1]-u*uv1[1]-v*uv2[1]);
2189                                 shi->uv[2]= 0.0;        // texture.c assumes there are 3 coords
2190                                 
2191                                 if(shi->osatex) {
2192                                         float duv[2];
2193                                         
2194                                         dl= shi->dxuv[0]+shi->dxuv[1];
2195                                         duv[0]= shi->dxuv[0]; 
2196                                         duv[1]= shi->dxuv[1];
2197                                         
2198                                         shi->dxuv[0]= 2.0*(dl*uv3[0]-duv[0]*uv1[0]-duv[1]*uv2[0]);
2199                                         shi->dxuv[1]= 2.0*(dl*uv3[1]-duv[0]*uv1[1]-duv[1]*uv2[1]);
2200         
2201                                         dl= shi->dyuv[0]+shi->dyuv[1];
2202                                         duv[0]= shi->dyuv[0]; 
2203                                         duv[1]= shi->dyuv[1];
2204         
2205                                         shi->dyuv[0]= 2.0*(dl*uv3[0]-duv[0]*uv1[0]-duv[1]*uv2[0]);
2206                                         shi->dyuv[1]= 2.0*(dl*uv3[1]-duv[0]*uv1[1]-duv[1]*uv2[1]);
2207                                 }
2208                                 if(mode & MA_FACETEXTURE) {
2209                                         if((mode & (MA_VERTEXCOL|MA_VERTEXCOLP))==0) {
2210                                                 shi->vcol[0]= 1.0;
2211                                                 shi->vcol[1]= 1.0;
2212                                                 shi->vcol[2]= 1.0;
2213                                         }
2214                                         if(vlr->tface) render_realtime_texture(shi);
2215                                 }
2216                         }
2217                         else {
2218                                 shi->uv[0]= 2.0*(u+.5);
2219                                 shi->uv[1]= 2.0*(v+.5);
2220                                 shi->uv[2]= 0.0;        // texture.c assumes there are 3 coords
2221                                 if(mode & MA_FACETEXTURE) {
2222                                         /* no tface? set at 1.0 */
2223                                         shi->vcol[0]= 1.0;
2224                                         shi->vcol[1]= 1.0;
2225                                         shi->vcol[2]= 1.0;
2226                                 }
2227                         }
2228                 }
2229                 if(texco & TEXCO_NORM) {
2230                         shi->orn[0]= -shi->vn[0];
2231                         shi->orn[1]= -shi->vn[1];
2232                         shi->orn[2]= -shi->vn[2];
2233                 }
2234                 if(mode & MA_RADIO) {
2235                         float *r1, *r2, *r3;
2236                         
2237                         r1= RE_vertren_get_rad(&R, v1, 0);
2238                         r2= RE_vertren_get_rad(&R, v2, 0);
2239                         r3= RE_vertren_get_rad(&R, v3, 0);
2240                         
2241                         if(r1 && r2 && r3) {
2242                                 shi->rad[0]= (l*r3[0] - u*r1[0] - v*r2[0]);
2243                                 shi->rad[1]= (l*r3[1] - u*r1[1] - v*r2[1]);
2244                                 shi->rad[2]= (l*r3[2] - u*r1[2] - v*r2[2]);
2245                         }
2246                         else {
2247                                 shi->rad[0]= shi->rad[1]= shi->rad[2]= 0.0;
2248                         }
2249                 }
2250                 else {
2251                         shi->rad[0]= shi->rad[1]= shi->rad[2]= 0.0;
2252                 }
2253                 if(texco & TEXCO_REFL) {
2254                         /* mirror reflection colour textures (and envmap) */
2255                         calc_R_ref(shi);        /* wrong location for normal maps! XXXXXXXXXXXXXX */
2256                 }
2257                 if(texco & TEXCO_STRESS) {
2258                         float *s1, *s2, *s3;
2259                         
2260                         s1= RE_vertren_get_stress(&R, v1, 0);
2261                         s2= RE_vertren_get_stress(&R, v2, 0);
2262                         s3= RE_vertren_get_stress(&R, v3, 0);
2263                         if(s1 && s2 && s3) {
2264                                 shi->stress= l*s3[0] - u*s1[0] - v*s2[0];
2265                                 if(shi->stress<1.0f) shi->stress-= 1.0f;
2266                                 else shi->stress= (shi->stress-1.0f)/shi->stress;
2267                         }
2268                         else shi->stress= 0.0f;
2269                 }
2270                 if(texco & TEXCO_TANGENT) {
2271                         if((mode & MA_TANGENT_V)==0) {
2272                                 /* just prevent surprises */
2273                                 shi->tang[0]= shi->tang[1]= shi->tang[2]= 0.0f;
2274                         }
2275                 }
2276         }
2277         else {
2278                 shi->rad[0]= shi->rad[1]= shi->rad[2]= 0.0;
2279         }
2280 }
2281
2282 #if 0
2283 /* return labda for view vector being closest to line v3-v4 */
2284 /* was used for wire render */
2285 static float isec_view_line(float *view, float *v3, float *v4)
2286 {
2287         float vec[3];
2288         float dot0, dot1, dot2, veclen, viewlen;
2289         float fac, div;
2290         
2291         vec[0]= v4[0] - v3[0];
2292         vec[1]= v4[1] - v3[1];
2293         vec[2]= v4[2] - v3[2];
2294         
2295         dot0 = v3[0]*vec[0] + v3[1]*vec[1] + v3[2]*vec[2];
2296         dot1 = vec[0]*view[0] + vec[1]*view[1] + vec[2]*view[2];
2297         dot2 = v3[0]*view[0] + v3[1]*view[1] + v3[2]*view[2];
2298         
2299         veclen = vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2];
2300         viewlen = view[0]*view[0] + view[1]*view[1] + view[2]*view[2];
2301         
2302         div = viewlen*veclen - dot1*dot1;
2303         if (div==0.0) return 0.0;
2304         
2305         fac = dot2*veclen - dot0*dot1;
2306         return fac/div;
2307 }
2308 #endif
2309
2310
2311 /* also used as callback for nodes */
2312 void shade_material_loop(ShadeInput *shi, ShadeResult *shr)
2313 {
2314         
2315         shade_lamp_loop(shi, shr);      /* clears shr */
2316         
2317         if(shi->translucency!=0.0) {
2318                 ShadeResult shr_t;
2319                 
2320                 VECCOPY(shi->vn, shi->vno);
2321                 VecMulf(shi->vn, -1.0);
2322                 VecMulf(shi->facenor, -1.0);
2323                 shade_lamp_loop(shi, &shr_t);
2324                 
2325                 shr->diff[0]+= shi->translucency*shr_t.diff[0];
2326                 shr->diff[1]+= shi->translucency*shr_t.diff[1];
2327                 shr->diff[2]+= shi->translucency*shr_t.diff[2];
2328                 VecMulf(shi->vn, -1.0);
2329                 VecMulf(shi->facenor, -1.0);
2330         }
2331         
2332         if(R.r.mode & R_RAYTRACE) {
2333                 if(shi->ray_mirror!=0.0 || ((shi->mat->mode & MA_RAYTRANSP) && shr->alpha!=1.0)) {
2334                         ray_trace(shi, shr);
2335                 }
2336         }
2337         else {
2338                 /* doesnt look 'correct', but is better for preview, plus envmaps dont raytrace this */
2339                 if(shi->mat->mode & MA_RAYTRANSP) shr->alpha= 1.0;
2340         }
2341         
2342 }
2343
2344 /* x,y: window coordinate from 0 to rectx,y */
2345 /* return pointer to rendered face */
2346 /* note, facenr declared volatile due to over-eager -O2 optimizations
2347  * on cygwin (particularly -frerun-cse-after-loop)
2348  */
2349 void *shadepixel(ShadePixelInfo *shpi, float x, float y, int z, volatile int facenr, int mask, float *rco)
2350 {
2351         ShadeResult *shr= &shpi->shr;
2352         ShadeInput shi;
2353         VlakRen *vlr=NULL;
2354         
2355         if(facenr< 0) { /* error */
2356                 return NULL;
2357         }
2358         /* currently in use for dithering (soft shadow) node preview */
2359         shi.xs= (int)(x+0.5f);
2360         shi.ys= (int)(y+0.5f);
2361
2362         shi.thread= shpi->thread;
2363         shi.do_preview= R.r.scemode & R_NODE_PREVIEW;
2364         shi.lay= shpi->lay;
2365
2366         /* mask is used to indicate amount of samples (ray shad/mir and AO) */
2367         shi.mask= mask;
2368         shi.depth= 0;   // means first hit, not raytracing
2369         
2370         if(facenr==0) { /* sky */
2371                 memset(shr, 0, sizeof(ShadeResult));
2372                 rco[0]= rco[1]= rco[2]= 0.0f;
2373         }
2374         else if( (facenr & RE_QUAD_MASK) <= R.totvlak) {
2375                 VertRen *v1;
2376                 float alpha, fac, zcor;
2377                 
2378                 vlr= RE_findOrAddVlak(&R, (facenr-1) & RE_QUAD_MASK);
2379                 
2380                 shi.vlr= vlr;
2381                 shi.mat= vlr->mat;
2382                 
2383                 shi.osatex= (shi.mat->texco & TEXCO_OSA);
2384                 
2385                 /* copy the face normal (needed because it gets flipped for tracing */
2386                 VECCOPY(shi.facenor, vlr->n);
2387                 shi.puno= vlr->puno;
2388                 
2389                 v1= vlr->v1;
2390                 
2391                 /* COXYZ AND VIEW VECTOR  */
2392                 calc_view_vector(shi.view, x, y);       /* returns not normalized, so is in viewplane coords */
2393
2394                 /* wire cannot use normal for calculating shi.co */
2395                 if(shi.mat->mode & MA_WIRE) {
2396                         float zco;
2397                         /* inverse of zbuf calc: zbuf = MAXZ*hoco_z/hoco_w */
2398                         
2399                         zco= ((float)z)/2147483647.0f;
2400                         shi.co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] );
2401                         
2402                         fac= zcor= shi.co[2]/shi.view[2];
2403                         
2404                         shi.co[0]= fac*shi.view[0];
2405                         shi.co[1]= fac*shi.view[1];
2406                 }
2407                 else {
2408                         float dface;
2409                         
2410                         dface= v1->co[0]*shi.facenor[0]+v1->co[1]*shi.facenor[1]+v1->co[2]*shi.facenor[2];
2411                         
2412                         /* ortho viewplane cannot intersect using view vector originating in (0,0,0) */
2413                         if(R.r.mode & R_ORTHO) {
2414                                 /* x and y 3d coordinate can be derived from pixel coord and winmat */
2415                                 float fx= 2.0/(R.winx*R.winmat[0][0]);
2416                                 float fy= 2.0/(R.winy*R.winmat[1][1]);
2417                                 
2418                                 shi.co[0]= (0.5 + x - 0.5*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0];
2419                                 shi.co[1]= (0.5 + y - 0.5*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1];
2420                                 
2421                                 /* using a*x + b*y + c*z = d equation, (a b c) is normal */
2422                                 if(shi.facenor[2]!=0.0f)
2423                                         shi.co[2]= (dface - shi.facenor[0]*shi.co[0] - shi.facenor[1]*shi.co[1])/shi.facenor[2];
2424                                 else
2425                                         shi.co[2]= 0.0f;
2426                                 
2427                                 zcor= 1.0; // only to prevent not-initialize
2428                                 
2429                                 if(shi.osatex || (R.r.mode & R_SHADOW) ) {
2430                                         shi.dxco[0]= fx;
2431                                         shi.dxco[1]= 0.0;
2432                                         if(shi.facenor[2]!=0.0f)
2433                                                 shi.dxco[2]= (shi.facenor[0]*fx)/shi.facenor[2];
2434                                         else 
2435                                                 shi.dxco[2]= 0.0f;
2436                                         
2437                                         shi.dyco[0]= 0.0;
2438                                         shi.dyco[1]= fy;
2439                                         if(shi.facenor[2]!=0.0f)
2440                                                 shi.dyco[2]= (shi.facenor[1]*fy)/shi.facenor[2];
2441                                         else 
2442                                                 shi.dyco[2]= 0.0f;
2443                                 }
2444                         }
2445                         else {
2446                                 float div;
2447                                 
2448                                 div= shi.facenor[0]*shi.view[0] + shi.facenor[1]*shi.view[1] + shi.facenor[2]*shi.view[2];
2449                                 if (div!=0.0) fac= zcor= dface/div;
2450                                 else fac= zcor= 0.0;
2451                                 
2452                                 shi.co[0]= fac*shi.view[0];
2453                                 shi.co[1]= fac*shi.view[1];
2454                                 shi.co[2]= fac*shi.view[2];
2455                         
2456                                 /* pixel dx/dy for render coord */
2457                                 if(shi.osatex || (R.r.mode & R_SHADOW) ) {
2458                                         float u= dface/(div - R.viewdx*shi.facenor[0]);
2459                                         float v= dface/(div - R.viewdy*shi.facenor[1]);
2460
2461                                         shi.dxco[0]= shi.co[0]- (shi.view[0]-R.viewdx)*u;
2462                                         shi.dxco[1]= shi.co[1]- (shi.view[1])*u;
2463                                         shi.dxco[2]= shi.co[2]- (shi.view[2])*u;
2464
2465                                         shi.dyco[0]= shi.co[0]- (shi.view[0])*v;
2466                                         shi.dyco[1]= shi.co[1]- (shi.view[1]-R.viewdy)*v;
2467                                         shi.dyco[2]= shi.co[2]- (shi.view[2])*v;
2468
2469                                 }
2470                         }
2471                 }
2472                 /* rco might be used for sky texture */
2473                 VECCOPY(rco, shi.co);
2474                 
2475                 /* cannot normalise earlier, code above needs it at viewplane level */
2476                 fac= Normalise(shi.view);
2477                 zcor*= fac;     // for mist, distance of point from camera
2478                 
2479                 if(shi.osatex) {
2480                         if( (shi.mat->texco & TEXCO_REFL) ) {
2481                                 shi.dxview= -R.viewdx/fac;
2482                                 shi.dyview= -R.viewdy/fac;
2483                         }
2484                 }
2485                 
2486                 /* calcuate normals, texture coords, vertex colors, etc */
2487                 if(facenr & RE_QUAD_OFFS)
2488                         shade_input_set_coords(&shi, 1.0, 1.0, 0, 2, 3);
2489                 else 
2490                         shade_input_set_coords(&shi, 1.0, 1.0, 0, 1, 2);
2491
2492                 /* this only avalailable for scanline */
2493                 if(shi.mat->texco & TEXCO_WINDOW) {
2494                         shi.winco[0]= -1.0f + 2.0f*x/(float)R.winx;
2495                         shi.winco[1]= -1.0f + 2.0f*y/(float)R.winy;
2496                         shi.winco[2]= 0.0;
2497                         if(shi.osatex) {
2498                                 shi.dxwin[0]= 2.0/(float)R.winx;
2499                                 shi.dywin[1]= 2.0/(float)R.winy;
2500                                 shi.dxwin[1]= shi.dxwin[2]= 0.0;
2501                                 shi.dywin[0]= shi.dywin[2]= 0.0;
2502                         }
2503                 }
2504                 /* after this the u and v AND shi.dxuv and shi.dyuv are incorrect */
2505                 if(shi.mat->texco & TEXCO_STICKY) {
2506                         VertRen *v2, *v3;
2507                         float *s1, *s2, *s3;
2508                         
2509                         if(facenr & RE_QUAD_OFFS) {
2510                                 v2= vlr->v3; v3= vlr->v4;
2511                         } else {
2512                                 v2= vlr->v2; v3= vlr->v3;
2513                         }
2514                         
2515                         s1= RE_vertren_get_sticky(&R, v1, 0);
2516                         s2= RE_vertren_get_sticky(&R, v2, 0);
2517                         s3= RE_vertren_get_sticky(&R, v3, 0);
2518                         
2519                         if(s1 && s2 && s3) {
2520                                 float Zmulx, Zmuly;
2521                                 float hox, hoy, l, dl, u, v;
2522                                 float s00, s01, s10, s11, detsh;
2523                                 
2524                                 /* XXXX */
2525                                 Zmulx= R.winx; Zmuly= R.winy;
2526                                 
2527                                 s00= v3->ho[0]/v3->ho[3] - v1->ho[0]/v1->ho[3];
2528                                 s01= v3->ho[1]/v3->ho[3] - v1->ho[1]/v1->ho[3];
2529                                 s10= v3->ho[0]/v3->ho[3] - v2->ho[0]/v2->ho[3];
2530                                 s11= v3->ho[1]/v3->ho[3] - v2->ho[1]/v2->ho[3];
2531                                 
2532                                 detsh= s00*s11-s10*s01;
2533                                 s00/= detsh; s01/=detsh; 
2534                                 s10/=detsh; s11/=detsh;
2535         
2536                                 /* recalc u and v again */
2537                                 hox= x/Zmulx -1.0;
2538                                 hoy= y/Zmuly -1.0;
2539                                 u= (hox - v3->ho[0]/v3->ho[3])*s11 - (hoy - v3->ho[1]/v3->ho[3])*s10;
2540                                 v= (hoy - v3->ho[1]/v3->ho[3])*s00 - (hox - v3->ho[0]/v3->ho[3])*s01;
2541                                 l= 1.0+u+v;
2542                                 
2543                                 shi.sticky[0]= l*s3[0]-u*s1[0]-v*s2[0];
2544                                 shi.sticky[1]= l*s3[1]-u*s1[1]-v*s2[1];
2545                                 shi.sticky[2]= 0.0;
2546                                 
2547                                 if(shi.osatex) {
2548                                         shi.dxuv[0]=  s11/Zmulx;
2549                                         shi.dxuv[1]=  - s01/Zmulx;
2550                                         shi.dyuv[0]=  - s10/Zmuly;
2551                                         shi.dyuv[1]=  s00/Zmuly;
2552                                         
2553                                         dl= shi.dxuv[0]+shi.dxuv[1];
2554                                         shi.dxsticky[0]= dl*s3[0]-shi.dxuv[0]*s1[0]-shi.dxuv[1]*s2[0];
2555                                         shi.dxsticky[1]= dl*s3[1]-shi.dxuv[0]*s1[1]-shi.dxuv[1]*s2[1];
2556                                         dl= shi.dyuv[0]+shi.dyuv[1];
2557                                         shi.dysticky[0]= dl*s3[0]-shi.dyuv[0]*s1[0]-shi.dyuv[1]*s2[0];
2558                                         shi.dysticky[1]= dl*s3[1]-shi.dyuv[0]*s1[1]-shi.dyuv[1]*s2[1];
2559                                 }
2560                         }
2561                 }
2562                 
2563                 /* ------  main shading loop -------- */
2564                 VECCOPY(shi.vno, shi.vn);
2565                 
2566                 if(shi.mat->nodetree && shi.mat->use_nodes) {
2567                         ntreeShaderExecTree(shi.mat->nodetree, &shi, shr);
2568                 }
2569                 else {
2570                         /* copy all relevant material vars, note, keep this synced with render_types.h */
2571                         memcpy(&shi.r, &shi.mat->r, 23*sizeof(float));
2572                         shi.har= shi.mat->har;
2573                         
2574 //                      if(passflag)
2575 //                              shade_lamp_loop_pass(&shi, shr, passflag);
2576 //                      else
2577                                 shade_material_loop(&shi, shr);
2578                 }
2579                 
2580                 /* after shading and composit layers */
2581                 if(shr->spec[0]<0.0f) shr->spec[0]= 0.0f;
2582                 if(shr->spec[1]<0.0f) shr->spec[1]= 0.0f;
2583                 if(shr->spec[2]<0.0f) shr->spec[2]= 0.0f;
2584                 
2585                 if(shr->diff[0]<0.0f) shr->diff[0]= 0.0f;
2586                 if(shr->diff[1]<0.0f) shr->diff[1]= 0.0f;
2587                 if(shr->diff[2]<0.0f) shr->diff[2]= 0.0f;
2588                 
2589 //              if(passflag==0) {
2590                         VECADD(shr->combined, shr->diff, shr->spec);
2591 //              }
2592                 
2593                 /* additional passes */
2594                 QUATCOPY(shr->winspeed, shi.winspeed);
2595                 VECCOPY(shr->nor, shi.vn);
2596                 
2597                 /* NOTE: this is not correct here, sky from raytrace gets corrected... */
2598                 /* exposure correction */
2599                 if(R.wrld.exp!=0.0 || R.wrld.range!=1.0) {
2600                         if((shi.mat->mode & MA_SHLESS)==0) {
2601                                 shr->combined[0]= R.wrld.linfac*(1.0-exp( shr->combined[0]*R.wrld.logfac) );
2602                                 shr->combined[1]= R.wrld.linfac*(1.0-exp( shr->combined[1]*R.wrld.logfac) );
2603                                 shr->combined[2]= R.wrld.linfac*(1.0-exp( shr->combined[2]*R.wrld.logfac) );
2604                         }
2605                 }
2606                 
2607                 /* MIST */
2608                 if((R.wrld.mode & WO_MIST) && (shi.mat->mode & MA_NOMIST)==0 ) {
2609                         if(R.r.mode & R_ORTHO)
2610                                 alpha= mistfactor(-shi.co[2], shi.co);
2611                         else
2612                                 alpha= mistfactor(zcor, shi.co);
2613                 }
2614                 else alpha= 1.0;
2615
2616                 if(shr->alpha!=1.0 || alpha!=1.0) {
2617                         if(shi.mat->mode & MA_RAYTRANSP) {
2618                                 fac= alpha;     
2619                                 shr->combined[3]= shr->alpha;
2620                         }
2621                         else {
2622                                 fac= alpha*(shr->alpha);
2623                                 shr->combined[3]= fac;
2624                         }                       
2625                         shr->combined[0]*= fac;
2626                         shr->combined[1]*= fac;
2627                         shr->combined[2]*= fac;
2628                 }
2629                 else shr->combined[3]= 1.0;
2630         }
2631         
2632         if(R.flag & R_LAMPHALO) {
2633                 if(shpi->layflag & SCE_LAY_HALO) {
2634
2635                         if(facenr<=0) { /* calc view vector and put shi.co at far */
2636                                 if(R.r.mode & R_ORTHO) {
2637                                         /* x and y 3d coordinate can be derived from pixel coord and winmat */
2638                                         float fx= 2.0/(R.rectx*R.winmat[0][0]);
2639                                         float fy= 2.0/(R.recty*R.winmat[1][1]);
2640                                         
2641                                         shi.co[0]= (0.5 + x - 0.5*R.rectx)*fx - R.winmat[3][0]/R.winmat[0][0];
2642                                         shi.co[1]= (0.5 + y - 0.5*R.recty)*fy - R.winmat[3][1]/R.winmat[1][1];
2643                                 }
2644                                 
2645                                 calc_view_vector(shi.view, x, y);
2646                                 shi.co[2]= 0.0;
2647                                 
2648                                 renderspothalo(&shi, shr->combined, 1.0);
2649                         }
2650                         else
2651                                 renderspothalo(&shi, shr->combined, shr->combined[3]);
2652                 }
2653         }
2654         
2655         return vlr;
2656 }
2657
2658 static void shadepixel_sky(ShadePixelInfo *shpi, float x, float y, int z, int facenr, int mask)
2659 {
2660         VlakRen *vlr;
2661         float collector[4], rco[3];
2662         
2663         vlr= shadepixel(shpi, x, y, z, facenr, mask, rco);
2664         if(shpi->shr.combined[3] != 1.0) {
2665                 
2666                 /* bail out when raytrace transparency (sky included already) */
2667                 if(vlr && (R.r.mode & R_RAYTRACE))
2668                         if(vlr->mat->mode & MA_RAYTRANSP) return;
2669                 
2670                 renderSkyPixelFloat(collector, x, y, vlr?rco:NULL);
2671                 addAlphaOverFloat(collector, shpi->shr.combined);
2672                 QUATCOPY(shpi->shr.combined, collector);
2673         }
2674 }
2675
2676 /* adds only alpha values */
2677 static void edge_enhance_calc(RenderPart *pa, float *rectf)     
2678 {
2679         /* use zbuffer to define edges, add it to the image */
2680         int y, x, col, *rz, *rz1, *rz2, *rz3;
2681         int zval1, zval2, zval3;
2682         float *rf;
2683         
2684         /* shift values in zbuffer 4 to the right, for filter we need multiplying with 12 max */
2685         rz= pa->rectz;
2686         if(rz==NULL) return;
2687         
2688         for(y=0; y<pa->recty; y++) {
2689                 for(x=0; x<pa->rectx; x++, rz++) (*rz)>>= 4;
2690         }
2691         
2692         rz1= pa->rectz;
2693         rz2= rz1+pa->rectx;
2694         rz3= rz2+pa->rectx;
2695         
2696         rf= rectf+pa->rectx+1;
2697         
2698         for(y=0; y<pa->recty-2; y++) {
2699                 for(x=0; x<pa->rectx-2; x++, rz1++, rz2++, rz3++, rf++) {
2700                         
2701                         /* prevent overflow with sky z values */
2702                         zval1=   rz1[0] + 2*rz1[1] +   rz1[2];
2703                         zval2=  2*rz2[0]           + 2*rz2[2];
2704                         zval3=   rz3[0] + 2*rz3[1] +   rz3[2];
2705                         
2706                         col= abs ( 4*rz2[1] - (zval1 + zval2 + zval3)/3 );
2707                         
2708                         col >>= 5;
2709                         if(col > (1<<16)) col= (1<<16);
2710                         else col= (R.r.edgeint*col)>>8;
2711                         
2712                         if(col>0) {
2713                                 float fcol;
2714                                 
2715                                 if(col>255) fcol= 1.0f;
2716                                 else fcol= (float)col/255.0f;
2717                                 
2718                                 if(R.osa)
2719                                         *rf+= fcol/(float)R.osa;
2720                                 else
2721                                         *rf= fcol;
2722                         }
2723                 }
2724                 rz1+= 2;
2725                 rz2+= 2;
2726                 rz3+= 2;
2727                 rf+= 2;
2728         }
2729 }
2730
2731 static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect)
2732 {
2733         float addcol[4];
2734         int pix;
2735         
2736         for(pix= pa->rectx*pa->recty; pix>0; pix--, arect++, rectf+=4) {
2737                 if(*arect != 0.0f) {
2738                         addcol[0]= *arect * R.r.edgeR;
2739                         addcol[1]= *arect * R.r.edgeG;
2740                         addcol[2]= *arect * R.r.edgeB;
2741                         addcol[3]= *arect;
2742                         addAlphaOverFloat(rectf, addcol);
2743                 }
2744         }
2745 }
2746
2747
2748 /* ********************* MAINLOOPS ******************** */
2749
2750 static void reset_sky_speedvectors(RenderPart *pa, RenderLayer *rl)
2751 {
2752         
2753         /* speed vector exception... if solid render was done, sky pixels are set to zero already */
2754         /* for all pixels with alpha zero, we re-initialize speed again then */
2755         if(rl->layflag & SCE_LAY_SOLID) {
2756                 float *fp, *col;
2757                 int a;
2758                 
2759                 fp= RE_RenderLayerGetPass(rl, SCE_PASS_VECTOR);
2760                 if(fp==NULL) return;
2761                 col= rl->rectf+3;
2762                 
2763                 for(a= 4*pa->rectx*pa->recty -4; a>=0; a-=4) {
2764                         if(col[a]==0.0f) {
2765                                 fp[a]= PASS_VECTOR_MAX;
2766                                 fp[a+1]= PASS_VECTOR_MAX;
2767                                 fp[a+2]= PASS_VECTOR_MAX;
2768                                 fp[a+3]= PASS_VECTOR_MAX;
2769                         }
2770                 }
2771         }
2772 }
2773
2774 /* osa version */
2775 static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, ShadeResult *shr)
2776 {
2777         RenderPass *rpass;
2778         
2779         for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
2780                 float *fp, *col= NULL;
2781                 int pixsize= 3;
2782                 
2783                 switch(rpass->passtype) {
2784                         case SCE_PASS_RGBA:
2785                                 col= shr->col;
2786                                 pixsize= 4;
2787                                 break;
2788                         case SCE_PASS_DIFFUSE:
2789                                 col= shr->diff;
2790                                 break;
2791                         case SCE_PASS_SPEC:
2792                                 col= shr->spec;
2793                                 break;
2794                         case SCE_PASS_SHADOW:
2795                                 col= shr->shad;
2796                                 break;
2797                         case SCE_PASS_AO:
2798                                 col= shr->ao;
2799                                 break;
2800                         case SCE_PASS_RAY:
2801                                 col= shr->ray;
2802                                 break;
2803                         case SCE_PASS_NORMAL:
2804                                 col= shr->nor;
2805                                 break;
2806                         case SCE_PASS_VECTOR:
2807                         {
2808                                 /* add minimum speed in pixel */
2809                                 fp= rpass->rect + 4*offset;
2810                                 if( (ABS(shr->winspeed[0]) + ABS(shr->winspeed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) {
2811                                         fp[0]= shr->winspeed[0];
2812                                         fp[1]= shr->winspeed[1];
2813                                 }