[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [34627] trunk/blender/source/blender/ render/intern/source/rayshade.c: Applying patch #25898 by Shinsuke Irie for rendering total external reflections

Janne Karhu jhkarh at gmail.com
Thu Feb 3 16:05:45 CET 2011


Revision: 34627
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=34627
Author:   jhk
Date:     2011-02-03 15:05:43 +0000 (Thu, 03 Feb 2011)
Log Message:
-----------
Applying patch #25898 by Shinsuke Irie for rendering total external reflections
* Tracing objects with IOR < 1.0 (like air bubbles under water) wasn't working correctly as a refraction was always assumed to be the first thing that happens for transparent materials.
* This fix is ok, but the fact that the internal renderer is not a physically based one is starting to show, as for example blurred reflections in this case are not really possible nicely without some slightly heavier modifications to the ray code.
* Also some cleaned up logic and better comments for my previous total internal reflection commit.

Modified Paths:
--------------
    trunk/blender/source/blender/render/intern/source/rayshade.c

Modified: trunk/blender/source/blender/render/intern/source/rayshade.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/rayshade.c	2011-02-03 13:25:05 UTC (rev 34626)
+++ trunk/blender/source/blender/render/intern/source/rayshade.c	2011-02-03 15:05:43 UTC (rev 34627)
@@ -66,7 +66,7 @@
 
 
 #define RAY_TRA		1
-#define RAY_TRAFLIP	2
+#define RAY_INSIDE	2
 
 #define DEPTH_SHADOW_TRA  10
 
@@ -758,7 +758,8 @@
 		shi.mat_override= origshi->mat_override;
 		
 		shade_ray(&isec, &shi, &shr);
-		if (traflag & RAY_TRA)
+		/* ray has traveled inside the material, so shade by transmission */
+		if (traflag & RAY_INSIDE)
 			d= shade_by_transmission(&isec, &shi, &shr);
 		
 		if(depth>0) {
@@ -773,27 +774,33 @@
 				tracol[3]= col[3];	// we pass on and accumulate alpha
 				
 				if((shi.mat->mode & MA_TRANSP) && (shi.mat->mode & MA_RAYTRANSP)) {
-					/* odd depths: use normal facing viewer, otherwise flip */
-					if(traflag & RAY_TRAFLIP) {
+					if(traflag & RAY_INSIDE) {
+						/* inside the material, so use inverse normal */
 						float norm[3];
 						norm[0]= - shi.vn[0];
 						norm[1]= - shi.vn[1];
 						norm[2]= - shi.vn[2];
-						if (!refraction(refract, norm, shi.view, shi.ang)) {
+
+						if (refraction(refract, norm, shi.view, shi.ang)) {
+							/* ray comes out from the material into air */
+							traflag &= ~RAY_INSIDE;
+						}
+						else {
+							/* total internal reflection (ray stays inside the material) */
 							reflection(refract, norm, shi.view, shi.vn);
-							/* for total internal reflection the ray stays inside the material, so don't flip the normal (double flip) */
-							traflag ^= RAY_TRAFLIP;
 						}
 					}
 					else {
-						if (!refraction(refract, shi.vn, shi.view, shi.ang)) {
+						if (refraction(refract, shi.vn, shi.view, shi.ang)) {
+							/* ray goes in to the material from air */
+							traflag |= RAY_INSIDE;
+						}
+						else {
+							/* total external reflection (ray doesn't enter the material) */
 							reflection(refract, shi.vn, shi.view, shi.vn);
-							/* same reason as above */
-							traflag ^= RAY_TRAFLIP;
 						}
 					}
-					traflag |= RAY_TRA;
-					traceray(origshi, origshr, depth-1, shi.co, refract, tracol, shi.obi, shi.vlr, traflag ^ RAY_TRAFLIP);
+					traceray(origshi, origshr, depth-1, shi.co, refract, tracol, shi.obi, shi.vlr, traflag);
 				}
 				else
 					traceray(origshi, origshr, depth-1, shi.co, shi.view, tracol, shi.obi, shi.vlr, 0);
@@ -1291,6 +1298,7 @@
 {
 	QMCSampler *qsa=NULL;
 	int samp_type;
+	int traflag=0;
 	
 	float samp3d[3], orthx[3], orthy[3];
 	float v_refract[3], v_refract_new[3];
@@ -1318,7 +1326,18 @@
 	
 
 	while (samples < max_samples) {		
-		refraction(v_refract, shi->vn, shi->view, shi->ang);
+		if(refraction(v_refract, shi->vn, shi->view, shi->ang)) {
+			traflag |= RAY_INSIDE;
+		} else {
+			/* total external reflection can happen for materials with IOR < 1.0 */
+			if((shi->vlr->flag & R_SMOOTH)) 
+				reflection(v_refract, shi->vn, shi->view, shi->facenor);
+			else
+				reflection(v_refract, shi->vn, shi->view, NULL);
+
+			/* can't blur total external reflection */
+			max_samples = 1;
+		}
 		
 		if (max_samples > 1) {
 			/* get a quasi-random vector from a phong-weighted disc */
@@ -1340,7 +1359,7 @@
 		
 		sampcol[0]= sampcol[1]= sampcol[2]= sampcol[3]= 0.0f;
 
-		traceray(shi, shr, shi->mat->ray_depth_tra, shi->co, v_refract_new, sampcol, shi->obi, shi->vlr, RAY_TRA|RAY_TRAFLIP);
+		traceray(shi, shr, shi->mat->ray_depth_tra, shi->co, v_refract_new, sampcol, shi->obi, shi->vlr, traflag);
 	
 		col[0] += sampcol[0];
 		col[1] += sampcol[1];




More information about the Bf-blender-cvs mailing list