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