EXTERN_ENV void Render(long my_node) /* assumes direction is +Z */ { if (my_node == ROOT) { Observer_Transform_Light_Vector(); Compute_Observer_Transformed_Highlight_Vector(); } Ray_Trace(my_node); }
void RayTraceUtil() { int xp, yp; float xv, yv, dx, dy, dz; float u, v; /* Generate a ray for each pixel in the desired image. */ printf("Ray tracing...\n"); for (xp=0; xp<xmax_pixel; xp++) { u = (float)xp/xmax_pixel; for (yp=0; yp<ymax_pixel; yp++) { v = (float)yp/ymax_pixel; /* Compute the corresponding view port coordinates. */ xv = VXL + xp * xinterval; yv = VYB + yp * yinterval; /* Compute the direction of the current ray from the "From" point to the current position on the image. */ dx = ax*xv*tanv2 + bx*yv*tanv2 + cx; dy = ay*xv*tanv2 + by*yv*tanv2 + cy; dz = az*xv*tanv2 + bz*yv*tanv2 + cz; rgb rgb_color = Ray_Trace(0,dx,dy,dz,from,1); /* Save the computed color intensity to the image buffer. */ texture_R[xp + xmax_pixel * yp] = rgb_color.r; texture_G[xp + xmax_pixel * yp] = rgb_color.g; texture_B[xp + xmax_pixel * yp] = rgb_color.b; } } /* Write the image to the output file. */ printf("Writing to image...\n"); fwrite(&xmax_pixel, sizeof(int), 1, outpfile); fwrite(&ymax_pixel, sizeof(int), 1, outpfile); fwrite(texture_R, sizeof(float), xmax_pixel*ymax_pixel, outpfile); fwrite(texture_G, sizeof(float), xmax_pixel*ymax_pixel, outpfile); fwrite(texture_B, sizeof(float), xmax_pixel*ymax_pixel, outpfile); fclose(outpfile); }
rgb Ray_Trace(int obj_num,float dx, float dy,float dz, points from, int depth) { int shadow_flag; int texture, buf_ptr = 0; int num_image = 1; float nx, ny, nz; float t_min, t1, t2, ipx = 0, ipy = 0, ipz = 0; float rlx, rly, rlz, rfx,rfy,rfz; rgb rgb_color; /* Check if the current ray intercepts spheres */ t_min = 999.0; //obj_num = 0; texture = 0; for(int i = 1; i <= NUM_SPHERES; i++) { Check_Sphere(from.x, from.y, from.z, dx, dy, dz, c[i-1][0], c[i-1][1], c[i-1][2], c[i-1][3], &t1, &t2); if (t1>=0.00001) { t_min = t1; obj_num = i; Compute_Intersection(from.x, from.y, from.z, dx, dy, dz, t1, &ipx, &ipy, &ipz); } if (t2>=0.00001 && t2<t_min) { t_min = t2; obj_num = i; Compute_Intersection(from.x, from.y, from.z, dx, dy, dz, t2, &ipx, &ipy, &ipz); } } /* Check if the current ray intercepts planes. */ for(int i = 1; i <= NUM_PLANES; i++) { Check_Plane(from.x, from.y, from.z, dx, dy, dz, p[i-1][0], p[i-1][1], p[i-1][2], p[i-1][3], &t1); if (t1 >= 0.00001 && t1<t_min) { /* Check if the intersection point is inside the min/max values. */ Compute_Intersection(from.x, from.y, from.z, dx, dy, dz, t1, &ipx, &ipy, &ipz); if (ipx >= pminmax[i-1][0][0] && ipx <= pminmax[i-1][0][1] && ipy >= pminmax[i-1][1][0] && ipy <= pminmax[i-1][1][1] && ipz >= pminmax[i-1][2][0] && ipz <= pminmax[i-1][2][1] ) { t_min = t1; obj_num = i+NUM_SPHERES; } } } int grain; float u,v,w,t,value,x; /* Compute the intensity to use at the current pixel. */ switch (obj_num) { /* The current ray does not intersect any of the objects. */ case 0 :rgb_color.r = 0.1; rgb_color.g = 0.1; rgb_color.b = 0.1; break; /* The current ray intercept sphere #1. */ case 1 : nx = ipx - c[0][0]; ny = ipy - c[0][1]; nz = ipz - c[0][2]; Normalize(&nx, &ny, &nz); shadow_flag = 0; shadow_flag = Check_Shadow(ipx, ipy, ipz, obj_num); texture = 0; rgb_color = Compute_Color(shadow_flag, ipx, ipy, ipz, nx, ny, nz, ia, ka_S[0], kd_S[0], ks_S[0], ns_S[0], krg_S[0], ktg_S[0], 1); break; /* The current ray intercepts sphere #2. */ case 2 : nx = ipx - c[1][0]; ny = ipy - c[1][1]; nz = ipz - c[1][2]; Normalize(&nx, &ny, &nz); shadow_flag = 0; shadow_flag = Check_Shadow(ipx, ipy, ipz, obj_num); texture = rand() % 2; if(texture == 1) { Bump_map(ipx,ipy,ipz,dx,dy,dz,1,&nx,&ny,&nz,2); rgb_color = Compute_Color(shadow_flag, ipx, ipy, ipz, nx, ny, nz, ia, ka_S[1], kd_S[1], ks_S[1], ns_S[1], krg_S[1], ktg_S[1], 1); } else rgb_color = Compute_Color(shadow_flag, ipx, ipy, ipz, nx, ny, nz, ia, ka_S[1], kd_S[1], ks_S[1], ns_S[1], krg_S[1], ktg_S[1], 1); break; /* The current ray intercepts sphere #3. */ case 3 : nx = ipx - c[2][0]; ny = ipy - c[2][1]; nz = ipz - c[2][2]; Normalize(&nx, &ny, &nz); shadow_flag = 0; shadow_flag = Check_Shadow(ipx, ipy, ipz, obj_num); texture = rand() % 2; if (texture==1) // Compute texture. */ { Bump_map(ipx,ipy,ipz,dx,dy,dz,1,&nx,&ny,&nz,1); rgb_color = Compute_Color(shadow_flag, ipx, ipy, ipz, nx, ny, nz, ia, tka3, tkd3, ks_S[2], ns_S[2], krg_S[2], ktg_S[2], 1); } else rgb_color = Compute_Color(shadow_flag, ipx, ipy, ipz, nx, ny, nz, ia, ka_S[2], kd_S[2], ks_S[2], ns_S[2], krg_S[2], ktg_S[2], 1); break; case 4 : /* The current ray intercepts plane #1. */ nx = p[0][0]; ny = p[0][1]; nz = p[0][2]; shadow_flag = 0; shadow_flag = Check_Shadow(ipx, ipy, ipz,obj_num); grain = wood_grain(ipx,ipy,ipz); if(grain < 3) rgb_color = Compute_Color(shadow_flag, ipx, ipy, ipz, nx, ny, nz, ia, tka4 ,tkd4 , ks_P[0], ns_P[0] ,krg_P[0], ktg_P[0], 1); else rgb_color = Compute_Color(shadow_flag, ipx, ipy, ipz, nx, ny, nz, ia, ka_P[0], kd_P[0], ks_P[0], ns_P[0], krg_P[0], ktg_P[0], 1); break; case 5 : /* The current ray intercepts plane #2. */ nx = p[1][0]; ny = p[1][1]; nz = p[1][2]; shadow_flag = 0; shadow_flag = Check_Shadow(ipx, ipy, ipz,obj_num); if (ipz < 2.0 || (ipz>=4.0 && ipz<6.0)) { if ((ipy>=2.0 && ipy<4.0) || (ipy>=6.0)) texture = 1; else texture = 0; } else { if ((ipy<2.0) || (ipy>=4.0 && ipy<6.0)) texture = 1; else texture = 0; } if (texture == 1) rgb_color = Compute_Color(shadow_flag, ipx, ipy, ipz, nx, ny, nz, ia, tka5, tkd5, ks_P[1], ns_P[1], krg_P[1], ktg_P[1], 1); else rgb_color = Compute_Color(shadow_flag, ipx, ipy, ipz, nx, ny, nz, ia, ka_P[1], kd_P[1], ks_P[1], ns_P[1], krg_P[1], ktg_P[1], 1); break; case 6 : /* The current ray intercepts plane #3. */ nx = p[2][0]; ny = p[2][1]; nz = p[2][2]; shadow_flag = 0; shadow_flag = Check_Shadow(ipx, ipy, ipz,obj_num); if (ipx < 2.0 || (ipx >= 4.0 && ipx < 6.0)) { if ((ipz >= 2.0 && ipz < 4.0) || (ipz >=6.0)) texture = 1; else texture = 0; } else { if ((ipz<2.0) || (ipz>=4.0 && ipz<6.0)) texture = 1; else texture = 0; } t = turbulence(ipx,ipy,ipz,0.5); value = ipx+t; x = sqrt( value + 1.0)*0.7071; get_marble_color( (float)sin(value*3.1415926), &rgb_color); get_marble_color( (float)sin(value*3.1415926), &rgb_color); get_marble_color( (float)sin(value*3.1415926), &rgb_color); /*if (texture == 1) rgb_color = Compute_Color(shadow_flag, ipx, ipy, ipz, nx, ny, nz, ia, tka6, tkd6, ks_P[2], ns_P[2], krg_P[2], ktg_P[2], 1); else rgb_color = Compute_Color(shadow_flag, ipx, ipy, ipz, nx, ny, nz, ia, ka_P[2], kd_P[2], ks_P[2], ns_P[2], krg_P[2], ktg_P[2], 1); */ break; default: break; } if(depth < MAX_DEPTH) { if(obj_num > 0 && obj_num !=4 && nx >= 0 && ny >= 0 && nz >= 0) { compute_reflected_ray(dx, dy, dz, nx, ny, nz, &rlx, &rly, &rlz); points newFrom; newFrom.x = ipx; newFrom.y = ipy; newFrom.z = ipz; rgb rcolor = Ray_Trace(obj_num,rlx,rly,rlz,newFrom,depth+1); switch(obj_num) { case 1: rgb_color.r += krg_S[0]*rcolor.r; rgb_color.g += krg_S[0]*rcolor.g; rgb_color.b += krg_S[0]*rcolor.b; break; case 2: rgb_color.r += krg_S[1]*rcolor.r; rgb_color.g += krg_S[1]*rcolor.g; rgb_color.b += krg_S[1]*rcolor.b; break; case 3: rgb_color.r += krg_S[2]*rcolor.r; rgb_color.g += krg_S[2]*rcolor.g; rgb_color.b += krg_S[2]*rcolor.b; break; case 4: rgb_color.r += krg_P[0]*rcolor.r; rgb_color.g += krg_P[0]*rcolor.g; rgb_color.b += krg_P[0]*rcolor.b; break; case 5: rgb_color.r += krg_P[1]*rcolor.r; rgb_color.g += krg_P[1]*rcolor.g; rgb_color.b += krg_P[1]*rcolor.b; break; case 6: rgb_color.r += krg_P[2]*rcolor.r; rgb_color.g += krg_P[2]*rcolor.g; rgb_color.b += krg_P[2]*rcolor.b; break; default: break; } } float n1 = 1.0003; /*refractive index air*/ /*nt - refractive index material*/ float thetha = 1000; if(obj_num > 0 && obj_num < 7) { if(obj_num < 4) { thetha = asin((float)n1/(float)nt_S[obj_num-1]); if(thetha < 41.2) /* Check if object is semi transparent */ { points newFrom; newFrom.x = ipx; newFrom.y = ipy; newFrom.z = ipz; compute_refracted_ray(dx,dy,dz,nx,ny,nz,&rfx,&rfy,&rfz,nt_S[obj_num-1]); /*Compute refracted ray*/ rgb rcolor = Ray_Trace(obj_num,rfx,rfy,rfz,newFrom,depth+1); rgb_color.r += ktg_P[0]*rcolor.r; rgb_color.g += ktg_P[0]*rcolor.g; rgb_color.b += ktg_P[0]*rcolor.b; } } else { int i = obj_num-NUM_SPHERES-1; thetha = asin((float)n1/(float)nt_P[i]); if(thetha < 41.2) /* Check if object is semi transparent */ { points newFrom; newFrom.x = ipx; newFrom.y = ipy; newFrom.z = ipz; compute_refracted_ray(dx,dy,dz,nx,ny,nz,&rfx,&rfy,&rfz,nt_P[i]); /*Compute refracted ray*/ rgb rcolor = Ray_Trace(obj_num,rfx,rfy,rfz,newFrom,depth+1); rgb_color.r += ktg_P[0]*rcolor.r; rgb_color.g += ktg_P[0]*rcolor.g; rgb_color.b += ktg_P[0]*rcolor.b; } } } } return rgb_color; }