LuxMancer: Mastering Light and Shadow- MINIRT: PART 2

SLEEPS
6 min readJan 22, 2024

--

Decoding 3D Worlds: A Guide to Parsing Maps for Ray Tracing

Collaborative Authors: Unraveling Map Parsing in Ray Tracing

This blog post is a joint endeavor by RIDWANE EL FILALI and MOHCINE GHALMI, as we navigate the intricacies of map parsing within the realm of ray tracing. Together, we explore the nuanced interplay of vector mathematics, graphics, and ray tracing to shed light on the applications of this technology in mapping scenarios.

Check out RIDWANE EL FILALI’s GitHub for more on map parsing in ray tracing.

Connect with RIDWANE EL FILALI on Medium to dive deeper into his perspectives and insights on map parsing in ray tracing.

Introduction

In the mesmerizing realm of computer graphics, the art of creating virtual worlds relies heavily on the ability to interpret and process intricate scene descriptions. In the context of ray tracing, where each pixel is meticulously calculated to simulate the interplay of light and materials, the foundation lies in parsing maps.

Understanding the Basics

Before delving into the parsing intricacies, let’s establish a solid understanding of the core components that constitute a scene description. In the context of ray tracing, a map typically contains details about the camera, lights, and various objects populating the virtual environment.

R 1024 720 (resolution)

A 0.2 255,255,255 (Ambient light)

c 0,1.8,-1 0,-0.15,1 70 (Camera)

l 0,3.8,3.8 0.4 255,0,0 (Light)

pl 0,0.3,0 0,1,0 255,255,255 (Plane)

cy 0,3.2,3.8 0,1,0 1 0.3 255,255,255 (Cylinder)

sp 0,3.5,3.8 1 255,255,255 (Sphere)

1-resolution: This line is specifying the resolution of an image height and width

2-Ambient lightning: non-directional light that helps illuminate a scene globally, simulating the indirect light that comes from all directions. The specified intensity and color will contribute to the overall lighting of the scene, providing a base level of illumination.

3- Camera Settings: Define the viewpoint and perspective through parameters such as position, orientation, and field of view (FOV). The camera acts as the eye through which the virtual world is observed. is the source where we shoot rays

4- Lights: Specify the light sources that illuminate the scene. This includes ambient lighting for overall illumination and point lights for localized brightness.

5- Objects: Describe the geometry present in the scene spheres, planes, cylinders, and more along with their respective attributes such as position, size, and material properties.

Setting the Stage:

  • The code begins by initializing key variables, clearing any previous scene data, and announcing its intent to parse the scene. It eagerly opens the scene file, ready to devour its contents.
  • The scene file is read into a string, ensuring a tasty meal for the parsing functions.
str = line(str, fd);
  • Dissecting the Elements The
parse_elems()

function takes center stage, leading the systematic analysis of the scene description. It diligently checks each character in the string, seeking meaningful patterns and clues. checking new lines and commented lines.

Identifying Key Components expertly distinguishes between essential scene elements, such as:

  • Resolution (R)
  • Ambient light (A)
  • Camera (C)
  • Various geometric shapes (cylinders, cubes, spheres, squares, planes, pyramids, triangles) For each element, it calls upon specialized parsing functions to extract and store their specific properties.

Enforcing Scene Integrity:

It acts as a vigilant gatekeeper, ensuring the scene description contains all necessary elements for rendering. If any crucial components are missing, it raises an error, preventing a subpar rendering experience.

 parse(mlx, scene, list, &str);

Assembling the Scene As it processes each element, it meticulously constructs a comprehensive representation of the 3D scene within the program’s memory. This intricate model forms the foundation for subsequent rendering steps.

Let’s break down the parsing logic for each relevant function:

