Skip to content

Commit d51bab4

Browse files
committed
Do Lab 2.02
1 parent 2586cc4 commit d51bab4

File tree

2 files changed

+71
-9
lines changed

2 files changed

+71
-9
lines changed

src/renderer/raytracer/raytracer.h

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,18 @@ namespace cg::renderer
5454
inline triangle<VB>::triangle(
5555
const VB& vertex_a, const VB& vertex_b, const VB& vertex_c)
5656
{
57-
// TODO Lab: 2.02 Implement a constructor of `triangle` struct
57+
a = float3{vertex_a.x, vertex_a.y, vertex_a.z};
58+
b = float3{vertex_b.x, vertex_b.y, vertex_b.z};
59+
c = float3{vertex_c.x, vertex_c.y, vertex_c.z};
60+
ba = b - a;
61+
ca = c - a;
62+
na = float3{vertex_a.nx, vertex_a.ny, vertex_a.nz};
63+
nb = float3{vertex_b.nx, vertex_b.ny, vertex_b.nz};
64+
nc = float3{vertex_c.nx, vertex_c.ny, vertex_c.nz};
65+
ambient = float3{vertex_a.ambient_r, vertex_a.ambient_g, vertex_a.ambient_b};
66+
diffuse = float3{vertex_a.diffuse_r, vertex_a.diffuse_g, vertex_a.diffuse_b};
67+
diffuse = float3{vertex_a.diffuse_r, vertex_a.diffuse_g, vertex_a.diffuse_b};
68+
emissive = float3{vertex_a.emissive_r, vertex_a.emissive_g, vertex_a.emissive_b};
5869
}
5970

6071
template<typename VB>
@@ -147,19 +158,32 @@ namespace cg::renderer
147158
template<typename VB, typename RT>
148159
inline void raytracer<VB, RT>::set_vertex_buffers(std::vector<std::shared_ptr<cg::resource<VB>>> in_vertex_buffers)
149160
{
150-
// TODO Lab: 2.02 Implement `set_vertex_buffers` and `set_index_buffers` of `raytracer` class
161+
vertex_buffers = in_vertex_buffers;
151162
}
152163

153164
template<typename VB, typename RT>
154165
void raytracer<VB, RT>::set_index_buffers(std::vector<std::shared_ptr<cg::resource<unsigned int>>> in_index_buffers)
155166
{
156-
// TODO Lab: 2.02 Implement `set_vertex_buffers` and `set_index_buffers` of `raytracer` class
167+
index_buffers = in_index_buffers;
157168
}
158169

159170
template<typename VB, typename RT>
160171
inline void raytracer<VB, RT>::build_acceleration_structure()
161172
{
162-
// TODO Lab: 2.02 Fill `triangles` vector in `build_acceleration_structure` of `raytracer` class
173+
for (size_t i = 0; i < index_buffers.size(); i++)
174+
{
175+
auto& index_buffer = index_buffers[i];
176+
auto& vertex_buffer = vertex_buffers[i];
177+
size_t index = 0;
178+
while (index < index_buffer->get_number_of_elements())
179+
{
180+
triangle<VB> triangle(
181+
vertex_buffer->item(index_buffer->item(index++)),
182+
vertex_buffer->item(index_buffer->item(index++)),
183+
vertex_buffer->item(index_buffer->item(index++)));
184+
triangles.push_back(triangle);
185+
}
186+
}
163187
// TODO Lab: 2.05 Implement `build_acceleration_structure` method of `raytracer` class
164188
}
165189

@@ -191,7 +215,22 @@ namespace cg::renderer
191215
return miss_shader(ray);
192216
}
193217
depth--;
194-
// TODO Lab: 2.02 Adjust `trace_ray` method of `raytracer` class to traverse geometry and call a closest hit shader
218+
payload closest_hit_payload{};
219+
closest_hit_payload.t = max_t;
220+
const triangle<VB>* closest_triangle = nullptr;
221+
for (auto& triangle: triangles)
222+
{
223+
payload payload = intersection_shader(triangle, ray);
224+
if (payload.t > min_t && payload.t < closest_hit_payload.t)
225+
{
226+
closest_hit_payload = payload;
227+
closest_triangle = &triangle;
228+
}
229+
}
230+
if (closest_hit_payload.t < max_t) {
231+
if (closest_hit_shader)
232+
return closest_hit_shader(ray, closest_hit_payload, *closest_triangle, depth);
233+
}
195234
// TODO Lab: 2.04 Adjust `trace_ray` method of `raytracer` to use `any_hit_shader`
196235
// TODO Lab: 2.05 Adjust `trace_ray` method of `raytracer` class to traverse the acceleration structure
197236
return miss_shader(ray);
@@ -201,8 +240,24 @@ namespace cg::renderer
201240
inline payload raytracer<VB, RT>::intersection_shader(
202241
const triangle<VB>& triangle, const ray& ray) const
203242
{
204-
// TODO Lab: 2.02 Implement an `intersection_shader` method of `raytracer` class
205-
return payload{};
243+
payload payload{};
244+
payload.t = -1.f;
245+
float3 pvec = cross(ray.direction, triangle.ca);
246+
float det = dot(triangle.ba, pvec);
247+
if (det > -1e-8 && det < 1e-8)
248+
return payload;
249+
float inv_det = 1.f / det;
250+
float3 tvec = ray.position - triangle.a;
251+
float u = dot(tvec, pvec) * inv_det;
252+
if (u < 0.f || u > 1.f)
253+
return payload;
254+
float3 qvec = cross(tvec, triangle.ba);
255+
float v = dot(ray.direction, qvec) * inv_det;
256+
if (v < 0.f || u + v > 1.f)
257+
return payload;
258+
payload.t = dot(triangle.ca, qvec) * inv_det;
259+
payload.bary = float3{1.f - u - v, u, v};
260+
return payload;
206261
}
207262

208263
template<typename VB, typename RT>

src/renderer/raytracer/raytracer_renderer.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ void cg::renderer::ray_tracing_renderer::init()
2727
raytracer = std::make_shared<cg::renderer::raytracer<cg::vertex, cg::unsigned_color>>();
2828
raytracer->set_viewport(settings->width, settings->height);
2929
raytracer->set_render_target(render_target);
30+
raytracer->set_vertex_buffers(model->get_vertex_buffers());
31+
raytracer->set_index_buffers(model->get_index_buffers());
3032
// TODO Lab: 2.03 Add light information to `lights` array of `ray_tracing_renderer`
3133
// TODO Lab: 2.04 Initialize `shadow_raytracer` in `ray_tracing_renderer`
3234
}
@@ -52,8 +54,13 @@ void cg::renderer::ray_tracing_renderer::render()
5254
std::chrono::duration<float, std::milli> rt_duration = stop-start;
5355
std::cout<<"Ray tracing took "<< rt_duration.count()<<"ms\n";
5456
cg::utils::save_resource(*render_target, settings->result_path);
55-
56-
// TODO Lab: 2.02 Add `closest_hit_shader` to `raytracer` class to return diffuse color
57+
raytracer->closest_hit_shader = [](const ray& ray, payload& payload,
58+
const triangle<cg::vertex>& triangle,
59+
size_t depth){
60+
payload.color = cg::color::from_float3(triangle.diffuse);
61+
return payload;
62+
};
63+
raytracer->build_acceleration_structure();
5764
// TODO Lab: 2.03 Adjust `closest_hit_shader` of `raytracer` to implement Lambertian shading model
5865
// TODO Lab: 2.04 Define `any_hit_shader` and `miss_shader` for `shadow_raytracer`
5966
// TODO Lab: 2.04 Adjust `closest_hit_shader` of `raytracer` to cast shadows rays and to ignore occluded lights

0 commit comments

Comments
 (0)