@@ -54,33 +54,51 @@ __device__ inline bool intersect(const int num_spheres, const Sphere* spheres, c
54
54
for (int i=int (n);i--;) if ((d=spheres[i].intersect (r))&&d<t){t=d;id=i;}
55
55
return t<inf;
56
56
}
57
- __device__ Vec radiance (const int num_spheres, const Sphere* spheres, const Ray & r, int depth, unsigned short *Xi, curandState* state){
57
+ __device__ Vec radiance (const int num_spheres, const Sphere* spheres, Ray r, int depth, unsigned short *Xi, curandState* state){
58
58
double t; // distance to intersection
59
59
int id=0 ; // id of intersected object
60
- if (depth > 1 ) return Vec ();
61
- if (!intersect (num_spheres, spheres, r, t, id)) return Vec (); // if miss, return black
62
- const Sphere &obj = spheres[id]; // the hit object
63
- Vec x=r.o +r.d *t, n=(x-obj.p ).norm (), nl=n.dot (r.d )<0 ?n:n*-1 , f=obj.c ;
64
- double p = f.x >f.y && f.x >f.z ? f.x : f.y >f.z ? f.y : f.z ; // max refl
65
- if (++depth>5 ) if (curand_uniform_double (state)<p) f=f*(1 /p); else return obj.e ; // R.R.
66
- if (obj.refl == DIFF){ // Ideal DIFFUSE reflection
67
- double r1=2 *M_PI*curand_uniform_double (state), r2=curand_uniform_double (state), r2s=sqrt (r2);
68
- Vec w=nl, u=((fabs (w.x )>.1 ?Vec (0 ,1 ):Vec (1 ))%w).norm (), v=w%u;
69
- Vec d = (u*cos (r1)*r2s + v*sin (r1)*r2s + w*sqrt (1 -r2)).norm ();
70
- return obj.e + f.mult (radiance (num_spheres, spheres,Ray (x,d),depth,Xi,state));
71
- } else if (obj.refl == SPEC) // Ideal SPECULAR reflection
72
- return obj.e + f.mult (radiance (num_spheres, spheres,Ray (x,r.d -n*2 *n.dot (r.d )),depth,Xi,state));
73
- Ray reflRay (x, r.d -n*2 *n.dot (r.d )); // Ideal dielectric REFRACTION
74
- bool into = n.dot (nl)>0 ; // Ray from outside going in?
75
- double nc=1 , nt=1.5 , nnt=into?nc/nt:nt/nc, ddn=r.d .dot (nl), cos2t;
76
- if ((cos2t=1 -nnt*nnt*(1 -ddn*ddn))<0 ) // Total internal reflection
77
- return obj.e + f.mult (radiance (num_spheres, spheres,reflRay,depth,Xi,state));
78
- Vec tdir = (r.d *nnt - n*((into?1 :-1 )*(ddn*nnt+sqrt (cos2t)))).norm ();
79
- double a=nt-nc, b=nt+nc, R0=a*a/(b*b), c = 1 -(into?-ddn:tdir.dot (n));
80
- double Re=R0+(1 -R0)*c*c*c*c*c,Tr=1 -Re,P=.25 +.5 *Re,RP=Re/P,TP=Tr/(1 -P);
81
- return obj.e + f.mult (depth>2 ? (curand_uniform_double (state)<P ? // Russian roulette
82
- radiance (num_spheres, spheres,reflRay,depth,Xi,state)*RP:radiance (num_spheres, spheres,Ray (x,tdir),depth,Xi,state)*TP) :
83
- radiance (num_spheres, spheres,reflRay,depth,Xi,state)*Re+radiance (num_spheres, spheres,Ray (x,tdir),depth,Xi,state)*Tr);
60
+
61
+ Vec s_e[10 ];
62
+ Vec s_f[10 ];
63
+ for (int i=0 ; i<10 ; i++){
64
+ if (!intersect (num_spheres, spheres, r, t, id)) return Vec (); // if miss, return black
65
+ const Sphere &obj = spheres[id]; // the hit object
66
+ Vec x=r.o +r.d *t, n=(x-obj.p ).norm (), nl=n.dot (r.d )<0 ?n:n*-1 , f=obj.c ;
67
+ double p = f.x >f.y && f.x >f.z ? f.x : f.y >f.z ? f.y : f.z ; // max refl
68
+ if (i>5 ) {
69
+ if (curand_uniform_double (state)<p) f=f*(1 /p);
70
+ else {
71
+ Vec res = obj.e ;
72
+ Vec e,f;
73
+ while (--i>=0 ){
74
+ e = s_e[i];
75
+ f = s_f[i];
76
+ res = e + f.mult (res);
77
+ }
78
+ return res;
79
+ }
80
+ } // return obj.e; //R.R.
81
+ s_e[i]=obj.e ;
82
+ s_f[i]=f;
83
+ if (obj.refl == DIFF){ // Ideal DIFFUSE reflection
84
+ double r1=2 *M_PI*curand_uniform_double (state), r2=curand_uniform_double (state), r2s=sqrt (r2);
85
+ Vec w=nl, u=((fabs (w.x )>.1 ?Vec (0 ,1 ):Vec (1 ))%w).norm (), v=w%u;
86
+ Vec d = (u*cos (r1)*r2s + v*sin (r1)*r2s + w*sqrt (1 -r2)).norm ();
87
+ r = Ray (x,d);
88
+ continue ;
89
+ // return obj.e + f.mult(radiance(num_spheres, spheres,Ray(x,d),depth,Xi,state));
90
+ } else if (obj.refl == SPEC) {r = Ray (x,r.d -n*2 *n.dot (r.d )); continue ;}
91
+ Ray reflRay (x, r.d -n*2 *n.dot (r.d )); // Ideal dielectric REFRACTION
92
+ bool into = n.dot (nl)>0 ; // Ray from outside going in?
93
+ double nc=1 , nt=1.5 , nnt=into?nc/nt:nt/nc, ddn=r.d .dot (nl), cos2t;
94
+ if ((cos2t=1 -nnt*nnt*(1 -ddn*ddn))<0 ) {r=reflRay; continue ;} // Total internal reflection
95
+ // return obj.e + f.mult(radiance(num_spheres, spheres,reflRay,depth,Xi,state));
96
+ Vec tdir = (r.d *nnt - n*((into?1 :-1 )*(ddn*nnt+sqrt (cos2t)))).norm ();
97
+ double a=nt-nc, b=nt+nc, R0=a*a/(b*b), c = 1 -(into?-ddn:tdir.dot (n));
98
+ double Re=R0+(1 -R0)*c*c*c*c*c,Tr=1 -Re,P=.25 +.5 *Re,RP=Re/P,TP=Tr/(1 -P);
99
+ r = Ray (x,tdir);
100
+ }
101
+ return Vec ();
84
102
}
85
103
86
104
__global__ void render (const int num_spheres, const Sphere* spheres, Vec* c, int samps){
0 commit comments