@@ -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 = ▵
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>
0 commit comments