Page MenuHome

transmissivity-and-tir.patch

File Metadata

Author
Ed Halley (halley)
Created
Nov 13 2013, 1:04 PM

transmissivity-and-tir.patch

Index: source/blender/render/intern/source/ray.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/render/intern/source/ray.c,v
retrieving revision 1.66
diff -u -b -B -u -r1.66 ray.c
--- source/blender/render/intern/source/ray.c 29 Nov 2005 20:18:31 -0000 1.66
+++ source/blender/render/intern/source/ray.c 28 Dec 2005 04:12:46 -0000
@@ -1442,30 +1442,31 @@
}
-static void refraction(float *refract, float *n, float *view, float index)
+static int refraction(float *refract, float *n, float *view, float index)
{
float dot, fac;
VECCOPY(refract, view);
- index= 1.0/index;
dot= view[0]*n[0] + view[1]*n[1] + view[2]*n[2];
if(dot>0.0) {
+ index = 1.0/index;
fac= 1.0 - (1.0 - dot*dot)*index*index;
- if(fac<= 0.0) return;
+ if(fac<= 0.0) return 0;
fac= -dot*index + sqrt(fac);
}
else {
- index = 1.0/index;
fac= 1.0 - (1.0 - dot*dot)*index*index;
- if(fac<= 0.0) return;
+ if(fac<= 0.0) return 0;
fac= -dot*index - sqrt(fac);
}
refract[0]= index*view[0] + fac*n[0];
refract[1]= index*view[1] + fac*n[1];
refract[2]= index*view[2] + fac*n[2];
+
+ return 1;
}
/* orn = original face normal */
@@ -1512,6 +1513,25 @@
}
#endif
+static float shade_by_transmission(Isect *is, ShadeInput *shi, ShadeResult *shr)
+{
+ float dx, dy, dz, d;
+
+ if (0 == (shi->mat->mode & (MA_RAYTRANSP|MA_ZTRA)))
+ return -1;
+
+ /* shi.co[] calculated by shade_ray() */
+ dx= shi->co[0] - is->start[0];
+ dy= shi->co[1] - is->start[1];
+ dz= shi->co[2] - is->start[2];
+ d= sqrt(dx*dx+dy*dy+dz*dz);
+
+ shr->alpha *= d;
+ if (shr->alpha > 1.0) shr->alpha= 1.0;
+
+ return d;
+}
+
/* the main recursive tracer itself */
static void traceray(short depth, float *start, float *vec, float *col, VlakRen *vlr, int mask, int osatex, int traflag)
{
@@ -1529,18 +1549,24 @@
isec.vlrorig= vlr;
if( d3dda(&isec) ) {
+ float d= 1.0;
shi.mask= mask;
shi.osatex= osatex;
shi.depth= 1; // only now to indicate tracing
shade_ray(&isec, &shi, &shr);
+ if (traflag & RAY_TRA)
+ d= shade_by_transmission(&isec, &shi, &shr);
if(depth>0) {
- if(shi.mat->mode & (MA_RAYTRANSP|MA_ZTRA) && shr.alpha!=1.0) {
- float f, f1, refract[3], tracol[4];
+ if(shi.mat->mode & (MA_RAYTRANSP|MA_ZTRA) && shr.alpha < 1.0) {
+ float nf, f, f1, refract[3], tracol[4];
+ tracol[0]= shi.r;
+ tracol[1]= shi.g;
+ tracol[2]= shi.b;
tracol[3]= col[3]; // we pass on and accumulate alpha
if(shi.mat->mode & MA_RAYTRANSP) {
@@ -1550,10 +1576,12 @@
norm[0]= - shi.vn[0];
norm[1]= - shi.vn[1];
norm[2]= - shi.vn[2];
- refraction(refract, norm, shi.view, shi.ang);
+ if (!refraction(refract, norm, shi.view, shi.ang))
+ reflection(refract, norm, shi.view, shi.vn);
}
else {
- refraction(refract, shi.vn, shi.view, shi.ang);
+ if (!refraction(refract, shi.vn, shi.view, shi.ang))
+ reflection(refract, shi.vn, shi.view, shi.vn);
}
traflag |= RAY_TRA;
traceray(depth-1, shi.co, refract, tracol, shi.vlr, shi.mask, osatex, traflag ^ RAY_TRAFLIP);
@@ -1562,9 +1590,10 @@
traceray(depth-1, shi.co, shi.view, tracol, shi.vlr, shi.mask, osatex, 0);
f= shr.alpha; f1= 1.0-f;
- fr= 1.0+ shi.mat->filter*(shi.r-1.0);
- fg= 1.0+ shi.mat->filter*(shi.g-1.0);
- fb= 1.0+ shi.mat->filter*(shi.b-1.0);
+ nf= d * shi.mat->filter;
+ fr= 1.0+ nf*(shi.r-1.0);
+ fg= 1.0+ nf*(shi.g-1.0);
+ fb= 1.0+ nf*(shi.b-1.0);
shr.diff[0]= f*shr.diff[0] + f1*fr*tracol[0];
shr.diff[1]= f*shr.diff[1] + f1*fg*tracol[1];
shr.diff[2]= f*shr.diff[2] + f1*fb*tracol[2];
@@ -1824,7 +1853,7 @@
shadfac[3]= (1.0-alpha)*shadfac[3];
}
-static void ray_trace_shadow_tra(Isect *is, int depth)
+static void ray_trace_shadow_tra(Isect *is, int depth, int traflag)
{
/* ray to lamp, find first face that intersects, check alpha properties,
if it has col[3]>0.0 continue. so exit when alpha is full */
@@ -1832,6 +1861,7 @@
ShadeResult shr;
if( d3dda(is)) {
+ float d= 1.0;
/* we got a face */
shi.mask= 1;
@@ -1839,9 +1869,11 @@
shi.depth= 1; // only now to indicate tracing
shade_ray(is, &shi, &shr);
+ if (traflag & RAY_TRA)
+ d= shade_by_transmission(is, &shi, &shr);
/* mix colors based on shadfac (rgb + amount of light factor) */
- addAlphaLight(is->col, shr.diff, shr.alpha, shi.mat->filter);
+ addAlphaLight(is->col, shr.diff, shr.alpha, d*shi.mat->filter);
if(depth>0 && is->col[3]>0.0) {
@@ -1849,7 +1881,7 @@
VECCOPY(is->start, shi.co);
is->vlrorig= shi.vlr;
- ray_trace_shadow_tra(is, depth-1);
+ ray_trace_shadow_tra(is, depth-1, traflag | RAY_TRA);
}
}
}
@@ -2184,7 +2216,7 @@
isec.col[0]= isec.col[1]= isec.col[2]= 1.0;
isec.col[3]= 1.0;
- ray_trace_shadow_tra(&isec, DEPTH_SHADOW_TRA);
+ ray_trace_shadow_tra(&isec, DEPTH_SHADOW_TRA, 0);
QUATCOPY(shadfac, isec.col);
//printf("shadfac %f %f %f %f\n", shadfac[0], shadfac[1], shadfac[2], shadfac[3]);
}
@@ -2240,7 +2272,7 @@
isec.col[0]= isec.col[1]= isec.col[2]= 1.0;
isec.col[3]= 1.0;
- ray_trace_shadow_tra(&isec, DEPTH_SHADOW_TRA);
+ ray_trace_shadow_tra(&isec, DEPTH_SHADOW_TRA, 0);
shadfac[0] += isec.col[0];
shadfac[1] += isec.col[1];
shadfac[2] += isec.col[2];

Event Timeline