void test_cast_ray(void){ struct sphere s[2]; struct color c1 = create_color(1,0,.3); s[0] = create_sphere(create_point(1.4,2.6,0), 2, c1); s[1] = create_sphere(create_point(4.5, 5, 0), 1,c1); struct ray r = create_ray(create_point(0,0,0), create_vector(1.4,2.6,0)); struct ray r2 = create_ray(create_point(-123.2,-4,-.3), create_vector(1.3,-2.9,-.3)); struct ray r3 = create_ray(create_point(-4.5,-4.3,0), create_vector(-23,-100,-100)); checkit_int(cast_ray(r,s,2).r, 1); checkit_int(cast_ray(r,s,2).g, 0); checkit_int(cast_ray(r,s,2).b, .3); checkit_int(cast_ray(r2,s,2).r, 1); checkit_int(cast_ray(r2,s,2).g, 1); checkit_int(cast_ray(r2,s,2).b, 1); checkit_int(cast_ray(r3,s,2).r, 1); checkit_int(cast_ray(r3,s,2).g, 1); checkit_int(cast_ray(r3,s,2).b, 1); }
color pathtracer::cast_ray(ray r, int step, bool internal) { intersection is = find_nearest(r); if (!is.object) // No intersection return *background_color; color out = color(); for (std::shared_ptr<light> l : *lights) { color lcol = color(); if (is.object.get() == dynamic_cast<const shape *>(l.get())) out += *is.object->shade(color(1, 1, 1), *is.norm, *is.norm, -r.d, *is.local_pos, internal); else { const std::shared_ptr<std::vector<intersection>> dirs = l->get_directions(*is.pos, cam->shadow_rays); for (intersection d : *dirs) { direction light_dir = (*is.pos - *d.pos) * 0.999; if (!cast_shadow(*is.pos, -light_dir)) { //light_dir = normalise(light_dir); lcol += *is.object->shade(*l->emit(light_dir, d), -normalise(light_dir), *is.norm, -r.d, *is.local_pos, internal); } } if (dirs->size() > 0) out += lcol * (1.0f / dirs->size()); } } if (step < cam->max_bounces - 1) { std::shared_ptr<ray> sctr_ray = is.object->scatter(-r.d, *is.norm, *is.pos); if (sctr_ray) { //color sctr_col = cast_ray(*sctr_ray, step + 1, internal); color sctr_col = *is.object->shade(cast_ray(*sctr_ray, step + 1, internal), sctr_ray->d, *is.norm, -r.d, *is.local_pos, internal) * static_cast<float>(M_PI); out += sctr_col; } std::shared_ptr<ray> refl_ray = internal ? nullptr : is.object->reflect(-r.d, *is.norm, *is.pos); if (refl_ray) { color refl_col = cast_ray(*refl_ray, step + 1, internal); refl_col = refl_col * is.object->get_reflectance(); out += refl_col; } std::shared_ptr<ray> refr_ray = is.object->refract(-r.d, internal ? -*is.norm : *is.norm, *is.pos, internal); if (refr_ray) { color refr_col = color(); refr_col += cast_ray(*refr_ray, step + 1, dot(refr_ray->d, internal ? -*is.norm : *is.norm) < 0 == !internal); refr_col = refr_col * (internal ? std::exp(-(1 - is.object->get_transmittance()) * length(*is.pos - r.o)) : is.object->get_transmittance()); out += refr_col; } } return out; }
colour get_the_scene(t_rt_client *rt, int x, int y) { t_ray ray; t_color color; t_obj *tmp; t_obj *obj_result; tmp = rt->objs; obj_result = NULL; ray.color = &color; init_ray(rt, &ray, x, y); while (rt && tmp && tmp->color) { assign_ray(rt, &ray, tmp); obj_result = cast_ray(&ray, tmp, obj_result); tmp = tmp->next; } if (obj_result && obj_result->color) { assign_ray(rt, &ray, obj_result); obj_result->color->color = perlin_color(rt, &ray, obj_result); lighting(&ray, obj_result, rt->spot); shadows(rt, &ray, obj_result); } return (ray.color->color); }
void cast_aa_ray(int x, int y) { double color[3],color1[3],color2[3],color3[3],color4[3]; /*Anti-Aliasing by super sampling for each pixel using grid algorithm method --------- | . . . | | . . . | | . . . | --------- */ cast_ray(x+.25f, y+.5f, color1); cast_ray(x+.5f, y+.75f, color2); cast_ray(x+.5f, y+.25f, color3); cast_ray(x+.75f, y+.5f, color4); /* I am using only 4 grids i.e averaging by 4 per pixel */ color[0] = (color1[0]+color2[0]+color3[0]+color4[0]) / 4; color[1] = (color1[1]+color2[1]+color3[1]+color4[1]) / 4; color[2] = (color1[2]+color2[2]+color3[2]+color4[2]) / 4; if(color[0] > 1) color[0] = 1; else if (color[0] < 0) color[0] = 0; color[0] *= 255; if(color[1] > 1) color[1] = 1; else if (color[1] < 0) color[1] = 0; color[1] *= 255; if(color[2] > 1) color[2] = 1; else if (color[2] < 0) color[2] = 0; color[2] *= 255; plot_pixel_jpeg(x,y,color[0],color[1],color[2]); }
int button_pess(int button, int x, int y, t_env *e) { t_vect ray; (void)button; e->test = 1; create_ray(e, &ray, x, y); cast_ray(e, &ray, x, y); e->test = 0; return (1); }
void update_sight() { list_node *c; line_point *p; memset(RAYS, 0, sizeof(RAYS)); RAY_INDEX = 0; double dx, dy; for (c = CORNERS->next; c->next != NULL; c = c->next) { if (((line_point *) c->data) != NULL) { p = (line_point *) c->data; dx = p->x - get_player_x(); dy = p->y - get_player_y(); cast_ray(sqrt(dy*dy + dx*dx), atan2(dy, dx) - 0.01, false); cast_ray(sqrt(dy*dy + dx*dx), atan2(dy, dx), false); cast_ray(sqrt(dy*dy + dx*dx), atan2(dy, dx) + 0.01, false); } } qsort(RAYS, RAY_INDEX, sizeof(ray), thetacmp); }
void TCOD_map_compute_fov_circular_raycastingi(TCOD_map_t map, int player_x, int player_y, int max_radius, bool light_walls) { int xo,yo; map_t *m = (map_t *)map; /* circular ray casting */ int xmin=0, ymin=0, xmax=m->width, ymax=m->height; int c; int r2=max_radius*max_radius; if ( max_radius > 0 ) { xmin=MAX(0,player_x-max_radius); ymin=MAX(0,player_y-max_radius); xmax=MIN(m->width,player_x+max_radius+1); ymax=MIN(m->height,player_y+max_radius+1); } for (c=m->nbcells-1; c >= 0; c--) { m->cells[c].fov=0; } xo=xmin; yo=ymin; while ( xo < xmax ) { cast_ray(m,player_x,player_y,xo++,yo,r2,light_walls); } xo=xmax-1;yo=ymin+1; while ( yo < ymax ) { cast_ray(m,player_x,player_y,xo,yo++,r2,light_walls); } xo=xmax-2;yo=ymax-1; while ( xo >= 0 ) { cast_ray(m,player_x,player_y,xo--,yo,r2,light_walls); } xo=xmin;yo=ymax-2; while ( yo > 0 ) { cast_ray(m,player_x,player_y,xo,yo--,r2,light_walls); } if ( light_walls ) { /* post-processing artefact fix */ TCOD_map_postproc(m,xmin,ymin,player_x,player_y,-1,-1); TCOD_map_postproc(m,player_x,ymin,xmax-1,player_y,1,-1); TCOD_map_postproc(m,xmin,player_y,player_x,ymax-1,-1,1); TCOD_map_postproc(m,player_x,player_y,xmax-1,ymax-1,1,1); } }
double Get_Skew::histogram( const Raster &raster, double angle) { int i; double sum; double mean; double angle_diff = tan(angle / (180.0 / M_PI)); int diff_y = -static_cast<int>( raster.width() * angle_diff); int min_y = max( 0, diff_y); int max_y = min( static_cast<int>( raster.height()) , raster.height() + diff_y); int num_rows; Fixed dx; int dy; if (raster.height() > m_max_rows) { delete []m_rows; m_rows = new unsigned[ raster.height()]; m_max_rows = raster.height(); } num_rows = (max_y - min_y) / m_sample_skip + 1; if (angle < 0) { dy = -1; } else { dy = +1; } if ((-0.05 < angle) && (angle < 0.05)) { dx = static_cast<int>( raster.width()); } else { dx = dy / (tan( angle / (180.0 / M_PI))); } for (i = 0; i < num_rows; ++i) { m_rows[ i] = cast_ray( raster, min_y + i * m_sample_skip, dx, dy); } sum = 0.0; for (i = 0; i < num_rows; ++i) { sum += m_rows[ i]; } mean = sum / num_rows; sum = 0.0; for (i = 0; i < num_rows; ++i) { sum += sqr( m_rows[ i] - mean); } return sum / num_rows; }
void draw_fov(t_env *env) { double angl; int i; angl = LOOK_DIR + FOV_ANGL / 2; angl -= (angl > 2 * M_PI) ? 2 * M_PI : 0; i = 0; while (i < X_SZE) { cast_ray(env, angl, i); angl -= FOV_ANGL / X_SZE; angl += (angl < 0) ? 2 * M_PI : 0; i++; } }
void calc_color_alias(t_rt *img, t_ray *ray, t_obj *tmp) { t_obj *obj_result; init_alias(img, ray); obj_result = NULL; while (img && ray && tmp && tmp->color) { assign_ray(img, ray, tmp); obj_result = cast_ray(ray, tmp, obj_result); tmp = tmp->next; } if (obj_result != NULL && obj_result->color) { assign_ray(img, ray, obj_result); obj_result->color->color = perlin_color(img, ray, obj_result); lighting(ray, obj_result, img->spot); shadows(img, ray, obj_result); } }
void render_scene(t_interface *env) { int x; int y; t_vec3f *image; t_vec3f *pixel; y = 0; image = (t_vec3f*)malloc(sizeof(t_vec3f) * (WIDTH * HEIGHT)); if ((pixel = image) == NULL) return ; while (y < HEIGHT && !(x = 0)) { while (x < WIDTH) { cast_ray(x, y, pixel++, env); x++; } y++; } paint_mlx(image, env->gui); free(image); }
void Player::UpdateRays(const long elapsed_time) { (void) elapsed_time; auto is_level_blocking = [&](const int map_x, const int map_y) { return mWorld.IsBlocking(map_x, map_y); }; const auto ray_count = mRays.size(); for (auto x = 0u; x < ray_count; x++) { // Current column position relative to the center of the screen. // Left edge is -1, right edge is 1, and center is 0. const double cam_x = 2.0 * x / ray_count - 1; // Starting direction of the current ray to be cast. const double ray_dir_x = mDirX + (mPlaneX * cam_x); const double ray_dir_y = mDirY + (mPlaneY * cam_x); cast_ray(mPosX, mPosY, ray_dir_x, ray_dir_y, is_level_blocking, mRays[x]); } }
color scene_3D::cast_ray(line_3D line, double threshold, unsigned int recursion_depth) { unsigned int k, l, m; triangle_3D triangle; color final_color, helper_color, add_color; double depth, t; double *texture_coords_a, *texture_coords_b, *texture_coords_c; double barycentric_a, barycentric_b, barycentric_c; point_3D starting_point; point_3D normal,normal_a,normal_b,normal_c; point_3D reflection_vector, incoming_vector_reverse; material mat; int color_sum[3]; line.get_point(0,starting_point); depth = 99999999; final_color.red = this->background_color.red; final_color.green = this->background_color.green; final_color.blue = this->background_color.blue; for (k = 0; k < this->meshes.size(); k++) { if (!line.intersects_sphere(this->meshes[k]->bounding_sphere_center,this->meshes[k]->bounding_sphere_radius)) continue; for (l = 0; l < this->meshes[k]->triangle_indices.size(); l += 3) { triangle.a = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l]].position; triangle.b = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 1]].position; triangle.c = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 2]].position; texture_coords_a = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l]].texture_coords; texture_coords_b = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 1]].texture_coords; texture_coords_c = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 2]].texture_coords; if (line.intersects_triangle(triangle,barycentric_a,barycentric_b,barycentric_c,t)) { point_3D intersection; line.get_point(t,intersection); double distance = point_distance(starting_point,intersection); mat = this->meshes[k]->get_material(); if (distance < depth && distance > threshold) // depth test { depth = distance; normal_a = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l]].normal; normal_b = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 1]].normal; normal_c = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 2]].normal; normal.x = 0; normal.y = 0; normal.z = 0; normal.x = barycentric_a * normal_a.x + barycentric_b * normal_b.x + barycentric_c * normal_c.x; normal.y = barycentric_a * normal_a.y + barycentric_b * normal_b.y + barycentric_c * normal_c.y; normal.z = barycentric_a * normal_a.z + barycentric_b * normal_b.z + barycentric_c * normal_c.z; normalize(normal); // interpolation breaks normalization if (!this->meshes[k]->use_3D_texture && this->meshes[k]->get_texture() != 0) // 2d texture { double u,v; u = barycentric_a * texture_coords_a[0] + barycentric_b * texture_coords_b[0] + barycentric_c * texture_coords_c[0]; v = barycentric_a * texture_coords_a[1] + barycentric_b * texture_coords_b[1] + barycentric_c * texture_coords_c[1]; color_buffer_get_pixel(this->meshes[k]->get_texture(),u * this->meshes[k]->get_texture()->width,v * this->meshes[k]->get_texture()->height,&final_color.red,&final_color.green,&final_color.blue); } else if (this->meshes[k]->use_3D_texture && this->meshes[k]->get_texture_3D() != 0) // 3d texture { final_color = this->meshes[k]->get_texture_3D()->get_color(intersection.x,intersection.y,intersection.z); } else // mesh color { final_color.red = 255; final_color.green = 255; final_color.blue = 255; } helper_color = compute_lighting(intersection,mat,normal); final_color = multiply_colors(helper_color,final_color); if (recursion_depth != 0) { incoming_vector_reverse = line.get_vector_to_origin(); if (mat.reflection > 0) // reflection { color_sum[0] = 0; color_sum[1] = 0; color_sum[2] = 0; for (m = 0; m < this->reflection_rays; m++) { point_3D helper_point; reflection_vector = make_reflection_vector(normal,incoming_vector_reverse); reflection_vector.x *= -1; reflection_vector.y *= -1; reflection_vector.z *= -1; if (m > 0) // alter the ray slightly alter_vector(reflection_vector,this->reflection_range); helper_point.x = intersection.x + reflection_vector.x; helper_point.y = intersection.y + reflection_vector.y; helper_point.z = intersection.z + reflection_vector.z; line_3D reflection_line(intersection,helper_point); add_color = cast_ray(reflection_line,ERROR_OFFSET,recursion_depth - 1); color_sum[0] += add_color.red; color_sum[1] += add_color.green; color_sum[2] += add_color.blue; } add_color.red = color_sum[0] / this->reflection_rays; add_color.green = color_sum[1] / this->reflection_rays; add_color.blue = color_sum[2] / this->reflection_rays; final_color = interpolate_colors(final_color,add_color,mat.reflection); } if (mat.transparency > 0) // refraction { color_sum[0] = 0; color_sum[1] = 0; color_sum[2] = 0; for (m = 0; m < this->refraction_rays; m++) { point_3D helper_point; point_3D refraction_vector; refraction_vector = make_refraction_vector(normal,incoming_vector_reverse,mat.refractive_index); if (m > 0) // alter the ray slightly alter_vector(refraction_vector,this->refraction_range); helper_point.x = intersection.x + refraction_vector.x; helper_point.y = intersection.y + refraction_vector.y; helper_point.z = intersection.z + refraction_vector.z; line_3D refraction_line(intersection,helper_point); add_color = cast_ray(refraction_line,ERROR_OFFSET,recursion_depth - 1); color_sum[0] += add_color.red; color_sum[1] += add_color.green; color_sum[2] += add_color.blue; } add_color.red = color_sum[0] / this->refraction_rays; add_color.green = color_sum[1] / this->refraction_rays; add_color.blue = color_sum[2] / this->refraction_rays; final_color = interpolate_colors(final_color,add_color,mat.transparency); } } } } } } return final_color; }
void render( int width, int height, Point campos, EulerRotation camangle, std::vector<SceneObject>& scenedesc, Bitmap& bmp) { double fov = 90; double factor = (double(height)/2)/tan(fov*M_PI/360.0); Vector lightdir = Vector(0.0,-2.0,-1.0); lightdir.normalize_l2(); // Construct a ray for each pixel. for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { Color skycol(0x9E,0xE2,0xEA); Color col = skycol; // Sets up ray origin and direction in view space, // image plane is at z = -1. Vector imagePlane; imagePlane[_X_] = (-double(width)/2 + j + 0.5)/factor; imagePlane[_Z_] = (-double(height)/2 + i + 0.5)/factor; imagePlane[_Y_] = -1; imagePlane = imagePlane.rotate(camangle); // TODO: Convert ray to world space and call // shadeRay(ray) to generate pixel color. Ray ray; // initialize ray and convert to world coords ray.origin = campos; ray.dir = imagePlane; ray.dir.normalize_l2(); cast_ray( ray, scenedesc ); double maxdist = 40; double occulddist = 0.1; if(ray.intersected) { Vector normal = -ray.gradient; normal.normalize_l2(); double diffuse = fmax(normal.dot(-lightdir),0.0); Vector c = -(2.0 * normal.dot(lightdir) * normal - lightdir); double specular = fmax(ray.dir.dot(c),0.0); specular = pow(specular,10.0); // only cast if diffuse is nonzero // if(diffuse!=0){ // Ray lightray; // lightray.origin = ray.intsec;// - 0.1*normal; // lightray.dir = lightdir; // cast_ray(lightray, scenedesc); // if(lightray.intersected){ // diffuse = 0; // specular = 0; // }// } else { // // double umbra = clamp(8*lightray.mindist, 0, 1); // // diffuse *= umbra; // // specular *= umbra; // // } // } // Vector normal2 = (2.0*normal/normal.linf() + Vector(1.0,1.0,1.0))/2.0; // Color normalcol; // normalcol[0] = normal2[0]; // normalcol[1] = normal2[1]; // normalcol[2] = normal2[2]; // double ambient = fmax(f(ray.intsec - occulddist*normal) / occulddist, 0.0); // ambient = 1-pow(1-ambient,2.0); //only apply ambient when diffuse is low // ambient = fmax(ambient,diffuse); // col = ambient*0.1*Color(0.7,0.65,0.6) + diffuse*0.8 * Color(0.7,0.65,0.6) + // pow(specular,50.0)*0.5 * Color(1.0,1.0,1.0); col = diffuse*Color(0.6,0.6,0.6) + specular*Color(1.0,1.0,1.0); double fog = (ray.intsec-campos).l2()/maxdist; fog = 1-pow(1-fog,2.0); col = fog * skycol + (1-fog) * col; } double sun = pow(fmax(ray.dir.dot(lightdir),0.0),200); col = col + sun*Color(1.0,1.0,0.8); col.clamp(); bmp(i,j) = col; if(j%100 == 0){ int percent = 100.0*(1.0*i*width + j) / (height*width); std::cerr << "\r"<< std::setw(3) << std::setfill('0') << percent << "% completed: "; std::cerr << std::string(percent/2, '|'); std::cerr.flush(); } } } }