Compare commits
	
		
			3 Commits
		
	
	
		
			a4e67ebc18
			...
			8b9ac28402
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 8b9ac28402 | |||
| f34e234609 | |||
| 0b7ca65967 | 
@@ -28,31 +28,46 @@ typedef struct {
 | 
			
		||||
#define vec_add(T, v1, v2) vec_add_##T(v1, v2)
 | 
			
		||||
#define vec_sub(T, v1, v2) vec_sub_##T(v1, v2)
 | 
			
		||||
#define vec_mul(T, v1, v2) vec_mul_##T(v1, v2)
 | 
			
		||||
#define vec_mul_num(T, v1, num) vec_mul_num_##T(v1, num)
 | 
			
		||||
#define vec_div_num(T, v1, num) vec_div_num_##T(v1, num)
 | 
			
		||||
#define vec_dot(T, v1, v2) vec_dot_##T(v1, v2)
 | 
			
		||||
#define vec_magnitude(T, v) vec_magnitude_##T(v)
 | 
			
		||||
#define vec_unit(T, v) vec_unit_##T(v)
 | 
			
		||||
 | 
			
		||||
vec2i_t vec_add_vec2i_t(vec2i_t v1, vec2i_t v2);
 | 
			
		||||
vec2i_t vec_sub_vec2i_t(vec2i_t v1, vec2i_t v2);
 | 
			
		||||
vec2i_t vec_mul_vec2i_t(vec2i_t v1, vec2i_t v2);
 | 
			
		||||
vec2i_t vec_mul_num_vec2i_t(vec2i_t v1, i32 num);
 | 
			
		||||
vec2i_t vec_div_num_vec2i_t(vec2i_t v1, i32 num);
 | 
			
		||||
i32 vec_dot_vec2i_t(vec2i_t v1, vec2i_t v2);
 | 
			
		||||
i32 vec_magnitude_vec2i_t(vec2i_t v);
 | 
			
		||||
vec2i_t vec_unit_vec2i_t(vec2i_t v);
 | 
			
		||||
 | 
			
		||||
vec2f_t vec_add_vec2f_t(vec2f_t v1, vec2f_t v2);
 | 
			
		||||
vec2f_t vec_sub_vec2f_t(vec2f_t v1, vec2f_t v2);
 | 
			
		||||
vec2f_t vec_mul_vec2f_t(vec2f_t v1, vec2f_t v2);
 | 
			
		||||
vec2f_t vec_mul_num_vec2f_t(vec2f_t v1, f32 num);
 | 
			
		||||
vec2f_t vec_div_num_vec2f_t(vec2f_t v1, f32 num);
 | 
			
		||||
f32 vec_dot_vec2f_t(vec2f_t v1, vec2f_t v2);
 | 
			
		||||
f32 vec_magnitude_vec2f_t(vec2f_t v);
 | 
			
		||||
vec2f_t vec_unit_vec2f_t(vec2f_t v);
 | 
			
		||||
 | 
			
		||||
vec3i_t vec_add_vec3i_t(vec3i_t v1, vec3i_t v2);
 | 
			
		||||
vec3i_t vec_sub_vec3i_t(vec3i_t v1, vec3i_t v2);
 | 
			
		||||
vec3i_t vec_mul_vec3i_t(vec3i_t v1, vec3i_t v2);
 | 
			
		||||
vec3i_t vec_mul_num_vec3i_t(vec3i_t v1, i32 num);
 | 
			
		||||
vec3i_t vec_div_num_vec3i_t(vec3i_t v1, i32 num);
 | 
			
		||||
i32 vec_dot_vec3i_t(vec3i_t v1, vec3i_t v2);
 | 
			
		||||
i32 vec_magnitude_vec3i_t(vec3i_t v);
 | 
			
		||||
vec3i_t vec_unit_vec3i_t(vec3i_t v);
 | 
			
		||||
 | 
			
		||||
vec3f_t vec_add_vec3f_t(vec3f_t v1, vec3f_t v2);
 | 
			
		||||
vec3f_t vec_sub_vec3f_t(vec3f_t v1, vec3f_t v2);
 | 
			
		||||
vec3f_t vec_mul_vec3f_t(vec3f_t v1, vec3f_t v2);
 | 
			
		||||
vec3f_t vec_mul_num_vec3f_t(vec3f_t v1, f32 num);
 | 
			
		||||
vec3f_t vec_div_num_vec3f_t(vec3f_t v1, f32 num);
 | 
			
		||||
f32 vec_dot_vec3f_t(vec3f_t v1, vec3f_t v2);
 | 
			
		||||
f32 vec_magnitude_vec3f_t(vec3f_t v);
 | 
			
		||||
vec3f_t vec_unit_vec3f_t(vec3f_t v);
 | 
			
		||||
 | 
			
		||||
#endif // !VEC_H
 | 
			
		||||
 
 | 
			
		||||
@@ -15,9 +15,28 @@ typedef struct {
 | 
			
		||||
  colour_t colour;
 | 
			
		||||
} sphere_t;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  LIGHT_TYPE_POINT,
 | 
			
		||||
  LIGHT_TYPE_DIRECTIONAL,
 | 
			
		||||
  LIGHT_TYPE_AMBIENT,
 | 
			
		||||
 | 
			
		||||
  COUNT_LIGHT_TYPE,
 | 
			
		||||
} light_type_t;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  light_type_t type;
 | 
			
		||||
  f32 intensity;
 | 
			
		||||
  union {
 | 
			
		||||
    vec3f_t position;
 | 
			
		||||
    vec3f_t direction;
 | 
			
		||||
  };
 | 
			
		||||
} light_t;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  sphere_t *spheres;
 | 
			
		||||
  u32 count;
 | 
			
		||||
  light_t *lights;
 | 
			
		||||
  u32 spheres_count;
 | 
			
		||||
  u32 lights_count;
 | 
			
		||||
} scene_t;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
@@ -29,6 +48,9 @@ solutions_t ray_intersects_sphere(vec3f_t origin, vec3f_t direction,
 | 
			
		||||
                                  sphere_t sphere);
 | 
			
		||||
