void display_scene(t_img *img) { int x; int y; t_ray *rayon; t_data *d; int time; d = data_init(); rayon = ray_new(); time = 0; y = 0; while (y < d->win_size_y) { x = 0; while (x < d->win_size_x) { display_pixel(img, x, y, rayon); x++; time++; if (time % 100000 == 0) eb_waiting(time/100000); } y++; } }
color_t getAntialiasedPixel(float x, float y, intersect_t *intersect, float antialiasLevel) { float antialiasLevelSquared = antialiasLevel * antialiasLevel; float precalculatedOffsetPart = 1.0 / (2.0 * antialiasLevel); point_t pos; vec_t rayDirection; ray_t ray; color_t color; float avgR = 0, avgG = 0, avgB = 0; for (int j = 0; j < antialiasLevel; j++) { for (int i = 0; i < antialiasLevel; i++) { float xOff = i / antialiasLevel + precalculatedOffsetPart; float yOff = j / antialiasLevel + precalculatedOffsetPart; float xPos = (x + xOff) * 2 / width - 1; float yPos = -((y + yOff) * 2 / height - 1); pos = point_new(xPos, yPos, -2); rayDirection = vec_normalize(point_direction(cameraPos, pos)); ray = ray_new(cameraPos, rayDirection); color = shootRay(ray, intersect, 0); avgR += (float)color.r / (float)antialiasLevelSquared; avgG += (float)color.g / (float)antialiasLevelSquared; avgB += (float)color.b / (float)antialiasLevelSquared; } } return rgb((char)avgR, (char)avgG, (char)avgB); }
color_t getPixel(float x, float y, intersect_t *intersect) { intersect->t = -1; x = (x + 0.5) * 2 / width - 1; y = -((y + 0.5) * 2 / height - 1); point_t pixelPos = point_new(x, y, -2); vec_t rayDirection = vec_normalize(point_direction(cameraPos, pixelPos)); ray_t ray = ray_new(cameraPos, rayDirection); return shootRay(ray, intersect, 0); }
pixel_data_t world_render(world_t *world, camera_t *camera) { pixel_t **pixels = calloc(camera->h, sizeof(pixel_t *)); for (uint32_t i = 0; i < camera->h; i++) { pixels[i] = malloc(sizeof(pixel_t) * camera->w); } pixel_data_t pixel_data = { camera->w, camera->h, pixels }; for (uint32_t x = 0; x < camera->w; x++) { for (uint32_t y = 0; y < camera->h; y++) { ray_t *ray = ray_new(camera->pos, dir_for_pixel(camera, x, y)); sphere_t *sphere = ptr_array_index(world->spheres, 0); vec3_t normal; double distance; if (!object_get_collision(OBJECT(sphere), ray, &distance, &normal)) continue; vec3_t p = vec3_add(ray->pos, vec3_mul(ray->dir, distance)); pixel_t pixel = { 1, 0, 0, 0 }; for (uint32_t i = 0; i < world->lights->len; i++) { light_t *light = ptr_array_index(world->lights, i); vec3_t l = vec3_normalize(vec3_sub(p, light->pos)); double lambert = MAX(0, vec3_dot(l, normal) * LAMBERT_COEF); pixel.a = 1; pixel.r += 1 * lambert; pixel.g += 1 * lambert; pixel.b += 1 * lambert; } pixels[x][y] = pixel; } } return pixel_data; }
Ray camera_ray(Camera*camera,float x, float y){//x,y {-1~+1} //ray_center = ((cam_center - (cam_x * x) - (cam_y * y)) - cam_pos) Vector3D center= vector3d_sub(vector3d_sub(camera->m_center,vector3d_mul_float(camera->x,x)),vector3d_mul_float(camera->y,y)); return ray_new(camera->m_pos,vector3d_normalize(vector3d_sub(center,camera->m_pos))); }
color_t shootRay(ray_t ray, intersect_t *intersect, int recursionCount) { rayIntersectionTest(ray, intersect); if (intersect->t > 0) { // We hit something color_t color; GeomType geomType = intersect->geomType; void *geomObject = intersect->object; bool reflective = false; // Check the material if (geomType == GeomTypeTriangle) { triangle_t *temp = (triangle_t *)geomObject; color = temp->material.color; reflective = temp->material.reflective; } else if (geomType == GeomTypeSphere) { sphere_t *temp = (sphere_t *)geomObject; color = temp->material.color; reflective = temp->material.reflective; } else if (geomType == GeomTypeLight) { return rgb(255, 255, 255); } // Get a normal where we intersected vec_t normal; if (geomType == GeomTypeTriangle) { triangle_t *temp = (triangle_t *)geomObject; normal = temp->normal; } else if (geomType == GeomTypeSphere) { sphere_t *temp = (sphere_t *)geomObject; normal = sphere_normal_at_point(*temp, intersect->point); } if (reflective && recursionCount < 10) { // First find the reflected ray vec_t r = vec_sub(ray.direction, vec_mult(normal, 2 * vec_dot(normal, ray.direction))); point_t start = point_offset(intersect->point, vec_mult(r, 0.0001)); ray_t reflectedRay = ray_new(start, r); // Shoot out a new ray and take its color color = shootRay(reflectedRay, intersect, recursionCount + 1); } else if (!reflective) { point_t sPos = intersect->point; ray_t sRay; float totalDiffuse = 0; for (int m = 0; m < numLights; m++) { if (lights[m].size == 0) { sRay = ray_to_light(lights[m], sPos); sRay.point = point_offset(sRay.point, vec_mult(sRay.direction, 0.0001)); rayIntersectionNonLightTest(sRay, intersect); if (intersect->t <= 0) { // We did't hit anything, diffuse like normal totalDiffuse += fabsf(vec_dot(sRay.direction, normal)); } // Otherwise, we're in shadow } else { float lightRays = 100 * lights[m].size; float lightDiffuse = 0; for (int l = 0; l < lightRays; l++) { sRay = ray_to_light(lights[m], sPos); sRay.point = point_offset(sRay.point, vec_mult(sRay.direction, 0.0001)); rayIntersectionNonLightTest(sRay, intersect); if (intersect->t <= 0) { // We didn't hit anything, diffuse like normal lightDiffuse += fabsf(vec_dot(sRay.direction, normal)); } // Otherwise, we're in shadow } totalDiffuse += lightDiffuse / lightRays; } } totalDiffuse /= numLights; // We want the total intensity of lights to be the // same no matter how many we have if (totalDiffuse < 0.2) totalDiffuse = 0.2; if (totalDiffuse > 1) totalDiffuse = 1; color.r *= totalDiffuse; color.g *= totalDiffuse; color.b *= totalDiffuse; } return color; } // No intersection, color black return rgb(0, 0, 0); }