GithubHelp home page GithubHelp logo

znichola / minirt Goto Github PK

View Code? Open in Web Editor NEW
0.0 1.0 0.0 8.39 MB

A ray tracer with the phong lightning mode, multiple light sources, texture mapping and 4 primitive shapes; sphere, cylinder, plane and cone.

Makefile 1.71% C 84.93% Objective-C 13.36%
ecole42 ray-tracing

minirt's Introduction

miniRT

Resources:

introdution

In this exercice, we have to write a basic raytracer in C. We need to support at least the following shapes:

  • sphere
  • plane
  • cylinder

parsing

We need to be able to parse files that contain the description of the scene we need to render.

The grammar is roughly as follows:

file         := {line}
line         := ( ambient | camera | light | sphere | plane | cylinder | cone ) line_end

ambient      := "a"  ratio color
camera       := "c"  position unitvector fov
light        := "l"  position ratio color

sphere       := "sp" position diameter color [optional]
plane        := "pl" position unitvector color [optional]
cylinder     := "cy" position unitvector diameter height color [optional]
cone         := "co" position unitvector diameter height angle color [optional]

optional        := [texture] [bmp] [normal_map] [checkerboard]

checkerboard := "checkerboard"

texture      := "texture:"path
bmp          := "bmp:"path
normal_map   := "normal_map:"path

path         := "relative_path/to/file.xpm"
line_end     := lf | crlf | eof

Some extra validation needs to be done after verifying the grammar, for example, there can only be one camera in the scene.

Here is an example of a valid scene containing 2 spheres:

A	0.2									255,255,255
C	0,0,0 0,0,1	70
L	-40,0,30		0.9					255,255,255
sp	10,0,51			10					250,100,200
sp	0,0,42			20					255,0,0

rendering

The raytracing technique consists in computing rays starting from the camera pinhole going through the pixels of the image we're rendering. By computing the color of the object that ray intersects with, we get the color of that corresponding pixel. This technique allows us to realistically compute shadows and reflection.

lighting

In this project, we use the ambiant, diffuse and specular lighting model. Specular reflection:

textures / bump maps / normal maps

UI

In this project we are required to be able to move all objects in the scene. This means we need to find a way for the user to interact with the objects and change their coordinates.

maths

In this project, we use a lot of operation between vectors.

minirt's People

Contributors

sophiakoulen avatar znichola avatar

Watchers

 avatar

minirt's Issues

float converstion lookup table

Just an ides, idk if it's worth exploring, but we can make a lookup table to convert 0-255 int to float. As we'll be doing that quite a bit I think.

Allow parsing of textures

internal structure needs to be able to hold texture, bmp and normal maps and the parsing should support any number of them.

The files are stored as a char* that is the string to the path of the file.

Refactor keybining

The keybinding should be able to bind the selected object and print only the changes variable to the terminal correctly named.

Extending this: changes variables should be displayed on the screen.

Interactivity

This is just to get some ideas down on paper, the possibility to modify stuff on the fly is kinda important for the dev process and also because it's cool.

// int	scale_property(t_app *a, float *property, char *ctrl, int key, float factor)

scale_property(a, &a->l_origin.z, "my", e_mouse_right, 1);

This is the function we have now, we can "animate" any property with a change in one of the two mouse axis.
For instance the configuration above will modify the light's z value when the right button is held based on the distance the mouse has moved since the last frame.

scale_property(a, &a->sp_radius, "ky", e_key_s, 0.2)

Or for instance the radius is modified while the "s" key is held with the a scaling factor of 0.2.

The limitation of this interaction model is that each action must be mapped to a unique key and only happens while it's held.

can't run the unit tets

➜  miniRT git:(refactor) cd tests 
➜  tests git:(refactor) ✗ make
make archive -C ..
gcc -Wall -Wextra -Ofast -Iincludes/. -Imlx -Ilibft/includes -Ignl -c srcs/render/render_world.c -o objs/render/render_world.o
srcs/render/render_world.c:143:14: warning: unused function 'list_obj_content' [-Wunused-function]
static void     *list_obj_content(t_list *obj)
                 ^