void parse(t_mlx *mlx, t_scene *scene, t_obj **list, char **str)
{
char *ret;
ret = *str;
if (*ret == 'R' && *(ret++))
parse_res(scene, &ret);
else if (*ret == 'A' && *(ret++))
parse_ambient_light(scene, &ret);
else if (*ret == 'c' && (*(ret + 1) == 32 || *(ret + 1) == 9) && *(ret++))
parse_camera(mlx, scene, &ret);
else if (*ret == 'c' && *(ret + 1) == 'y' && *(ret++) && *(ret++))
parse_cylinder(list, &ret);
else if (*ret == 'c' && *(ret + 1) == 'u' && *(ret++) && *(ret++))
parse_cube(list, &ret);
else if (*ret == 'l' && (*(ret + 1) == 32 || *(ret + 1) == 9) && *(ret++))
parse_light(&scene, &ret);
else if (*ret == 's' && *(ret + 1) == 'p' && *(ret++) && *(ret++))
parse_sphere(list, &ret);
else if (*ret == 's' && *(ret + 1) == 'q' && *(ret++) && *(ret++))
parse_square(list, &ret);
else if (*ret == 'p' && *(ret + 1) == 'l' && *(ret++) && *(ret++))
parse_plane(list, &ret);
parse2(list , ret);
*str = ret;
}

1- Resolution Parsing:

typedef struct  s_scene
{
int res_init;
int xres;
int yres;
int cam_nb;
t_light *l;
int al_init;
double ambient_light;
int al_color;
int bgr;
} t_scene;
  • Initialization:

Check if resolution (R) has already been initialized (int res_init). If yes, display an error. If not, mark resolution as initialized

  • Parsing:

Move the string pointer to the next character.
Parse and set the (int xres)(X Resolution) and (int yres) (Y Resolution) values.
Check if the parsed values are within a valid range.

2- Ambient Light Parsing:

typedef struct  s_scene
{
int res_init;
int xres;
int yres;
int cam_nb;
t_light *l;
int al_init;
double ambient_light;
int al_color;
int bgr;
} t_scene;
  • Initialization:

Check if ambient light (A) has already been initialized (int al_init). If yes, display an error. If not, mark ambient light as initialized

  • Parsing:

Move the string pointer to the next character.

next(str);

Parse and set the ambient light intensity (double ambient_light).
Check if the parsed value is within a valid range.
Parse and set the ambient light color (int al_color).

3- Camera Parsing:

typedef struct  s_scene
{
int res_init;
int xres;
int yres;
int cam_nb;
t_light *l;
int al_init;
double ambient_light;
int al_color;
int bgr;
} t_scene;

typedef struct s_mlx
{
void *mlx;
void *win;
t_cam *cam;
t_cam *begin;
} t_mlx;

typedef struct s_cam
{
int idx;
t_point o;
t_point nv;
int fov;
void *img_ptr;
int *px_img;
int bits_per_pixel;
int size_line;
int endian;
struct s_cam *next;
} t_cam;
  • Initialization:

Create a new camera element.
Track the previous camera index to assign a unique index (int idx)to the new camera.

  • Parsing:

Move the string pointer to the next character.
Parse and set the camera position (o) (t_point o).
Parse and set the camera normalized view (nv) (t_point nv).
Parse and set the camera field of view (fov) (int fov).
Check if the parsed field of view is within a valid range.
Assign a unique index to the camera. Update the camera list.

typedef struct  s_scene
{
int res_init;
int xres;
int yres;
int cam_nb;
t_light *l;
int al_init;
double ambient_light;
int al_color;
int bgr;
} t_scene;

typedef struct s_light
{
t_point o;
double br;
int color;
struct s_light *next;
} t_light;

3- Light Parsing:

  • Initialization:

TCreate a new light element.
Track the initial light list pointer.

  • Parsing:

Move the string pointer to the next character.
Parse and set the light position (o) (t_point o).
Parse and set the light brightness (br) (double br).
Check if the parsed brightness is within a valid range.
Parse and set the light color (int color).
Update the light list.

union   u_figures
{
t_sphere sp;
t_plane pl;
t_square sq;
t_cylinder cy;
t_triangle tr;
};

4- Figure Parsing:

  • Initialization:

Create a new figure element.
Track the initial figure list pointer.

  • Parsing:

Move the string pointer to the next character.
Parse and set figure-specific properties (position, size, color, etc.).
Check if the parsed values are within valid ranges.
Update the figure list.

--

--