Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <limits>
- #include "Scene.h"
- #include "task1b.h"
- #include <iostream>
- constexpr float epsilon = 0.0001f;
- const triangle_t* findClosestHit(
- const float3& p, const float3& d,
- const triangle_t* triangles, std::size_t num_triangles,
- const float3* vertices,
- float& t, float& lambda_1, float& lambda_2)
- {
- // TODO: implement intersection test between a ray and a set of triangles.
- // This function should find the CLOSEST intersection with a triangle along the ray.
- // The ray is given by its start point p and direction d.
- // A triangle is represented as an array of three vertex indices.
- // The position of each vertex can be looked up from the vertex array via the vertex index.
- // triangles points to the first element of an array of num_triangles triangles.
- // If an intersection is found, set t to the ray parameter and
- // lambda_1 and lambda_2 to the barycentric coordinates corresponding to the
- // closest point of intersection, and return a pointer to the hit triangle.
- // If no intersection is found, return nullptr.
- for(int i = 0; i < num_triangles; i++)
- {
- float3 e = vertices[triangles[i][1]] - vertices[triangles[i][0]];
- float3 e2 = vertices[triangles[i][2]] - vertices[triangles[i][0]];
- float3 q = p - vertices[triangles[i][0]];
- //float3 e = normalize(e_temp);
- //float3 e2 = normalize(e2_temp);
- //float3 q = normalize(q_temp);
- float check_intersect = (dot(cross(d,e2),e));
- if(check_intersect > 0.000000f)
- {
- t = (dot(cross(q,e),e2))/ (dot(cross(d,e2),e));
- lambda_1 = (dot(cross(d,e2),q))/ (dot(cross(d,e2),e));
- lambda_2 = (dot(cross(q,e),d))/ (dot(cross(d,e2),e));
- if(lambda_1 >= 0.000000f && lambda_2 >= 0.0000000f && (lambda_1+lambda_2) <= 1.000000f)
- {
- return &triangles[i];
- }
- }
- }
- //std::cout << triangles[0][1] << std::endl;
- return nullptr;
- }
- bool intersectsRay(
- const float3& p, const float3& d,
- const triangle_t* triangles, std::size_t num_triangles,
- const float3* vertices,
- float t_min, float t_max)
- {
- // TODO: implement intersection test between a ray and a set of triangles.
- // This method only has to detect whether there is an intersection with ANY triangle
- // along the given subset of the ray.
- // The ray is given by its start point p and direction d.
- // A triangle is represented as an array of three vertex indices.
- // The position of each vertex can be looked up from the vertex array via the vertex index.
- // triangles points to an array of num_triangles.
- // If an intersection is found that falls on a point on the ray between
- // t_min and t_max, return true.
- // Otherwise, return false.
- for(int i = 0; i < num_triangles; i++)
- {
- float3 e = vertices[triangles[i][1]] - vertices[triangles[i][0]];
- float3 e2 = vertices[triangles[i][2]] - vertices[triangles[i][0]];
- float3 q = p - vertices[triangles[i][0]];
- float check_intersect = (dot(cross(d,e2),e));
- if(check_intersect > 0.000000f)
- {
- float t = (dot(cross(q,e),e2))/ (dot(cross(d,e2),e));
- //t = (dot(cross(q,e),e2))/ (dot(cross(d,e2),e));
- float lambda_1 = (dot(cross(d,e2),q))/ (dot(cross(d,e2),e));
- float lambda_2 = (dot(cross(q,e),d))/ (dot(cross(d,e2),e));
- if(lambda_1 >= 0.000000f && lambda_2 >= 0.000000f && (lambda_1+lambda_2) <= 1.000000f && t_min < t && t < t_max )
- return true;
- }
- }
- return false;
- }
- float3 shade(
- const float3& p, const float3& d,
- const HitPoint& hit,
- const Scene& scene,
- const Pointlight* lights, std::size_t num_lights)
- {
- // TODO: implement phong shading.
- // hit represents the surface point to be shaded.
- // hit.position, hit.normal, and hit.k_d and hit.k_s contain the position,
- // surface normal, and diffuse and specular reflection coefficients,
- // hit.m the specular power.
- // lights is a pointer to the first element of an array of num_lights
- // point light sources to consider.
- // Each light contains a member to give its position and color.
- // Return the shaded color.
- float3 light_color = {0.0f, 0.0f,0.0f};
- float3 cd = {0.0f, 0.0f,0.0f};
- float3 cs = {0.0f, 0.0f,0.0f};
- //float3 temp = {0.0f, 0.0f,0.0f};
- for(int i = 0; i < num_lights; i++)
- {
- //float3 p_new = normalize(p);
- float3 light_dir = lights[i].position - hit.position;
- float3 light_dir_n = normalize(light_dir);
- float3 n = normalize(hit.normal);
- float cos_ = dot(light_dir_n,n);
- cd = (hit.k_d * std::fmax(cos_,0.0f));
- //float3 cd = normalize(cd_tmp);
- float3 r = light_dir_n - (2*(dot(light_dir_n, n)) * n) ;///I - 2 * dotProduct(I, N) * N
- //*d = normalize(d);
- //float3 r = normalize(light_dir + p_new);
- float3 r_n = normalize(r);
- float3 d_new = normalize(d);
- float cos_r = dot(r_n, d_new);
- //cd.x = cd.x * lights[i].color.x;
- //cd.y = cd.y * lights[i].color.y;
- //cd.z = cd.z * lights[i].color.z;
- // temp = temp+ cs + cd;
- //temp.x = temp.x * lights[i].color.x;
- //temp.y = temp.y * lights[i].color.y;
- //temp.z = temp.z * lights[i].color.z;
- //float light_color_temp = dot((cs+cd),lights[i].color);
- //light_color = light_color + cs + cd + lights[i].color;
- ///light_color = light_color * light_color_temp;
- //float3 light_color_1 = (cs + cd) * lights[i].color.x;
- //float3 light_color_2 = (cs + cd) * lights[i].color.y;
- //float3 light_color_3 = (cs+cd) * lights[i].color.z;
- //light_color = light_color + (cs + cd) * (lights[i].color.x * lights[i].color.y * lights[i].color.z);
- //light_color = (cs + cd) * lights[i].color.y;
- //light_color = (cs + cd) * lights[i].color.z;
- // t_min = (hit.position.x + epsilon) * hit.normal.x;
- //light_color = light_color + (cs + cd);
- float3 start = hit.position + (hit.normal * epsilon);
- if(scene.intersectsRay(start, light_dir,epsilon, std::numeric_limits<float>::infinity()))
- continue;
- if(cos_ + epsilon > 0.0000f)
- {
- cs = (hit.k_s * std::pow(std::fmax(cos_r,0.0f),hit.m));
- // cs.x = (hit.k_s.x * std::pow(std::fmax(cos_r,0.0f),hit.m));
- // cs.x = cs.x * lights[i].color.x;
- //cs.y = cs.y * lights[i].color.y;
- //cs.z = cs.z * lights[i].color.z;
- }
- else
- {
- cs = {0.f,0.f,0.f};
- }
- light_color.x += (cs.x + cd.x) * lights[i].color.x;
- light_color.y += (cs.y + cd.y)* lights[i].color.y;
- light_color.z += (cs.z + cd.z) * lights[i].color.z;
- //else
- //light_color = light_color + (cs + cd);
- //return light_color;
- }
- //scene.intersectsRay(p,d,0.0f,20.f);
- return light_color;
- // To implement shadows, use scene.intersectsRay(p, d, t_min, t_max) to test
- // whether a ray given by start point p and direction d intersects any
- // object on the section between t_min and t_max.
- //scene.intersectsRay(p,d,0,0);
- // return hit.k_d;
- }
- void render(
- image2D<float3>& framebuffer,
- int left, int top, int right, int bottom,
- const Scene& scene,
- const Camera& camera,
- const Pointlight* lights, std::size_t num_lights,
- const float3& background_color,
- int max_bounces)
- {
- // TODO: implement raytracing, render the given portion of the framebuffer.
- // left, top, right, and bottom specify the part of the image to compute
- // (inclusive left, top and exclusive right and bottom).
- // camera.eye, camera.lookat, and camera.up specify the position and
- // orientation of the camera, camera.w_s the width of the image plane,
- // and camera.f the focal length to use.
- // Use scene.findClosestHit(p, d) to find the closest point where the ray
- // hits an object.
- // The method returns an std::optional<HitPoint>.
- // If an object is hit, call the function shade to compute the color value
- // of the HitPoint illuminated by the given array of lights.
- // If the ray does not hit an object, use background_color.
- // BONUS: extend your implementation to recursive ray tracing.
- // max_bounces specifies the maximum number of secondary rays to trace.
- float aspect_ratio = width(framebuffer) / (float)height(framebuffer);
- float h_s = camera.w_s/aspect_ratio;
- // float x = camera.eye;
- // float3 x = (camera.eye - camera.lookat);
- //float3 y = (normalize(camera.eye - camera.lookat));
- float3 w = normalize(camera.eye-camera.lookat);
- // float3 w;
- // w.x = x.x/check;
- // w.y = x.y/check;
- // w.z = x.z/check;
- float3 u = normalize(cross(camera.up, w));
- //float leng = length(u_temp);
- //float3 u;
- //u.x = u_temp.x/leng;
- // u.y = u_temp.y/leng;
- //u.z = u_temp.z/leng;
- float3 v = cross(w,u);
- //float3 p_origin = camera.eye;
- //Camera y = normalize(camera.eye-camera.lookat);
- for (int y = top; y < bottom; ++y)
- {
- float y_position = - h_s*(y+0.5f)/height(framebuffer) + h_s/2.0f;
- for (int x = left; x < right; ++x)
- {
- float x_position = - camera.w_s/2.0f + camera.w_s*(x + 0.5f)/width(framebuffer);
- //float f = -camera.f;
- float3 d = (-(camera.f*w)) + x_position*u + y_position*v;
- //float3 d = {camera.f*w,(float)x*u,(float)y*w};
- std::optional<HitPoint> hit = scene.findClosestHit(camera.eye,d);
- max_bounces--;
- if(hit)
- {
- ///std::cout<<"inside\n";
- framebuffer(x,y) = shade(camera.eye,d,*hit,scene,lights,num_lights);
- }
- else
- {
- framebuffer(x, y) = background_color;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement