void render(void) { int x, y; vec3 fcolor, origin, dir; for (y = 0; y < HEIGHT; y++) { for (x = 0; x < WIDTH; x++) { origin = viewpoint + (vp_u * ((1.0 / WIDTH)*(x + .5) - .5)) + (vp_v * ((1.0 / HEIGHT)*(y + .5) - .5)) + (vp_w * vp_d); dir = normalize(origin - viewpoint); fcolor = traceray(origin, dir, 2); fb[(HEIGHT - y) * WIDTH + x][0] = fcolor.x * 255; fb[(HEIGHT - y) * WIDTH + x][1] = fcolor.y * 255; fb[(HEIGHT - y) * WIDTH + x][2] = fcolor.z * 255; } } }
vec3 traceray(const vec3 &origin, const vec3 &dir, int depth) { if (depth == 0) return vec3(); vec3 fcolor = bgcolor; int obj; float t; if ((obj = intersect(origin, dir, t)) != -1) { fcolor = ambient.mult(myobj_mat[obj].color); int light_size = sizeof(light_pos) / sizeof(vec3); int obj_size = sizeof(mysph_pos) / sizeof(vec3); vec3 pos = origin + (dir * t); for (int i = 0; i < light_size; i++) { vec3 lightray = normalize(light_pos[i] - pos); float temp; if (intersect(pos, lightray, temp) == -1) { if (myobj_mat[obj].kd > 0) { vec3 nor = normalize(pos - mysph_pos[obj]); fcolor = fcolor + ((light_color[i] * (nor.dot(lightray)) * myobj_mat[obj].kd).mult(myobj_mat[obj].color)); } if (myobj_mat[obj].ks > 0) { vec3 refDir = mirrorDir(pos, lightray, obj) * (-1); fcolor = fcolor + ((light_color[i] * (dir.dot(refDir)) * myobj_mat[obj].ks).mult(myobj_mat[obj].color)); } } if(myobj_mat[obj].kr > 0) fcolor = fcolor + ((traceray(pos, mirrorDir(pos, dir, obj), depth - 1) * myobj_mat[obj].kr).mult(myobj_mat[obj].color)); } } // note that, before returning the color, the computed color may be rounded to [0.0, 1.0]. fcolor = clamp(fcolor); return fcolor; }
void raytrace(int im, inputPars *par, struct grid *g, molData *m, image *img){ int *counta, *countb,nlinetot,aa; int ichan,px,iline,tmptrans,i,threadI,nRaysDone; double size,minfreq,absDeltaFreq; double cutoff; const gsl_rng_type *ranNumGenType = gsl_rng_ranlxs2; gsl_rng *ran = gsl_rng_alloc(ranNumGenType); /* Random number generator */ #ifdef TEST gsl_rng_set(ran,178490); #else gsl_rng_set(ran,time(0)); #endif gsl_rng **threadRans; threadRans = malloc(sizeof(gsl_rng *)*par->nThreads); for (i=0;i<par->nThreads;i++){ threadRans[i] = gsl_rng_alloc(ranNumGenType); gsl_rng_set(threadRans[i],(int)gsl_rng_uniform(ran)*1e6); } size=img[im].distance*img[im].imgres; /* Determine whether there are blended lines or not */ lineCount(par->nSpecies, m, &counta, &countb, &nlinetot); if(img[im].doline==0) nlinetot=1; /* Fix the image parameters */ if(img[im].freq < 0) img[im].freq=m[0].freq[img[im].trans]; if(img[im].nchan == 0 && img[im].bandwidth>0){ img[im].nchan=(int) (img[im].bandwidth/(img[im].velres/CLIGHT*img[im].freq)); } else if (img[im].velres<0 && img[im].bandwidth>0){ img[im].velres = img[im].bandwidth*CLIGHT/img[im].freq/img[im].nchan; } else img[im].bandwidth = img[im].nchan*img[im].velres/CLIGHT * img[im].freq; if(img[im].trans<0){ iline=0; minfreq=fabs(img[im].freq-m[0].freq[iline]); tmptrans=iline; for(iline=1;iline<m[0].nline;iline++){ absDeltaFreq=fabs(img[im].freq-m[0].freq[iline]); if(absDeltaFreq<minfreq){ minfreq=absDeltaFreq; tmptrans=iline; } } } else tmptrans=img[im].trans; cutoff = par->minScale*1.0e-7; for(px=0;px<(img[im].pxls*img[im].pxls);px++){ for(ichan=0;ichan<img[im].nchan;ichan++){ img[im].pixel[px].intense[ichan]=0.0; img[im].pixel[px].tau[ichan]=0.0; } } nRaysDone=0; omp_set_dynamic(0); #pragma omp parallel private(px,aa,threadI) num_threads(par->nThreads) { threadI = omp_get_thread_num(); /* Declaration of thread-private pointers */ rayData ray; ray.intensity=malloc(sizeof(double) * img[im].nchan); ray.tau=malloc(sizeof(double) * img[im].nchan); #pragma omp for /* Main loop through pixel grid */ for(px=0;px<(img[im].pxls*img[im].pxls);px++){ #pragma omp atomic ++nRaysDone; for(aa=0;aa<par->antialias;aa++){ ray.x = size*(gsl_rng_uniform(threadRans[threadI])+px%img[im].pxls)-size*img[im].pxls/2.; ray.y = size*(gsl_rng_uniform(threadRans[threadI])+px/img[im].pxls)-size*img[im].pxls/2.; traceray(ray, tmptrans, im, par, g, m, img, nlinetot, counta, countb, cutoff); #pragma omp critical { for(ichan=0;ichan<img[im].nchan;ichan++){ img[im].pixel[px].intense[ichan] += ray.intensity[ichan]/(double) par->antialias; img[im].pixel[px].tau[ichan] += ray.tau[ichan]/(double) par->antialias; } } } } if (threadI == 0){ // i.e., is master thread if(!silent) progressbar((double)(nRaysDone)/(double)(img[im].pxls*img[im].pxls-1), 13); } free(ray.tau); free(ray.intensity); } // end of parallel block. img[im].trans=tmptrans; free(counta); free(countb); for (i=0;i<par->nThreads;i++){ gsl_rng_free(threadRans[i]); } free(threadRans); gsl_rng_free(ran); }