/* Not really the best or most accurate way, but it works... */ double AutoExposure(scene *myScene) { #define ACCUMULATION_SIZE 256 double exposure = -1.0f; double accumulationfactor = (double)max(myScene->width, myScene->height); double projectionDistance = 0.0f; if ((myScene->persp.type == CONIC) && myScene->persp.FOV > 0.0f && myScene->persp.FOV < 189.0f) { projectionDistance = 0.5f * myScene->width / tanf ((double)(PIOVER180) * 0.5f * myScene->persp.FOV); } accumulationfactor = accumulationfactor / ACCUMULATION_SIZE; colour mediumPoint = {0.0f, 0.0f, 0.0f}; const double mediumPointWeight = 1.0f / (ACCUMULATION_SIZE*ACCUMULATION_SIZE); int x,y; for (y = 0; y < ACCUMULATION_SIZE; ++y) { for (x = 0 ; x < ACCUMULATION_SIZE; ++x) { if (myScene->persp.type == ORTHOGONAL || projectionDistance == 0.0f) { ray viewRay = { {(double)x*accumulationfactor, (double)y * accumulationfactor, -10000.0f}, { 0.0f, 0.0f, 1.0f}}; colour currentColor = raytrace(&viewRay, myScene); colour tmp = colourMul(¤tColor, ¤tColor); tmp = colourCoefMul(mediumPointWeight, &tmp); mediumPoint = colourAdd(&mediumPoint,&tmp); } else { vector dir = {((double)(x)*accumulationfactor - 0.5f * myScene->width) / projectionDistance, ((double)(y)*accumulationfactor - 0.5f * myScene->height) / projectionDistance, 1.0f }; double norm = vectorDot(&dir,&dir); if (norm == 0.0f) break; dir = vectorScale(invsqrtf(norm), &dir); ray viewRay = { {0.5f * myScene->width, 0.5f * myScene->height, 0.0f}, {dir.x, dir.y, dir.z} }; colour currentColor = raytrace(&viewRay, myScene); colour tmp = colourMul(¤tColor, ¤tColor); tmp = colourCoefMul(mediumPointWeight, &tmp); mediumPoint = colourAdd(&mediumPoint,&tmp); } } } double mediumLuminance = sqrtf(0.2126f * mediumPoint.red + 0.715160f * mediumPoint.green + 0.072169f * mediumPoint.blue); if (mediumLuminance > 0.001f) { // put the medium luminance to an intermediate gray value exposure = logf(0.6f) / mediumLuminance; } return exposure; }
void display() { if(lastTime == 0) { lastTime = glutGet(GLUT_ELAPSED_TIME); } now = glutGet(GLUT_ELAPSED_TIME); delta_t = (now - lastTime) / 1000.0f; //lastTime = now; //1 / delta_t here means the frame rate. fpsTracker.timestamp(); //update camera information per frame updateCamera(); checkClear(); if(moved) lastTime = now; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //do raytrace raytrace(); //render result as texture displayTexture(); //draw tool bar TwDraw(); drawFps(); glutSwapBuffers(); glutPostRedisplay(); }
void RayTracer::raytrace(SetPixelFunction* putPixel, Resolution resolution) { if (resolution == 0) { raytrace(putPixel); } else { //Width and height of the image int width = _camera._w2D; int height = _camera._h2D; //Iterate over all the pixels of the screen/image for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { Color c = Color(0, 0, 0); for (double dx = -0.45; dx <= 0.45; dx += 0.9 / resolution) { for (double dy = -0.45; dy <= 0.45; dy += 0.9 / resolution) { //Create the ray from the observer point, passing through the pixel Ray r = Ray(_camera._observer, _camera.getPixel(x + dx, y + dy) - _camera._observer); c += calculateColor(r, NB_OF_INTERATIONS); } } //Set the pixel accoring to the calculated Color/Light Color newC = c / ((resolution + 1) * (resolution + 1)); newC.clamp(); putPixel->setPixel(x, y, newC); } } } }
ImageRef Scene::raytrace(CameraRef camera, RenderOption option) { Rect rect(0.0f, 0.0f, camera->width(), camera->height()); ImageRef image = new Image(rect.size.width, rect.size.height); raytrace(camera, Rect(0.0f, 0.0f, camera->width(), camera->height()), option, image); return image; }
/*Trace line from centers of blocks.*/ void raytrace_3i(V3i a_i, V3i b_i) { V3f a = v3i_to_v3f(a_i); V3f b = v3i_to_v3f(b_i); a.z = (a.z + 1) / 2.0f; b.z = (b.z + 1) / 2.0f; raytrace(a, b); }
Color Refl::shade(const Ray& ray, const IntersectionInfo& info) { Vector n = faceforward(ray.dir, info.normal); if (glossiness == 1) { Ray newRay = ray; newRay.start = info.ip + n * 0.000001; newRay.dir = reflect(ray.dir, n); newRay.depth++; return raytrace(newRay) * multiplier; } else { Random& rnd = getRandomGen(); Color result(0, 0, 0); int count = numSamples; if (ray.depth > 0) count = 2; for (int i = 0; i < count; i++) { Vector a, b; orthonormalSystem(n, a, b); double x, y, scaling; rnd.unitDiscSample(x, y); // scaling = tan((1 - glossiness) * PI/2); x *= scaling; y *= scaling; Vector modifiedNormal = n + a * x + b * y; Ray newRay = ray; newRay.start = info.ip + n * 0.000001; newRay.dir = reflect(ray.dir, modifiedNormal); newRay.depth++; result += raytrace(newRay) * multiplier; } return result / count; } }
void render(t_env *e) { key_up_down(e); key_left_right(e); e->img = mlx_new_image(e->mlx, WIDTH, HEIGHT); e->imgpx = mlx_get_data_addr(e->img, &(e->bpp), &(e->size_line), &(e->endian)); raytrace(e); mlx_put_image_to_window(e->mlx, e->win, e->img, 0, 0); usleep(50); mlx_destroy_image(e->mlx, e->img); }
static int luaScene_raytrace(lua_State* L){ auto scene = reinterpret_cast<Scene*>(lua_touserdata(L, lua_upvalueindex(1))); int x = lua_tointeger(L, 1); int y = lua_tointeger(L, 2); int pid; if(scene->raytrace(x, y, pid)){ lua_pushinteger(L, pid); } else{ lua_pushnil(L); } return 1; }
void laserCallback(const sensor_msgs::LaserScan::ConstPtr& msg) { sensor_msgs::LaserScan newScan = *msg; double xx, yy, yaw; getTransform("/map", msg->header.frame_id, msg->header.stamp, ros::Duration(1.0), xx, yy, yaw); for (unsigned int i = 0; i < msg->ranges.size(); i++) { double theta = yaw + msg->angle_min + (int)i * msg->angle_increment; newScan.ranges[i] = std::min((double)msg->ranges[i], raytrace(xx, yy, theta)); } newScan.range_max = rosParams.laserRange; laserPub.publish(newScan); }
image_t render(sphere_t *spheres, int nspheres, unsigned width, unsigned height, int depth) { struct vector raydir; /* Ray direction. */ unsigned x, y; float xx, yy; image_t img; float invwidth; /* width^-1 */ float invheight; /* height^-1 */ float angle; float fov; struct vector pixel; float aspectratio; /* Image's aspect ratio. */ max_depth = depth; img = image_create(width, height); invwidth = 1.0 / width; invheight = 1.0 /height; fov = 30; aspectratio = width / ((float)height); angle = tan(PI*0.5*fov/180.0); for (y = 0; y < height; ++y) { #pragma omp parallel for \ default(shared) private(x,xx,yy,raydir,pixel) schedule(dynamic) for (x = 0; x < width; x++) { xx = (2 * ((x + 0.5) * invwidth) - 1) * angle * aspectratio; yy = (1 - 2 * ((y + 0.5) * invheight)) * angle; raydir = vector_normalize(VECTOR(xx, yy, -1)); pixel = raytrace(VECTOR(0, 0, 0), raydir, spheres, nspheres, 0); IMAGE(img, x, y).r = (unsigned char) (min(1.0, pixel.x)*255); IMAGE(img, x, y).g = (unsigned char) (min(1.0, pixel.y)*255); IMAGE(img, x, y).b = (unsigned char) (min(1.0, pixel.z)*255); } } return (img); }
Color Refr::shade(const Ray& ray, const IntersectionInfo& info) { // ior = eta2 / eta1 Vector refr; if (dot(ray.dir, info.normal) < 0) { // entering the geometry refr = refract(ray.dir, info.normal, 1 / ior); } else { // leaving the geometry refr = refract(ray.dir, -info.normal, ior); } if (refr.lengthSqr() == 0) return Color(0, 0, 0); Ray newRay = ray; newRay.start = info.ip - faceforward(ray.dir, info.normal) * 0.000001; newRay.dir = refr; newRay.depth++; return raytrace(newRay) * multiplier; }
void MyScene::render(int type, int width, int height, unsigned char* pixels) { if (!isLoaded) { progress = 1.0; return; } bDoRender = true; // Add your rendering code here. // Keep track of your progress as a value between 0 and 1 // so the progress bar can update as the rendering progresses progress = 0.0; switch (type) { case RenderingUI::RENDER_SCANLINE: scanline(width, height, pixels); break; case RenderingUI::RENDER_RAY_TRACING: raytrace(width, height, pixels); break; case RenderingUI::RENDER_PATH_TRACING: break; default: break; } progress = 1.0; }
int main(int argc, char **argv) { t_env env; if (argc != 2) { ft_printf("Please include a scene file\n"); return (0); } get_input(&env, argv[1]); env.mlx = mlx_init(); env.win = mlx_new_window(env.mlx, WIN_X, WIN_Y, "rtv1"); env.img.img = mlx_new_image(env.mlx, WIN_X, WIN_Y); env.img.data = mlx_get_data_addr(env.img.img, &env.img.bpp, &env.img.s, &env.img.e); raytrace(&env); mlx_expose_hook(env.win, expose, &env); mlx_key_hook(env.win, key_hook, &env); mlx_hook(env.win, 17, 0L, &close_window, &env); mlx_loop(env.mlx); return (0); }
void Whitted::integrate() const { Vector origin, direction ; float d ; Hit hit ; cimg_library::CImg<float> buffer(_camera->width(), _camera->height(), 1, 3, 0.0f) ; for(unsigned int i=0; i<_camera->width(); ++i) for(unsigned int j=0; j<_camera->height(); ++j) { Vector spectrum(0.0f, 0.0f, 0.0f) ; _camera->sample(i+0.5f, j+0.5f, origin, direction) ; spectrum = raytrace(origin, direction, 0) ; buffer(i, j, 0, 0) = 255.0f * spectrum[0] ; buffer(i, j, 0, 1) = 255.0f * spectrum[1] ; buffer(i, j, 0, 2) = 255.0f * spectrum[2] ; } buffer.save(filename().c_str()) ; }
//Rendering Scene from Cam void Renderer::render(std::string const& cam_name){ Camera cam = scene_.cameras_[cam_name]; float width = (float)width_; float half_height = ((float)height_) / 2; float half_width = ((float)width_) / 2; for(unsigned y = 0; y < height_; ++y){ for (unsigned x = 0; x < width_; ++x){ Pixel p(x,y); int maxRecursion = 5; Color color{}; //Antialiasing for(float i = 0.0f; i < 1.0f; i += 0.5f){ for(float j = 0.0f; j < 1.0f; j += 0.5f){ float y1 = (float)y + i; float x1 = (float)x + j; x1 = (x1 - half_width)/width; y1 = (y1 - half_height)/width; Ray camRay = cam.createRay(x1, y1); Color subcolor = raytrace(camRay, maxRecursion); color += 0.25f * subcolor; } } p.color = color; write(p); } } ppm_.save(filename_); }
void Renderer::render() { if(scene_.sizeShape > 0) { for (unsigned y = 0; y < height_; ++y) { for (unsigned x = 0; x < width_; ++x) { std::vector<Ray> rays; rays.push_back({scene_.cam->calculateRay(x, y)}); rays.push_back({scene_.cam->calculateRay(x + 0.5, y)}); rays.push_back({scene_.cam->calculateRay(x, y + 0.5)}); rays.push_back({scene_.cam->calculateRay(x + 0.5, y + 0.5)}); Color colorAA(0.0f,0.0f,0.0f); for (auto ronny : rays) { colorAA += raytrace(ronny, 1); } Pixel p(x,y); p.color = 1.0f / rays.size() * colorAA; //std::cout<<"Pixel ["<<x<<","<<y<<"]"<<" RGB ["<<p.color.r<<","<<p.color.g<<","<<p.color.b<<"]"<<std::endl; write(p); } }//hier ist der colorbuffer geladen //antialias(); } else { std::cout<<"Es wurden keine Objekte geladen."<<std::endl; } ppm_.save(filename_); }
s_liret iter_light(s_light light, s_liret liret, s_res res) { s_liret ret; vec3 li; vec3 pos; float occlu; ret = liret; li = light.pos - liret.cam.pos; liret.cam.ray = normalize(li); li.z = dot(li, li); li.y = raytrace(liret.cam).dst; li.x = sqrt(li.z); if (li.y < li.x && li.y != -1) return (ret); pos = light.pos - liret.cam.pos; li.z = min(1, 1 / li.x * 100); ret.diffuse += (occlu = max(dot(res.normal, liret.cam.ray), 0)) * light.color * li.z; ret.specular += pow(max(dot(reflect(res.cam.ray, res.normal), normalize(pos)), 0), length(pos) * 20 * res.mat.smoothness) * light.color * li.z * res.mat.metallic * step(0, occlu); return (ret); }
int main() { std::string separator = "\n----------------------------------------------\n"; std::string separatorStar = "\n**********************************************\n"; std::cout << separator << "RTIS - Ray Tracer for \"Imatge Sintetica\"" << separator << std::endl; // Create an empty film Film *film; film = new Film(720, 576); // Declare the shader Vector3D bgColor(0.0, 0.0, 0.0); // Background color (for rays which do not intersect anything) Vector3D intersectionColor(1,0,0); Shader *shader = new IntersectionShader (intersectionColor, bgColor); Shader *depthShader = new DepthShader(Vector3D(0.4, 1, 0.4), 8, bgColor); Shader *directShader = new DirectShader(Vector3D(0.4, 1, 0.4), 8, bgColor); // Declare pointers to all the variables which describe the scene Camera *cam; std::vector<Shape*> *objectsList; std::vector<PointLightSource> *lightSourceList = new std::vector<PointLightSource>; // Build the scene buildSceneSphere(cam, film, objectsList, lightSourceList); // Launch some rays! raytrace(cam, directShader, film, objectsList, lightSourceList); // Save the final result to file std::cout << "\n\nSaving the result to file output.bmp\n" << std::endl; film->save(); std::cout << "\n\n" << std::endl; return 0; }
//Calc Color depending on Ray Color Renderer::raytrace(Ray const& ray, int maxRecursion){ maxRecursion --; Color color{}; Hit camHit = findHit(scene_.shapes_, ray); if(camHit.hit_ == false){ color = scene_.ambient_; } else { //auto it = camHits.begin(); //Hit firstHit = it->second; Material mat = scene_.materials_[camHit.matname_]; color.r += mat.ka_.r * scene_.ambient_.r; color.g += mat.ka_.g * scene_.ambient_.g; color.b += mat.ka_.b * scene_.ambient_.b; for(auto it = scene_.lights_.begin(); it != scene_.lights_.end(); ++ it){ glm::vec3 lightVec = (*it).position_ - camHit.intersec_; lightVec = glm::normalize(lightVec); Ray lightRay; if(camHit.type_ == "sphere"){ lightRay = {camHit.intersec_+ 0.01f * lightVec, lightVec}; } else if(camHit.type_ == "box"){ lightRay = {(camHit.intersec_ + 0.01f * lightVec), lightVec}; } Hit lightHits = findHit(scene_.shapes_, lightRay); glm::vec3 spec_light = glm::reflect(lightVec, camHit.normvec_); float r_v_ = pow(glm::dot(glm::normalize(ray.direction), glm::normalize(spec_light)), mat.m_); //Spiegelende Reflexion //Shadow if(!lightHits.hit_){ color.r += mat.kd_.r * (*it).ld_.r * (glm::dot(camHit.normvec_, lightRay.direction) + mat.ks_.r * r_v_); color.g += mat.kd_.g * (*it).ld_.g * (glm::dot(camHit.normvec_, lightRay.direction) + mat.ks_.g * r_v_); color.b += mat.kd_.b * (*it).ld_.b * (glm::dot(camHit.normvec_, lightRay.direction) + mat.ks_.b * r_v_); } } if(maxRecursion > 0){ if(mat.s_ > 0.0f){ glm::vec3 object_reflect = glm::reflect(ray.direction, camHit.normvec_); glm::normalize(object_reflect); Ray reflectionRay{camHit.intersec_+ 0.01f * object_reflect, object_reflect}; Color reflectedCol = raytrace(reflectionRay, maxRecursion); //ALTERNATIVE REFLECTION MODEL //color = color * (1.0f - mat.s_); color += mat.s_ * reflectedCol; } //REFRACTION FAILED /* if(mat.t_ > 0.0f){ //glm::vec3 refraction = glm::refract(ray.direction, camHit.normvec_, mat.eta_); //Ray refractionRay{camHit.intersec_ + 0.01f * refraction, refraction}; Ray new_ray{camHit.intersec_ + 0.001f * ray.direction, ray.direction}; Color refractedCol = raytrace(new_ray, maxRecursion); color = ((1.0f - mat.t_) * color) + (mat.t_ * refractedCol); }*/ } } return color; }
// MAIN int main(int argc, char ** argv) { int scene_id = 0; bool use_octree = false; char basename[256] = ""; if (argc > 1) scene_id = atoi(argv[1]); if (argc > 2) strcpy(basename, argv[2]); // scene_id 0, 1, 2, 3 is for tp 1 tests; switch (scene_id) { case 0: fill_red(output_image); break; case 1: fill(output_image, vector_init(0.7, 0.3, 0.1)); fill_rect(output_image, vector_init(0.2, 0.6, 0.7), vector_init(WIDTH / 4, HEIGHT / 5, 0), vector_init(WIDTH / 3, HEIGHT / 4, 0)); break; case 2: horizontal_gradient(output_image, vector_init(0, 0, 1), vector_init(1, 1, 1)); break; case 3: horizontal_gradient(output_image, vector_init(0, 0, 1), vector_init(1, 1, 1)); fill_circle(output_image, WIDTH / 20, vector_init(4 * WIDTH / 5, 4 * HEIGHT / 5, 0), vector_init(1, 1, 0)); fill_rect(output_image, vector_init(0.1, 0.8, 0.4), vector_init(0, 0, 0), vector_init(WIDTH, HEIGHT / 4, 0)); break; case 4: horizontal_gradient(output_image, vector_init(0.5, 0.8, 1), vector_init(1, 1, 1)); fill_circle(output_image, WIDTH / 20, vector_init(4 * WIDTH / 5, 4 * HEIGHT / 5, 0), vector_init(1, 1, 0)); fill_circle(output_image, WIDTH / 21, vector_init(3 * WIDTH / 5, 3 * HEIGHT / 5, 0), vector_init(1, 0.3, 0.1)); fill_rect(output_image, vector_init(0.85, 0.85, 0.3), vector_init(0, 0, 0), vector_init(WIDTH, HEIGHT / 4, 0)); break; default: setup_scene(scene_id - 5); raytrace(); break; } #ifdef USE_FREEIMAGE FreeImage_Initialise(); FIBITMAP *bitmap = FreeImage_Allocate(WIDTH, HEIGHT, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK); if (bitmap) { // bitmap successfully created! // Calculate the number of bytes per pixel (3 for 24-bit or 4 for 32-bit) color *ptr = output_image; int bytespp = FreeImage_GetLine(bitmap) / FreeImage_GetWidth(bitmap); for(unsigned y = 0; y < FreeImage_GetHeight(bitmap); y++) { BYTE *bits = FreeImage_GetScanLine(bitmap, y); for(unsigned x = 0; x < FreeImage_GetWidth(bitmap); x++) { // Set pixel color to green with a transparency of 128 *ptr = vector_clamp(*ptr, 0.f, 1.f); bits[FI_RGBA_RED] = ptr->x*255; bits[FI_RGBA_GREEN] = ptr->y*255; bits[FI_RGBA_BLUE] = ptr->z*255; bits[FI_RGBA_ALPHA] = 255; // jump to next pixel bits += bytespp; ptr++; } } // FreeImage_Save(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, const char *filename, int flags FI_DEFAULT(0)); char filename[256]; strcpy(filename, basename); strcat(filename, ".png"); if (FreeImage_Save(FIF_PNG, bitmap, filename, 0)) { // bitmap successfully saved! } FreeImage_Unload(bitmap); } FreeImage_DeInitialise(); #endif // le code ci dessous crée et sauvegarde une image sous le nom output.png dans le repertoire d'execution { FILE *fp = NULL; char filename[256]; strcpy(filename, basename); strcat(filename, ".ppm"); fp = fopen(filename, "w"); if (fp) { // création réussi fprintf(fp, "P3\n"); fprintf(fp, "%d %d\n255\n", WIDTH, HEIGHT); // La c'est pour faire la boucle for (unsigned y = 0; y < HEIGHT; y++) { color *ptr = &(output_image[(HEIGHT - y - 1) * WIDTH]); for (unsigned x = 0; x < WIDTH; x++) { *ptr = vector_clamp(*ptr, 0.f, 1.f); unsigned char r = ptr->x * 255; unsigned char g = ptr->y * 255; unsigned char b = ptr->z * 255; ptr++; fprintf(fp, "%d %d %d ", r, g, b); } fprintf(fp, "\n"); } fclose(fp); } } return 0; }
/** * raytrace with antialiasing * */ void RayTracer::raytrace(Image& img, Resolution resolution) { ImgSetPixel isp(img); raytrace(&isp, resolution); }
/*! This function advances the system in momentum space, i.e. it does apply * the 'kick' operation after the forces have been computed. Additionally, it * assigns new timesteps to particles. At start-up, a half-timestep is * carried out, as well as at the end of the simulation. In between, the * half-step kick that ends the previous timestep and the half-step kick for * the new timestep are combined into one operation. */ void advance_and_find_timesteps(void) { int i, j, no; long long int ti_step, ti_min, tend, tstart; double dt_entr, dt_entr2, dt_gravkick, dt_hydrokick, dt_gravkick2, dt_hydrokick2, t0, t1; double t2, t3; double aphys; double gam_fac; #if !defined(CHEMCOOL) && !defined(POLYTROPE) double minentropy; #endif FLOAT dv[3]; #ifdef FLEXSTEPS long long int ti_grp; #endif #if defined(PSEUDOSYMMETRIC) && !defined(FLEXSTEPS) double apred, prob; long long int ti_step2; #endif #ifdef PMGRID double dt_gravkickA, dt_gravkickB; #endif #ifdef MAKEGLASS double disp, dispmax, globmax, dmean, fac, disp2sum, globdisp2sum; #endif #ifdef CHEMCOOL double old_entropy, dt_entr_cc; #endif t0 = second(); if(All.ComovingIntegrationOn) { fac1 = 1 / (All.Time * All.Time); #ifndef CHEMCOOL fac2 = 1 / pow(All.Time, 3 * GAMMA - 2); fac3 = pow(All.Time, 3 * (1 - GAMMA) / 2.0); #endif hubble_a = All.Omega0 / (All.Time * All.Time * All.Time) + (1 - All.Omega0 - All.OmegaLambda) / (All.Time * All.Time) + All.OmegaLambda; hubble_a = All.Hubble * sqrt(hubble_a); a3inv = 1 / (All.Time * All.Time * All.Time); atime = All.Time; } else fac1 = fac2 = fac3 = hubble_a = a3inv = atime = 1; #ifdef NOPMSTEPADJUSTMENT dt_displacement = All.MaxSizeTimestep; #else if(Flag_FullStep || dt_displacement == 0) find_dt_displacement_constraint(hubble_a * atime * atime); #endif #ifdef PMGRID if(All.ComovingIntegrationOn) dt_gravkickB = get_gravkick_factor(All.PM_Ti_begstep, All.Ti_Current) - get_gravkick_factor(All.PM_Ti_begstep, (All.PM_Ti_begstep + All.PM_Ti_endstep) / 2); else dt_gravkickB = (All.Ti_Current - (All.PM_Ti_begstep + All.PM_Ti_endstep) / 2) * All.Timebase_interval; if(All.PM_Ti_endstep == All.Ti_Current) /* need to do long-range kick */ { /* make sure that we reconstruct the domain/tree next time because we don't kick the tree nodes in this case */ All.NumForcesSinceLastDomainDecomp = 1 + All.TotNumPart * All.TreeDomainUpdateFrequency; } #endif #ifdef MAKEGLASS for(i = 0, dispmax = 0, disp2sum = 0; i < NumPart; i++) { if(P[i].Type == 0 && P[i].ID < 0) /*SINK*/ continue; for(j = 0; j < 3; j++) { P[i].GravPM[j] *= -1; P[i].GravAccel[j] *= -1; P[i].GravAccel[j] += P[i].GravPM[j]; P[i].GravPM[j] = 0; } disp = sqrt(P[i].GravAccel[0] * P[i].GravAccel[0] + P[i].GravAccel[1] * P[i].GravAccel[1] + P[i].GravAccel[2] * P[i].GravAccel[2]); disp *= 2.0 / (3 * All.Hubble * All.Hubble); disp2sum += disp * disp; if(disp > dispmax) dispmax = disp; } MPI_Allreduce(&dispmax, &globmax, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); MPI_Allreduce(&disp2sum, &globdisp2sum, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); dmean = pow(P[0].Mass / (All.Omega0 * 3 * All.Hubble * All.Hubble / (8 * M_PI * All.G)), 1.0 / 3); if(globmax > dmean) fac = dmean / globmax; else fac = 1.0; if(ThisTask == 0) { printf("\nglass-making: dmean= %g global disp-maximum= %g rms= %g\n\n", dmean, globmax, sqrt(globdisp2sum / All.TotNumPart)); fflush(stdout); } for(i = 0, dispmax = 0; i < NumPart; i++) { if(P[i].Type == 0 && P[i].ID < 0) /*SINK*/ continue; for(j = 0; j < 3; j++) { P[i].Vel[j] = 0; P[i].Pos[j] += fac * P[i].GravAccel[j] * 2.0 / (3 * All.Hubble * All.Hubble); P[i].GravAccel[j] = 0; } } #endif /* Update column densities before doing chemistry update below. * NB. We only need to do this when using the raytracing approx. */ #if defined RAYTRACE && defined CHEMCOOL t2 = second(); if (All.PhotochemApprox == 2) { raytrace(); } t3 = second(); All.CPU_Raytrace += timediff(t2, t3); #endif /* RAYTRACE && CHEMCOOL */ /* Now assign new timesteps and kick */ if((All.Ti_Current % (4 * All.PresentMinStep)) == 0) if(All.PresentMinStep < TIMEBASE) All.PresentMinStep *= 2; for(i = 0; i < NumPart; i++) { if(P[i].ID < 0) /*SINK*/ continue; //if(P[i].Type == 0 && SphP[i].sink > 0.5) /*other SINK*/ // continue; if(P[i].Ti_endstep == All.Ti_Current) { ti_step = get_timestep(i, &aphys, 0); /* make it a power 2 subdivision */ ti_min = TIMEBASE; while(ti_min > ti_step) ti_min >>= 1; ti_step = ti_min; if(ti_step < All.PresentMinStep) All.PresentMinStep = ti_step; } }
struct vector raytrace(struct vector rayorig, struct vector raydir, sphere_t *spheres, int nspheres, int depth) { int inside; int i, j; /* Loop indexes. */ float t0; float t1; sphere_t s; struct vector surface_color; /* Color of the surface. */ struct vector phit; /* Point of intersection. */ struct vector nhit; /* Normal at the intersection point. */ struct vector lightdir; /* Light direction. */ struct vector refldir; struct vector refrdir; struct vector tmp1, tmp3; struct vector reflection; struct vector refraction; float tnear; float facingratio; float fresneleffect; float ior; float cosi; float k; float eta; int transmission; t0 = INFINITY; t1 = INFINITY; tnear = INFINITY; s = NULL; /* * Find closest sphere in the scene * that the ray intercepts. */ for (i = 0; i < nspheres; i++) { /* This sphere is intercepted. */ if (sphere_intersects(spheres[i], rayorig, raydir, &t0, &t1)) { if (t0 < 0) t0 = t1; /* Closest sphere found. */ if (t0 < tnear) { tnear = t0; s = spheres[i]; } } } /* * There is no intersection * so return background color. */ if (s == NULL) return (VECTOR(2, 2, 2)); surface_color = VECTOR(0, 0, 0); phit = vector_scalar(raydir, tnear); phit = vector_add(phit, rayorig); nhit = vector_sub(phit, sphere_center(s)); nhit = vector_normalize(nhit); inside = 0; if (vector_dot(raydir, nhit) > 0) { nhit = vector_invert(nhit); inside = 1; } tmp3 = vector_scalar(nhit, BIAS); tmp3 = vector_add(tmp3, phit); if (((s->transparency > 0) || (s->reflection > 0)) && (depth < max_depth)) { facingratio = -vector_dot(raydir, nhit); fresneleffect = mix(pow(1 - facingratio, 3), 1, 0.1); tmp1 = vector_scalar(nhit, 2*vector_dot(raydir, nhit)); refldir = vector_sub(raydir, tmp1); refldir = vector_normalize(refldir); reflection = raytrace(tmp3, refldir, spheres, nspheres, depth + 1); refraction = VECTOR(0, 0, 0); if (s->transparency > 0) { ior = 1.1; eta = (inside) ? ior : 1/ior; cosi = -vector_dot(nhit, raydir); k = 1 - eta*eta*(1 - cosi*cosi); refrdir = vector_scalar(raydir, eta); tmp1 = vector_scalar(nhit, eta*cosi - sqrt(k)); refrdir = vector_add(refrdir, tmp1); refrdir = vector_normalize(refrdir); tmp3 = vector_scalar(nhit, BIAS); tmp3 = vector_sub(phit, tmp3); refraction = raytrace(tmp3, refrdir, spheres, nspheres, depth + 1); } refraction =vector_scalar(refraction,(1-fresneleffect)*s->transparency); reflection = vector_scalar(reflection, fresneleffect); tmp1 = vector_add(reflection, refraction); surface_color = vector_cross(tmp1, s->surface_color); } else { /* * It is a diffuse object, so there * is no need to raytrace any further. */ for (i = 0; i < nspheres; i++) { /* This is a light source. */ if (spheres[i]->emission_color.x > 0) { transmission = 1; lightdir = vector_sub(spheres[i]->center, phit); lightdir = vector_normalize(lightdir); for (j = 0; j < nspheres; j++) { if (i == j) continue; /* Shade this point. */ if (sphere_intersects(spheres[j], tmp3, lightdir, NULL, NULL)) { transmission = 0; break; } } if (transmission) { tmp1 = vector_scalar(s->surface_color, max(0, vector_dot(nhit, lightdir))); tmp1 = vector_cross(tmp1, spheres[i]->emission_color); surface_color = vector_add(surface_color, tmp1); } } } } return (vector_add(surface_color, s->emission_color)); }
// IRQ1 interrupt handler sets keys buffer for this function to read void handle_key(uint8_t key) { hit info; // If the highest bit is not set, this key has not changed if (!(keys[key] & 0x80)) { return; } bool down = keys[key] & 1; // Mark key state as read keys[key] &= 1; switch (key) { // View case KEY_UP: dPitch += down ? 1.0f : -1.0f; break; case KEY_DOWN: dPitch += down ? -1.0f : 1.0f; break; case KEY_LEFT: dYaw += down ? 1.0f : -1.0f; break; case KEY_RIGHT: dYaw += down ? -1.0f : 1.0f; break; case KEY_SPACE: if (down) { playerPos.y += 0.1f; velocity.y += 8.0f; } break; // Check if a block was hit and place a new block next to it case KEY_Q: if (!down) { raytrace(playerPos, ray_dir(160, 100), &info); if (info.hit) { int bx = info.x + info.nx; int by = info.y + info.ny; int bz = info.z + info.nz; if (IN_WORLD(bx, by, bz)) { set_block(bx, by, bz, BLOCK_DIRT); } } } break; // Check if a block was hit and remove it case KEY_E: if (!down) { raytrace(playerPos, ray_dir(160, 100), &info); if (info.hit) { set_block(info.x, info.y, info.z, BLOCK_AIR); } } break; case KEY_ESC: init_world(); break; } // Make sure view look speed doesn't add up with low framerates if (dPitch != 0.0f) dPitch /= absf(dPitch); if (dYaw != 0.0f) dYaw /= absf(dYaw); }
bool Engine::render(void) { std::ofstream debugfile; debugfile.open("E:\\code\\debug2.txt", std::ios_base::app); debugfile << "Starting currLine = " << currLine << std::endl; // render scene Vector3 o(0.0, 0.0, -5.0); // initialize timer unsigned int msecs = get_msec(); // reset last found primitive pointer Primitive *lastprim = nullptr; // render remaining lines for (unsigned int y = currLine; y < (height - 20); y++) { SX = WX1; // render pixels for current line for (unsigned int x = 0; x < width; x++) { // fire primary ray Color acc(0.0, 0.0, 0.0); Vector3 dir = Vector3(SX, SY, 0) - o; dir.normalize(); Ray r(o, dir); double dist; unsigned int prev = get_msec(); Primitive *prim = raytrace(r, acc, 1, 1.0, dist); unsigned int post = get_msec(); if (post - prev != 0) { if (prim) debugfile << prim->getName() << " @ "; debugfile << x << ", " << y << ": "; debugfile << post - prev << std::endl; } int red = (int)(acc.R() * 256); int green = (int)(acc.G() * 256); int blue = (int)(acc.B() * 256); if (red > 255) red = 255; if (green > 255) green = 255; if (blue > 255) blue = 255; dest[ppos++] = RGBA_to_Pixel(red, green, blue); SX += DX; } SY += DY; // see if we've been working to long already // TODO if ((get_msec() - msecs) > 100) { // return control to windows so the screen gets updated currLine = y + 1; debugfile << "exiting currLine = " << currLine << std::endl; debugfile.close(); return false; } } // all done debugfile.close(); return true; }
void castRays( Scene scene, Ray *rays, int numRays, int width, int height, Color **buffer ) { for (int i = 0; i < numRays; i++) buffer[rays[i].i][rays[i].j] = raytrace( scene, rays[i] ); }
/** * - Iterate over all the pixels of the screen * - calculate colors with calculateColor */ void RayTracer::raytrace(Image& img) { ImgSetPixel isp(img); raytrace(&isp); }
void *renderThread(void *arg) { int x,y; thread_info *tinfo = (thread_info *)arg; /* Calculate which part to render based on thread id */ int limits[]={(tinfo->thread_num*sectionsize),(tinfo->thread_num*sectionsize)+sectionsize}; /* Autoexposure */ double exposure = AutoExposure(myScene); double projectionDistance = 0.0f; if ((myScene->persp.type == CONIC) && myScene->persp.FOV > 0.0f && myScene->persp.FOV < 189.0f) { projectionDistance = 0.5f * myScene->width / tanf((double)(PIOVER180) * 0.5f * myScene->persp.FOV); } for (y = limits[0]; y < limits[1]; ++y) { for (x = 0; x < myScene->width; ++x) { colour output = {0.0f, 0.0f, 0.0f}; double fragmentx, fragmenty; /* Antialiasing */ for (fragmentx = x; fragmentx < x + 1.0f; fragmentx += 0.5f) { for (fragmenty = y; fragmenty < y + 1.0f; fragmenty += 0.5f) { double sampleRatio=0.25f; colour temp = {0.0f, 0.0f, 0.0f}; double totalWeight = 0.0f; if (myScene->persp.type == ORTHOGONAL || projectionDistance == 0.0f) { ray viewRay = { {fragmentx, fragmenty, -10000.0f},{ 0.0f, 0.0f, 1.0f}}; int i; for (i = 0; i < myScene->complexity; ++i) { colour result = raytrace(&viewRay, myScene); totalWeight += 1.0f; temp = colourAdd(&temp,&result); } temp = colourCoefMul((1.0f/totalWeight), &temp); } else { vector dir = {(fragmentx - 0.5f * myScene->width) / projectionDistance, (fragmenty - 0.5f * myScene->height) / projectionDistance, 1.0f }; double norm = vectorDot(&dir,&dir); if (norm == 0.0f) break; dir = vectorScale(invsqrtf(norm),&dir); vector start = {0.5f * myScene->width, 0.5f * myScene->height, 0.0f}; vector tmp = vectorScale(myScene->persp.clearPoint,&dir); vector observed = vectorAdd(&start,&tmp); int i; for (i = 0; i < myScene->complexity; ++i) { ray viewRay = { {start.x, start.y, start.z}, {dir.x, dir.y, dir.z} }; if (myScene->persp.dispersion != 0.0f) { vector disturbance; disturbance.x = (myScene->persp.dispersion / RAND_MAX) * (1.0f * rand()); disturbance.y = (myScene->persp.dispersion / RAND_MAX) * (1.0f * rand()); disturbance.z = 0.0f; viewRay.start = vectorAdd(&viewRay.start, &disturbance); viewRay.dir = vectorSub(&observed, &viewRay.start); norm = vectorDot(&viewRay.dir,&viewRay.dir); if (norm == 0.0f) break; viewRay.dir = vectorScale(invsqrtf(norm),&viewRay.dir); } colour result = raytrace(&viewRay, myScene); totalWeight += 1.0f; temp = colourAdd(&temp,&result); } temp = colourCoefMul((1.0f/totalWeight), &temp); } temp.blue = (1.0f - expf(temp.blue * exposure)); temp.red = (1.0f - expf(temp.red * exposure)); temp.green = (1.0f - expf(temp.green * exposure)); colour adjusted = colourCoefMul(sampleRatio, &temp); output = colourAdd(&output, &adjusted); } } /* gamma correction */ double invgamma = 0.45f; //Fixed value from sRGB standard output.blue = powf(output.blue, invgamma); output.red = powf(output.red, invgamma); output.green = powf(output.green, invgamma); img[(x+y*myScene->width)*3+2] = (unsigned char)min(output.red*255.0f, 255.0f); img[(x+y*myScene->width)*3+1] = (unsigned char)min(output.green*255.0f, 255.0f); img[(x+y*myScene->width)*3+0] = (unsigned char)min(output.blue*255.0f,255.0f); } } pthread_exit((void *) arg); }