1 warning generated.
mkdir -p tmp1 tmp2 tmp3
cd tmp1; ar -x ../mlx/libmlx.a
cd tmp2; ar -x ../gnl/libgnl.a
cd tmp3; ar -x ../libft/libft.a
ar -rcs libminirt.a tmp1/* tmp2/* tmp3/* objs/main.o objs/ui/destroy_window.o objs/ui/mouse_hooks.o objs/ui/keyboard_hooks.o objs/render/render_frame.o objs/render/put_pixel.o objs/render/render_sphere.o objs/render/trpg_colour.o objs/render/light.o objs/render/lerp_colour.o objs/render/the_moon.o objs/render/multithread.o objs/render/render_colour.o objs/render/render_world.o objs/maths/vector.o objs/maths/matrix.o objs/maths/poi_sphere.o objs/utils/debug_prints.o objs/utils/singletons.o objs/parsing/parse.o objs/parsing/parse_utils.o objs/parsing/parse_scalar.o objs/parsing/parse_properties.o objs/parsing/parse_objects1.o objs/parsing/parse_objects2.o objs/parsing/scene.o objs/parsing/parse_error.o objs/parsing/scene_add_object.o objs/primitives/sphere.o objs/primitives/plane.o objs/primitives/cylinder.o
rm -rf tmp1 tmp2 tmp3
gcc -Wall -Wextra -c -I. -I../includes/ -I../mlx -I../gnl -I../libft/includes -I/include -o main.o main.c
In file included from main.c:13:
./test.h:19:11: fatal error: 'check.h' file not found
# include "check.h"
          ^~~~~~~~~
1 error generated.
make: *** [main.o] Error 1
➜  tests git:(refactor) ✗ 

Sphere intersection finds all intersection points, even thoes behind the viewer!

The green sphere is behind the camera, but it still shows up as in view. Interestingly it's normals seems to be inverted per pixel.
Screen Shot 2023-03-25 at 4 56 34 PM

Found this bug while doing the shadows and was getting un-explained results.

The shadow at a pixel is calculated from the colour of the first intersecting object when going from the surface towards the light.
You can see that any objects along this line count as an intersection for this pixel which is not correct.
https://user-images.githubusercontent.com/12100623/227728794-09ea7a1c-efd3-4770-8045-4d6fc44204df.mov

Dynamic object selection

trace a ray from the mouse position at click and shoot a ray to select an object in world space.

Enum mismatched

emus order is mismatched so things are extremely wonky, it's impressive the level of mess C lets you get with.

new camera orientation is bugged

orientation vector can't have any terms negative when loading from map, idk it's a strange bug as it's the same validation code as the other shapes which can...

Parsing is broken after norming

The error messages are incorrect. It always outputs: invalid identifier on line ....
This is because i used some tricks to reduce the number of lines of code in the parse() function.

Selected object structure

Represent the currently selected object, and create the accessor functions that return a pointer to the position colour etc, whatever we might want to change via a keybind.

I broke the sphere unit tests

poi_sphere should be returning the distance to the poi from the origin, not an int 1/0. I tried changing the tests to fix, but can't run them to check.

Some wierd issue with bmp maps

They currently very strongly affect the direction the light is overall coming from but show little gradual effect. And the results just seem to be wrong.

refactor find poi

t_v3	pix_shader(t_scene *s, t_object *me, t_v3 poo, t_v3 poi)
{
	t_v3	obj_col;
	t_v3	ambiant;
	t_v3	diffuse;
	t_v3	specular;
	t_v3	poi_norm;

	poi_norm = v3_unitvec(v3_subtract(get_obj_pos(me), poi)); // need to pass this to other functions for opti!
	obj_col = get_obj_emmision(me, poi);
	ambiant = v3_multiply(s->ambiant.colour, s->ambiant.ratio);

	t_v3	tmp = ORIGIN;
	if (find_poi(s, v3_unitvec(v3_subtract(poi, get_light(s, 0)->position)), poi, &tmp))
		return (col_multi(ambiant, obj_col));
	else
	{
		diffuse = get_light_diffuse(s, 0, me, poi);
		specular = get_light_specular(s, poo, poi, poi_norm);
	}

	// specular = ORIGIN; // uncomment to switch off spec component.
	// diffuse = ORIGIN;
	// ambiant = ORIGIN;
	// obj_col = (t_v3){1.0f, 1.0f, 1.0f};

	// return (col_multi(col_add(col_add(ambiant, diffuse), specular), obj_col));
	return (col_add(col_multi(col_add(ambiant, diffuse), obj_col), specular)); // I think this is correct but it's not how the openGL site explains it.
}

We need to check if the light ray hits another object after a bounce, this can be kinda annoying, maybe the solution is the refactor find poi so it doesn't look for intersections with an object.

ToDO for finish

  • - Cylinder
  • - - it is broken, must fix
  • - - - poi on cap
  • - - - normal on cap
  • - - - normal on body, all cases, don't cheat with the weird inside out cylinder
  • - - Refactor sphere to use new poi variable
  • - - FIx plane rendering
  • - Object selection UI indicator
  • - Object property modifier
  • - Finalise the frikin' parsing
  • - Refactor pix shader to use t_intersection
  • - Plug leaks!
  • - - Do more thorough tests

Bonus !

  • - checkerboard
  • - - cylinder uv unwrap!
  • - texture integration
  • - - cylinder uv unwrap!
  • - skybox
  • - multithreading !?
  • - cone!
  • - - same todo list as cylinder

For now...

data races

WARNING: ThreadSanitizer: data race (pid=59476)
  Read of size 4 at 0x00010a0e82b4 by thread T8:
    #0 get_ratio singletons.c:105 (miniRT:x86_64+0x100013fe8)
    #1 pixel_to_ray render_world.c:44 (miniRT:x86_64+0x1000084b7)
    #2 partial_render multithread.c:119 (miniRT:x86_64+0x100020c4c)
    #3 thread_routine multithread.c:96 (miniRT:x86_64+0x100020b08)

  Previous write of size 4 at 0x00010a0e82b4 by thread T7:
    #0 get_ratio singletons.c:109 (miniRT:x86_64+0x1000140dd)
    #1 pixel_to_ray render_world.c:44 (miniRT:x86_64+0x1000084b7)
    #2 partial_render multithread.c:119 (miniRT:x86_64+0x100020c4c)
    #3 thread_routine multithread.c:96 (miniRT:x86_64+0x100020b08)

  As if synchronized via sleep:
    #0 usleep <null>:3 (libclang_rt.tsan_osx_dynamic.dylib:x86_64h+0x2c5ae)
    #1 thread_routine multithread.c:95 (miniRT:x86_64+0x100020ad4)

  Location is global 'get_ratio.extents' at 0x00010a0e82b4 (miniRT+0x0001000482b4)

  Thread T8 (tid=2616602, running) created by main thread at:
    #0 pthread_create <null>:3 (libclang_rt.tsan_osx_dynamic.dylib:x86_64h+0x2d8fd)
    #1 start_threads multithread.c:68 (miniRT:x86_64+0x100020961)
    #2 main main.c:49 (miniRT:x86_64+0x100003665)

  Thread T7 (tid=2616601, running) created by main thread at:
    #0 pthread_create <null>:3 (libclang_rt.tsan_osx_dynamic.dylib:x86_64h+0x2d8fd)
    #1 start_threads multithread.c:68 (miniRT:x86_64+0x100020961)
    #2 main main.c:49 (miniRT:x86_64+0x100003665)

SUMMARY: ThreadSanitizer: data race singletons.c:105 in get_ratio
==================
ThreadSanitizer: reported 10 warnings

write funciton to free images

The t_image_data is a struct that we need to free if we want to overwrite loaded image data, so something to free it!

Shadow bug

Screen Shot 2023-03-27 at 6 47 47 PM

There should not be a shadow on the red sphere as the light is not being intersected, it's difficult to tell but this seems logical.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.