Three fixes;
[blender.git] / source / blender / render / intern / source / pixelshading.c
1 /**
2  *
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. 
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  *
19  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20  * All rights reserved.
21  *
22  * Contributor(s): 2004-2006, Blender Foundation, full recode
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 #include <math.h>
28 #include "BLI_arithb.h"
29
30 /* External modules: */
31 #include "IMB_imbuf_types.h"
32 #include "IMB_imbuf.h"
33 #include "MTC_matrixops.h"
34 #include "MTC_vectorops.h"
35
36 #include "DNA_camera_types.h"
37 #include "DNA_group_types.h"
38 #include "DNA_material_types.h"
39 #include "DNA_object_types.h"
40 #include "DNA_image_types.h"
41 #include "DNA_texture_types.h"
42 #include "DNA_lamp_types.h"
43
44 #include "BKE_image.h"
45 #include "BKE_global.h"
46 #include "BKE_texture.h"
47 #include "BKE_utildefines.h"
48
49 /* own module */
50 #include "render_types.h"
51 #include "renderpipeline.h"
52 #include "renderdatabase.h"
53 #include "texture.h"
54 #include "pixelblending.h"
55 #include "rendercore.h"
56 #include "shadbuf.h"
57 #include "gammaCorrectionTables.h"
58 #include "pixelshading.h"
59
60 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
61 /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
62 /* only to be used here in this file, it's for speed */
63 extern struct Render R;
64 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
65
66
67 extern float hashvectf[];
68
69 static void render_lighting_halo(HaloRen *har, float *colf)
70 {
71         GroupObject *go;
72         LampRen *lar;
73         float i, inp, inpr, rco[3], dco[3], lv[3], lampdist, ld, t, *vn;
74         float ir, ig, ib, shadfac, soft, lacol[3];
75         
76         ir= ig= ib= 0.0;
77         
78         VECCOPY(rco, har->co);  
79         dco[0]=dco[1]=dco[2]= 1.0/har->rad;
80         
81         vn= har->no;
82         
83         for(go=R.lights.first; go; go= go->next) {
84                 lar= go->lampren;
85                 
86                 /* test for lamplayer */
87                 if(lar->mode & LA_LAYER) if((lar->lay & har->lay)==0) continue;
88                 
89                 /* lampdist cacluation */
90                 if(lar->type==LA_SUN || lar->type==LA_HEMI) {
91                         VECCOPY(lv, lar->vec);
92                         lampdist= 1.0;
93                 }
94                 else {
95                         lv[0]= rco[0]-lar->co[0];
96                         lv[1]= rco[1]-lar->co[1];
97                         lv[2]= rco[2]-lar->co[2];
98                         ld= sqrt(lv[0]*lv[0]+lv[1]*lv[1]+lv[2]*lv[2]);
99                         lv[0]/= ld;
100                         lv[1]/= ld;
101                         lv[2]/= ld;
102                         
103                         /* ld is re-used further on (texco's) */
104                         
105                         if(lar->mode & LA_QUAD) {
106                                 t= 1.0;
107                                 if(lar->ld1>0.0)
108                                         t= lar->dist/(lar->dist+lar->ld1*ld);
109                                 if(lar->ld2>0.0)
110                                         t*= lar->distkw/(lar->distkw+lar->ld2*ld*ld);
111                                 
112                                 lampdist= t;
113                         }
114                         else {
115                                 lampdist= (lar->dist/(lar->dist+ld));
116                         }
117                         
118                         if(lar->mode & LA_SPHERE) {
119                                 t= lar->dist - ld;
120                                 if(t<0.0) continue;
121                                 
122                                 t/= lar->dist;
123                                 lampdist*= (t);
124                         }
125                         
126                 }
127                 
128                 lacol[0]= lar->r;
129                 lacol[1]= lar->g;
130                 lacol[2]= lar->b;
131                 
132                 if(lar->mode & LA_TEXTURE) {
133                         ShadeInput shi;
134                         VECCOPY(shi.co, rco);
135                         shi.osatex= 0;
136                         do_lamp_tex(lar, lv, &shi, lacol);
137                 }
138                 
139                 if(lar->type==LA_SPOT) {
140                         
141                         if(lar->mode & LA_SQUARE) {
142                                 if(lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]>0.0) {
143                                         float x, lvrot[3];
144                                         
145                                         /* rotate view to lampspace */
146                                         VECCOPY(lvrot, lv);
147                                         MTC_Mat3MulVecfl(lar->imat, lvrot);
148                                         
149                                         x= MAX2(fabs(lvrot[0]/lvrot[2]) , fabs(lvrot[1]/lvrot[2]));
150                                         /* 1.0/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */
151                                         
152                                         inpr= 1.0/(sqrt(1.0+x*x));
153                                 }
154                                 else inpr= 0.0;
155                         }
156                         else {
157                                 inpr= lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2];
158                         }
159                         
160                         t= lar->spotsi;
161                         if(inpr<t) continue;
162                         else {
163                                 t= inpr-t;
164                                 i= 1.0;
165                                 soft= 1.0;
166                                 if(t<lar->spotbl && lar->spotbl!=0.0) {
167                                         /* soft area */
168                                         i= t/lar->spotbl;
169                                         t= i*i;
170                                         soft= (3.0*t-2.0*t*i);
171                                         inpr*= soft;
172                                 }
173                                 if(lar->mode & LA_ONLYSHADOW) {
174                                         /* if(ma->mode & MA_SHADOW) { */
175                                         /* dot product positive: front side face! */
176                                         inp= vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2];
177                                         if(inp>0.0) {
178                                                 /* testshadowbuf==0.0 : 100% shadow */
179                                                 shadfac = testshadowbuf(lar->shb, rco, dco, dco, inp);
180                                                 if( shadfac>0.0 ) {
181                                                         shadfac*= inp*soft*lar->energy;
182                                                         ir -= shadfac;
183                                                         ig -= shadfac;
184                                                         ib -= shadfac;
185                                                         
186                                                         continue;
187                                                 }
188                                         }
189                                         /* } */
190                                 }
191                                 lampdist*=inpr;
192                         }
193                         if(lar->mode & LA_ONLYSHADOW) continue;
194                         
195                 }
196                 
197                 /* dot product and  reflectivity*/
198                 
199                 inp= 1.0-fabs(vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2]);
200                 
201                 /* inp= cos(0.5*M_PI-acos(inp)); */
202                 
203                 i= inp;
204                 
205                 if(lar->type==LA_HEMI) {
206                         i= 0.5*i+0.5;
207                 }
208                 if(i>0.0) {
209                         i*= lampdist;
210                 }
211                 
212                 /* shadow  */
213                 if(i> -0.41) {                  /* heuristic valua! */
214                         shadfac= 1.0;
215                         if(lar->shb) {
216                                 shadfac = testshadowbuf(lar->shb, rco, dco, dco, inp);
217                                 if(shadfac==0.0) continue;
218                                 i*= shadfac;
219                         }
220                 }
221                 
222                 if(i>0.0) {
223                         ir+= i*lacol[0];
224                         ig+= i*lacol[1];
225                         ib+= i*lacol[2];
226                 }
227         }
228         
229         if(ir<0.0) ir= 0.0;
230         if(ig<0.0) ig= 0.0;
231         if(ib<0.0) ib= 0.0;
232
233         colf[0]*= ir;
234         colf[1]*= ig;
235         colf[2]*= ib;
236         
237 }
238
239
240
241 void shadeHaloFloat(HaloRen *har,  float *col, int zz, 
242                                         float dist, float xn,  float yn, short flarec)
243 {
244         /* fill in col */
245         float t, zn, radist, ringf=0.0, linef=0.0, alpha, si, co;
246         int a;
247    
248         if(R.wrld.mode & WO_MIST) {
249        if(har->type & HA_ONLYSKY) {
250            /* stars but no mist */
251            alpha= har->alfa;
252        }
253        else {
254            /* a bit patchy... */
255            alpha= mistfactor(-har->co[2], har->co)*har->alfa;
256        }
257         }
258         else alpha= har->alfa;
259         
260         if(alpha==0.0) {
261                 col[0] = 0.0;
262                 col[1] = 0.0;
263                 col[2] = 0.0;
264                 col[3] = 0.0;
265                 return;
266         }
267
268         radist= sqrt(dist);
269
270         /* watch it: not used nicely: flarec is set at zero in pixstruct */
271         if(flarec) har->pixels+= (int)(har->rad-radist);
272
273         if(har->ringc) {
274                 float *rc, fac;
275                 int ofs;
276                 
277                 /* per ring an antialised circle */
278                 ofs= har->seed;
279                 
280                 for(a= har->ringc; a>0; a--, ofs+=2) {
281                         
282                         rc= hashvectf + (ofs % 768);
283                         
284                         fac= fabs( rc[1]*(har->rad*fabs(rc[0]) - radist) );
285                         
286                         if(fac< 1.0) {
287                                 ringf+= (1.0-fac);
288                         }
289                 }
290         }
291
292         if(har->type & HA_VECT) {
293                 dist= fabs( har->cos*(yn) - har->sin*(xn) )/har->rad;
294                 if(dist>1.0) dist= 1.0;
295                 if(har->tex) {
296                         zn= har->sin*xn - har->cos*yn;
297                         yn= har->cos*xn + har->sin*yn;
298                         xn= zn;
299                 }
300         }
301         else dist= dist/har->radsq;
302
303         if(har->type & HA_FLARECIRC) {
304                 
305                 dist= 0.5+fabs(dist-0.5);
306                 
307         }
308
309         if(har->hard>=30) {
310                 dist= sqrt(dist);
311                 if(har->hard>=40) {
312                         dist= sin(dist*M_PI_2);
313                         if(har->hard>=50) {
314                                 dist= sqrt(dist);
315                         }
316                 }
317         }
318         else if(har->hard<20) dist*=dist;
319
320         dist=(1.0-dist);
321         
322         if(har->linec) {
323                 float *rc, fac;
324                 int ofs;
325                 
326                 /* per starpoint an antialiased line */
327                 ofs= har->seed;
328                 
329                 for(a= har->linec; a>0; a--, ofs+=3) {
330                         
331                         rc= hashvectf + (ofs % 768);
332                         
333                         fac= fabs( (xn)*rc[0]+(yn)*rc[1]);
334                         
335                         if(fac< 1.0 ) {
336                                 linef+= (1.0-fac);
337                         }
338                 }
339                 
340                 linef*= dist;
341                 
342         }
343
344         if(har->starpoints) {
345                 float ster, hoek;
346                 /* rotation */
347                 hoek= atan2(yn, xn);
348                 hoek*= (1.0+0.25*har->starpoints);
349                 
350                 co= cos(hoek);
351                 si= sin(hoek);
352                 
353                 hoek= (co*xn+si*yn)*(co*yn-si*xn);
354                 
355                 ster= fabs(hoek);
356                 if(ster>1.0) {
357                         ster= (har->rad)/(ster);
358                         
359                         if(ster<1.0) dist*= sqrt(ster);
360                 }
361         }
362         
363         /* halo being intersected? */
364         if(har->zs> zz-har->zd) {
365                 t= ((float)(zz-har->zs))/(float)har->zd;
366                 alpha*= sqrt(sqrt(t));
367         }
368
369         dist*= alpha;
370         ringf*= dist;
371         linef*= alpha;
372         
373         if(dist<0.003) {
374                 col[0] = 0.0;
375                 col[1] = 0.0;
376                 col[2] = 0.0;
377                 col[3] = 0.0;
378                 return;
379         }
380
381         /* The colour is either the rgb spec-ed by the user, or extracted from   */
382         /* the texture                                                           */
383         if(har->tex) {
384                 col[0]= har->r; 
385                 col[1]= har->g; 
386                 col[2]= har->b;
387                 col[3]= dist;
388                 
389                 do_halo_tex(har, xn, yn, col);
390                 
391                 col[0]*= col[3];
392                 col[1]*= col[3];
393                 col[2]*= col[3];
394                 
395         }
396         else {
397                 col[0]= dist*har->r;
398                 col[1]= dist*har->g;
399                 col[2]= dist*har->b;
400                 if(har->type & HA_XALPHA) col[3]= dist*dist;
401                 else col[3]= dist;
402         }
403
404         if(har->mat) {
405                 if(har->mat->mode & MA_HALO_SHADE) {
406                         /* we test for lights because of preview... */
407                         if(R.lights.first) render_lighting_halo(har, col);
408                 }
409
410                 /* Next, we do the line and ring factor modifications. */
411                 if(linef!=0.0) {
412                         Material *ma= har->mat;
413                         
414                         col[0]+= linef * ma->specr;
415                         col[1]+= linef * ma->specg;
416                         col[2]+= linef * ma->specb;
417                         
418                         if(har->type & HA_XALPHA) col[3]+= linef*linef;
419                         else col[3]+= linef;
420                 }
421                 if(ringf!=0.0) {
422                         Material *ma= har->mat;
423
424                         col[0]+= ringf * ma->mirr;
425                         col[1]+= ringf * ma->mirg;
426                         col[2]+= ringf * ma->mirb;
427                         
428                         if(har->type & HA_XALPHA) col[3]+= ringf*ringf;
429                         else col[3]+= ringf;
430                 }
431         }
432 }
433
434 /* ------------------------------------------------------------------------- */
435 /*
436   
437   There are three different modes for blending sky behind a picture:       
438   1. sky    = blend in sky directly                                        
439   2. premul = don't do sky, but apply alpha (so pretend the picture ends   
440      exactly at it's boundaries)                                  
441   3. key    = don't do anything                                            
442   Now the stupid thing is that premul means do nothing for us, and key     
443   we have to adjust a bit...
444
445 */
446
447
448 /* This one renders into collector, as always.                               */
449 void renderSkyPixelFloat(float *collector, float x, float y, float *rco)
450 {
451
452         switch (R.r.alphamode) {
453         case R_ALPHAPREMUL:
454         case R_ALPHAKEY:
455                 /* Premul or key: don't fill, and don't change the values! */
456                 /* key alpha used to fill in color in 'empty' pixels, doesn't work anymore this way */
457                 collector[0] = 0.0; 
458                 collector[1] = 0.0; 
459                 collector[2] = 0.0; 
460                 collector[3] = 0.0; 
461                 break;
462         case R_ADDSKY:
463                 /* Fill in the sky as if it were a normal face. */
464                 shadeSkyPixel(collector, x, y, rco);
465                 collector[3]= 0.0;
466                 break;
467         default:
468                 ; /* Error: illegal alpha blending state */
469         }
470 }
471
472 /*
473   Stuff the sky colour into the collector.
474  */
475 void shadeSkyPixel(float *collector, float fx, float fy, float *rco) 
476 {
477         float view[3], dxyview[2];
478         
479         /*
480           The rules for sky:
481           1. Draw an image, if a background image was provided. Stop
482           2. get texture and colour blend, and combine these.
483         */
484
485         float fac;
486
487         /* 1. Do a backbuffer image: */ 
488         if(R.r.bufflag & 1) {
489 //              fillBackgroundImage(collector, fx, fy);
490                 return;
491         } else if((R.wrld.skytype & (WO_SKYBLEND+WO_SKYTEX))==0) {
492                 /*
493                   2. Test for these types of sky. The old renderer always had to check for
494                   coverage, but we don't need that anymore                                 
495                   - SKYBLEND or SKYTEX disabled: fill in a flat colour                     
496                   - otherwise, do the appropriate mapping (tex or colour blend)            
497                   There used to be cached chars here, but they are not useful anymore
498                 */
499                 collector[0] = R.wrld.horr;
500                 collector[1] = R.wrld.horg;
501                 collector[2] = R.wrld.horb;
502                 collector[3] = 1.0f;
503         } else {
504                 /*
505                   3. Which type(s) is(are) this (these)? This has to be done when no simple
506                   way of determining the colour exists.
507                 */
508
509                 /* This one true because of the context of this routine  */
510                 if(R.wrld.skytype & WO_SKYPAPER) {
511                         view[0]= -1.0f + 2.0f*(fx/(float)R.winx);
512                         view[1]= -1.0f + 2.0f*(fy/(float)R.winy);
513                         view[2]= 0.0;
514                         
515                         dxyview[0]= 1.0f/(float)R.winx;
516                         dxyview[1]= 1.0f/(float)R.winy;
517                 }
518                 else {
519                         calc_view_vector(view, fx, fy);
520                         fac= Normalise(view);
521                         
522                         if(R.wrld.skytype & WO_SKYTEX) {
523                                 dxyview[0]= -R.viewdx/fac;
524                                 dxyview[1]= -R.viewdy/fac;
525                         }
526                 }
527                 
528                 if(R.r.mode & R_PANORAMA) {
529                         float u= view[0]; float v= view[2];
530                         
531                         view[0]= R.panoco*u + R.panosi*v;
532                         view[2]= -R.panosi*u + R.panoco*v;
533                 }
534         
535                 /* get sky colour in the collector */
536                 shadeSkyPixelFloat(collector, rco, view, dxyview);
537                 collector[3] = 1.0f;
538         }
539 }
540
541 /* Only view vector is important here. Result goes to colf[3] */
542 void shadeSkyPixelFloat(float *colf, float *rco, float *view, float *dxyview)
543 {
544         float lo[3], zen[3], hor[3], blend, blendm;
545         
546         /* Why is this setting forced? Seems silly to me. It is tested in the texture unit. */
547         R.wrld.skytype |= WO_ZENUP;
548         
549         /* Some view vector stuff. */
550         if(R.wrld.skytype & WO_SKYREAL) {
551         
552                 blend= view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2];
553
554                 if(blend<0.0) R.wrld.skytype-= WO_ZENUP;
555                 blend= fabs(blend);
556         }
557         else if(R.wrld.skytype & WO_SKYPAPER) {
558                 blend= 0.5+ 0.5*view[1];
559         }
560         else {
561                 /* the fraction of how far we are above the bottom of the screen */
562                 blend= fabs(0.5+ view[1]);
563         }
564
565         hor[0]= R.wrld.horr; hor[1]= R.wrld.horg; hor[2]= R.wrld.horb;
566         zen[0]= R.wrld.zenr; zen[1]= R.wrld.zeng; zen[2]= R.wrld.zenb;
567         
568         /* Careful: SKYTEX and SKYBLEND are NOT mutually exclusive! If           */
569         /* SKYBLEND is active, the texture and colour blend are added.           */
570         if(R.wrld.skytype & WO_SKYTEX) {
571                 VECCOPY(lo, view);
572                 if(R.wrld.skytype & WO_SKYREAL) {
573                         
574                         MTC_Mat3MulVecfl(R.imat, lo);
575
576                         SWAP(float, lo[1],  lo[2]);
577                         
578                 }
579                 do_sky_tex(rco, lo, dxyview, hor, zen, &blend);
580         }
581
582         if(blend>1.0) blend= 1.0;
583         blendm= 1.0-blend;
584
585         /* No clipping, no conversion! */
586         if(R.wrld.skytype & WO_SKYBLEND) {
587                 colf[0] = (blendm*hor[0] + blend*zen[0]);
588                 colf[1] = (blendm*hor[1] + blend*zen[1]);
589                 colf[2] = (blendm*hor[2] + blend*zen[2]);
590         } else {
591                 /* Done when a texture was grabbed. */
592                 colf[0]= hor[0];
593                 colf[1]= hor[1];
594                 colf[2]= hor[2];
595         }
596 }
597
598
599 /* eof */