colour_t trace_ray(vec3f_t origin, vec3f_t direction, f32 t_min, f32 t_max,
 | 
			
		||||
                   const scene_t *scene, colour_t default_colour);
 | 
			
		||||
f32 compute_lighting(vec3f_t P, vec3f_t N, const scene_t *scene);
 | 
			
		||||
f32 light_diffuse(f32 light_intensity, vec3f_t light_direction,
 | 
			
		||||
                  vec3f_t surface_normal);
 | 
			
		||||
 | 
			
		||||
i32 main(i32 argc, char *argv[]) {
 | 
			
		||||
  colour_t bg =
 | 
			
		||||
@@ -67,11 +89,37 @@ i32 main(i32 argc, char *argv[]) {
 | 
			
		||||
              (colour_t){
 | 
			
		||||
                  .rgba.r = 171, .rgba.g = 52, .rgba.b = 40, .rgba.a = 255},
 | 
			
		||||
      },
 | 
			
		||||
      (sphere_t){
 | 
			
		||||
          .radius = 5000.0f,
 | 
			
		||||
          .centre = (vec3f_t){.x = 0.0f, .y = -5001.0f, .z = 0.0f},
 | 
			
		||||
          .colour =
 | 
			
		||||
              (colour_t){
 | 
			
		||||
                  .rgba.r = 255, .rgba.g = 255, .rgba.b = 0, .rgba.a = 255},
 | 
			
		||||
      },
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  light_t lights[] = {
 | 
			
		||||
      (light_t){
 | 
			
		||||
          .type = LIGHT_TYPE_AMBIENT,
 | 
			
		||||
          .intensity = 0.2f,
 | 
			
		||||
      },
 | 
			
		||||
      (light_t){
 | 
			
		||||
          .type = LIGHT_TYPE_POINT,
 | 
			
		||||
          .intensity = 0.6f,
 | 
			
		||||
          .position = (vec3f_t){.x = 2.0f, .y = 1.0f, .z = 0.0f},
 | 
			
		||||
      },
 | 
			
		||||
      (light_t){
 | 
			
		||||
          .type = LIGHT_TYPE_DIRECTIONAL,
 | 
			
		||||
          .intensity = 0.2f,
 | 
			
		||||
          .direction = (vec3f_t){.x = 1.0f, .y = 4.0f, .z = 4.0f},
 | 
			
		||||
      },
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  scene_t scene = {
 | 
			
		||||
      .spheres = spheres,
 | 
			
		||||
      .count = ARR_LEN(spheres),
 | 
			
		||||
      .lights = lights,
 | 
			
		||||
      .spheres_count = ARR_LEN(spheres),
 | 
			
		||||
      .lights_count = ARR_LEN(lights),
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  i32 w_min = ((i32)window.half_width) * -1;
 | 
			
		||||
@@ -131,7 +179,7 @@ colour_t trace_ray(vec3f_t origin, vec3f_t direction, f32 t_min, f32 t_max,
 | 
			
		||||
  f32 closest_t = INFINITY;
 | 
			
		||||
  sphere_t *closest_sphere = NULL;
 | 
			
		||||
 | 
			
		||||
  for (u32 i = 0; i < scene->count; ++i) {
 | 
			
		||||
  for (u32 i = 0; i < scene->spheres_count; ++i) {
 | 
			
		||||
    solutions_t solutions =
 | 
			
		||||
        ray_intersects_sphere(origin, direction, scene->spheres[i]);
 | 
			
		||||
 | 
			
		||||
@@ -152,5 +200,63 @@ colour_t trace_ray(vec3f_t origin, vec3f_t direction, f32 t_min, f32 t_max,
 | 
			
		||||
    return default_colour;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return closest_sphere->colour;
 | 
			
		||||
  vec3f_t P =
 | 
			
		||||
      vec_add(vec3f_t, origin, vec_mul_num(vec3f_t, direction, closest_t));
 | 
			
		||||
  vec3f_t N = vec_sub(vec3f_t, P, closest_sphere->centre);
 | 
			
		||||
  N = vec_div_num(vec3f_t, N, vec_magnitude(vec3f_t, N));
 | 
			
		||||
 | 
			
		||||
  f32 light = compute_lighting(P, N, scene);
 | 
			
		||||
 | 
			
		||||
  return (colour_t){.rgba.r = closest_sphere->colour.rgba.r * light,
 | 
			
		||||
                    .rgba.g = closest_sphere->colour.rgba.g * light,
 | 
			
		||||
                    .rgba.b = closest_sphere->colour.rgba.b * light,
 | 
			
		||||
                    .rgba.a = closest_sphere->colour.rgba.a};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
f32 compute_lighting(vec3f_t P, vec3f_t N, const scene_t *scene) {
 | 
			
		||||
  f32 I = 0.0f;
 | 
			
		||||
  light_t light = {0};
 | 
			
		||||
 | 
			
		||||
  for (u32 i = 0; i < scene->lights_count; ++i) {
 | 
			
		||||
    light = scene->lights[i];
 | 
			
		||||
 | 
			
		||||
    if (light.type == LIGHT_TYPE_AMBIENT) {
 | 
			
		||||
      I += light.intensity;
 | 
			
		||||
    } else {
 | 
			
		||||
      vec3f_t L = {0};
 | 
			
		||||
 | 
			
		||||
      switch (light.type) {
 | 
			
		||||
      case LIGHT_TYPE_POINT:
 | 
			
		||||
        L = vec_sub(vec3f_t, light.position, P);
 | 
			
		||||
        break;
 | 
			
		||||
      case LIGHT_TYPE_DIRECTIONAL:
 | 
			
		||||
        L = light.direction;
 | 
			
		||||
        break;
 | 
			
		||||
      default:
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      I += light_diffuse(light.intensity, L, N);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return I;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
f32 light_diffuse(f32 light_intensity, vec3f_t light_direction,
 | 
			
		||||
                  vec3f_t surface_normal) {
 | 
			
		||||
  f32 dot_product = vec_dot(vec3f_t, light_direction, surface_normal);
 | 
			
		||||
 | 
			
		||||
  if (dot_product < 0.0f) {
 | 
			
		||||
    return 0.0f;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  f32 divisor = vec_magnitude(vec3f_t, light_direction) *
 | 
			
		||||
                vec_magnitude(vec3f_t, surface_normal);
 | 
			
		||||
 | 
			
		||||
  if (divisor == 0.0f) {
 | 
			
		||||
    return 0.0f;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return light_intensity * dot_product / divisor;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,14 @@ vec2i_t vec_mul_vec2i_t(vec2i_t v1, vec2i_t v2) {
 | 
			
		||||
  return (vec2i_t){.x = v1.x * v2.x, .y = v1.y * v2.y};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vec2i_t vec_mul_num_vec2i_t(vec2i_t v1, i32 num) {
 | 
			
		||||
  return (vec2i_t){.x = v1.x * num, .y = v1.y * num};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vec2i_t vec_div_num_vec2i_t(vec2i_t v1, i32 num) {
 | 
			
		||||
  return (vec2i_t){.x = v1.x / num, .y = v1.y / num};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
i32 vec_dot_vec2i_t(vec2i_t v1, vec2i_t v2) {
 | 
			
		||||
  return v1.x * v2.x + v1.y * v2.y;
 | 
			
		||||
}
 | 
			
		||||
@@ -22,6 +30,11 @@ i32 vec_magnitude_vec2i_t(vec2i_t v) {
 | 
			
		||||
  return (i32)sqrtf((f32)dot_product);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vec2i_t vec_unit_vec2i_t(vec2i_t v) {
 | 
			
		||||
  i32 magnitude = vec_magnitude_vec2i_t(v);
 | 
			
		||||
  return (vec2i_t){v.x / magnitude, v.y / magnitude};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vec2f_t vec_add_vec2f_t(vec2f_t v1, vec2f_t v2) {
 | 
			
		||||
  return (vec2f_t){.x = v1.x + v2.x, .y = v1.y + v2.y};
 | 
			
		||||
}
 | 
			
		||||
@@ -34,6 +47,14 @@ vec2f_t vec_mul_vec2f_t(vec2f_t v1, vec2f_t v2) {
 | 
			
		||||
  return (vec2f_t){.x = v1.x * v2.x, .y = v1.y * v2.y};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vec2f_t vec_mul_num_vec2f_t(vec2f_t v1, f32 num) {
 | 
			
		||||
  return (vec2f_t){.x = v1.x * num, .y = v1.y * num};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vec2f_t vec_div_num_vec2f_t(vec2f_t v1, f32 num) {
 | 
			
		||||
  return (vec2f_t){.x = v1.x / num, .y = v1.y / num};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
f32 vec_dot_vec2f_t(vec2f_t v1, vec2f_t v2) {
 | 
			
		||||
  return v1.x * v2.x + v1.y * v2.y;
 | 
			
		||||
}
 | 
			
		||||
@@ -43,6 +64,11 @@ f32 vec_magnitude_vec2f_t(vec2f_t v) {
 | 
			
		||||
  return sqrtf(dot_product);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vec2f_t vec_unit_vec2f_t(vec2f_t v) {
 | 
			
		||||
  f32 magnitude = vec_magnitude_vec2f_t(v);
 | 
			
		||||
  return (vec2f_t){v.x / magnitude, v.y / magnitude};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vec3i_t vec_add_vec3i_t(vec3i_t v1, vec3i_t v2) {
 | 
			
		||||
  return (vec3i_t){.x = v1.x + v2.x, .y = v1.y + v2.y, .z = v1.z + v2.z};
 | 
			
		||||
}
 | 
			
		||||
@@ -55,6 +81,14 @@ vec3i_t vec_mul_vec3i_t(vec3i_t v1, vec3i_t v2) {
 | 
			
		||||
  return (vec3i_t){.x = v1.x * v2.x, .y = v1.y * v2.y, .z = v1.z * v2.z};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vec3i_t vec_mul_num_vec3i_t(vec3i_t v1, i32 num) {
 | 
			
		||||
  return (vec3i_t){.x = v1.x * num, .y = v1.y * num, .z = v1.z * num};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vec3i_t vec_div_num_vec3i_t(vec3i_t v1, i32 num) {
 | 
			
		||||
  return (vec3i_t){.x = v1.x / num, .y = v1.y / num, .z = v1.z / num};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
i32 vec_dot_vec3i_t(vec3i_t v1, vec3i_t v2) {
 | 
			
		||||
  return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
 | 
			
		||||
}
 | 
			
		||||
@@ -64,6 +98,11 @@ i32 vec_magnitude_vec3i_t(vec3i_t v) {
 | 
			
		||||
  return (i32)sqrtf((f32)dot_product);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vec3i_t vec_unit_vec3i_t(vec3i_t v) {
 | 
			
		||||
  i32 magnitude = vec_magnitude_vec3i_t(v);
 | 
			
		||||
  return (vec3i_t){v.x / magnitude, v.y / magnitude, v.z / magnitude};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vec3f_t vec_add_vec3f_t(vec3f_t v1, vec3f_t v2) {
 | 
			
		||||
  return (vec3f_t){.x = v1.x + v2.x, .y = v1.y + v2.y, .z = v1.z + v2.z};
 | 
			
		||||
}
 | 
			
		||||
@@ -72,6 +111,14 @@ vec3f_t vec_sub_vec3f_t(vec3f_t v1, vec3f_t v2) {
 | 
			
		||||
  return (vec3f_t){.x = v1.x - v2.x, .y = v1.y - v2.y, .z = v1.z - v2.z};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vec3f_t vec_mul_num_vec3f_t(vec3f_t v1, f32 num) {
 | 
			
		||||
  return (vec3f_t){.x = v1.x * num, .y = v1.y * num, .z = v1.z * num};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vec3f_t vec_div_num_vec3f_t(vec3f_t v1, f32 num) {
 | 
			
		||||
  return (vec3f_t){.x = v1.x / num, .y = v1.y / num, .z = v1.z / num};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vec3f_t vec_mul_vec3f_t(vec3f_t v1, vec3f_t v2) {
 | 
			
		||||
  return (vec3f_t){.x = v1.x * v2.x, .y = v1.y * v2.y, .z = v1.z * v2.z};
 | 
			
		||||
}
 | 
			
		||||
@@ -84,3 +131,8 @@ f32 vec_magnitude_vec3f_t(vec3f_t v) {
 | 
			
		||||
  f32 dot_product = vec_dot_vec3f_t(v, v);
 | 
			
		||||
  return sqrtf(dot_product);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vec3f_t vec_unit_vec3f_t(vec3f_t v) {
 | 
			
		||||
  f32 magnitude = vec_magnitude_vec3f_t(v);
 | 
			
		||||
  return (vec3f_t){v.x / magnitude, v.y / magnitude, v.z / magnitude};
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user