├── CSDL.h ├── LICENSE ├── Makefile ├── README.md ├── TODO.txt ├── _config.yml ├── index.html ├── iocccray.json ├── iocccray.real ├── main14.png ├── origins.json ├── origins.real ├── ray_go ├── raygo.go └── src │ └── vec │ ├── vec.go │ └── vec_test.go ├── ray_rust ├── Cargo.lock ├── Cargo.toml └── src │ ├── lib.rs │ └── main.rs ├── ray_v ├── README.md ├── rayv.v └── vec │ └── vec.v ├── rayc.c ├── raycpp.cpp ├── raypy.py ├── realist.cpp ├── rtiow ├── C │ ├── Makefile │ ├── main02.c │ ├── main03.c │ ├── main04.c │ ├── main05.c │ ├── main06_1.c │ ├── main06_2.c │ ├── main07.c │ ├── main08_1.c │ ├── main08_2.c │ ├── main09_1.c │ ├── main09_2.c │ ├── main10_2.c │ ├── main10_3.c │ ├── main11_1.c │ ├── main11_2.c │ ├── main11_3.c │ ├── main12_1.c │ ├── main13_1.c │ ├── main14.c │ ├── random.h │ ├── ray.h │ └── vec3.h ├── C2 │ ├── Makefile │ ├── main02.c │ ├── main03.c │ ├── main04.c │ ├── ray.h │ └── vec3.h ├── CPP │ ├── Makefile │ ├── bugcpp.cpp │ ├── camera.h │ ├── hitable.h │ ├── hitable_list.h │ ├── main02.cpp │ ├── main03.cpp │ ├── main04.cpp │ ├── main05.cpp │ ├── main06_1.cpp │ ├── main06_2.cpp │ ├── main07.cpp │ ├── main08_1.cpp │ ├── main08_2.cpp │ ├── main09_1.cpp │ ├── main09_2.cpp │ ├── main10_2.cpp │ ├── main10_3.cpp │ ├── main11_1.cpp │ ├── main11_2.cpp │ ├── main11_3.cpp │ ├── main12_1.cpp │ ├── main13_1.cpp │ ├── main14.cpp │ ├── random.h │ ├── ray.cpp │ ├── ray.h │ ├── ray5.cpp │ ├── ray6.cpp │ ├── sphere.h │ ├── vec3.cpp │ └── vec3.h ├── Forth │ ├── Makefile │ └── main02.fs ├── Go │ ├── Makefile │ ├── main02.go │ ├── main03.go │ ├── main04.go │ ├── main05.go │ ├── main06_1.go │ ├── main06_2.go │ ├── main07.go │ ├── main08_1.go │ ├── main08_2.go │ ├── main09_1.go │ ├── main09_2.go │ ├── main10_2.go │ ├── main10_3.go │ ├── main11_1.go │ ├── main11_2.go │ ├── main11_3.go │ ├── main12_1.go │ ├── main13_1.go │ ├── main14.go │ └── src │ │ └── pcg │ │ └── pcg.go ├── JS │ ├── README.md │ ├── common.js │ ├── index.html │ ├── main02_2.js │ ├── main02_3.js │ ├── main03_3.js │ ├── main04_2.js │ ├── main05_2.js │ ├── main06_1.js │ ├── main06_7.js │ ├── main07_2.js │ ├── main08_2.js │ ├── main08_3.js │ ├── random.js │ ├── ray.js │ └── vec3.js ├── Makefile ├── NOTES.md ├── Nelua │ ├── Makefile │ ├── main02.nelua │ ├── main03.nelua │ ├── main04.nelua │ ├── main05.nelua │ ├── main06_1.nelua │ ├── main06_2.nelua │ ├── main07.nelua │ ├── main08_1.nelua │ ├── main08_2.nelua │ ├── main09_1.nelua │ ├── main09_2.nelua │ ├── main10_2.nelua │ ├── main10_3.nelua │ ├── main11_1.nelua │ ├── main11_2.nelua │ ├── main11_3.nelua │ ├── main12_1.nelua │ ├── main13_1.nelua │ ├── main14.nelua │ ├── pcg.nelua │ ├── ray.nelua │ └── vec.nelua ├── Nim │ ├── Makefile │ ├── main02.nim │ ├── main03.nim │ ├── main04.nim │ ├── main05.nim │ ├── main06_1.nim │ ├── main06_2.nim │ ├── main07.nim │ ├── main08_1.nim │ ├── main08_2.nim │ ├── main09_1.nim │ ├── main09_2.nim │ ├── main10_2.nim │ ├── main10_3.nim │ ├── main11_1.nim │ ├── main11_2.nim │ ├── main11_3.nim │ ├── main12_1.nim │ ├── main13_1.nim │ ├── main14.nim │ ├── pcg.nim │ ├── ray.nim │ └── vec3.nim ├── Odin │ ├── Makefile │ ├── main02.odin │ ├── main03.odin │ ├── main04.odin │ ├── main05.odin │ ├── main06_1.odin │ ├── main06_2.odin │ ├── main07.odin │ ├── main08_1.odin │ ├── main08_2.odin │ ├── main09_1.odin │ ├── main09_2.odin │ ├── main10_2.odin │ ├── main10_3.odin │ ├── main11_1.odin │ ├── main11_2.odin │ ├── main11_3.odin │ ├── main12_1.odin │ ├── main13_1.odin │ ├── main14.odin │ └── pcg │ │ └── pcg.odin ├── README.md ├── Rust │ ├── Makefile │ ├── main02.rs │ ├── main03.rs │ ├── main04.rs │ ├── main05.rs │ ├── main06_1.rs │ ├── main06_2.rs │ ├── main07.rs │ ├── main08_1.rs │ ├── main08_2.rs │ ├── main09_1.rs │ ├── main09_2.rs │ ├── main10_2.rs │ ├── main10_3.rs │ ├── main11_1.rs │ ├── main11_2.rs │ ├── main11_3.rs │ ├── main12_1.rs │ ├── main13_1.rs │ ├── main14.rs │ └── pcg.rs ├── V │ ├── Makefile │ ├── main02.v │ ├── main03.v │ ├── main04.v │ ├── main05.v │ ├── main06_1.v │ ├── main06_2.v │ ├── main07.v │ ├── main08_1.v │ ├── main08_2.v │ ├── main09_1.v │ ├── main09_2.v │ ├── main10_2.v │ ├── main10_3.v │ ├── main11_1.v │ ├── main11_2.v │ ├── main11_3.v │ ├── main12_1.v │ ├── main13_1.v │ ├── main14.v │ ├── pcg │ │ └── pcg.v │ ├── ray │ │ └── ray.v │ ├── tstc_new.v │ └── vec │ │ └── vec.v ├── V_old │ ├── Makefile │ ├── main02.v │ ├── main03.v │ ├── main04.v │ ├── main05.v │ ├── main06_1.v │ ├── main06_2.v │ ├── main07.v │ ├── main08_1.v │ ├── main08_2.v │ ├── main09_1.v │ ├── main09_2.v │ ├── main10_2.v │ ├── main10_3.v │ ├── main11_1.v │ ├── main11_2.v │ ├── main11_3.v │ ├── main12_1.v │ ├── main13_1.v │ ├── main14.v │ ├── pcg │ │ └── pcg.v │ ├── ray │ │ └── ray.v │ └── vec │ │ └── vec.v ├── Zig │ ├── Makefile │ └── main02.zig ├── rttnw │ └── CPP │ │ ├── Makefile │ │ ├── camera.h │ │ ├── earthmap.jpg │ │ ├── hittable.h │ │ ├── hittable_list.h │ │ ├── random.h │ │ ├── ray.h │ │ ├── rttnw10.cpp │ │ ├── rttnw11.cpp │ │ ├── rttnw2.cpp │ │ ├── rttnw3.cpp │ │ ├── rttnw4.cpp │ │ ├── rttnw5.cpp │ │ ├── rttnw6.cpp │ │ ├── rttnw7.cpp │ │ ├── rttnw8.cpp │ │ ├── rttnw9.cpp │ │ ├── sphere.h │ │ ├── stb_image.h │ │ └── vec3.h └── rttroyl │ ├── main02_1.py │ ├── main02_2.py │ ├── main02_3.py │ ├── random.h │ ├── rttroyl2.cpp │ ├── rttroyl3.cpp │ ├── rttroyl4.cpp │ └── vec3.h ├── rttnw11.png ├── sdl.mak ├── sph.pov ├── sph.real ├── sphs.pov ├── sphs.real ├── spyr.json ├── spyr.real ├── vec.h ├── vecc.h └── veccpp.h /Makefile: -------------------------------------------------------------------------------- 1 | TARGET=realist 2 | TARGET+=raycpp 3 | TARGET+=rayc 4 | 5 | GO=go 6 | ifeq (x$(shell which $(GO) > /dev/null ; echo $$?),x0) 7 | HAVE_GO=1 8 | endif 9 | 10 | HAVE_V:=1 11 | ifdef HAVE_V 12 | TARGET+=rayv 13 | endif 14 | 15 | ifdef HAVE_GO 16 | TARGET+=raygo 17 | endif 18 | 19 | CFLAGS=-Wall -Werror 20 | CFLAGS+=-Wextra 21 | 22 | CXXFLAGS=-Wall -Werror 23 | CXXFLAGS+=-Wextra 24 | 25 | CFLAGS+=-g 26 | 27 | CXXFLAGS+=-g 28 | 29 | CFLAGS+=-pipe 30 | CXXFLAGS+=-pipe 31 | 32 | LDFLAGS+=-pipe 33 | 34 | CXXFLAGS+=-std=c++11 35 | 36 | CFLAGS+=-std=gnu99 37 | 38 | LDLIBS+=-lm 39 | 40 | USE_OPT=1 41 | ifdef USE_OPT 42 | CXXFLAGS+=-O3 -flto 43 | CFLAGS+=-O3 -flto 44 | #CXXFLAGS+=-DUSE_OPT 45 | else 46 | CXXFLAGS+=-O0 47 | CFLAGS+=-O0 48 | endif 49 | 50 | #USE_VEC=1 51 | ifdef USE_VEC 52 | CXXFLAGS+=-DUSE_VEC 53 | endif 54 | 55 | #USE_FLASH=1 56 | ifdef USE_FLASH 57 | CXXFLAGS+=-DUSE_FLASH 58 | endif 59 | 60 | #USE_REFL=1 61 | ifdef USE_REFL 62 | CXXFLAGS+=-DUSE_REFL 63 | endif 64 | 65 | #USE_LAMP=1 66 | ifdef USE_LAMP 67 | CXXFLAGS+=-DUSE_LAMP 68 | endif 69 | 70 | ifdef STATIC 71 | LDFLAGS+=-static 72 | endif 73 | 74 | CXXFLAGS+=-I. 75 | 76 | all: SDL_CHECK $(TARGET) 77 | 78 | include sdl.mak 79 | ifeq ($(SDL_VER),1) 80 | SDL_CXXFLAGS+=-DSDL1 81 | else 82 | SDL_CXXFLAGS+=-DSDL2 83 | endif 84 | 85 | SDL_CXXFLAGS+=$(SDL_FLAGS) 86 | SDL_LDLIBS+=$(SDL_LIBS) 87 | 88 | realist: CXXFLAGS+=$(SDL_CXXFLAGS) 89 | realist: LDLIBS+=$(SDL_LDLIBS) 90 | 91 | raygo: 92 | # GOPATH=$(shell pwd)/ray_go $(GO) build -o $@ ray_go/raygo.go 93 | GOPATH=`pwd`/ray_go $(GO) build -o $@ ray_go/raygo.go 94 | 95 | V:=v/v 96 | v/v: 97 | git clone https://github.com/vlang/v 98 | (cd $(@D) ; $(MAKE) ; cd -) 99 | 100 | #VFLAGS:=-debug -show_c_cmd 101 | rayv_v.c: $(V) 102 | cd ray_v ; ../$(V) $(VFLAGS) -o ../$@ . ; cd .. 103 | 104 | rayv: rayv_v.c 105 | $(CC) -w $(CFLAGS) $(LDFLAGS) $^ -lm -o $@ 106 | 107 | realist: realist.cpp vec.h CSDL.h 108 | 109 | BENCH_SIZE:=10000 110 | BENCH_ARGS=$(BENCH_SIZE) $(BENCH_SIZE) 111 | BENCH_TARGETS:= rayc raycpp rayv 112 | ifdef HAVE_GO 113 | BENCH_TARGETS+=raygo 114 | endif 115 | bench: $(BENCH_TARGETS) 116 | /usr/bin/time ./rayc $(BENCH_ARGS) rayc.ppm && md5sum rayc.ppm 117 | /usr/bin/time ./rayv $(BENCH_ARGS) rayv.ppm && md5sum rayv.ppm 118 | /usr/bin/time ./raycpp $(BENCH_ARGS) raycpp.ppm && md5sum raycpp.ppm 119 | ifdef HAVE_GO 120 | /usr/bin/time ./raygo $(BENCH_ARGS) raygo.ppm && md5sum raygo.ppm 121 | endif 122 | 123 | benchpy: bench 124 | /usr/bin/time ./raypy.py $(BENCH_ARGS) > raypy.ppm && md5sum raypy.ppm 125 | 126 | vgcheck: BENCH_SIZE=100 127 | VGOPTS:=--leak-check=full 128 | vgcheck: rayc rayv 129 | valgrind $(VGOPTS) ./rayc $(BENCH_ARGS) rayc.ppm 130 | valgrind $(VGOPTS) ./rayv $(BENCH_ARGS) rayv.ppm 131 | 132 | clean: 133 | @$(RM) $(TARGET) 134 | 135 | clobber: clean 136 | @$(RM) *~ 137 | @$(RM) *_v.c 138 | @$(RM) *.ppm 139 | 140 | mrproper: clobber 141 | @$(RM) -Rf v 142 | @$(MAKE) -C rtiow $@ 143 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rtiow 2 | This is my implementation of the excellent [RTIOW ray tracing book](https://raytracing.github.io/) in : 3 | Rust, Nelua, Nim, C, C++, Odin, V and Go. 4 | NEW! An interactive RTIOW Javascript version can be [explored here](https://nsauzede.github.io/realist/) (WIP, code is [here](rtiow/JS)) 5 | 6 | ![C RTIOW screenshot](main14.png) 7 | 8 | ![C++ RTTNW screenshot](rttnw11.png) 9 | 10 | Check out [RTIOW Readme](rtiow/README.md) 11 | 12 | # realist 13 | Simple, naive, C++ ray-tracer 14 | 15 | # rayXX 16 | Simple ray-tracer benchmark to compare between C, C++, Vlang and golang. 17 | 18 | To run the benchmark : 19 | ``` 20 | $ make clobber bench BENCH_SIZE=10000 21 | gcc -Wall -Werror -Wextra -g -pipe -std=c99 -O3 -pipe rayc.c -lm -o rayc 22 | g++ -Wall -Werror -Wextra -g -pipe -std=c++11 -O3 -I. -pipe raycpp.cpp -lm -o raycpp 23 | cd ray_v ; ../v/v -o ../rayv_v.c . ; cd .. 24 | gcc -Wall -Werror -Wextra -g -pipe -std=c99 -O3 -pipe rayv_v.c -lm -o rayv -w 25 | GOPATH=`pwd`/ray_go go build -o raygo ray_go/raygo.go 26 | /usr/bin/time ./rayc 10000 10000 rayc.ppm && md5sum rayc.ppm 27 | 7.67user 0.20system 0:07.88elapsed 99%CPU (0avgtext+0avgdata 294688maxresident)k 28 | 0inputs+585944outputs (0major+764minor)pagefaults 0swaps 29 | 0ae8911109ff4a32f471bd704829a44c rayc.ppm 30 | /usr/bin/time ./rayv 10000 10000 rayv.ppm && md5sum rayv.ppm 31 | 11.37user 0.21system 0:11.60elapsed 99%CPU (0avgtext+0avgdata 294684maxresident)k 32 | 0inputs+585944outputs (0major+762minor)pagefaults 0swaps 33 | 0ae8911109ff4a32f471bd704829a44c rayv.ppm 34 | /usr/bin/time ./raycpp 10000 10000 raycpp.ppm && md5sum raycpp.ppm 35 | 12.09user 0.21system 0:12.32elapsed 99%CPU (0avgtext+0avgdata 296096maxresident)k 36 | 0inputs+585944outputs (0major+819minor)pagefaults 0swaps 37 | 0ae8911109ff4a32f471bd704829a44c raycpp.ppm 38 | /usr/bin/time ./raygo 10000 10000 raygo.ppm && md5sum raygo.ppm 39 | 15.55user 0.23system 0:15.87elapsed 99%CPU (0avgtext+0avgdata 309420maxresident)k 40 | 0inputs+585944outputs (0major+898minor)pagefaults 0swaps 41 | 0ae8911109ff4a32f471bd704829a44c raygo.ppm 42 | ``` 43 | 44 | # Acknowledgements 45 | Many thanks to Aurélie Alvet for her significant Rust optimization 46 | and the Rust community for help with my initial Rust rampup. 47 | Many thanks to Cieric for his C/C++ PCG implementation. 48 | Many thanks to Delyan Angelov for his significant V optimization 49 | done to the V port (both perfs and accuracy). 50 | Many thanks to Amaury for initial rust port. 51 | -------------------------------------------------------------------------------- /TODO.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | -eclairage frontal 4 | 5 | -eclairage lampe => cosinus(normal,lamp)/d^2 6 | -reflexion speculaire : miroir 7 | -gamma : SRGB=encodedRGB=f(x)=x^(1/2.2)*255 8 | -linearRGB=g(x)=(x/255)^2.2 9 | 10 | -rgbe => HDR, non-normalized double, super RAW 11 | 12 | (-reflexion diffuse : lambertian, inversion de matrice, 1 / (1 - A)) 13 | 14 | 15 | TODO: 16 | -support more objects (facet, etc..) 17 | -support colored lamps 18 | -support object as lamp 19 | -support focal view (lens ?) 20 | -support parameterized normals 21 | -support refraction 22 | 23 | 24 | Stats: spyr.json, linux 25 | (see here for interesting post about C, Rust, Go, .. : 26 | http://www.viva64.com/en/b/0324/) 27 | 28 | -1000x1000: 29 | raypy : 0:55.11 = 56 = 56x 30 | raygo : 0:02.38 = 3 = 3x 31 | raycpp: 0:00.72 = 1 32 | 33 | -10000x1000: 34 | raypy : 35 | raygo : 36 | raycpp: 37 | 38 | Stats: spyr.json, windows, write to rayXX.ppm 39 | 40 | -1000x1000: 41 | raypy : 1:05.46 = 72 => 90.92x 42 | raygo : 0:01.58 = 2 => 2.19x 43 | raycpp: 0:00.88 = 1 => 1.22x 44 | rayc : 0:00.72 = 1 => 1x 45 | 46 | -1000x10000: 47 | raypy :10:52.79 = 657 => 126.75x code: 101 48 | raygo : 0:14.32 = 16 => 2.78x code: 173 49 | raycpp: 0:06.86 = 7 => 1.33x code: 706 50 | rayc : 0:05.15 = 5 => 1x code: 190 51 | 52 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |

Please follow this link to visit RTIOW/JS.

10 | 11 | 12 | -------------------------------------------------------------------------------- /iocccray.json: -------------------------------------------------------------------------------- 1 | # initial #objects: 0 2 | { 3 | 'screen': { 'w':100, 'h':80, 'ratiox':1, 'ratioy':2 }, 4 | 'camera': { 'loc':[0, 0, 1], 'front':[0, 0, -1], 'up':[0, 1, 0]}, 5 | 'objects': [ 6 | {'type':'sphere', 'data': [-0.35, 0.32, 0, 0.05, 1, 1, 1]}, 7 | {'type':'sphere', 'data': [-0.15, 0.32, 0, 0.05, 1, 1, 1]}, 8 | {'type':'sphere', 'data': [0.1, 0.32, 0, 0.05, 1, 1, 1]}, 9 | {'type':'sphere', 'data': [0.25, 0.32, 0, 0.05, 1, 1, 1]}, 10 | {'type':'sphere', 'data': [0.4, 0.32, 0, 0.05, 1, 1, 1]}, 11 | {'type':'sphere', 'data': [-0.35, 0.24, 0, 0.05, 1, 1, 1]}, 12 | {'type':'sphere', 'data': [-0.2, 0.24, 0, 0.05, 1, 1, 1]}, 13 | {'type':'sphere', 'data': [-0.1, 0.24, 0, 0.05, 1, 1, 1]}, 14 | {'type':'sphere', 'data': [0.05, 0.24, 0, 0.05, 1, 1, 1]}, 15 | {'type':'sphere', 'data': [0.2, 0.24, 0, 0.05, 1, 1, 1]}, 16 | {'type':'sphere', 'data': [0.35, 0.24, 0, 0.05, 1, 1, 1]}, 17 | {'type':'sphere', 'data': [-0.35, 0.16, 0, 0.05, 1, 1, 1]}, 18 | {'type':'sphere', 'data': [-0.2, 0.16, 0, 0.05, 1, 1, 1]}, 19 | {'type':'sphere', 'data': [-0.1, 0.16, 0, 0.05, 1, 1, 1]}, 20 | {'type':'sphere', 'data': [0.05, 0.16, 0, 0.05, 1, 1, 1]}, 21 | {'type':'sphere', 'data': [0.2, 0.16, 0, 0.05, 1, 1, 1]}, 22 | {'type':'sphere', 'data': [0.35, 0.16, 0, 0.05, 1, 1, 1]}, 23 | {'type':'sphere', 'data': [-0.35, 0.08, 0, 0.05, 1, 1, 1]}, 24 | {'type':'sphere', 'data': [-0.15, 0.08, 0, 0.05, 1, 1, 1]}, 25 | {'type':'sphere', 'data': [0.1, 0.08, 0, 0.05, 1, 1, 1]}, 26 | {'type':'sphere', 'data': [0.25, 0.08, 0, 0.05, 1, 1, 1]}, 27 | {'type':'sphere', 'data': [0.4, 0.08, 0, 0.05, 1, 1, 1]}, 28 | {'type':'sphere', 'data': [-0.275, -0.065, 0.25, 0.05, 1, 0, 0]}, 29 | {'type':'sphere', 'data': [-0.225, -0.065, 0.25, 0.05, 1, 0, 0]}, 30 | {'type':'sphere', 'data': [0, -0.065, 0.25, 0.05, 0, 1, 0]}, 31 | {'type':'sphere', 'data': [0.175, -0.065, 0.25, 0.05, 0, 0, 1]}, 32 | {'type':'sphere', 'data': [0.275, -0.065, 0.25, 0.05, 0, 0, 1]}, 33 | {'type':'sphere', 'data': [-0.275, -0.13, 0.25, 0.05, 1, 0, 0]}, 34 | {'type':'sphere', 'data': [-0.175, -0.13, 0.25, 0.05, 1, 0, 0]}, 35 | {'type':'sphere', 'data': [-0.05, -0.13, 0.25, 0.05, 0, 1, 0]}, 36 | {'type':'sphere', 'data': [0.05, -0.13, 0.25, 0.05, 0, 1, 0]}, 37 | {'type':'sphere', 'data': [0.175, -0.13, 0.25, 0.05, 0, 0, 1]}, 38 | {'type':'sphere', 'data': [0.275, -0.13, 0.25, 0.05, 0, 0, 1]}, 39 | {'type':'sphere', 'data': [-0.275, -0.195, 0.25, 0.05, 1, 0, 0]}, 40 | {'type':'sphere', 'data': [-0.225, -0.195, 0.25, 0.05, 1, 0, 0]}, 41 | {'type':'sphere', 'data': [-0.05, -0.195, 0.25, 0.05, 0, 1, 0]}, 42 | {'type':'sphere', 'data': [0, -0.195, 0.25, 0.05, 0, 1, 0]}, 43 | {'type':'sphere', 'data': [0.05, -0.195, 0.25, 0.05, 0, 1, 0]}, 44 | {'type':'sphere', 'data': [0.225, -0.195, 0.25, 0.05, 0, 0, 1]}, 45 | {'type':'sphere', 'data': [-0.275, -0.26, 0.25, 0.05, 1, 0, 0]}, 46 | {'type':'sphere', 'data': [-0.175, -0.26, 0.25, 0.05, 1, 0, 0]}, 47 | {'type':'sphere', 'data': [-0.05, -0.26, 0.25, 0.05, 0, 1, 0]}, 48 | {'type':'sphere', 'data': [0.05, -0.26, 0.25, 0.05, 0, 1, 0]}, 49 | {'type':'sphere', 'data': [0.225, -0.26, 0.25, 0.05, 0, 0, 1]}, 50 | {'type':'sphere', 'data': [0, -0.5, 0.5, 0.02, 1, 1, 0]} 51 | ] 52 | } 53 | #e={0.000000,0.000000,1.000000} 54 | #f={0.000000,0.000000,-1.000000} 55 | #u={0.000000,1.000000,0.000000} 56 | #r={1.000000,-0.000000,0.000000} 57 | 58 | # using OPT 59 | # ww=1.000000 hh=0.750000 60 | # found 46 objects 61 | -------------------------------------------------------------------------------- /iocccray.real: -------------------------------------------------------------------------------- 1 | 0 0 1 2 | 0 0 -1 3 | 0 1 0 4 | 5 | 0 8 6 | 0 7 | 1 1 1 8 | -0.35 0.32 0 9 | 0.05 10 | 11 | 12 | 0 8 13 | 0 14 | 1 1 1 15 | -0.15 0.32 0 16 | 0.05 17 | 18 | 19 | 0 8 20 | 0 21 | 1 1 1 22 | 0.1 0.32 0 23 | 0.05 24 | 25 | 26 | 0 8 27 | 0 28 | 1 1 1 29 | 0.25 0.32 0 30 | 0.05 31 | 32 | 33 | 0 8 34 | 0 35 | 1 1 1 36 | 0.4 0.32 0 37 | 0.05 38 | 39 | 40 | 0 8 41 | 0 42 | 1 1 1 43 | -0.35 0.24 0 44 | 0.05 45 | 46 | 47 | 0 8 48 | 0 49 | 1 1 1 50 | -0.2 0.24 0 51 | 0.05 52 | 53 | 54 | 0 8 55 | 0 56 | 1 1 1 57 | -0.1 0.24 0 58 | 0.05 59 | 60 | 61 | 0 8 62 | 0 63 | 1 1 1 64 | 0.05 0.24 0 65 | 0.05 66 | 67 | 68 | 0 8 69 | 0 70 | 1 1 1 71 | 0.2 0.24 0 72 | 0.05 73 | 74 | 75 | 0 8 76 | 0 77 | 1 1 1 78 | 0.35 0.24 0 79 | 0.05 80 | 81 | 82 | 0 8 83 | 0 84 | 1 1 1 85 | -0.35 0.16 0 86 | 0.05 87 | 88 | 89 | 0 8 90 | 0 91 | 1 1 1 92 | -0.2 0.16 0 93 | 0.05 94 | 95 | 96 | 0 8 97 | 0 98 | 1 1 1 99 | -0.1 0.16 0 100 | 0.05 101 | 102 | 103 | 0 8 104 | 0 105 | 1 1 1 106 | 0.05 0.16 0 107 | 0.05 108 | 109 | 110 | 0 8 111 | 0 112 | 1 1 1 113 | 0.2 0.16 0 114 | 0.05 115 | 116 | 117 | 0 8 118 | 0 119 | 1 1 1 120 | 0.35 0.16 0 121 | 0.05 122 | 123 | 124 | 0 8 125 | 0 126 | 1 1 1 127 | -0.35 0.08 0 128 | 0.05 129 | 130 | 131 | 0 8 132 | 0 133 | 1 1 1 134 | -0.15 0.08 0 135 | 0.05 136 | 137 | 138 | 0 8 139 | 0 140 | 1 1 1 141 | 0.1 0.08 0 142 | 0.05 143 | 144 | 145 | 0 8 146 | 0 147 | 1 1 1 148 | 0.25 0.08 0 149 | 0.05 150 | 151 | 152 | 0 8 153 | 0 154 | 1 1 1 155 | 0.4 0.08 0 156 | 0.05 157 | 158 | 159 | 0 8 160 | 0 161 | 1 0 0 162 | -0.275 -0.065 0.25 163 | 0.05 164 | 165 | 166 | 0 8 167 | 0 168 | 1 0 0 169 | -0.225 -0.065 0.25 170 | 0.05 171 | 172 | 173 | 0 8 174 | 0 175 | 0 1 0 176 | 0 -0.065 0.25 177 | 0.05 178 | 179 | 180 | 0 8 181 | 0 182 | 0 0 1 183 | 0.175 -0.065 0.25 184 | 0.05 185 | 186 | 187 | 0 8 188 | 0 189 | 0 0 1 190 | 0.275 -0.065 0.25 191 | 0.05 192 | 193 | 194 | 0 8 195 | 0 196 | 1 0 0 197 | -0.275 -0.13 0.25 198 | 0.05 199 | 200 | 201 | 0 8 202 | 0 203 | 1 0 0 204 | -0.175 -0.13 0.25 205 | 0.05 206 | 207 | 208 | 0 8 209 | 0 210 | 0 1 0 211 | -0.05 -0.13 0.25 212 | 0.05 213 | 214 | 215 | 0 8 216 | 0 217 | 0 1 0 218 | 0.05 -0.13 0.25 219 | 0.05 220 | 221 | 222 | 0 8 223 | 0 224 | 0 0 1 225 | 0.175 -0.13 0.25 226 | 0.05 227 | 228 | 229 | 0 8 230 | 0 231 | 0 0 1 232 | 0.275 -0.13 0.25 233 | 0.05 234 | 235 | 236 | 0 8 237 | 0 238 | 1 0 0 239 | -0.275 -0.195 0.25 240 | 0.05 241 | 242 | 243 | 0 8 244 | 0 245 | 1 0 0 246 | -0.225 -0.195 0.25 247 | 0.05 248 | 249 | 250 | 0 8 251 | 0 252 | 0 1 0 253 | -0.05 -0.195 0.25 254 | 0.05 255 | 256 | 257 | 0 8 258 | 0 259 | 0 1 0 260 | 0 -0.195 0.25 261 | 0.05 262 | 263 | 264 | 0 8 265 | 0 266 | 0 1 0 267 | 0.05 -0.195 0.25 268 | 0.05 269 | 270 | 271 | 0 8 272 | 0 273 | 0 0 1 274 | 0.225 -0.195 0.25 275 | 0.05 276 | 277 | 278 | 0 8 279 | 0 280 | 1 0 0 281 | -0.275 -0.26 0.25 282 | 0.05 283 | 284 | 285 | 0 8 286 | 0 287 | 1 0 0 288 | -0.175 -0.26 0.25 289 | 0.05 290 | 291 | 292 | 0 8 293 | 0 294 | 0 1 0 295 | -0.05 -0.26 0.25 296 | 0.05 297 | 298 | 299 | 0 8 300 | 0 301 | 0 1 0 302 | 0.05 -0.26 0.25 303 | 0.05 304 | 305 | 306 | 0 8 307 | 0 308 | 0 0 1 309 | 0.225 -0.26 0.25 310 | 0.05 311 | -------------------------------------------------------------------------------- /main14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsauzede/realist/c1a62019d55c3f7abed7f7c3f06ae3b2778cf47f/main14.png -------------------------------------------------------------------------------- /origins.json: -------------------------------------------------------------------------------- 1 | { 2 | 'screen': { "w":100, "h":80, "ratiox":1., "ratioy":2.}, 3 | "camera": { "loc": [3,3,3], "front": [-1,-1,-1], "up": [-1, -1, 1]}, 4 | #"sphere": [ 5 | # [ #center #radius #color 6 | # 0,0,0, 0.1, 1,1,1 ], 7 | # [ #center #radius #color 8 | # 1,0,0, 0.1, 1,0,0 ], 9 | # [ #center #radius #color 10 | # 0,1,0, 0.1, 0,1,0 ], 11 | # [ #center #radius #color 12 | # 0,0,1, 0.1, 0,0,1 ], 13 | #], 14 | #'sphere': [0, 0, 0, 0.1, 1, 1, 1], 15 | #'sphere': [1, 0, 0, 0.1, 1, 0, 0], 16 | 'objects': [ 17 | 18 | {'type':'sphere', 'data':[0, 0, 0, 0.1, 1, 1, 1]}, 19 | 20 | {'type':'sphere', #center #radius #color 21 | 'data':[ 1, 0, 0, 0.1, 1, 0, 0 ]}, 22 | 23 | {'type':'sphere', #center #radius #color 24 | 'data':[ 0, 1, 0, 0.1, 0, 1, 0 ]}, 25 | 26 | {'type':'sphere', #center #radius #color 27 | 'data':[ 0, 0, 1, 0.1, 0, 0, 1 ]}, 28 | ], 29 | } 30 | -------------------------------------------------------------------------------- /origins.real: -------------------------------------------------------------------------------- 1 | 30 30 30 2 | -1 -1 -1 3 | -0.408248 -0.408248 0.816497 4 | 5 | 0 8 6 | 0 7 | 1 1 1 8 | 0 0 0 9 | 1.1 10 | 11 | 0 8 12 | 0 13 | 1 0 0 14 | 10 0 0 15 | 1.1 16 | 17 | 0 8 18 | 0 19 | 0 1 0 20 | 0 10 0 21 | 1.1 22 | 23 | 0 8 24 | 0 25 | 0 0 1 26 | 0 0 10 27 | 1.1 28 | -------------------------------------------------------------------------------- /ray_go/src/vec/vec.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016-2019 Nicolas Sauzede (nsauzede@laposte.net) 3 | * SPDX-License-Identifier: GPL-3.0-or-later 4 | */ 5 | package vec 6 | 7 | import "math" 8 | 9 | type Vector struct { 10 | X, Y, Z float64 11 | } 12 | 13 | func (v Vector) IsEqual(ov Vector) bool { 14 | return v.X == ov.X && v.Y == ov.Y && v.Z == ov.Z 15 | } 16 | 17 | func (v Vector) Dot(ov Vector) float64 { 18 | return v.X * ov.X + v.Y * ov.Y + v.Z * ov.Z 19 | } 20 | 21 | func (v Vector) Cross(ov Vector) Vector { 22 | var rv Vector 23 | rv.X = v.Y * ov.Z - v.Z * ov.Y 24 | rv.Y = v.Z * ov.X - v.X * ov.Z 25 | rv.Z = v.X * ov.Y - v.Y * ov.X 26 | return rv 27 | } 28 | 29 | func (v Vector) Norm() float64 { 30 | return math.Sqrt( v.Dot( v)) 31 | } 32 | 33 | func (v Vector) Mult(f float64) Vector { 34 | var rv Vector 35 | rv.X = v.X * f 36 | rv.Y = v.Y * f 37 | rv.Z = v.Z * f 38 | return rv 39 | } 40 | 41 | func (v Vector) Div(f float64) Vector { 42 | var rv Vector 43 | rv.X = v.X / f 44 | rv.Y = v.Y / f 45 | rv.Z = v.Z / f 46 | return rv 47 | } 48 | 49 | func (v *Vector) Normalize() { 50 | *v = v.Div( v.Norm()) 51 | } 52 | 53 | func (v Vector) Add(ov Vector) Vector { 54 | var rv Vector 55 | rv.X = v.X + ov.X 56 | rv.Y = v.Y + ov.Y 57 | rv.Z = v.Z + ov.Z 58 | return rv 59 | } 60 | 61 | func (v Vector) Sub(ov Vector) Vector { 62 | var rv Vector 63 | rv.X = v.X - ov.X 64 | rv.Y = v.Y - ov.Y 65 | rv.Z = v.Z - ov.Z 66 | return rv 67 | } 68 | -------------------------------------------------------------------------------- /ray_go/src/vec/vec_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016-2019 Nicolas Sauzede (nsauzede@laposte.net) 3 | * SPDX-License-Identifier: GPL-3.0-or-later 4 | */ 5 | package vec 6 | 7 | import ( 8 | "math" 9 | "testing" 10 | ) 11 | 12 | func float64Eq(x, y float64) bool { return math.Abs(x-y) < 1e-14} 13 | 14 | func TestDot(t *testing.T) { 15 | tests := []struct { 16 | v1, v2 Vector 17 | want float64 18 | }{ 19 | {Vector{1, 1, 1}, Vector{-1, -1, -1}, -3}, 20 | } 21 | for _, test := range tests { 22 | v1 := test.v1 23 | v2 := test.v2 24 | res := v1.Dot(v2) 25 | if !float64Eq(res, test.want) { 26 | t.Errorf("%v . %v = %v, want %v", v1, v2, res, test.want) 27 | } 28 | } 29 | } 30 | 31 | func TestCross(t *testing.T) { 32 | tests := []struct { 33 | v1, v2 Vector 34 | want Vector 35 | }{ 36 | {Vector{1, 1, 1}, Vector{1, 2, 3}, Vector{1, -2, 1}}, 37 | } 38 | for _, test := range tests { 39 | v1 := test.v1 40 | v2 := test.v2 41 | res := v1.Cross(v2) 42 | if !res.IsEqual(test.want) { 43 | t.Errorf("%v ^ %v = %v, want %v", v1, v2, res, test.want) 44 | } 45 | } 46 | } 47 | 48 | func TestMult(t *testing.T) { 49 | tests := []struct { 50 | v1 Vector 51 | f1 float64 52 | want Vector 53 | }{ 54 | {Vector{1, 1, 1}, -3, Vector{-3, -3, -3}}, 55 | } 56 | for _, test := range tests { 57 | v1 := test.v1 58 | f1 := test.f1 59 | res := v1.Mult(f1) 60 | if !res.IsEqual(test.want) { 61 | t.Errorf("%v * %v = %v, want %v", v1, f1, res, test.want) 62 | } 63 | } 64 | } 65 | 66 | func TestDiv(t *testing.T) { 67 | tests := []struct { 68 | v1 Vector 69 | f1 float64 70 | want Vector 71 | }{ 72 | {Vector{2, 4, 6}, -2, Vector{-1, -2, -3}}, 73 | } 74 | for _, test := range tests { 75 | v1 := test.v1 76 | f1 := test.f1 77 | res := v1.Div(f1) 78 | if !res.IsEqual(test.want) { 79 | t.Errorf("%v / %v = %v, want %v", v1, f1, res, test.want) 80 | } 81 | } 82 | } 83 | 84 | func TestNormalize(t *testing.T) { 85 | tests := []struct { 86 | v1 Vector 87 | want Vector 88 | }{ 89 | {Vector{4, 2, 4}, Vector{2./3, 1./3, 2./3}}, 90 | } 91 | for _, test := range tests { 92 | res := test.v1 93 | res.Normalize() 94 | if !res.IsEqual(test.want) { 95 | t.Errorf("!%v = %v, want %v", test.v1, res, test.want) 96 | } 97 | } 98 | } 99 | 100 | func TestAdd(t *testing.T) { 101 | tests := []struct { 102 | v1 Vector 103 | v2 Vector 104 | want Vector 105 | }{ 106 | {Vector{1, 1, 1}, Vector{ -1, -2, -3}, Vector{0, -1, -2}}, 107 | } 108 | for _, test := range tests { 109 | v1 := test.v1 110 | v2 := test.v2 111 | res := v1.Add(v2) 112 | if !res.IsEqual(test.want) { 113 | t.Errorf("%v + %v = %v, want %v", v1, v2, res, test.want) 114 | } 115 | } 116 | } 117 | 118 | func TestSub(t *testing.T) { 119 | tests := []struct { 120 | v1 Vector 121 | v2 Vector 122 | want Vector 123 | }{ 124 | {Vector{1, 1, 1}, Vector{ -1, -2, -3}, Vector{2, 3, 4}}, 125 | } 126 | for _, test := range tests { 127 | v1 := test.v1 128 | v2 := test.v2 129 | res := v1.Sub(v2) 130 | if !res.IsEqual(test.want) { 131 | t.Errorf("%v - %v = %v, want %v", v1, v2, res, test.want) 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /ray_rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "rayrust" 5 | version = "0.1.0" 6 | 7 | -------------------------------------------------------------------------------- /ray_rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rayrust" 3 | version = "0.1.0" 4 | authors = ["YruamaLairba "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /ray_v/README.md: -------------------------------------------------------------------------------- 1 | # V port 2 | See here to build the v impl : https://vlang.io/ 3 | (note that the top Makefile autmatically install the V compiler) 4 | -------------------------------------------------------------------------------- /ray_v/vec/vec.v: -------------------------------------------------------------------------------- 1 | module vec 2 | 3 | /* 4 | * Copyright(c) 2016-2019 Nicolas Sauzede (nsauzede@laposte.net) 5 | * SPDX-License-Identifier: GPL-3.0-or-later 6 | */ 7 | import math 8 | 9 | pub struct Vector { 10 | x f64 11 | y f64 12 | z f64 13 | // x, y, z f64 14 | } 15 | 16 | pub fn (v Vector) str() string { 17 | return '[$v.x, $v.y, $v.z]' 18 | } 19 | 20 | pub fn (v Vector) dot(ov Vector) f64 { 21 | return v.x * ov.x + v.y * ov.y + v.z * ov.z 22 | } 23 | 24 | pub fn (v Vector) cross(ov Vector) Vector { 25 | return Vector{v.y * ov.z - v.z * ov.y, v.z * ov.x - v.x * ov.z, v.x * ov.y - v.y * ov.x} 26 | } 27 | 28 | pub fn (v Vector) norm() f64 { 29 | return math.sqrt(v.dot(v)) 30 | } 31 | 32 | pub fn (v Vector) mult(f f64) Vector { 33 | return Vector{v.x * f, v.y * f, v.z * f} 34 | } 35 | 36 | pub fn (v Vector) div(f f64) Vector { 37 | return Vector{v.x / f, v.y / f, v.z / f} 38 | } 39 | 40 | pub fn (mut v Vector) normalize() { 41 | unsafe { 42 | *v = v.div(v.norm()) 43 | } 44 | } 45 | 46 | pub fn (v Vector) add(ov Vector) Vector { 47 | return Vector{v.x + ov.x, v.y + ov.y, v.z + ov.z} 48 | } 49 | 50 | pub fn (v Vector) sub(ov Vector) Vector { 51 | return Vector{v.x - ov.x, v.y - ov.y, v.z - ov.z} 52 | } 53 | -------------------------------------------------------------------------------- /raypy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright(c) 2016-2019 Nicolas Sauzede (nsauzede@laposte.net) 4 | # SPDX-License-Identifier: GPL-3.0-or-later 5 | # 6 | import math 7 | import numpy.matlib as np 8 | import sys 9 | 10 | w=10 11 | h=10 12 | fnameout="" 13 | ratiox=1. 14 | ratioy=1. 15 | ww=1.*ratiox 16 | hh=ww*h/w*ratioy 17 | 18 | if len(sys.argv) > 1: 19 | w=int(sys.argv[1]) 20 | if len(sys.argv) > 2: 21 | h=int(sys.argv[2]) 22 | if len(sys.argv) > 3: 23 | fnameout=sys.argv[3] 24 | if len(sys.argv) > 4: 25 | ratiox=float(sys.argv[4]) 26 | if len(sys.argv) > 5: 27 | ratioy=float(sys.argv[5]) 28 | 29 | sphs=[] 30 | sphs += [np.array([0, -0.1, 0,0.05,0.8, 0.8, 0.8],dtype=float)] 31 | sphs += [np.array([0, 0, 0,0.05,0.8, 0.8, 0.8],dtype=float)] 32 | sphs += [np.array([0, 0.1, 0,0.05,0.8, 0.8, 0.8],dtype=float)] 33 | sphs += [np.array([0.1, -0.05, 0,0.05,0.8, 0, 0],dtype=float)] 34 | sphs += [np.array([0.1, 0.05, 0,0.05,0, 0, 0.8],dtype=float)] 35 | sphs += [np.array([0.2, 0, 0,0.05,0, 0.8, 0],dtype=float)] 36 | sphs += [np.array([0.05, -0.05, 0.1,0.05,0.8, 0.8, 0.8],dtype=float)] 37 | sphs += [np.array([0.05, 0.05, 0.1,0.05,0.8, 0.8, 0.8],dtype=float)] 38 | sphs += [np.array([0, -0.5, 0.5,0.02,1, 1, 0],dtype=float)] 39 | 40 | e=np.array([0.4,0,0.4],dtype=float) 41 | f=np.array([-1,0,-1],dtype=float) 42 | u=np.array([-0.707107,0,0.707107],dtype=float) 43 | u/=np.linalg.norm(u) 44 | r=np.cross(f,u) 45 | u=np.cross(r,f) 46 | u/=np.linalg.norm(u) 47 | r/=np.linalg.norm(r) 48 | 49 | def SolveTri(a,b,c): 50 | d=b*b-4*a*c 51 | t1,t2 = 0., 0. 52 | sol=0 53 | if d>0: 54 | sd=math.sqrt(d) 55 | t1=(-b-sd)/2/a 56 | t2=(-b+sd)/2/a 57 | sol=2 58 | elif d==0: 59 | t1=-b/2/a 60 | sol=1 61 | return sol,t1,t2 62 | 63 | HUGE_VAL=1e100 64 | def Intersec(s,o,v): 65 | cent=np.array(s[0:3]) 66 | rad=s[3] 67 | vt=o-cent 68 | a=np.dot(v,v) 69 | b=2*np.dot(v,vt) 70 | c=np.dot(vt,vt)-rad*rad 71 | sol,t1,t2=SolveTri(a,b,c) 72 | if sol==2: 73 | if t10 and t this one breaks bit-exact non-reg 26 | OPT+=-fno-plt 27 | OPT+=-flto 28 | # OPT+=-march=native # ==> this one breaks bit-exact non-reg 29 | OPT+=-DNDEBUG 30 | # OPT:=-Ofast -fno-plt -flto -march=native -DNDEBUG 31 | # OPT:=-Ofast -fno-plt -flto -DNDEBUG 32 | endif 33 | 34 | #PROF:=1 35 | ifdef PROF 36 | OPT+=-pg 37 | endif 38 | 39 | %.elf: %.c 40 | $(CC) -o $@ $^ $(OPT) -lm 41 | 42 | %.ppm: %.elf 43 | ./$^ $(ARGS) > $@ 44 | 45 | clean: 46 | $(RM) *.elf *.ppm 47 | -------------------------------------------------------------------------------- /rtiow/C/main02.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | int nx = 200; 5 | int ny = 100; 6 | printf("P3\n"); 7 | printf("%d %d\n", nx, ny); 8 | printf("255\n"); 9 | for (int j = ny-1; j >= 0; j--) { 10 | for (int i = 0; i < nx; i++) { 11 | float r = (float)i / (float)nx; 12 | float g = (float)j / (float)ny; 13 | float b = 0.2; 14 | int ir = (int)(255.99f*r); 15 | int ig = (int)(255.99f*g); 16 | int ib = (int)(255.99f*b); 17 | printf("%d %d %d\n", ir, ig, ib); 18 | } 19 | } 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /rtiow/C/main03.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "vec3.h" 4 | 5 | int main() { 6 | int nx = 200; 7 | int ny = 100; 8 | printf("P3\n"); 9 | printf("%d %d\n", nx, ny); 10 | printf("255\n"); 11 | for (int j = ny-1; j >= 0; j--) { 12 | for (int i = 0; i < nx; i++) { 13 | vec3 col = {(float)i / (float)nx, (float)j / (float)ny, 0.2}; 14 | int ir = (int)(255.99f*col[0]); 15 | int ig = (int)(255.99f*col[1]); 16 | int ib = (int)(255.99f*col[2]); 17 | printf("%d %d %d\n", ir, ig, ib); 18 | } 19 | } 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /rtiow/C/main04.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "vec3.h" 5 | #include "ray.h" 6 | 7 | void color(vec3 col, const ray r) { 8 | vec3 unit_direction; 9 | unit_vector(unit_direction, r.direction); 10 | float t = 0.5*(unit_direction[1] + 1.0); 11 | vec3 col0 = {1.0, 1.0, 1.0}; 12 | vec3 col1 = {0.5, 0.7, 1.0}; 13 | vmul(col0, 1.0-t, col0); 14 | vmul(col1, t, col1); 15 | vadd(col, col0, col1); 16 | } 17 | 18 | int main() { 19 | int nx = 200; 20 | int ny = 100; 21 | printf("P3\n"); printf("%d %d\n", nx, ny); printf("255\n"); 22 | vec3 lower_left_corner = {-2.0, -1.0, -1.0}; 23 | // vprint(lower_left_corner); 24 | vec3 horizontal = {4.0, 0.0, 0.0}; 25 | vec3 vertical = {0.0, 2.0, 0.0}; 26 | vec3 origin = {0.0, 0.0, 0.0}; 27 | for (int j = ny-1; j >= 0; j--) { 28 | for (int i = 0; i < nx; i++) { 29 | float u = (float)i / (float)nx; 30 | float v = (float)j / (float)ny; 31 | ray r; 32 | vec3 direction, direction0, direction1; 33 | vmul(direction0, v, vertical); 34 | vmul(direction1, u, horizontal); 35 | vadd(direction, direction0, direction1); 36 | vadd(direction, direction, lower_left_corner); 37 | rmake(&r, origin, direction); 38 | // rprint(&r);exit(0); 39 | vec3 col; 40 | color(col, r); 41 | int ir = (int)(255.99f*col[0]); 42 | int ig = (int)(255.99f*col[1]); 43 | int ib = (int)(255.99f*col[2]); 44 | printf("%d %d %d\n", ir, ig, ib); 45 | } 46 | } 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /rtiow/C/main05.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "vec3.h" 5 | #include "ray.h" 6 | 7 | int hit_sphere(const vec3 center, float radius, const ray *r) { 8 | vec3 oc; 9 | vsub(oc, r->origin, center); 10 | float a = vdot(r->direction, r->direction); 11 | float b = 2.0f * vdot(oc, r->direction); 12 | float c = vdot(oc, oc) - radius*radius; 13 | float discriminant = b*b - 4*a*c; 14 | return (discriminant > 0); 15 | } 16 | 17 | void color(vec3 col, const ray *r) { 18 | if (hit_sphere(VEC3(0,0,-1), 0.5, r)) { 19 | vcopy(col, VEC3(1, 0, 0)); 20 | return; 21 | } 22 | vec3 unit_direction; 23 | unit_vector(unit_direction, r->direction); 24 | float t = 0.5*(unit_direction[1] + 1.0); 25 | vec3 col0 = {1.0, 1.0, 1.0}; 26 | vec3 col1 = {0.5, 0.7, 1.0}; 27 | vmul(col0, 1.0-t, col0); 28 | vmul(col1, t, col1); 29 | vadd(col, col0, col1); 30 | } 31 | 32 | int main() { 33 | int nx = 200; 34 | int ny = 100; 35 | printf("P3\n"); printf("%d %d\n", nx, ny); printf("255\n"); 36 | vec3 lower_left_corner = {-2.0, -1.0, -1.0}; 37 | // vprint(lower_left_corner); 38 | vec3 horizontal = {4.0, 0.0, 0.0}; 39 | vec3 vertical = {0.0, 2.0, 0.0}; 40 | vec3 origin = {0.0, 0.0, 0.0}; 41 | for (int j = ny-1; j >= 0; j--) { 42 | for (int i = 0; i < nx; i++) { 43 | float u = (float)i / (float)nx; 44 | float v = (float)j / (float)ny; 45 | ray r; 46 | vec3 direction, direction0, direction1; 47 | vmul(direction0, v, vertical); 48 | vmul(direction1, u, horizontal); 49 | vadd(direction, direction0, direction1); 50 | vadd(direction, direction, lower_left_corner); 51 | rmake(&r, origin, direction); 52 | // rprint(&r);exit(0); 53 | vec3 col; 54 | color(col, &r); 55 | int ir = (int)(255.99f*col[0]); 56 | int ig = (int)(255.99f*col[1]); 57 | int ib = (int)(255.99f*col[2]); 58 | printf("%d %d %d\n", ir, ig, ib); 59 | } 60 | } 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /rtiow/C/main06_1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "vec3.h" 5 | #include "ray.h" 6 | 7 | float hit_sphere(const vec3 center, float radius, const ray *r) { 8 | vec3 oc; 9 | vsub(oc, r->origin, center); 10 | float a = vdot(r->direction, r->direction); 11 | float b = 2.0f * vdot(oc, r->direction); 12 | float c = vdot(oc, oc) - radius*radius; 13 | float discriminant = b*b - 4*a*c; 14 | if (discriminant < 0) { 15 | return -1.0; 16 | } 17 | else { 18 | return (-b - sqrtf(discriminant) ) / (2.0*a); 19 | } 20 | } 21 | 22 | void color(vec3 col, const ray *r) { 23 | float t = hit_sphere(VEC3(0,0,-1), 0.5, r); 24 | if (t > 0.0) { 25 | vec3 N; 26 | point_at_parameter(N, r, t); 27 | vsub(N, N, VEC3(0, 0, -1)); 28 | unit_vector(N, N); 29 | vadd(N, N, VEC3(1, 1, 1)); 30 | vmul(col, 0.5, N); 31 | return; 32 | } 33 | vec3 unit_direction; 34 | unit_vector(unit_direction, r->direction); 35 | t = 0.5*(unit_direction[1] + 1.0); 36 | vec3 col0 = {1.0, 1.0, 1.0}; 37 | vec3 col1 = {0.5, 0.7, 1.0}; 38 | vmul(col0, 1.0-t, col0); 39 | vmul(col1, t, col1); 40 | vadd(col, col0, col1); 41 | } 42 | 43 | int main() { 44 | int nx = 200; 45 | int ny = 100; 46 | printf("P3\n"); printf("%d %d\n", nx, ny); printf("255\n"); 47 | vec3 lower_left_corner = {-2.0, -1.0, -1.0}; 48 | vec3 horizontal = {4.0, 0.0, 0.0}; 49 | vec3 vertical = {0.0, 2.0, 0.0}; 50 | vec3 origin = {0.0, 0.0, 0.0}; 51 | for (int j = ny-1; j >= 0; j--) { 52 | for (int i = 0; i < nx; i++) { 53 | float u = (float)i / (float)nx; 54 | float v = (float)j / (float)ny; 55 | ray r; 56 | vec3 direction, direction0, direction1; 57 | vmul(direction0, v, vertical); 58 | vmul(direction1, u, horizontal); 59 | vadd(direction, direction0, direction1); 60 | vadd(direction, direction, lower_left_corner); 61 | rmake(&r, origin, direction); 62 | vec3 col; 63 | color(col, &r); 64 | int ir = (int)(255.99f*col[0]); 65 | int ig = (int)(255.99f*col[1]); 66 | int ib = (int)(255.99f*col[2]); 67 | printf("%d %d %d\n", ir, ig, ib); 68 | } 69 | } 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /rtiow/C/random.h: -------------------------------------------------------------------------------- 1 | #ifndef RANDOMH 2 | #define RANDOMH 3 | 4 | #include 5 | #include 6 | 7 | #include "vec3.h" 8 | 9 | #ifdef DEBUG 10 | extern unsigned long rfcnt; 11 | extern unsigned long riuscnt; 12 | extern unsigned long riudcnt; 13 | #define INLINE 14 | #else 15 | #define INLINE static inline 16 | #endif 17 | 18 | /********************************************** 19 | PCG random implementation - credits to Cieric 20 | */ 21 | typedef struct { uint64_t state; uint64_t inc; } pcg32_random_t; 22 | #ifdef RANDOM_IMPL 23 | static pcg32_random_t seed = {0, 0}; 24 | void pcg_srand(unsigned val) { 25 | seed.state = val; 26 | seed.inc = 0; 27 | } 28 | 29 | INLINE uint32_t pcg_rand() { 30 | uint64_t oldstate = seed.state; 31 | seed.state = oldstate * 6364136223846793005ULL + (seed.inc|1); 32 | uint32_t xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u; 33 | uint32_t rot = oldstate >> 59u; 34 | return (xorshifted >> rot) | (xorshifted << ((-rot) & 31)); 35 | } 36 | #else 37 | extern void pcg_srand(unsigned val) { 38 | extern uint32_t pcg_rand() { 39 | #endif 40 | 41 | #define PCG_RAND_MAX UINT_MAX 42 | /* 43 | **********************************************/ 44 | 45 | #ifdef RANDOM_IMPL 46 | unsigned long rfcnt; 47 | unsigned long riuscnt; 48 | unsigned long riudcnt; 49 | #endif 50 | 51 | INLINE float random_f() { 52 | #ifdef DEBUG 53 | rfcnt++; 54 | #endif 55 | return (float)pcg_rand() / ((float)PCG_RAND_MAX + (float)1.0); 56 | } 57 | uint32_t n_rand = 0; 58 | // unroll loop tentative by Cieric 59 | // seems slightly slower.. 60 | //#define UNROLL_LOOP 61 | #ifdef UNROLL_LOOP 62 | void random_in_unit_sphere(vec3 p) { 63 | #ifdef DEBUG 64 | riuscnt++; 65 | #endif 66 | float u = random_f(); 67 | float v = random_f(); 68 | float theta = u * 2.0f * (float)M_PI; 69 | float phi = acosf(2.0f * v - 1.0f); 70 | float r = cbrtf(random_f()); 71 | float sinTheta = sinf(theta); 72 | float cosTheta = cosf(theta); 73 | float sinPhi = sinf(phi); 74 | float cosPhi = cosf(phi); 75 | p[0] = r * sinPhi * cosTheta; 76 | p[1] = r * sinPhi * sinTheta; 77 | p[2] = r * cosPhi; 78 | } 79 | 80 | void random_in_unit_disk(vec3 p) { 81 | #ifdef DEBUG 82 | riudcnt++; 83 | #endif 84 | float a = random_f() * 2.0f * (float)M_PI; 85 | float r = sqrt(random_f()); 86 | p[0] = r * cosf(a); 87 | p[1] = r * sinf(a); 88 | p[2] = 0.0f; 89 | } 90 | #else 91 | void random_in_unit_sphere(vec3 p) { 92 | #ifdef DEBUG 93 | riuscnt++; 94 | #endif 95 | do { 96 | float r1 = random_f(); 97 | float r2 = random_f(); 98 | float r3 = random_f(); 99 | n_rand+=3; 100 | vmul(p, 2.0, VEC3(r1,r2,r3)); 101 | vsub(p, p, VEC3(1,1,1)); 102 | } while (vsqlen(p) >= 1.0); 103 | } 104 | 105 | void random_in_unit_disk(vec3 p) { 106 | #ifdef DEBUG 107 | riudcnt++; 108 | #endif 109 | do { 110 | float r1 = random_f(); 111 | float r2 = random_f(); 112 | n_rand+=2; 113 | vmul(p, 2.0, VEC3(r1,r2,0)); 114 | vsub(p, p, VEC3(1,1,0)); 115 | } while (vsqlen(p) >= 1.0); 116 | } 117 | #endif 118 | 119 | #endif 120 | -------------------------------------------------------------------------------- /rtiow/C/ray.h: -------------------------------------------------------------------------------- 1 | #ifndef RAYH 2 | #define RAYH 3 | 4 | #include "vec3.h" 5 | 6 | typedef struct ray_s { 7 | #if 0 8 | ray() {} 9 | ray(const vec3& a, const vec3& b) { A = a; B = b; } 10 | vec3 origin() const { return A; } 11 | vec3 direction() const { return B; } 12 | vec3 point_at_parameter(float t) const { return A + t*B; } 13 | #endif 14 | vec3 origin; // A 15 | vec3 direction; // B 16 | } ray; 17 | 18 | void rprint(const ray *r) { 19 | printf("{"); 20 | vprint(r->origin); 21 | printf(", "); 22 | vprint(r->direction); 23 | printf("}"); 24 | } 25 | 26 | API void rmake(ray *l, const vec3 r1, const vec3 r2) { 27 | vcopy(l->origin, r1); 28 | vcopy(l->direction, r2); 29 | } 30 | 31 | API void point_at_parameter(vec3 l, const ray *r1, float r2) { 32 | vmul(l, r2, r1->direction); 33 | vadd(l, r1->origin, l); 34 | } 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /rtiow/C/vec3.h: -------------------------------------------------------------------------------- 1 | #ifndef VEC3_H 2 | #define VEC3_H 3 | 4 | #include 5 | 6 | #include 7 | 8 | typedef float vec3[3]; 9 | #define VEC3(x,y,z) ((vec3){x, y, z}) 10 | 11 | #define API static inline 12 | // #define API 13 | 14 | void vprint(const vec3 r) { 15 | #if 0 16 | printf("{%.6f, %.6f, %.6f}", r[0], r[1], r[2]); 17 | // printf("{%g, %g, %g}", r[0], r[1], r[2]); 18 | #else 19 | #if 1 20 | union { 21 | float v[3]; 22 | uint32_t i[3]; 23 | } u; 24 | u.v[0] = r[0]; 25 | u.v[1] = r[1]; 26 | u.v[2] = r[2]; 27 | // printf("{0x%" PRIx32 ", 0x%" PRIx32 ", 0x%" PRIx32 "}", u.i[0], u.i[1], u.i[2]); 28 | printf("{%.6f, %.6f, %.6f;%" PRIx32 ", %" PRIx32 ", %" PRIx32 "}", r[0], r[1], r[2], u.i[0], u.i[1], u.i[2]); 29 | #else 30 | printf("pointer : %d\n", (int)sizeof(void *)); 31 | printf("float : %d\n", (int)sizeof(float)); 32 | printf("double : %d\n", (int)sizeof(double)); 33 | exit(0); 34 | #endif 35 | #endif 36 | } 37 | 38 | API void vcopy(vec3 l, const vec3 r) { 39 | l[0] = r[0]; 40 | l[1] = r[1]; 41 | l[2] = r[2]; 42 | } 43 | 44 | API float vsqlen(const vec3 r) { 45 | return r[0] * r[0] + r[1] * r[1] + r[2] * r[2]; 46 | } 47 | 48 | API float vlen(const vec3 r) { 49 | return sqrtf(vsqlen(r)); 50 | } 51 | 52 | API void vadd(vec3 l, const vec3 r1, const vec3 r2) { 53 | l[0] = r1[0] + r2[0]; 54 | l[1] = r1[1] + r2[1]; 55 | l[2] = r1[2] + r2[2]; 56 | } 57 | 58 | API void vsub(vec3 l, const vec3 r1, const vec3 r2) { 59 | l[0] = r1[0] - r2[0]; 60 | l[1] = r1[1] - r2[1]; 61 | l[2] = r1[2] - r2[2]; 62 | } 63 | 64 | API void vmul(vec3 l, float r1, const vec3 r2) { 65 | l[0] = r1 * r2[0]; 66 | l[1] = r1 * r2[1]; 67 | l[2] = r1 * r2[2]; 68 | } 69 | 70 | API void vmulv(vec3 l, const vec3 r1, const vec3 r2) { 71 | l[0] = r1[0] * r2[0]; 72 | l[1] = r1[1] * r2[1]; 73 | l[2] = r1[2] * r2[2]; 74 | } 75 | 76 | API void vcross(vec3 l, const vec3 r1, const vec3 r2) { 77 | l[0] = r1[1] * r2[2] - r1[2] * r2[1]; 78 | l[1] = r1[2] * r2[0] - r1[0] * r2[2]; 79 | l[2] = r1[0] * r2[1] - r1[1] * r2[0]; 80 | } 81 | 82 | API void vdiv(vec3 l, const vec3 r1, float r2) { 83 | l[0] = r1[0] / r2; 84 | l[1] = r1[1] / r2; 85 | l[2] = r1[2] / r2; 86 | } 87 | 88 | API float vdot(const vec3 r1, const vec3 r2) { 89 | return r1[0] * r2[0] 90 | + r1[1] * r2[1] 91 | + r1[2] * r2[2]; 92 | } 93 | 94 | API void unit_vector(vec3 l, const vec3 r) { 95 | vdiv(l, r, vlen(r)); 96 | } 97 | 98 | #endif/*VEC3_H*/ 99 | -------------------------------------------------------------------------------- /rtiow/C2/Makefile: -------------------------------------------------------------------------------- 1 | SRC:=$(wildcard main*.c) 2 | EXE:=$(patsubst %.c,%.elf,$(SRC)) 3 | PPM:=$(patsubst %.c,%.ppm,$(SRC)) 4 | 5 | #CC=$(CXX) 6 | 7 | all: $(EXE) 8 | du -sh . 9 | 10 | check: $(PPM) 11 | md5sum *.ppm 12 | md5sum *.ppm | md5sum 13 | 14 | bench: main14.elf 15 | time ./main14.elf 1024 768 10 main14.ppm && md5sum main14.ppm 16 | 17 | # OPT=$(CFLAGS) -O3 18 | # OPT+=-march=native 19 | #DEBUG:=1 20 | ifdef DEBUG 21 | OPT:=-O0 -g 22 | OPT+=-DDEBUG 23 | else 24 | OPT:=-O3 25 | # OPT:=-Ofast # ==> this one breaks bit-exact non-reg 26 | OPT+=-fno-plt 27 | OPT+=-flto 28 | # OPT+=-march=native # ==> this one breaks bit-exact non-reg 29 | OPT+=-DNDEBUG 30 | # OPT:=-Ofast -fno-plt -flto -march=native -DNDEBUG 31 | # OPT:=-Ofast -fno-plt -flto -DNDEBUG 32 | endif 33 | 34 | #PROF:=1 35 | ifdef PROF 36 | OPT+=-pg 37 | endif 38 | 39 | %.elf: %.c 40 | $(CC) -o $@ $^ $(OPT) -lm 41 | 42 | %.ppm: %.elf 43 | ./$^ $(ARGS) > $@ 44 | 45 | clean: 46 | $(RM) *.elf *.ppm 47 | -------------------------------------------------------------------------------- /rtiow/C2/main02.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | int nx = 200, ny = 100; 5 | printf("P3\n%d %d\n255\n", nx, ny); 6 | for (int j = ny -1; j >= 0; j--) { 7 | for (int i = 0; i < nx; i++) { 8 | float r = (float)i / nx; 9 | float g = (float)j / ny; 10 | float b = 0.2; 11 | int ir = 255.99 * r; 12 | int ig = 255.99 * g; 13 | int ib = 255.99 * b; 14 | printf("%d %d %d\n", ir, ig, ib); 15 | } 16 | } 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /rtiow/C2/main03.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | int nx = 200, ny = 100; 5 | printf("P3\n%d %d\n255\n", nx, ny); 6 | for (int j = ny -1; j >= 0; j--) { 7 | for (int i = 0; i < nx; i++) { 8 | float col[3] = {(float)i / nx, (float)j / ny, 0.2}; 9 | int ir = 255.99 * col[0]; 10 | int ig = 255.99 * col[1]; 11 | int ib = 255.99 * col[2]; 12 | printf("%d %d %d\n", ir, ig, ib); 13 | } 14 | } 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /rtiow/C2/main04.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "vec3.h" 3 | #include "ray.h" 4 | 5 | void color(vec3 col, ray r) { 6 | vec3 unit_direction; 7 | unit_vector(unit_direction, r.direction); 8 | float t = 0.5f * (unit_direction[1] + 1.f); 9 | vec3 col0 = {1.0, 1.0, 1.0}; 10 | vec3 col1 = {0.5, 0.7, 1.0}; 11 | vmul(col0, 1.f - t, col0); 12 | vmul(col1, t, col1); 13 | vadd(col, col0, col1); 14 | } 15 | 16 | int main() { 17 | int nx = 200, ny = 100; 18 | printf("P3\n%d %d\n255\n", nx, ny); 19 | vec3 lower_left_corner={-2, -1, -1}; 20 | vec3 horizontal={4, 0, 0}; 21 | vec3 vertical={0, 2, 0}; 22 | vec3 origin={0, 0, 0}; 23 | for (int j = ny -1; j >= 0; j--) { 24 | for (int i = 0; i < nx; i++) { 25 | float u = (float)i / nx, v = (float)j / ny; 26 | vec3 direction, direction0, direction1; 27 | vmul(direction0, v, vertical); 28 | vmul(direction1, u, horizontal); 29 | vadd(direction, direction0, direction1); 30 | vadd(direction, direction, lower_left_corner); 31 | ray r; 32 | rmake(&r, origin, direction); 33 | // rprint(&r);exit(0); 34 | vec3 col; 35 | color(col, r); 36 | int ir = 255.99f * col[0]; 37 | int ig = 255.99f * col[1]; 38 | int ib = 255.99f * col[2]; 39 | printf("%d %d %d\n", ir, ig, ib); 40 | } 41 | } 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /rtiow/C2/ray.h: -------------------------------------------------------------------------------- 1 | #ifndef RAYH 2 | #define RAYH 3 | 4 | #include "vec3.h" 5 | 6 | typedef struct ray_s { 7 | #if 0 8 | ray() {} 9 | ray(const vec3& a, const vec3& b) { A = a; B = b; } 10 | vec3 origin() const { return A; } 11 | vec3 direction() const { return B; } 12 | vec3 point_at_parameter(float t) const { return A + t*B; } 13 | #endif 14 | vec3 origin; // A 15 | vec3 direction; // B 16 | } ray; 17 | 18 | void rprint(const ray *r) { 19 | printf("{"); 20 | vprint(r->origin); 21 | printf(", "); 22 | vprint(r->direction); 23 | printf("}"); 24 | } 25 | 26 | static inline void rmake(ray *l, const vec3 r1, const vec3 r2) { 27 | vcopy(l->origin, r1); 28 | vcopy(l->direction, r2); 29 | } 30 | 31 | static inline void point_at_parameter(vec3 l, const ray *r1, float r2) { 32 | vmul(l, r2, r1->direction); 33 | vadd(l, r1->origin, l); 34 | } 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /rtiow/C2/vec3.h: -------------------------------------------------------------------------------- 1 | #ifndef VEC3_H 2 | #define VEC3_H 3 | 4 | #include 5 | 6 | #include 7 | 8 | typedef float vec3[3]; 9 | #define VEC3(x,y,z) ((vec3){x, y, z}) 10 | 11 | #define API static inline 12 | // #define API 13 | 14 | void vprint(const vec3 r) { 15 | #if 0 16 | printf("{%.6f, %.6f, %.6f}", r[0], r[1], r[2]); 17 | // printf("{%g, %g, %g}", r[0], r[1], r[2]); 18 | #else 19 | #if 1 20 | union { 21 | float v[3]; 22 | uint32_t i[3]; 23 | } u; 24 | u.v[0] = r[0]; 25 | u.v[1] = r[1]; 26 | u.v[2] = r[2]; 27 | // printf("{0x%" PRIx32 ", 0x%" PRIx32 ", 0x%" PRIx32 "}", u.i[0], u.i[1], u.i[2]); 28 | printf("{%.6f, %.6f, %.6f;%" PRIx32 ", %" PRIx32 ", %" PRIx32 "}", r[0], r[1], r[2], u.i[0], u.i[1], u.i[2]); 29 | #else 30 | printf("pointer : %d\n", (int)sizeof(void *)); 31 | printf("float : %d\n", (int)sizeof(float)); 32 | printf("double : %d\n", (int)sizeof(double)); 33 | exit(0); 34 | #endif 35 | #endif 36 | } 37 | 38 | API void vcopy(vec3 l, const vec3 r) { 39 | l[0] = r[0]; 40 | l[1] = r[1]; 41 | l[2] = r[2]; 42 | } 43 | 44 | API float vsqlen(const vec3 r) { 45 | return r[0] * r[0] + r[1] * r[1] + r[2] * r[2]; 46 | } 47 | 48 | API float vlen(const vec3 r) { 49 | return sqrtf(vsqlen(r)); 50 | } 51 | 52 | API void vadd(vec3 l, const vec3 r1, const vec3 r2) { 53 | l[0] = r1[0] + r2[0]; 54 | l[1] = r1[1] + r2[1]; 55 | l[2] = r1[2] + r2[2]; 56 | } 57 | 58 | API void vsub(vec3 l, const vec3 r1, const vec3 r2) { 59 | l[0] = r1[0] - r2[0]; 60 | l[1] = r1[1] - r2[1]; 61 | l[2] = r1[2] - r2[2]; 62 | } 63 | 64 | API void vmul(vec3 l, float r1, const vec3 r2) { 65 | l[0] = r1 * r2[0]; 66 | l[1] = r1 * r2[1]; 67 | l[2] = r1 * r2[2]; 68 | } 69 | 70 | API void vmulv(vec3 l, const vec3 r1, const vec3 r2) { 71 | l[0] = r1[0] * r2[0]; 72 | l[1] = r1[1] * r2[1]; 73 | l[2] = r1[2] * r2[2]; 74 | } 75 | 76 | API void vcross(vec3 l, const vec3 r1, const vec3 r2) { 77 | l[0] = r1[1] * r2[2] - r1[2] * r2[1]; 78 | l[1] = r1[2] * r2[0] - r1[0] * r2[2]; 79 | l[2] = r1[0] * r2[1] - r1[1] * r2[0]; 80 | } 81 | 82 | API void vdiv(vec3 l, const vec3 r1, float r2) { 83 | l[0] = r1[0] / r2; 84 | l[1] = r1[1] / r2; 85 | l[2] = r1[2] / r2; 86 | } 87 | 88 | API float vdot(const vec3 r1, const vec3 r2) { 89 | return r1[0] * r2[0] 90 | + r1[1] * r2[1] 91 | + r1[2] * r2[2]; 92 | } 93 | 94 | API void unit_vector(vec3 l, const vec3 r) { 95 | vdiv(l, r, vlen(r)); 96 | } 97 | 98 | #endif/*VEC3_H*/ 99 | -------------------------------------------------------------------------------- /rtiow/CPP/Makefile: -------------------------------------------------------------------------------- 1 | SRC:=$(wildcard main*.cpp) 2 | EXE:=$(patsubst %.cpp,%.elf,$(SRC)) 3 | PPM:=$(patsubst %.cpp,%.ppm,$(SRC)) 4 | 5 | all: $(EXE) 6 | du -sh . 7 | 8 | check: $(PPM) 9 | md5sum *.ppm 10 | md5sum *.ppm | md5sum 11 | 12 | bench: main14.elf 13 | time ./main14.elf 1024 768 10 main14.ppm && md5sum main14.ppm 14 | 15 | ifdef DEBUG 16 | OPT:=-O0 -g 17 | OPT+=-DDEBUG 18 | else 19 | # OPT:=-O3 20 | # OPT:=-Ofast -fno-plt -flto -march=native -DNDEBUG 21 | # OPT:=-Ofast -fno-plt -flto -DNDEBUG 22 | OPT:=-O3 -fno-plt -flto -DNDEBUG 23 | endif 24 | 25 | #PROF:=1 26 | ifdef PROF 27 | OPT+=-pg 28 | endif 29 | 30 | %.elf: %.cpp 31 | $(CXX) -o $@ $^ $(OPT) -lm 32 | 33 | %.ppm: %.elf 34 | ./$^ $(ARGS) > $@ 35 | 36 | clean: 37 | $(RM) *.elf *.ppm 38 | -------------------------------------------------------------------------------- /rtiow/CPP/bugcpp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int main() { 3 | float v1[3] = {9.000000,1002.000000,2.600000}; 4 | float v2[3] = {-6.562669,-0.491479,-0.021382}; 5 | printf("DOT %.6f,%.6f,%.6f;%.6f,%.6f,%.6f", 6 | v1[0], v1[1], v1[2], 7 | v2[0], v2[1], v2[2] 8 | ); 9 | float ret = v1[0] *v2[0] + v1[1] *v2[1] + v1[2] *v2[2]; 10 | printf(" => %.6f\n", ret); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /rtiow/CPP/camera.h: -------------------------------------------------------------------------------- 1 | #ifndef CAMERAH 2 | #define CAMERAH 3 | 4 | #include "random.h" 5 | #include "ray.h" 6 | 7 | class camera { 8 | public: 9 | camera() { 10 | lower_left_corner = vec3(-2.0, -1.0, -1.0); 11 | horizontal = vec3(4.0, 0.0, 0.0); 12 | vertical = vec3(0.0, 2.0, 0.0); 13 | origin = vec3(0.0, 0.0, 0.0); 14 | } 15 | camera(vec3 lookfrom, vec3 lookat, vec3 vup, float vfov, float aspect) { 16 | float aperture = 0; 17 | float focus_dist = (lookfrom-lookat).length(); 18 | lens_radius = aperture / 2.f; 19 | float theta = vfov*(float)M_PI/180; 20 | float half_height = tanf(theta/2.f); 21 | float half_width = aspect * half_height; 22 | origin = lookfrom; 23 | w = unit_vector(lookfrom - lookat); 24 | u = unit_vector(cross(vup, w)); 25 | v = cross(w, u); 26 | lower_left_corner = origin 27 | - half_width * focus_dist * u 28 | - half_height * focus_dist * v 29 | - focus_dist * w; 30 | horizontal = 2*half_width*focus_dist*u; 31 | vertical = 2*half_height*focus_dist*v; 32 | } 33 | camera(vec3 lookfrom, vec3 lookat, vec3 vup, float vfov, float aspect, 34 | float aperture, float focus_dist) { 35 | lens_radius = aperture / 2; 36 | float theta = vfov*(float)M_PI/180; 37 | float half_height = tanf(theta/2); 38 | float half_width = aspect * half_height; 39 | origin = lookfrom; 40 | w = unit_vector(lookfrom - lookat); 41 | u = unit_vector(cross(vup, w)); 42 | v = cross(w, u); 43 | lower_left_corner = origin 44 | - half_width * focus_dist * u 45 | - half_height * focus_dist * v 46 | - focus_dist * w; 47 | horizontal = 2*half_width*focus_dist*u; 48 | vertical = 2*half_height*focus_dist*v; 49 | } 50 | void print() { 51 | printf("Origin: ");origin.print(); 52 | printf("\nLower_left: ");lower_left_corner.print(); 53 | printf("\nhorizontal: ");horizontal.print(); 54 | printf("\nvertical: ");vertical.print(); 55 | printf("\nu: ");u.print(); 56 | printf("\nv: ");v.print(); 57 | printf("\nw: ");w.print(); 58 | printf("\nlens_radius=%.6f\n", lens_radius); 59 | } 60 | 61 | ray get_ray(float s, float t) { 62 | #ifdef DEBUG 63 | printf("s=%g t=%g\n", s, t); 64 | #endif 65 | #if 0 66 | vec3 rd = lens_radius*random_in_unit_disk(); 67 | vec3 offset = u * rd.x() + v * rd.y(); 68 | return ray(origin + offset, 69 | lower_left_corner + s*horizontal + t*vertical 70 | - origin - offset); 71 | #else 72 | vec3 rd = lens_radius*random_in_unit_disk(); 73 | vec3 offset = u * rd.x() + v * rd.y(); 74 | ray r = ray(origin + offset, 75 | lower_left_corner + s*horizontal + t*vertical 76 | - origin - offset); 77 | return r; 78 | #endif 79 | } 80 | 81 | vec3 origin; 82 | vec3 lower_left_corner; 83 | vec3 horizontal; 84 | vec3 vertical; 85 | vec3 u, v, w; 86 | float lens_radius; 87 | }; 88 | #endif 89 | 90 | -------------------------------------------------------------------------------- /rtiow/CPP/hitable.h: -------------------------------------------------------------------------------- 1 | #ifndef HITABLEH 2 | #define HITABLEH 3 | 4 | #include "ray.h" 5 | 6 | class material; 7 | 8 | struct hit_record 9 | { 10 | float t; 11 | vec3 p; 12 | vec3 normal; 13 | material *mat_ptr; 14 | }; 15 | 16 | class hitable { 17 | public: 18 | virtual bool hit( 19 | const ray& r, float t_min, float t_max, hit_record& rec) const = 0; 20 | virtual void print() const = 0; 21 | }; 22 | 23 | class material { 24 | public: 25 | virtual bool scatter( 26 | const ray& r_in, const hit_record& rec, vec3& attenuation, 27 | ray& scattered) const = 0; 28 | virtual int type() const { 29 | return -1; 30 | } 31 | }; 32 | #endif 33 | 34 | -------------------------------------------------------------------------------- /rtiow/CPP/hitable_list.h: -------------------------------------------------------------------------------- 1 | #ifndef HITABLELISTH 2 | #define HITABLELISTH 3 | 4 | #include "hitable.h" 5 | 6 | class hitable_list: public hitable { 7 | public: 8 | hitable_list() {} 9 | hitable_list(hitable **l, int n) {list = l; list_size = n; } 10 | virtual bool hit( 11 | const ray& r, float tmin, float tmax, hit_record& rec) const; 12 | virtual void print() const; 13 | hitable **list; 14 | int list_size; 15 | }; 16 | 17 | void hitable_list::print() const { 18 | printf("["); 19 | for (int i = 0; i < list_size; i++) { 20 | if (i > 0) { 21 | printf(", "); 22 | } 23 | list[i]->print(); 24 | } 25 | printf("]\n"); 26 | } 27 | 28 | bool hitable_list::hit( 29 | const ray& r, float t_min, float t_max, hit_record& rec) const { 30 | 31 | hit_record temp_rec; 32 | bool hit_anything = false; 33 | float closest_so_far = t_max; 34 | for (int i = 0; i < list_size; i++) { 35 | if (list[i]->hit(r, t_min, closest_so_far, temp_rec)) { 36 | hit_anything = true; 37 | closest_so_far = temp_rec.t; 38 | rec = temp_rec; 39 | } 40 | } 41 | return hit_anything; 42 | } 43 | 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /rtiow/CPP/main02.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | int nx = 200; 5 | int ny = 100; 6 | std::cout << "P3\n" << nx << " " << ny << "\n255\n"; 7 | for (int j = ny-1; j >= 0; j--) { 8 | for (int i = 0; i < nx; i++) { 9 | float r = (float)i / (float)nx; 10 | float g = (float)j / (float)ny; 11 | float b = 0.2; 12 | int ir = (int)(255.99f*r); 13 | int ig = (int)(255.99f*g); 14 | int ib = (int)(255.99f*b); 15 | std::cout << ir << " " << ig << " " << ib << "\n"; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /rtiow/CPP/main03.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "vec3.h" 3 | 4 | int main() { 5 | int nx = 200; 6 | int ny = 100; 7 | std::cout << "P3\n" << nx << " " << ny << "\n255\n"; 8 | for (int j = ny-1; j >= 0; j--) { 9 | for (int i = 0; i < nx; i++) { 10 | vec3 col((float)i / (float)nx, (float)j / (float)ny, 0.2); 11 | int ir = (int)(255.99f*col[0]); 12 | int ig = (int)(255.99f*col[1]); 13 | int ib = (int)(255.99f*col[2]); 14 | std::cout << ir << " " << ig << " " << ib << "\n"; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /rtiow/CPP/main04.cpp: -------------------------------------------------------------------------------- 1 | #include "ray.h" 2 | 3 | #include 4 | 5 | vec3 color(const ray& r) { 6 | vec3 unit_direction = unit_vector(r.direction()); 7 | float t = 0.5*(unit_direction.y() + 1.0); 8 | return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); 9 | } 10 | 11 | int main() { 12 | int nx = 200; 13 | int ny = 100; 14 | std::cout << "P3\n" << nx << " " << ny << "\n255\n"; 15 | vec3 lower_left_corner(-2.0, -1.0, -1.0); 16 | // lower_left_corner.print(); 17 | vec3 horizontal(4.0, 0.0, 0.0); 18 | vec3 vertical(0.0, 2.0, 0.0); 19 | vec3 origin(0.0, 0.0, 0.0); 20 | for (int j = ny-1; j >= 0; j--) { 21 | for (int i = 0; i < nx; i++) { 22 | float u = (float)i / (float)nx; 23 | float v = (float)j / (float)ny; 24 | ray r(origin, lower_left_corner + u*horizontal + v*vertical); 25 | // r.print();exit(0); 26 | vec3 col = color(r); 27 | int ir = (int)(255.99f*col[0]); 28 | int ig = (int)(255.99f*col[1]); 29 | int ib = (int)(255.99f*col[2]); 30 | 31 | std::cout << ir << " " << ig << " " << ib << "\n"; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /rtiow/CPP/main05.cpp: -------------------------------------------------------------------------------- 1 | #include "ray.h" 2 | 3 | #include 4 | 5 | bool hit_sphere(const vec3& center, float radius, const ray& r) { 6 | vec3 oc = r.origin() - center; 7 | float a = dot(r.direction(), r.direction()); 8 | float b = 2.0 * dot(oc, r.direction()); 9 | float c = dot(oc, oc) - radius*radius; 10 | float discriminant = b*b - 4*a*c; 11 | return (discriminant > 0); 12 | } 13 | 14 | vec3 color(const ray& r) { 15 | if (hit_sphere(vec3(0,0,-1), 0.5, r)) 16 | return vec3(1, 0, 0); 17 | vec3 unit_direction = unit_vector(r.direction()); 18 | float t = 0.5*(unit_direction.y() + 1.0); 19 | return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); 20 | } 21 | 22 | int main() { 23 | int nx = 200; 24 | int ny = 100; 25 | std::cout << "P3\n" << nx << " " << ny << "\n255\n"; 26 | vec3 lower_left_corner(-2.0, -1.0, -1.0); 27 | // lower_left_corner.print(); 28 | vec3 horizontal(4.0, 0.0, 0.0); 29 | vec3 vertical(0.0, 2.0, 0.0); 30 | vec3 origin(0.0, 0.0, 0.0); 31 | for (int j = ny-1; j >= 0; j--) { 32 | for (int i = 0; i < nx; i++) { 33 | float u = (float)i / (float)nx; 34 | float v = (float)j / (float)ny; 35 | ray r(origin, lower_left_corner + u*horizontal + v*vertical); 36 | // r.print();exit(0); 37 | vec3 col = color(r); 38 | int ir = (int)(255.99f*col[0]); 39 | int ig = (int)(255.99f*col[1]); 40 | int ib = (int)(255.99f*col[2]); 41 | 42 | std::cout << ir << " " << ig << " " << ib << "\n"; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /rtiow/CPP/main06_1.cpp: -------------------------------------------------------------------------------- 1 | #include "ray.h" 2 | 3 | #include 4 | 5 | float hit_sphere(const vec3& center, float radius, const ray& r) { 6 | vec3 oc = r.origin() - center; 7 | float a = dot(r.direction(), r.direction()); 8 | float b = 2.0 * dot(oc, r.direction()); 9 | float c = dot(oc, oc) - radius*radius; 10 | float discriminant = b*b - 4*a*c; 11 | if (discriminant < 0) { 12 | return -1.0; 13 | } 14 | else { 15 | return (-b - sqrtf(discriminant) ) / (2.0*a); 16 | } 17 | } 18 | 19 | vec3 color(const ray& r) { 20 | float t = hit_sphere(vec3(0,0,-1), 0.5, r); 21 | if (t > 0.0) { 22 | vec3 N = unit_vector(r.point_at_parameter(t) - vec3(0,0,-1)); 23 | return 0.5*vec3(N.x()+1, N.y()+1, N.z()+1); 24 | } 25 | vec3 unit_direction = unit_vector(r.direction()); 26 | t = 0.5*(unit_direction.y() + 1.0); 27 | return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); 28 | } 29 | 30 | int main() { 31 | int nx = 200; 32 | int ny = 100; 33 | std::cout << "P3\n" << nx << " " << ny << "\n255\n"; 34 | vec3 lower_left_corner(-2.0, -1.0, -1.0); 35 | // lower_left_corner.print(); 36 | vec3 horizontal(4.0, 0.0, 0.0); 37 | vec3 vertical(0.0, 2.0, 0.0); 38 | vec3 origin(0.0, 0.0, 0.0); 39 | for (int j = ny-1; j >= 0; j--) { 40 | for (int i = 0; i < nx; i++) { 41 | float u = (float)i / (float)nx; 42 | float v = (float)j / (float)ny; 43 | ray r(origin, lower_left_corner + u*horizontal + v*vertical); 44 | // r.print();exit(0); 45 | vec3 col = color(r); 46 | int ir = (int)(255.99f*col[0]); 47 | int ig = (int)(255.99f*col[1]); 48 | int ib = (int)(255.99f*col[2]); 49 | 50 | std::cout << ir << " " << ig << " " << ib << "\n"; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /rtiow/CPP/main06_2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sphere.h" 3 | #include "hitable_list.h" 4 | #include "float.h" 5 | 6 | vec3 color(const ray& r, hitable *world) { 7 | hit_record rec; 8 | if (world->hit(r, 0.0, FLT_MAX, rec)) { 9 | return 0.5*vec3(rec.normal.x()+1, rec.normal.y()+1, rec.normal.z()+1); 10 | } 11 | else { 12 | vec3 unit_direction = unit_vector(r.direction()); 13 | float t = 0.5*(unit_direction.y() + 1.0); 14 | return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); 15 | } 16 | } 17 | 18 | int main() { 19 | int nx = 200; 20 | int ny = 100; 21 | std::cout << "P3\n" << nx << " " << ny << "\n255\n"; 22 | vec3 lower_left_corner(-2.0, -1.0, -1.0); 23 | vec3 horizontal(4.0, 0.0, 0.0); 24 | vec3 vertical(0.0, 2.0, 0.0); 25 | vec3 origin(0.0, 0.0, 0.0); 26 | hitable *list[2]; 27 | list[0] = new sphere(vec3(0,0,-1), 0.5); 28 | list[1] = new sphere(vec3(0,-100.5,-1), 100); 29 | hitable *world = new hitable_list(list,2); 30 | for (int j = ny-1; j >= 0; j--) { 31 | for (int i = 0; i < nx; i++) { 32 | float u = (float)i / (float)nx; 33 | float v = (float)j / (float)ny; 34 | ray r(origin, lower_left_corner + u*horizontal + v*vertical); 35 | 36 | vec3 col = color(r, world); 37 | int ir = (int)(255.99f*col[0]); 38 | int ig = (int)(255.99f*col[1]); 39 | int ib = (int)(255.99f*col[2]); 40 | 41 | std::cout << ir << " " << ig << " " << ib << "\n"; 42 | } 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /rtiow/CPP/main07.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sphere.h" 3 | #include "hitable_list.h" 4 | #include "float.h" 5 | #define RANDOM_IMPL 6 | #include "random.h" 7 | 8 | class camera { 9 | public: 10 | camera() { 11 | lower_left_corner = vec3(-2.0, -1.0, -1.0); 12 | horizontal = vec3(4.0, 0.0, 0.0); 13 | vertical = vec3(0.0, 2.0, 0.0); 14 | origin = vec3(0.0, 0.0, 0.0); 15 | } 16 | ray get_ray(float u, float v) { 17 | return ray(origin, 18 | lower_left_corner + u*horizontal + v*vertical - origin); 19 | } 20 | 21 | vec3 origin; 22 | vec3 lower_left_corner; 23 | vec3 horizontal; 24 | vec3 vertical; 25 | }; 26 | 27 | vec3 color(const ray& r, hitable *world) { 28 | hit_record rec; 29 | if (world->hit(r, 0.0, FLT_MAX, rec)) { 30 | return 0.5*vec3(rec.normal.x()+1, rec.normal.y()+1, rec.normal.z()+1); 31 | } 32 | else { 33 | vec3 unit_direction = unit_vector(r.direction()); 34 | float t = 0.5*(unit_direction.y() + 1.0); 35 | return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); 36 | } 37 | } 38 | 39 | int main() { 40 | pcg_srand(0); 41 | int nx = 200; 42 | int ny = 100; 43 | int ns = 100; 44 | std::cout << "P3\n" << nx << " " << ny << "\n255\n"; 45 | hitable *list[2]; 46 | list[0] = new sphere(vec3(0,0,-1), 0.5); 47 | list[1] = new sphere(vec3(0,-100.5,-1), 100); 48 | hitable *world = new hitable_list(list,2); 49 | camera cam; 50 | for (int j = ny-1; j >= 0; j--) { 51 | for (int i = 0; i < nx; i++) { 52 | vec3 col(0, 0, 0); 53 | for (int s=0; s < ns; s++) { 54 | float u = ((float)i + random_f()) / (float)nx; 55 | float v = ((float)j + random_f()) / (float)ny; 56 | ray r = cam.get_ray(u, v); 57 | col += color(r, world); 58 | } 59 | col /= (float)ns; 60 | int ir = (int)(255.99f*col[0]); 61 | int ig = (int)(255.99f*col[1]); 62 | int ib = (int)(255.99f*col[2]); 63 | std::cout << ir << " " << ig << " " << ib << "\n"; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /rtiow/CPP/main08_1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sphere.h" 3 | #include "hitable_list.h" 4 | #include "float.h" 5 | #define RANDOM_IMPL 6 | #include "random.h" 7 | 8 | #ifdef DEBUG 9 | unsigned long rfcnt = 0; 10 | unsigned long riudcnt = 0; 11 | unsigned long riuscnt = 0; 12 | #endif 13 | 14 | class camera { 15 | public: 16 | camera() { 17 | lower_left_corner = vec3(-2.0, -1.0, -1.0); 18 | horizontal = vec3(4.0, 0.0, 0.0); 19 | vertical = vec3(0.0, 2.0, 0.0); 20 | origin = vec3(0.0, 0.0, 0.0); 21 | } 22 | ray get_ray(float u, float v) { 23 | return ray(origin, 24 | lower_left_corner + u*horizontal + v*vertical - origin); 25 | } 26 | 27 | vec3 origin; 28 | vec3 lower_left_corner; 29 | vec3 horizontal; 30 | vec3 vertical; 31 | void print() { 32 | printf("Origin: ");origin.print(); 33 | printf("\nLower_left: ");lower_left_corner.print(); 34 | printf("\nhorizontal: ");horizontal.print(); 35 | printf("\nvertical: ");vertical.print(); 36 | #if 0 37 | printf("\nu: ");u.print(); 38 | printf("\nv: ");v.print(); 39 | printf("\nw: ");w.print(); 40 | printf("\nlens_radius=%.6f\n", lens_radius); 41 | #endif 42 | } 43 | }; 44 | 45 | vec3 color(const ray& r, hitable *world) { 46 | hit_record rec; 47 | // if (world->hit(r, 0, FLT_MAX, rec)) { 48 | if (world->hit(r, 0.001, FLT_MAX, rec)) { 49 | #ifdef DEBUG 50 | printf("HIT\n"); 51 | #endif 52 | vec3 target = rec.normal + random_in_unit_sphere(); 53 | return 0.5 * color(ray(rec.p, target), world); 54 | } 55 | else { 56 | #ifdef DEBUG 57 | printf("NOT HIT\n"); 58 | #endif 59 | vec3 unit_direction = unit_vector(r.direction()); 60 | float t = 0.5*(unit_direction.y() + 1.0); 61 | return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); 62 | } 63 | } 64 | 65 | int main() { 66 | pcg_srand(0); 67 | int nx = 200; 68 | int ny = 100; 69 | int ns = 100; 70 | std::cout << "P3\n" << nx << " " << ny << "\n255\n"; 71 | hitable *list[2]; 72 | list[0] = new sphere(vec3(0,0,-1), 0.5); 73 | list[1] = new sphere(vec3(0,-100.5,-1), 100); 74 | hitable *world = new hitable_list(list,2); 75 | camera cam; 76 | // cam.print(); 77 | for (int j = ny-1; j >= 0; j--) { 78 | for (int i = 0; i < nx; i++) { 79 | vec3 col(0, 0, 0); 80 | for (int s=0; s < ns; s++) { 81 | #ifdef DEBUG 82 | printf("rfcnt=%lu riuscnt=%lu riudcnt=%lu\n", rfcnt, riuscnt, riudcnt); 83 | #endif 84 | float u = ((float)i + random_f()) / (float)nx; 85 | float v = ((float)j + random_f()) / (float)ny; 86 | #ifdef DEBUG 87 | printf("u=%.6f v=%.6f\n", u, v); 88 | #endif 89 | ray r = cam.get_ray(u, v); 90 | #ifdef DEBUG 91 | printf("r=");r.print();printf(" \n"); 92 | #endif 93 | col += color(r, world); 94 | } 95 | col /= (float)ns; 96 | int ir = (int)(255.99f*col[0]); 97 | int ig = (int)(255.99f*col[1]); 98 | int ib = (int)(255.99f*col[2]); 99 | std::cout << ir << " " << ig << " " << ib << "\n"; 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /rtiow/CPP/main08_2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sphere.h" 3 | #include "hitable_list.h" 4 | #include "float.h" 5 | #define RANDOM_IMPL 6 | #include "random.h" 7 | 8 | class camera { 9 | public: 10 | camera() { 11 | lower_left_corner = vec3(-2.0, -1.0, -1.0); 12 | horizontal = vec3(4.0, 0.0, 0.0); 13 | vertical = vec3(0.0, 2.0, 0.0); 14 | origin = vec3(0.0, 0.0, 0.0); 15 | } 16 | ray get_ray(float u, float v) { 17 | return ray(origin, 18 | lower_left_corner + u*horizontal + v*vertical - origin); 19 | } 20 | 21 | vec3 origin; 22 | vec3 lower_left_corner; 23 | vec3 horizontal; 24 | vec3 vertical; 25 | }; 26 | 27 | vec3 color(const ray& r, hitable *world) { 28 | hit_record rec; 29 | // remove acne by starting at 0.001 30 | if (world->hit(r, 0.001, FLT_MAX, rec)) { 31 | vec3 target = rec.normal + random_in_unit_sphere(); 32 | return 0.5 * color(ray(rec.p, target), world); 33 | } 34 | else { 35 | vec3 unit_direction = unit_vector(r.direction()); 36 | float t = 0.5*(unit_direction.y() + 1.0); 37 | return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); 38 | } 39 | } 40 | int main() { 41 | pcg_srand(0); 42 | int nx = 200; 43 | int ny = 100; 44 | int ns = 100; 45 | std::cout << "P3\n" << nx << " " << ny << "\n255\n"; 46 | hitable *list[2]; 47 | list[0] = new sphere(vec3(0,0,-1), 0.5); 48 | list[1] = new sphere(vec3(0,-100.5,-1), 100); 49 | hitable *world = new hitable_list(list,2); 50 | camera cam; 51 | for (int j = ny-1; j >= 0; j--) { 52 | for (int i = 0; i < nx; i++) { 53 | vec3 col(0, 0, 0); 54 | for (int s=0; s < ns; s++) { 55 | float u = ((float)i + random_f()) / (float)nx; 56 | float v = ((float)j + random_f()) / (float)ny; 57 | ray r = cam.get_ray(u, v); 58 | col += color(r, world); 59 | } 60 | col /= (float)ns; 61 | col = vec3( sqrtf(col[0]), sqrtf(col[1]), sqrtf(col[2]) ); 62 | int ir = (int)(255.99f*col[0]); 63 | int ig = (int)(255.99f*col[1]); 64 | int ib = (int)(255.99f*col[2]); 65 | std::cout << ir << " " << ig << " " << ib << "\n"; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /rtiow/CPP/random.h: -------------------------------------------------------------------------------- 1 | #ifndef RANDOMH 2 | #define RANDOMH 3 | 4 | //#include 5 | #include 6 | #include 7 | 8 | #include "vec3.h" 9 | 10 | #ifdef DEBUG 11 | extern unsigned long rfcnt; 12 | extern unsigned long riuscnt; 13 | extern unsigned long riudcnt; 14 | #define INLINE 15 | #else 16 | #define INLINE static inline 17 | #endif 18 | 19 | /********************************************** 20 | PCG random implementation - credits to Cieric 21 | */ 22 | typedef struct { uint64_t state; uint64_t inc; } pcg32_random_t; 23 | #ifdef RANDOM_IMPL 24 | static pcg32_random_t seed = {0, 0}; 25 | #endif 26 | 27 | INLINE void pcg_srand(unsigned val) { 28 | seed.state = val; 29 | seed.inc = 0; 30 | } 31 | 32 | INLINE uint32_t pcg_rand() { 33 | uint64_t oldstate = seed.state; 34 | seed.state = oldstate * 6364136223846793005ULL + (seed.inc|1); 35 | uint32_t xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u; 36 | uint32_t rot = oldstate >> 59u; 37 | return (xorshifted >> rot) | (xorshifted << ((-rot) & 31)); 38 | } 39 | #define PCG_RAND_MAX UINT_MAX 40 | /* 41 | **********************************************/ 42 | 43 | #ifdef RANDOM_IMPL 44 | unsigned long rfcnt; 45 | unsigned long riuscnt; 46 | unsigned long riudcnt; 47 | #endif 48 | 49 | 50 | 51 | INLINE float random_f() { 52 | #ifdef DEBUG 53 | rfcnt++; 54 | #endif 55 | // return (float)pcg_rand() / ((float)PCG_RAND_MAX + (float)1.0); 56 | float r = (float)pcg_rand() / ((float)PCG_RAND_MAX + (float)1.0); 57 | // printf("r=%.6f\n", r); 58 | return r; 59 | } 60 | vec3 random_in_unit_sphere() { 61 | #ifdef DEBUG 62 | riuscnt++; 63 | #endif 64 | vec3 p; 65 | do { 66 | float r1 = random_f(); 67 | float r2 = random_f(); 68 | float r3 = random_f(); 69 | p = 2.0*vec3(r1, r2, r3) - vec3(1,1,1); 70 | } while (p.squared_length() >= 1.0); 71 | return p; 72 | } 73 | 74 | vec3 random_in_unit_disk() { 75 | #ifdef DEBUG 76 | riudcnt++; 77 | #endif 78 | vec3 p; 79 | do { 80 | float r1 = random_f(); 81 | float r2 = random_f(); 82 | p = 2.0*vec3(r1,r2,0) - vec3(1,1,0); 83 | // } while (dot(p,p) >= 1.0); 84 | } while (p.squared_length() >= 1.0); 85 | return p; 86 | } 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /rtiow/CPP/ray.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "ray.h" 4 | 5 | vec3 color(const ray& r 6 | //, hitable *world, int depth 7 | ) { 8 | vec3 unit_direction = unit_vector(r.direction()); 9 | float t = 0.5*(unit_direction.y() + 1.0); 10 | return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); 11 | } 12 | 13 | int main() { 14 | int nx = 200; 15 | int ny = 100; 16 | std::cout << "P3\n" << nx << " " << ny << "\n255\n"; 17 | vec3 lower_left_corner(-2.0, -1.0, -1.0); 18 | vec3 horizontal(4.0, 0.0, 0.0); 19 | vec3 vertical(0.0, 2.0, 0.0); 20 | vec3 origin(0.0, 0.0, 0.0); 21 | for (int j = ny-1; j >= 0; j--) { 22 | for (int i = 0; i < nx; i++) { 23 | float u = (float)i / (float)nx; 24 | float v = (float)j / (float)ny; 25 | ray r(origin, lower_left_corner + u*horizontal + v*vertical); 26 | vec3 col = color(r); 27 | int ir = (int)(255.99f*col[0]); 28 | int ig = (int)(255.99f*col[1]); 29 | int ib = (int)(255.99f*col[2]); 30 | 31 | std::cout << ir << " " << ig << " " << ib << "\n"; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /rtiow/CPP/ray.h: -------------------------------------------------------------------------------- 1 | #ifndef RAYH 2 | #define RAYH 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include "vec3.h" 9 | 10 | class ray 11 | { 12 | public: 13 | ray() {} 14 | ray(const vec3& a, const vec3& b) { A = a; B = b; } 15 | inline vec3 origin() const { return A; } 16 | inline vec3 direction() const { return B; } 17 | // vec3 point_at_parameter(float t) const { return A + t*B; } 18 | inline vec3 point_at_parameter(float t) const { return A + t * B; } 19 | void print() const { 20 | #if 0 21 | union { 22 | float v[3]; 23 | uint32_t i[3]; 24 | } u; 25 | printf("{"); 26 | u.v[0] = A.e[0]; 27 | u.v[1] = A.e[1]; 28 | u.v[2] = A.e[2]; 29 | printf("{%" PRIx64 ", %" PRIx64 ", %" PRIx64 "}", u.i[0], u.i[1], u.i[2]); 30 | printf(", "); 31 | u.v[0] = B.e[0]; 32 | u.v[1] = B.e[1]; 33 | u.v[2] = B.e[2]; 34 | printf("{%" PRIx64 ", %" PRIx64 ", %" PRIx64 "}", u.i[0], u.i[1], u.i[2]); 35 | printf("}"); 36 | #else 37 | printf("{"); 38 | A.print(); 39 | printf(", "); 40 | B.print(); 41 | printf("}"); 42 | #endif 43 | } 44 | 45 | vec3 A; 46 | vec3 B; 47 | }; 48 | 49 | #endif 50 | 51 | -------------------------------------------------------------------------------- /rtiow/CPP/ray5.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ray.h" 3 | 4 | bool hit_sphere(const vec3& center, float radius, const ray& r) { 5 | vec3 oc = r.origin() - center; 6 | float a = dot(r.direction(), r.direction()); 7 | float b = 2.0 * dot(oc, r.direction()); 8 | float c = dot(oc, oc) - radius*radius; 9 | float discriminant = b*b - 4*a*c; 10 | return (discriminant > 0); 11 | } 12 | 13 | vec3 color(const ray& r) { 14 | if (hit_sphere(vec3(0,0,-1), 0.5, r)) 15 | return vec3(1, 0, 0); 16 | vec3 unit_direction = unit_vector(r.direction()); 17 | float t = 0.5*(unit_direction.y() + 1.0); 18 | return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); 19 | } 20 | 21 | int main() { 22 | int nx = 200; 23 | int ny = 100; 24 | std::cout << "P3\n" << nx << " " << ny << "\n255\n"; 25 | vec3 lower_left_corner(-2.0, -1.0, -1.0); 26 | vec3 horizontal(4.0, 0.0, 0.0); 27 | vec3 vertical(0.0, 2.0, 0.0); 28 | vec3 origin(0.0, 0.0, 0.0); 29 | for (int j = ny-1; j >= 0; j--) { 30 | for (int i = 0; i < nx; i++) { 31 | float u = (float)i / (float)nx; 32 | float v = (float)j / (float)ny; 33 | ray r(origin, lower_left_corner + u*horizontal + v*vertical); 34 | vec3 col = color(r); 35 | int ir = (int)(255.99f*col[0]); 36 | int ig = (int)(255.99f*col[1]); 37 | int ib = (int)(255.99f*col[2]); 38 | 39 | std::cout << ir << " " << ig << " " << ib << "\n"; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /rtiow/CPP/ray6.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ray.h" 3 | 4 | float hit_sphere(const vec3& center, float radius, const ray& r) { 5 | vec3 oc = r.origin() - center; 6 | float a = dot(r.direction(), r.direction()); 7 | float b = 2.0 * dot(oc, r.direction()); 8 | float c = dot(oc, oc) - radius*radius; 9 | float discriminant = b*b - 4*a*c; 10 | if (discriminant < 0) { 11 | return -1.0; 12 | } 13 | else { 14 | return (-b - sqrtf(discriminant) ) / (2.0*a); 15 | } 16 | } 17 | 18 | vec3 color(const ray& r) { 19 | float t = hit_sphere(vec3(0,0,-1), 0.5, r); 20 | if (t > 0.0) { 21 | vec3 N = unit_vector(r.point_at_parameter(t) - vec3(0,0,-1)); 22 | return 0.5*vec3(N.x()+1, N.y()+1, N.z()+1); 23 | } 24 | vec3 unit_direction = unit_vector(r.direction()); 25 | t = 0.5*(unit_direction.y() + 1.0); 26 | return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); 27 | } 28 | 29 | int main() { 30 | int nx = 200; 31 | int ny = 100; 32 | std::cout << "P3\n" << nx << " " << ny << "\n255\n"; 33 | vec3 lower_left_corner(-2.0, -1.0, -1.0); 34 | vec3 horizontal(4.0, 0.0, 0.0); 35 | vec3 vertical(0.0, 2.0, 0.0); 36 | vec3 origin(0.0, 0.0, 0.0); 37 | for (int j = ny-1; j >= 0; j--) { 38 | for (int i = 0; i < nx; i++) { 39 | float u = (float)i / (float)nx; 40 | float v = (float)j / (float)ny; 41 | ray r(origin, lower_left_corner + u*horizontal + v*vertical); 42 | vec3 col = color(r); 43 | int ir = (int)(255.99f*col[0]); 44 | int ig = (int)(255.99f*col[1]); 45 | int ib = (int)(255.99f*col[2]); 46 | 47 | std::cout << ir << " " << ig << " " << ib << "\n"; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /rtiow/CPP/sphere.h: -------------------------------------------------------------------------------- 1 | #ifndef SPHEREH 2 | #define SPHEREH 3 | 4 | #include 5 | 6 | #include "hitable.h" 7 | 8 | class sphere: public hitable { 9 | public: 10 | sphere() {} 11 | sphere(vec3 cen, float r, material *m = 0) 12 | : center(cen), radius(r), mat_ptr(m) {}; 13 | virtual bool hit(const ray& r, float tmin, float tmax, hit_record& rec) const; 14 | virtual void print() const; 15 | vec3 center; 16 | float radius; 17 | material *mat_ptr; /* NEW */ 18 | }; 19 | 20 | void sphere::print() const { 21 | printf("{S:");center.print();printf(" ,%.6f}", radius); 22 | } 23 | 24 | bool sphere::hit(const ray& r, float t_min, float t_max, hit_record& rec) const { 25 | vec3 oc = r.origin() - center; 26 | float a = dot(r.direction(), r.direction()); 27 | float b = dot(oc, r.direction()); 28 | float c = dot(oc, oc) - radius*radius; 29 | float discriminant = b*b - a*c; 30 | if (discriminant > 0) { 31 | float temp = (-b - sqrtf(discriminant))/a; 32 | if (temp < t_max && temp > t_min) { 33 | rec.t = temp; 34 | rec.p = r.point_at_parameter(rec.t); 35 | rec.normal = (rec.p - center) / radius; 36 | rec.mat_ptr = mat_ptr; /* NEW */ 37 | return true; 38 | } 39 | temp = (-b + sqrtf(discriminant)) / a; 40 | if (temp < t_max && temp > t_min) { 41 | rec.t = temp; 42 | rec.p = r.point_at_parameter(rec.t); 43 | rec.normal = (rec.p - center) / radius; 44 | rec.mat_ptr = mat_ptr; /* NEW */ 45 | return true; 46 | } 47 | } 48 | return false; 49 | } 50 | 51 | #endif 52 | 53 | -------------------------------------------------------------------------------- /rtiow/CPP/vec3.cpp: -------------------------------------------------------------------------------- 1 | 2 | inline std::istream& operator>>(std::istream &is, vec3 &t) { 3 | is >> t.e[0] >> t.e[1] >> t.e[2]; 4 | return is; 5 | } 6 | 7 | inline std::ostream& operator<<(std::ostream &os, const vec3 &t) { 8 | os << t.e[0] << " " << t.e[1] << " " << t.e[2]; 9 | return os; 10 | } 11 | 12 | inline void vec3::make_unit_vector() { 13 | float k = 1.0 / sqrtf(e[0]*e[0] + e[1]*e[1] + e[2]*e[2]); 14 | e[0] *= k; e[1] *= k; e[2] *= k; 15 | } 16 | 17 | inline vec3 operator+(const vec3 &v1, const vec3 &v2) { 18 | return vec3(v1.e[0] + v2.e[0], v1.e[1] + v2.e[1], v1.e[2] + v2.e[2]); 19 | } 20 | 21 | inline vec3 operator-(const vec3 &v1, const vec3 &v2) { 22 | return vec3(v1.e[0] - v2.e[0], v1.e[1] - v2.e[1], v1.e[2] - v2.e[2]); 23 | } 24 | 25 | inline vec3 operator*(const vec3 &v1, const vec3 &v2) { 26 | return vec3(v1.e[0] * v2.e[0], v1.e[1] * v2.e[1], v1.e[2] * v2.e[2]); 27 | } 28 | 29 | inline vec3 operator/(const vec3 &v1, const vec3 &v2) { 30 | return vec3(v1.e[0] / v2.e[0], v1.e[1] / v2.e[1], v1.e[2] / v2.e[2]); 31 | } 32 | 33 | inline vec3 operator*(float t, const vec3 &v) { 34 | return vec3(t*v.e[0], t*v.e[1], t*v.e[2]); 35 | } 36 | 37 | inline vec3 operator/(vec3 v, float t) { 38 | return vec3(v.e[0]/t, v.e[1]/t, v.e[2]/t); 39 | } 40 | 41 | inline vec3 operator*(const vec3 &v, float t) { 42 | return vec3(t*v.e[0], t*v.e[1], t*v.e[2]); 43 | } 44 | 45 | inline float dot(const vec3 &v1, const vec3 &v2) { 46 | return v1.e[0] *v2.e[0] + v1.e[1] *v2.e[1] + v1.e[2] *v2.e[2]; 47 | } 48 | 49 | inline vec3 cross(const vec3 &v1, const vec3 &v2) { 50 | return vec3(v1.e[1] * v2.e[2] - v1.e[2] * v2.e[1], 51 | v1.e[2] * v2.e[0] - v1.e[0] * v2.e[2], 52 | v1.e[0] * v2.e[1] - v1.e[1] * v2.e[0]); 53 | } 54 | 55 | inline vec3& vec3::operator+=(const vec3 &v){ 56 | e[0] += v.e[0]; 57 | e[1] += v.e[1]; 58 | e[2] += v.e[2]; 59 | return *this; 60 | } 61 | 62 | inline vec3& vec3::operator*=(const vec3 &v){ 63 | e[0] *= v.e[0]; 64 | e[1] *= v.e[1]; 65 | e[2] *= v.e[2]; 66 | return *this; 67 | } 68 | 69 | inline vec3& vec3::operator/=(const vec3 &v){ 70 | e[0] /= v.e[0]; 71 | e[1] /= v.e[1]; 72 | e[2] /= v.e[2]; 73 | return *this; 74 | } 75 | 76 | inline vec3& vec3::operator-=(const vec3& v) { 77 | e[0] -= v.e[0]; 78 | e[1] -= v.e[1]; 79 | e[2] -= v.e[2]; 80 | return *this; 81 | } 82 | 83 | inline vec3& vec3::operator*=(const float t) { 84 | e[0] *= t; 85 | e[1] *= t; 86 | e[2] *= t; 87 | return *this; 88 | } 89 | 90 | inline vec3& vec3::operator/=(const float t) { 91 | #if 0 92 | float k = 1.0/t; 93 | 94 | e[0] *= k; 95 | e[1] *= k; 96 | e[2] *= k; 97 | #else 98 | e[0] /= t; 99 | e[1] /= t; 100 | e[2] /= t; 101 | #endif 102 | return *this; 103 | } 104 | 105 | inline vec3 unit_vector(vec3 v) { 106 | return v / v.length(); 107 | } 108 | -------------------------------------------------------------------------------- /rtiow/Forth/Makefile: -------------------------------------------------------------------------------- 1 | SRC:=$(wildcard main*.fs) 2 | # EXE:=$(patsubst %.fs,%.elf,$(SRC)) 3 | PPM:=$(patsubst %.fs,%.ppm,$(SRC)) 4 | 5 | F:=gforth 6 | 7 | all: $(PPM) 8 | du -sh . 9 | 10 | check: $(PPM) 11 | md5sum *.ppm 12 | md5sum *.ppm | md5sum 13 | 14 | bench: 15 | time $(F) ./main14.fs 1024 768 10 main14.ppm && md5sum main14.ppm 16 | 17 | VFLAGS+=--enable-globals 18 | #DEBUG:=1 19 | ifdef DEBUG 20 | VFLAGS+=-d dbg 21 | #VFLAGS+=-profile profile.txt 22 | else 23 | # OPT:=-O3 24 | # OPT:=-Ofast -fno-plt -flto -DNDEBUG 25 | OPT:=-O3 -fno-plt -flto -DNDEBUG 26 | endif 27 | 28 | #PROF:=1 29 | ifdef PROF 30 | OPT+=-pg 31 | endif 32 | 33 | # %.elf: %_v.c 34 | # $(CC) -o $@ $^ $(OPT) -lm 35 | 36 | %.ppm: %.fs 37 | $(F) ./$^ > $@ 38 | 39 | clean: 40 | $(RM) *.elf *.ppm 41 | -------------------------------------------------------------------------------- /rtiow/Forth/main02.fs: -------------------------------------------------------------------------------- 1 | : r/ ( n n -- r ) swap s>f s>f f/ ; 2 | : .notrail s>d 0 d.r ; 3 | variable nx 200 nx ! 4 | variable ny 100 ny ! 5 | : main 6 | ." P3" cr 7 | nx ? ny @ .notrail cr 8 | 255 .notrail cr 9 | 0 ny @ 1 - do 10 | nx @ 0 do 11 | ( b) 0.2e 12 | ( g) j ny @ r/ 13 | ( r) i nx @ r/ 14 | ( ir) 255.99e f* f>s . 15 | ( ig) 255.99e f* f>s . 16 | ( ib) 255.99e f* f>s .notrail 17 | cr 18 | loop 19 | -1 +loop 20 | ; main bye 21 | -------------------------------------------------------------------------------- /rtiow/Go/Makefile: -------------------------------------------------------------------------------- 1 | SRC:=$(wildcard main*.go) 2 | EXE:=$(patsubst %.go,%.elf,$(SRC)) 3 | PPM:=$(patsubst %.go,%.ppm,$(SRC)) 4 | 5 | GO=go 6 | 7 | all: $(EXE) 8 | du -sh . 9 | 10 | check: $(PPM) 11 | md5sum *.ppm 12 | md5sum *.ppm | md5sum 13 | 14 | bench: main14.elf 15 | time ./main14.elf 1024 768 10 main14.ppm && md5sum main14.ppm 16 | 17 | #OPT:=--ldflags '-extldflags "-lm"' 18 | #DEBUG:=1 19 | ifdef DEBUG 20 | OPT+=-DDEBUG 21 | endif 22 | 23 | #PROF:=1 24 | ifdef PROF 25 | OPT+=-pg 26 | endif 27 | 28 | %.elf: %.go src/pcg/pcg.go 29 | $(GO) build $(OPT) -o $@ $< 30 | 31 | %.ppm: %.elf 32 | ./$^ $(ARGS) > $@ 33 | 34 | clean: 35 | $(RM) *.elf *.ppm 36 | -------------------------------------------------------------------------------- /rtiow/Go/main02.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ("fmt") 4 | 5 | func main() { 6 | var nx = 200 7 | var ny = 100 8 | fmt.Printf("P3\n") 9 | fmt.Printf("%d %d\n", nx, ny) 10 | fmt.Printf("%d\n", 255) 11 | for j := ny-1; j >= 0; j-- { 12 | for i := 0; i < nx; i++ { 13 | r := float32(i) / float32(nx) 14 | g := float32(j) / float32(ny) 15 | b := float32(0.2) 16 | ir := int(255.99 * r) 17 | ig := int(255.99 * g) 18 | ib := int(255.99 * b) 19 | fmt.Printf("%d %d %d\n", ir, ig, ib) 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /rtiow/Go/main03.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ("fmt") 4 | 5 | type Vec3 [3]float32 6 | 7 | func main() { 8 | var nx = 200 9 | var ny = 100 10 | fmt.Printf("P3\n") 11 | fmt.Printf("%d %d\n", nx, ny) 12 | fmt.Printf("%d\n", 255) 13 | for j := ny-1; j >= 0; j-- { 14 | for i := 0; i < nx; i++ { 15 | col := Vec3{float32(i) / float32(nx), float32(j) / float32(ny), float32(0.2)} 16 | ir := int(255.99 * col[0]) 17 | ig := int(255.99 * col[1]) 18 | ib := int(255.99 * col[2]) 19 | fmt.Printf("%d %d %d\n", ir, ig, ib) 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /rtiow/Go/main04.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ("fmt"; "math"; "C") 4 | 5 | type Vec3 [3]float32 6 | 7 | type Ray struct { 8 | origin Vec3 9 | direction Vec3 10 | } 11 | 12 | func vmul(f float32, v Vec3) Vec3 { 13 | return Vec3{f * v[0], f * v[1], f * v[2]} 14 | } 15 | 16 | func vdiv(v Vec3, f float32) Vec3 { 17 | return Vec3{v[0] / f, v[1] / f, v[2] / f} 18 | } 19 | 20 | func vadd(v1 Vec3, v2 Vec3) Vec3 { 21 | return Vec3{v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]} 22 | } 23 | 24 | // #include 25 | func Sqrtf(x float32) float32 { 26 | return float32(math.Sqrt(float64(x))) 27 | } 28 | func (v Vec3) len() float32 { 29 | // return math.Sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]) 30 | return Sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]) 31 | // return C.sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]) 32 | } 33 | 34 | func (v Vec3) unit_vector() Vec3 { 35 | return vdiv(v, v.len()) 36 | } 37 | 38 | func (r Ray) point_at_parameter(t float32) Vec3 { 39 | return vadd(r.origin, vmul(t, r.direction)) 40 | } 41 | 42 | func color(r Ray) Vec3 { 43 | unit_direction := r.direction.unit_vector() 44 | t := 0.5 * (unit_direction[1] + 1.0) 45 | return vadd(vmul(1.0 - t, Vec3{1.0, 1.0, 1.0}), vmul(t, Vec3{0.5, 0.7, 1.0})) 46 | } 47 | 48 | func main() { 49 | nx := 200 50 | ny := 100 51 | fmt.Printf("P3\n") 52 | fmt.Printf("%d %d\n", nx, ny) 53 | fmt.Printf("%d\n", 255) 54 | lower_left_corner := Vec3{-2.0, -1.0, -1.0} 55 | horizontal := Vec3{4.0, 0.0, 0.0} 56 | vertical := Vec3{0.0, 2.0, 0.0} 57 | origin := Vec3{0.0, 0.0, 0.0} 58 | for j := ny-1; j >= 0; j-- { 59 | for i := 0; i < nx; i++ { 60 | u := float32(i) / float32(nx) 61 | v := float32(j) / float32(ny) 62 | // fmt.Println(Vec3{u, v, 0}) 63 | r := Ray{origin, vadd(lower_left_corner, vadd(vmul(u, horizontal), vmul(v, vertical)))} 64 | col := color(r) 65 | ir := int(255.99 * col[0]) 66 | ig := int(255.99 * col[1]) 67 | ib := int(255.99 * col[2]) 68 | fmt.Printf("%d %d %d\n", ir, ig, ib) 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /rtiow/Go/main05.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ("fmt"; "math"; "C") 4 | 5 | type Vec3 [3]float32 6 | 7 | type Ray struct { 8 | origin Vec3 9 | direction Vec3 10 | } 11 | 12 | func vmul(f float32, v Vec3) Vec3 { 13 | return Vec3{f * v[0], f * v[1], f * v[2]} 14 | } 15 | 16 | func vdiv(v Vec3, f float32) Vec3 { 17 | return Vec3{v[0] / f, v[1] / f, v[2] / f} 18 | } 19 | 20 | func vadd(v1 Vec3, v2 Vec3) Vec3 { 21 | return Vec3{v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]} 22 | } 23 | 24 | func vsub(v1 Vec3, v2 Vec3) Vec3 { 25 | return Vec3{v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2]} 26 | } 27 | 28 | func vdot(v1 Vec3, v2 Vec3) float32 { 29 | return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2] 30 | } 31 | 32 | // #include 33 | func Sqrtf(x float32) float32 { 34 | return float32(math.Sqrt(float64(x))) 35 | } 36 | func (v Vec3) len() float32 { 37 | // return math.Sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]) 38 | return Sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]) 39 | // return C.sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]) 40 | } 41 | 42 | func (v Vec3) unit_vector() Vec3 { 43 | return vdiv(v, v.len()) 44 | } 45 | 46 | func (r Ray) point_at_parameter(t float32) Vec3 { 47 | return vadd(r.origin, vmul(t, r.direction)) 48 | } 49 | 50 | func hit_sphere(center Vec3, radius float32, r Ray) bool { 51 | oc := vsub(r.origin, center) 52 | // fmt.Println("oc=", oc) 53 | a := vdot(r.direction, r.direction) 54 | b := 2.0 * vdot(oc, r.direction) 55 | c := vdot(oc, oc) - radius * radius 56 | // fmt.Println("abc=", Vec3{a, b, c}) 57 | discriminant := b * b - 4 * a * c 58 | return discriminant > 0 59 | } 60 | 61 | func color(r Ray) Vec3 { 62 | if hit_sphere(Vec3{0, 0, -1}, 0.5, r) { 63 | return Vec3{1, 0, 0} 64 | } 65 | unit_direction := r.direction.unit_vector() 66 | t := 0.5 * (unit_direction[1] + 1.0) 67 | return vadd(vmul(1.0 - t, Vec3{1.0, 1.0, 1.0}), vmul(t, Vec3{0.5, 0.7, 1.0})) 68 | } 69 | 70 | func main() { 71 | nx := 200 72 | ny := 100 73 | fmt.Printf("P3\n") 74 | fmt.Printf("%d %d\n", nx, ny) 75 | fmt.Printf("%d\n", 255) 76 | lower_left_corner := Vec3{-2.0, -1.0, -1.0} 77 | horizontal := Vec3{4.0, 0.0, 0.0} 78 | vertical := Vec3{0.0, 2.0, 0.0} 79 | origin := Vec3{0.0, 0.0, 0.0} 80 | for j := ny-1; j >= 0; j-- { 81 | for i := 0; i < nx; i++ { 82 | u := float32(i) / float32(nx) 83 | v := float32(j) / float32(ny) 84 | r := Ray{origin, vadd(lower_left_corner, vadd(vmul(u, horizontal), vmul(v, vertical)))} 85 | col := color(r) 86 | ir := int(255.99 * col[0]) 87 | ig := int(255.99 * col[1]) 88 | ib := int(255.99 * col[2]) 89 | fmt.Printf("%d %d %d\n", ir, ig, ib) 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /rtiow/Go/main06_1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ("fmt"; "math"; "C") 4 | 5 | type Vec3 [3]float32 6 | 7 | type Ray struct { 8 | origin Vec3 9 | direction Vec3 10 | } 11 | 12 | func vmul(f float32, v Vec3) Vec3 { 13 | return Vec3{f * v[0], f * v[1], f * v[2]} 14 | } 15 | 16 | func vdiv(v Vec3, f float32) Vec3 { 17 | return Vec3{v[0] / f, v[1] / f, v[2] / f} 18 | } 19 | 20 | func vadd(v1 Vec3, v2 Vec3) Vec3 { 21 | return Vec3{v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]} 22 | } 23 | 24 | func vsub(v1 Vec3, v2 Vec3) Vec3 { 25 | return Vec3{v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2]} 26 | } 27 | 28 | func vdot(v1 Vec3, v2 Vec3) float32 { 29 | return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2] 30 | } 31 | 32 | // #include 33 | func Sqrtf(x float32) float32 { 34 | return float32(math.Sqrt(float64(x))) 35 | } 36 | func (v Vec3) len() float32 { 37 | // return math.Sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]) 38 | return Sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]) 39 | // return C.sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]) 40 | } 41 | 42 | func (v Vec3) unit_vector() Vec3 { 43 | return vdiv(v, v.len()) 44 | } 45 | 46 | func (r Ray) point_at_parameter(t float32) Vec3 { 47 | return vadd(r.origin, vmul(t, r.direction)) 48 | } 49 | 50 | func hit_sphere(center Vec3, radius float32, r Ray) float32 { 51 | oc := vsub(r.origin, center) 52 | a := vdot(r.direction, r.direction) 53 | b := 2.0 * vdot(oc, r.direction) 54 | c := vdot(oc, oc) - radius * radius 55 | discriminant := b * b - 4 * a * c 56 | if discriminant < 0 { 57 | return -1.0 58 | } else { 59 | return (-b - Sqrtf(discriminant)) / (2.0 * a) 60 | } 61 | } 62 | 63 | func color(r Ray) Vec3 { 64 | t := hit_sphere(Vec3{0, 0, -1}, 0.5, r) 65 | if t > 0.0 { 66 | N := vsub(r.point_at_parameter(t), Vec3{0, 0, -1}).unit_vector() 67 | return vmul(0.5, Vec3{N[0] + 1, N[1] + 1, N[2] + 1}) 68 | } 69 | unit_direction := r.direction.unit_vector() 70 | t = 0.5 * (unit_direction[1] + 1.0) 71 | return vadd(vmul(1.0 - t, Vec3{1.0, 1.0, 1.0}), vmul(t, Vec3{0.5, 0.7, 1.0})) 72 | } 73 | 74 | func main() { 75 | nx := 200 76 | ny := 100 77 | fmt.Printf("P3\n") 78 | fmt.Printf("%d %d\n", nx, ny) 79 | fmt.Printf("%d\n", 255) 80 | lower_left_corner := Vec3{-2.0, -1.0, -1.0} 81 | horizontal := Vec3{4.0, 0.0, 0.0} 82 | vertical := Vec3{0.0, 2.0, 0.0} 83 | origin := Vec3{0.0, 0.0, 0.0} 84 | for j := ny-1; j >= 0; j-- { 85 | for i := 0; i < nx; i++ { 86 | u := float32(i) / float32(nx) 87 | v := float32(j) / float32(ny) 88 | r := Ray{origin, vadd(lower_left_corner, vadd(vmul(u, horizontal), vmul(v, vertical)))} 89 | col := color(r) 90 | ir := int(255.99 * col[0]) 91 | ig := int(255.99 * col[1]) 92 | ib := int(255.99 * col[2]) 93 | fmt.Printf("%d %d %d\n", ir, ig, ib) 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /rtiow/Go/src/pcg/pcg.go: -------------------------------------------------------------------------------- 1 | package pcg 2 | 3 | /********************************************** 4 | PCG random implementation - credits to Cieric for original Odin/C version 5 | */ 6 | const RAND_MAX = uint64(4294967295) 7 | 8 | type pcg32_random_t struct { 9 | state, inc uint64 10 | } 11 | 12 | var seed = pcg32_random_t {0, 0} 13 | 14 | func Srand(val uint32) { 15 | seed.state = uint64(val) 16 | seed.inc = 0 17 | } 18 | 19 | func Rand() uint32 { 20 | oldstate := seed.state 21 | seed.state = oldstate * uint64(6364136223846793005) + (seed.inc | 1) 22 | xorshifted := uint32(((oldstate >> 18) ^ oldstate) >> 27) 23 | rot := uint32(oldstate >> 59) 24 | return (xorshifted >> rot) | (xorshifted << ((-rot) & 31)) 25 | } 26 | /* 27 | **********************************************/ 28 | -------------------------------------------------------------------------------- /rtiow/JS/README.md: -------------------------------------------------------------------------------- 1 | # Javascript RTIOW 2 | 3 | Click [here](https://nsauzede.github.io/realist/) to see it in action 4 | -------------------------------------------------------------------------------- /rtiow/JS/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | RTIOW 6 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 46 | 49 | 50 | 51 | 52 | 53 |
CanvasZoomedHovered colorSelected color
44 | Canvas not supported! 45 | 47 | Canvas not supported! 48 |
54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 |
SPPDepth
72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /rtiow/JS/main02_2.js: -------------------------------------------------------------------------------- 1 | function main02_2() { 2 | const func = arguments.callee.name || "anonymous"; 3 | cls(); 4 | println(`${func}`); 5 | var canvas = document.getElementById('canvas'); 6 | const w = canvas.width; 7 | const h = canvas.height; 8 | if (canvas.getContext) { 9 | var ctx = canvas.getContext('2d', { alpha: false }); 10 | image = ctx.getImageData(0, 0, w, h); 11 | for (let j = 0; j < (h - 1); j++) { 12 | for (let i = 0; i < (w - 1); i++) { 13 | const r = parseFloat(i) / (w - 1); 14 | const g = parseFloat(h - 1 - j) / (h - 1); 15 | const b = 0.25; 16 | image.data[(j * w + i) * 4 + 0] = 255.999 * r; 17 | image.data[(j * w + i) * 4 + 1] = 255.999 * g; 18 | image.data[(j * w + i) * 4 + 2] = 255.999 * b; 19 | } 20 | } 21 | ctx.putImageData(image, 0, 0); 22 | println(`Done. ${func}`); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /rtiow/JS/main02_3.js: -------------------------------------------------------------------------------- 1 | function main02_3() { 2 | const func = arguments.callee.name || "anonymous"; 3 | cls(); 4 | println(`${func}`); 5 | var canvas = document.getElementById('canvas'); 6 | const w = canvas.width; 7 | const h = canvas.height; 8 | if (canvas.getContext) { 9 | var ctx = canvas.getContext('2d', { alpha: false }); 10 | image = ctx.getImageData(0, 0, w, h); 11 | for (let j = 0; j < h; j++) { 12 | println(`Scanlines remaining: ${h - j - 1}`); 13 | for (let i = 0; i < w; i++) { 14 | const r = parseFloat(i) / (w - 1); 15 | const g = parseFloat(h - 1 - j) / (h - 1); 16 | const b = 0.25; 17 | image.data[(j * w + i) * 4 + 0] = 255.999 * r; 18 | image.data[(j * w + i) * 4 + 1] = 255.999 * g; 19 | image.data[(j * w + i) * 4 + 2] = 255.999 * b; 20 | } 21 | } 22 | ctx.putImageData(image, 0, 0); 23 | println(`Done. ${func}`); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /rtiow/JS/main03_3.js: -------------------------------------------------------------------------------- 1 | function main03_3() { 2 | const func = arguments.callee.name || "anonymous"; 3 | cls(); 4 | println(`${func}`); 5 | var canvas = document.getElementById('canvas'); 6 | const w = canvas.width; 7 | const h = canvas.height; 8 | if (canvas.getContext) { 9 | var ctx = canvas.getContext('2d', { alpha: false }); 10 | image = ctx.getImageData(0, 0, w, h); 11 | for (let j = 0; j < h; j++) { 12 | println(`Scanlines remaining: ${h - j - 1}`); 13 | for (let i = 0; i < w; i++) { 14 | const pixel_color = new Float32Array([parseFloat(i) / (w - 1), parseFloat(h - 1 - j) / (h - 1), 0.25]); 15 | image.data[(j * w + i) * 4 + 0] = 255.999 * pixel_color[0]; 16 | image.data[(j * w + i) * 4 + 1] = 255.999 * pixel_color[1]; 17 | image.data[(j * w + i) * 4 + 2] = 255.999 * pixel_color[2]; 18 | } 19 | } 20 | ctx.putImageData(image, 0, 0); 21 | println(`Done. ${func}`); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /rtiow/JS/main04_2.js: -------------------------------------------------------------------------------- 1 | function main04_2() { 2 | function ray_color(r) { 3 | const unit_direction = unit_vector(r.dir); 4 | const t = 0.5 * (unit_direction[1] + 1.0); 5 | return new Float32Array([1.0 - t + 0.5 * t, 1.0 - t + 0.7 * t, 1.0]); 6 | } 7 | const func = arguments.callee.name || "anonymous"; 8 | cls(); 9 | println(`${func}`); 10 | var canvas = document.getElementById('canvas'); 11 | const w = canvas.width; 12 | const h = canvas.height; 13 | if (canvas.getContext) { 14 | var ctx = canvas.getContext('2d', { alpha: false }); 15 | image = ctx.getImageData(0, 0, w, h); 16 | const aspect_ratio = 16.0 / 9.0; 17 | const image_width = w; 18 | const image_height = h; 19 | const viewport_height = 2.0; 20 | const viewport_width = aspect_ratio * viewport_height; 21 | const focal_length = 1.0; 22 | const origin = new Float32Array([0, 0, 0]); 23 | const horizontal = new Float32Array([viewport_width, 0, 0]); 24 | const vertical = new Float32Array([0, viewport_height, 0]); 25 | const lower_left_corner = vsub(vsub(vsub(origin, vdiv(horizontal, 2.0)), vdiv(horizontal, 2.0)), new Float32Array([0, 0, focal_length])); 26 | for (let j = 0; j < h; j++) { 27 | println(`Scanlines remaining: ${h - j - 1}`); 28 | for (let i = 0; i < w; i++) { 29 | const u = parseFloat(i) / (w - 1); 30 | const v = parseFloat(h - 1 - j) / (h - 1); 31 | const r = { orig: origin, dir: vsub(vadd(vadd(lower_left_corner, vmul(u, horizontal)), vmul(v, vertical)), origin) }; 32 | const pixel_color = ray_color(r); 33 | image.data[(j * w + i) * 4 + 0] = 255.999 * pixel_color[0]; 34 | image.data[(j * w + i) * 4 + 1] = 255.999 * pixel_color[1]; 35 | image.data[(j * w + i) * 4 + 2] = 255.999 * pixel_color[2]; 36 | } 37 | } 38 | ctx.putImageData(image, 0, 0); 39 | println(`Done. ${func}`); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /rtiow/JS/main05_2.js: -------------------------------------------------------------------------------- 1 | function hit_sphere(center, radius, r) { 2 | const oc = vsub(r.orig, center); 3 | const a = dot(r.dir, r.dir); 4 | const b = 2.0 * dot(oc, r.dir); 5 | const c = dot(oc, oc) - radius * radius; 6 | const discriminant = b * b - 4 * a * c; 7 | return discriminant > 0.0; 8 | } 9 | function main05_2() { 10 | function ray_color(r) { 11 | if (hit_sphere(new Float32Array([0, 0, -1]), 0.5, r)) { 12 | return new Float32Array([1, 0, 0]); 13 | } 14 | const unit_direction = unit_vector(r.dir); 15 | const t = 0.5 * (unit_direction[1] + 1.0); 16 | return new Float32Array([1.0 - t + 0.5 * t, 1.0 - t + 0.7 * t, 1.0]); 17 | } 18 | const func = arguments.callee.name || "anonymous"; 19 | cls(); 20 | println(`${func}`); 21 | var canvas = document.getElementById('canvas'); 22 | const w = canvas.width; 23 | const h = canvas.height; 24 | if (canvas.getContext) { 25 | var ctx = canvas.getContext('2d', { alpha: false }); 26 | image = ctx.getImageData(0, 0, w, h); 27 | const aspect_ratio = 16.0 / 9.0; 28 | const image_width = w; 29 | const image_height = h; 30 | const viewport_height = 2.0; 31 | const viewport_width = aspect_ratio * viewport_height; 32 | const focal_length = 1.0; 33 | const origin = new Float32Array([0, 0, 0]); 34 | const horizontal = new Float32Array([viewport_width, 0, 0]); 35 | const vertical = new Float32Array([0, viewport_height, 0]); 36 | const lower_left_corner = vsub(vsub(vsub(origin, vdiv(horizontal, 2.0)), vdiv(vertical, 2.0)), new Float32Array([0, 0, focal_length])); 37 | for (let j = 0; j < h; j++) { 38 | println(`Scanlines remaining: ${h - j - 1}`); 39 | for (let i = 0; i < w; i++) { 40 | const u = parseFloat(i) / (w - 1); 41 | const v = parseFloat(h - 1 - j) / (h - 1); 42 | const r = { orig: origin, dir: vsub(vadd(vadd(lower_left_corner, vmul(u, horizontal)), vmul(v, vertical)), origin) }; 43 | const pixel_color = ray_color(r); 44 | image.data[(j * w + i) * 4 + 0] = 255.999 * pixel_color[0]; 45 | image.data[(j * w + i) * 4 + 1] = 255.999 * pixel_color[1]; 46 | image.data[(j * w + i) * 4 + 2] = 255.999 * pixel_color[2]; 47 | } 48 | } 49 | ctx.putImageData(image, 0, 0); 50 | println(`Done. ${func}`); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /rtiow/JS/main06_1.js: -------------------------------------------------------------------------------- 1 | function main06_1() { 2 | function hit_sphere(center, radius, r) { 3 | const oc = vsub(r.orig, center); 4 | const a = dot(r.dir, r.dir); 5 | const b = 2.0 * dot(oc, r.dir); 6 | const c = dot(oc, oc) - radius * radius; 7 | const discriminant = b * b - 4 * a * c; 8 | if (discriminant < 0) { 9 | return -1.0; 10 | } else { 11 | return (-b - Math.sqrt(discriminant)) / (2.0 * a); 12 | } 13 | } 14 | function ray_color(r) { 15 | var t = hit_sphere(new Float32Array([0, 0, -1]), 0.5, r); 16 | if (t > 0.0) { 17 | const N = unit_vector(vsub(rat(r, t), new Float32Array([0, 0, -1]))); 18 | return vmul(0.5, vadd(N, new Float32Array([1, 1, 1]))); 19 | } 20 | const unit_direction = unit_vector(r.dir); 21 | t = 0.5 * (unit_direction[1] + 1.0); 22 | return new Float32Array([1.0 - t + 0.5 * t, 1.0 - t + 0.7 * t, 1.0]); 23 | } 24 | const func = arguments.callee.name || "anonymous"; 25 | cls(); 26 | println(`${func}`); 27 | var canvas = document.getElementById('canvas'); 28 | const w = canvas.width; 29 | const h = canvas.height; 30 | if (canvas.getContext) { 31 | var ctx = canvas.getContext('2d', { alpha: false }); 32 | image = ctx.getImageData(0, 0, w, h); 33 | const aspect_ratio = 16.0 / 9.0; 34 | const image_width = w; 35 | const image_height = h; 36 | const viewport_height = 2.0; 37 | const viewport_width = aspect_ratio * viewport_height; 38 | const focal_length = 1.0; 39 | const origin = new Float32Array([0, 0, 0]); 40 | const horizontal = new Float32Array([viewport_width, 0, 0]); 41 | const vertical = new Float32Array([0, viewport_height, 0]); 42 | const lower_left_corner = vsub(vsub(vsub(origin, vdiv(horizontal, 2.0)), vdiv(vertical, 2.0)), new Float32Array([0, 0, focal_length])); 43 | for (let j = 0; j < h; j++) { 44 | println(`Scanlines remaining: ${h - j - 1}`); 45 | for (let i = 0; i < w; i++) { 46 | const u = parseFloat(i) / (w - 1); 47 | const v = parseFloat(h - 1 - j) / (h - 1); 48 | const r = { orig: origin, dir: vsub(vadd(vadd(lower_left_corner, vmul(u, horizontal)), vmul(v, vertical)), origin) }; 49 | const pixel_color = ray_color(r); 50 | image.data[(j * w + i) * 4 + 0] = 255.999 * pixel_color[0]; 51 | image.data[(j * w + i) * 4 + 1] = 255.999 * pixel_color[1]; 52 | image.data[(j * w + i) * 4 + 2] = 255.999 * pixel_color[2]; 53 | } 54 | } 55 | ctx.putImageData(image, 0, 0); 56 | println(`Done. ${func}`); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /rtiow/JS/main06_7.js: -------------------------------------------------------------------------------- 1 | function main06_7() { 2 | function hit_sphere(d, r, tmin, tmax, rec) { 3 | const center = d[0], radius = d[1]; 4 | const oc = vsub(r.orig, center); 5 | const a = dot(r.dir, r.dir); 6 | const hb = dot(oc, r.dir); 7 | const c = dot(oc, oc) - radius * radius; 8 | const discriminant = hb * hb - a * c; 9 | if (discriminant < 0) return false; 10 | const sqrtd = Math.sqrt(discriminant); 11 | var root = (-hb - sqrtd) / a; 12 | if (root < tmin || root > tmax) { 13 | root = (-hb + sqrtd) / a; 14 | if (root < tmin || root > tmax) { 15 | return false; 16 | } 17 | } 18 | rec.t = root; 19 | rec.p = rat(r, rec.t); 20 | rec.normal = vdiv(vsub(rec.p, center), radius); 21 | return true; 22 | } 23 | function ray_color(r, world) { 24 | var ret = 0; 25 | for (const h of world) { 26 | if (h.t === 'sphere') { 27 | // println(`hitting sphere ${h}`) 28 | var temp_rec = {}; 29 | if (hit_sphere(h.d, r, 0, infinity, temp_rec)) { 30 | return vmul(0.5, vadd(temp_rec.normal, new Float32Array([1, 1, 1]))); 31 | } 32 | } 33 | } 34 | 35 | const unit_direction = unit_vector(r.dir); 36 | t = 0.5 * (unit_direction[1] + 1.0); 37 | return new Float32Array([1.0 - t + 0.5 * t, 1.0 - t + 0.7 * t, 1.0]); 38 | } 39 | const func = arguments.callee.name || "anonymous"; 40 | cls(); 41 | println(`${func}`); 42 | var canvas = document.getElementById('canvas'); 43 | const w = canvas.width; 44 | const h = canvas.height; 45 | if (canvas.getContext) { 46 | var ctx = canvas.getContext('2d', { alpha: false }); 47 | image = ctx.getImageData(0, 0, w, h); 48 | // image 49 | const aspect_ratio = 16.0 / 9.0; 50 | const image_width = w; 51 | const image_height = h; 52 | // world 53 | const world = [{ t: 'sphere', d: [[0, 0, -1], 0.5] }, { t: 'sphere', d: [[0, -100.5, -1], 100] }]; 54 | // camera 55 | const viewport_height = 2.0; 56 | const viewport_width = aspect_ratio * viewport_height; 57 | const focal_length = 1.0; 58 | const origin = new Float32Array([0, 0, 0]); 59 | const horizontal = new Float32Array([viewport_width, 0, 0]); 60 | const vertical = new Float32Array([0, viewport_height, 0]); 61 | const lower_left_corner = vsub(vsub(vsub(origin, vdiv(horizontal, 2.0)), vdiv(vertical, 2.0)), new Float32Array([0, 0, focal_length])); 62 | for (let j = 0; j < h; j++) { 63 | println(`Scanlines remaining: ${h - j - 1}`); 64 | for (let i = 0; i < w; i++) { 65 | const u = parseFloat(i) / (w - 1); 66 | const v = parseFloat(h - 1 - j) / (h - 1); 67 | const r = { orig: origin, dir: vsub(vadd(vadd(lower_left_corner, vmul(u, horizontal)), vmul(v, vertical)), origin) }; 68 | const pixel_color = ray_color(r, world); 69 | image.data[(j * w + i) * 4 + 0] = 255.999 * pixel_color[0]; 70 | image.data[(j * w + i) * 4 + 1] = 255.999 * pixel_color[1]; 71 | image.data[(j * w + i) * 4 + 2] = 255.999 * pixel_color[2]; 72 | } 73 | } 74 | ctx.putImageData(image, 0, 0); 75 | println(`Done. ${func}`); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /rtiow/JS/random.js: -------------------------------------------------------------------------------- 1 | function random_double(min = 0.0, max = 1.0) { 2 | return min + (max - min) * Math.random(); 3 | } 4 | function clamp(x, min, max) { 5 | if (x < min) return min; 6 | if (x > max) return max; 7 | return x; 8 | } 9 | function random(min = 0, max) { 10 | return new Float32Array([random_double(min, max), random_double(min, max), random_double(min, max)]); 11 | } 12 | function random_in_unit_sphere() { 13 | while (true) { 14 | const p = random(-1, 1); 15 | if (vlensq(p) >= 1) continue; 16 | return p; 17 | } 18 | } -------------------------------------------------------------------------------- /rtiow/JS/ray.js: -------------------------------------------------------------------------------- 1 | function rat(r, t) { 2 | return vadd(r.orig, vmul(t, r.dir)); 3 | } 4 | -------------------------------------------------------------------------------- /rtiow/JS/vec3.js: -------------------------------------------------------------------------------- 1 | function vsub(v1, v2) { 2 | return new Float32Array([v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2]]); 3 | } 4 | function vadd(v1, v2) { 5 | return new Float32Array([v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]]); 6 | } 7 | function vdiv(v, f) { 8 | return new Float32Array([v[0] / f, v[1] / f, v[2] / f]); 9 | } 10 | function vmul(f, v) { 11 | return new Float32Array([f * v[0], f * v[1], f * v[2]]); 12 | } 13 | function dot(v1, v2) { 14 | return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; 15 | } 16 | function vlensq(v) { 17 | return dot(v, v); 18 | } 19 | function vlen(v) { 20 | return Math.sqrt(vlensq(v)); 21 | } 22 | function unit_vector(v) { 23 | return vdiv(v, vlen(v)); 24 | } 25 | -------------------------------------------------------------------------------- /rtiow/Makefile: -------------------------------------------------------------------------------- 1 | DIRS:= 2 | DIRS+=Rust 3 | DIRS+=Nelua 4 | #DIRS+=Nim 5 | DIRS+=C 6 | DIRS+=V 7 | DIRS+=CPP 8 | #DIRS+=Odin 9 | #DIRS+=V_old 10 | #DIRS+=Go 11 | TARGETS:=$(patsubst %,%/main14.elf,$(DIRS)) 12 | 13 | all: $(TARGETS) 14 | 15 | %/main14.elf: 16 | (cd $(@D); make clean ; time make main14.elf) 17 | 18 | bench: all 19 | for d in $(DIRS); do make -C $$d bench; done 20 | 21 | #./main14.elf 1024 768 10 main14.ppm 22 | #HYP:=$(patsubst %,'cd %;./main14.elf 1024 768 10 main14.ppm',$(DIRS)) 23 | #HYP:=$(patsubst %,'cd %;./main14.elf 800 600 8 main14.ppm',$(DIRS)) 24 | HYP:=$(patsubst %,'cd %;./main14.elf 640 480 10 main14.ppm',$(DIRS)) 25 | #HYP:='echo 1' 'echo 2' 'echo 3' 26 | bench2: all 27 | echo "HYP=$(HYP)" 28 | # for c in "$(HYP)"; do echo "c=$$c"; done 29 | # hyperfine --warmup 2 $(HYP) 30 | /usr/bin/time hyperfine $(HYP) 31 | 32 | clean: 33 | $(RM) $(TARGETS) 34 | 35 | clobber: clean 36 | $(RM) *_v.c 37 | 38 | mrproper: clobber 39 | $(RM) *.ppm 40 | for d in $(DIRS); do make -C $$d clean; done 41 | make -C Forth clean 42 | make -C C2 clean 43 | make -C V_old clean 44 | make -C Go clean 45 | -------------------------------------------------------------------------------- /rtiow/NOTES.md: -------------------------------------------------------------------------------- 1 | 2 | Conclusion (old) : 3 | ------------------- 4 | - V version is slower than C++ (+89%, x1.85) 5 | - This is both suspect and frustrating 6 | 7 | NOTE: current V (AST) is buggy; only v0.1.25 is know to work. 8 | 9 | ``` 10 | $ /usr/bin/time V/A14 > A14.ppm 11 | 26.43user 0.00system 0:26.46elapsed 99%CPU (0avgtext+0avgdata 3108maxresident)k 12 | 0inputs+488outputs (0major+323minor)pagefaults 0swaps 13 | $ /usr/bin/time CPP/main14 > main14.ppm 14 | 13.98user 0.00system 0:13.99elapsed 99%CPU (0avgtext+0avgdata 3904maxresident)k 15 | 0inputs+528outputs (0major+149minor)pagefaults 0swaps 16 | ``` 17 | 18 | Notes : 19 | 2/output an image 20 | -output text PPM image RGB888 21 | -graphics hello world : R:0=>1 LTR, G:0=>1 BTT; G=>Y, B=>R 22 | 23 | 3/the vec3 class 24 | -vec3 class : color,location,direction,offset,... 25 | -operators : `+,-,[],&[], +=,-=,*=,/=,*=f,/=f` 26 | 27 | TODO : 28 | -understand why V version is slower and fix it 29 | 30 | # rttnw vs. rttroyl 31 | Tests revealed that rttnw (brute force) produce more noisy result 32 | that rttroyl (stochastic) 33 | 34 | rttnw 500 500 1000 => 7min lot of noise 35 | rttroyl 500 500 1000 => 8min less noise 36 | 37 | rttnw 500 500 2000 => 15min still more noise 38 | -------------------------------------------------------------------------------- /rtiow/Nelua/Makefile: -------------------------------------------------------------------------------- 1 | SRC:=$(wildcard main*.nelua) 2 | EXE:=$(patsubst %.nelua,%.elf,$(SRC)) 3 | PPM:=$(patsubst %.nelua,%.ppm,$(SRC)) 4 | 5 | NELUA:=nelua 6 | 7 | all: $(EXE) 8 | du -sh . 9 | 10 | check: $(PPM) 11 | md5sum *.ppm 12 | md5sum *.ppm | md5sum 13 | 14 | bench: main14.elf 15 | time ./main14.elf 1024 768 10 main14.ppm && md5sum main14.ppm 16 | 17 | #DEBUG:=1 18 | NFLAGS+=-q --no-cache --cache-dir . -c 19 | ifdef DEBUG 20 | OPT:=-O0 -g 21 | #NFLAGS+= 22 | else 23 | # OPT:=-O3 24 | # OPT:=-Ofast -fno-plt -flto -march=native -DNDEBUG 25 | OPT:=-O3 -fno-plt -flto -DNDEBUG 26 | # OPT:=-Ofast -fno-plt -flto -DNDEBUG 27 | # NFLAGS+=-Pnochecks -Pnogc # ==> gcc: 44s instead of 38s, clang: 33s instead of 35s 28 | # NFLAGS+=-Pnochecks # ==> gcc: 46s instead of 38s, clang: 34s instead of 35s 29 | NFLAGS+=-Pnogc # ==> gcc: 36s instead of 38s, clang: 34s instead of 35s 30 | endif 31 | 32 | #PROF:=1 33 | ifdef PROF 34 | OPT+=-pg 35 | endif 36 | 37 | %.c: %.nelua 38 | $(NELUA) $(NFLAGS) -o $@ $^ 39 | 40 | # main14.elf: main14.nelua 41 | # # $(NELUA) --maximum-performance -b -o $@ $^ 42 | # $(NELUA) --release -Pnochecks -Pnogc -b -o $@ $^ 43 | 44 | %.elf: %.c 45 | $(CC) -o $@ $^ $(OPT) -lm 46 | 47 | %.ppm: %.elf 48 | ./$^ > $@ 49 | 50 | clean: 51 | $(RM) *.c *.elf *.ppm 52 | -------------------------------------------------------------------------------- /rtiow/Nelua/main02.nelua: -------------------------------------------------------------------------------- 1 | require 'C.stdio' 2 | local nx = 200_i32 3 | local ny = 100_i32 4 | print('P3') 5 | C.printf("%d %d\n", nx,ny) 6 | print(255) 7 | for j=ny-1,0,-1 do 8 | for i=0, 0 12 | end 13 | 14 | local function color(r: Ray) 15 | if hit_sphere(Vec3{0,0,-1}, 0.5, r) then 16 | return Vec3{1, 0, 0} 17 | end 18 | local unit_direction = r.direction:unit_vector() 19 | local t = 0.5 * (unit_direction.y + 1.0) 20 | return (1.0 - t) * Vec3{1.0, 1.0, 1.0} + t * Vec3{0.5, 0.7, 1.0} 21 | end 22 | 23 | local nx, ny = 200_i32, 100_i32 24 | C.printf("P3\n%d %d\n255\n", nx,ny) 25 | local lower_left_corner=Vec3{-2, -1, -1} 26 | local horizontal=Vec3{4, 0, 0} 27 | local vertical=Vec3{0, 2, 0} 28 | local origin=Vec3{0, 0, 0} 29 | for j=ny-1,0,-1 do 30 | for i=0, 0.0 then 21 | local N = (r:point_at_parameter(t) - Vec3{0,0,-1}):unit_vector() 22 | return 0.5*Vec3{N.x+1, N.y+1, N.z+1} 23 | end 24 | local unit_direction = r.direction:unit_vector() 25 | local t = 0.5 * (unit_direction.y + 1.0) 26 | return (1.0 - t) * Vec3{1.0, 1.0, 1.0} + t * Vec3{0.5, 0.7, 1.0} 27 | end 28 | 29 | local nx, ny = 200_i32, 100_i32 30 | C.printf("P3\n%d %d\n255\n", nx,ny) 31 | local lower_left_corner=Vec3{-2, -1, -1} 32 | local horizontal=Vec3{4, 0, 0} 33 | local vertical=Vec3{0, 2, 0} 34 | local origin=Vec3{0, 0, 0} 35 | for j=ny-1,0,-1 do 36 | for i=0,0 then 31 | local temp = (-b - math.sqrt(discriminant)) / a 32 | if temp < t_max and temp > t_min then 33 | rec.t = temp 34 | rec.p = r:point_at_parameter(rec.t) 35 | rec.normal = (rec.p - sphere.center) / sphere.radius 36 | return true 37 | end 38 | temp = (-b + math.sqrt(discriminant)) / a 39 | if temp < t_max and temp > t_min then 40 | rec.t = temp 41 | rec.p = r:point_at_parameter(rec.t) 42 | rec.normal = (rec.p - sphere.center) / sphere.radius 43 | return true 44 | end 45 | end 46 | return false 47 | end 48 | 49 | local function hit(world: span(HSphere), r: Ray, t_min: float32, t_max: float32, rec: *HitRec) 50 | local hit_anything = false 51 | local temp_rec = HitRec{} 52 | local closest_so_far = t_max 53 | for i=0,<#world do 54 | if hit_sphere(world[i], r, t_min, closest_so_far, &temp_rec) then 55 | hit_anything = true 56 | closest_so_far = temp_rec.t 57 | $rec = temp_rec 58 | end 59 | end 60 | return hit_anything 61 | end 62 | 63 | local function color(r: Ray, world: span(HSphere)) 64 | local rec=HitRec{} 65 | if hit(world, r, 0, 99999, &rec) then 66 | return 0.5 * (rec.normal + Vec3{1, 1, 1}) 67 | else 68 | local unit_direction = r.direction:unit_vector() 69 | local t = 0.5 * (unit_direction.y + 1.0) 70 | return (1.0 - t) * Vec3{1.0, 1.0, 1.0} + t * Vec3{0.5, 0.7, 1.0} 71 | end 72 | end 73 | 74 | local nx, ny = 200_i32, 100_i32 75 | C.printf("P3\n%d %d\n255\n", nx,ny) 76 | local lower_left_corner=Vec3{-2, -1, -1} 77 | local horizontal=Vec3{4, 0, 0} 78 | local vertical=Vec3{0, 2, 0} 79 | local origin=Vec3{0, 0, 0} 80 | local world: []HSphere = { 81 | {{0,0,-1}, 0.5}, 82 | {{0,-100.5, -1}, 100.}, 83 | } 84 | for j=ny-1,0,-1 do 85 | for i=0,0 then 44 | local temp = (-b - math.sqrt(discriminant)) / a 45 | if temp < t_max and temp > t_min then 46 | rec.t = temp 47 | rec.p = r:point_at_parameter(rec.t) 48 | rec.normal = (rec.p - sphere.center) / sphere.radius 49 | return true 50 | end 51 | temp = (-b + math.sqrt(discriminant)) / a 52 | if temp < t_max and temp > t_min then 53 | rec.t = temp 54 | rec.p = r:point_at_parameter(rec.t) 55 | rec.normal = (rec.p - sphere.center) / sphere.radius 56 | return true 57 | end 58 | end 59 | return false 60 | end 61 | 62 | local function hit(world: span(HSphere), r: Ray, t_min: float32, t_max: float32, rec: *HitRec) 63 | local hit_anything = false 64 | local temp_rec = HitRec{} 65 | local closest_so_far = t_max 66 | for i=0,<#world do 67 | if hit_sphere(world[i], r, t_min, closest_so_far, &temp_rec) then 68 | hit_anything = true 69 | closest_so_far = temp_rec.t 70 | $rec = temp_rec 71 | end 72 | end 73 | return hit_anything 74 | end 75 | 76 | local function color(r: Ray, world: span(HSphere)) 77 | local rec=HitRec{} 78 | if hit(world, r, 0, 99999, &rec) then 79 | return 0.5 * (rec.normal + Vec3{1, 1, 1}) 80 | else 81 | local unit_direction = r.direction:unit_vector() 82 | local t = 0.5 * (unit_direction.y + 1.0) 83 | return (1.0 - t) * Vec3{1.0, 1.0, 1.0} + t * Vec3{0.5, 0.7, 1.0} 84 | end 85 | end 86 | 87 | srand(0) 88 | local nx, ny, ns = 200_i32, 100_i32, 100_int32 89 | C.printf("P3\n%d %d\n255\n", nx,ny) 90 | local world: []HSphere = { 91 | {{0,0,-1}, 0.5}, 92 | {{0,-100.5, -1}, 100.}, 93 | } 94 | local cam = Camera{ 95 | Vec3{0, 0, 0}, 96 | Vec3{-2, -1, -1}, 97 | Vec3{4, 0, 0}, 98 | Vec3{0, 2, 0}, 99 | } 100 | for j=ny-1,0,-1 do 101 | for i=0, = 4294967295_uint32 3 | global Pcg32RandomT: type = @record{ 4 | state: uint64, 5 | inc: uint64, 6 | } 7 | global SEED = Pcg32RandomT{0, 0} 8 | 9 | global function srand(val: uint32) 10 | SEED.state = val 11 | SEED.inc = 0 12 | end 13 | 14 | global function rand(): uint32 15 | local oldstate = SEED.state 16 | SEED.state = oldstate * uint64(6364136223846793005) + (SEED.inc | 1) 17 | local xorshifted = uint32(((oldstate >> 18) ~ oldstate) >> 27) 18 | local rot = uint32(oldstate >> 59) 19 | return (xorshifted >> rot) | (xorshifted << ((-int32(rot)) & 31)) 20 | end 21 | 22 | global function random_f(): float32 23 | return float32(rand()) / (float32(RAND_MAX) + 1_float32) 24 | end 25 | -------------------------------------------------------------------------------- /rtiow/Nelua/ray.nelua: -------------------------------------------------------------------------------- 1 | require 'vec' 2 | global Ray:type=@record{origin:Vec3, direction:Vec3} 3 | 4 | function Ray.point_at_parameter(self: Ray, t: float32): Vec3 5 | return self.origin + t * self.direction 6 | end 7 | -------------------------------------------------------------------------------- /rtiow/Nelua/vec.nelua: -------------------------------------------------------------------------------- 1 | require 'math' 2 | -- global Vec3: type = @record{a: array(float32,3)} 3 | global Vec3: type = @record{x:float32,y:float32,z:float32} 4 | 5 | function Vec3.__add(a: Vec3, b: Vec3): Vec3 6 | return Vec3{a.x + b.x, a.y + b.y, a.z + b.z} 7 | end 8 | 9 | function Vec3.__sub(a: Vec3, b: Vec3): Vec3 10 | return Vec3{a.x - b.x, a.y - b.y, a.z - b.z} 11 | end 12 | 13 | function Vec3.__mul(t: float32, v: Vec3): Vec3 14 | return Vec3{t*v.x, t*v.y, t*v.z} 15 | end 16 | 17 | global function vmul(a: Vec3, b: Vec3): Vec3 18 | return Vec3{a.x*b.x, a.y*b.y, a.z*b.z} 19 | end 20 | 21 | function Vec3.__div(v: Vec3, t: float32): Vec3 22 | return Vec3{v.x / t, v.y / t, v.z / t} 23 | end 24 | 25 | global function vdot(v1: Vec3, v2: Vec3): float32 26 | return v1.x *v2.x + v1.y * v2.y + v1.z * v2.z 27 | end 28 | 29 | function Vec3.vdot(self: Vec3, v2: Vec3): float32 30 | return vdot(self, v2) 31 | end 32 | 33 | global function vcross(v1: Vec3, v2: Vec3): Vec3 34 | return Vec3{ 35 | v1.y * v2.z - v1.z * v2.y, 36 | v1.z * v2.x - v1.x * v2.z, 37 | v1.x * v2.y - v1.y * v2.x, 38 | } 39 | end 40 | 41 | function Vec3.print(self: Vec3) 42 | print(self.x, self.y, self.z) 43 | end 44 | 45 | function Vec3.squared_length(self: Vec3): float32 46 | return self.x * self.x + self.y * self.y + self.z * self.z 47 | end 48 | 49 | global function length(self: Vec3): float32 50 | return math.sqrt(self:squared_length()) 51 | end 52 | 53 | function Vec3.length(self: Vec3): float32 54 | return length(self) 55 | end 56 | 57 | global function unit_vector(self: Vec3): Vec3 58 | return self / self:length() 59 | end 60 | 61 | function Vec3.unit_vector(self: Vec3): Vec3 62 | return unit_vector(self) 63 | end 64 | 65 | global function vreflect(self: Vec3, n: Vec3): Vec3 66 | return self - 2_f32 * vdot(self, n) * n 67 | end 68 | 69 | function Vec3.vreflect(self: Vec3, n: Vec3): Vec3 70 | return vreflect(self, n) 71 | end 72 | -------------------------------------------------------------------------------- /rtiow/Nim/Makefile: -------------------------------------------------------------------------------- 1 | SRC:=$(wildcard main*.nim) 2 | EXE:=$(patsubst %.nim,%.elf,$(SRC)) 3 | PPM:=$(patsubst %.nim,%.ppm,$(SRC)) 4 | 5 | NIM=nim 6 | 7 | all: $(EXE) 8 | du -sh . 9 | 10 | check: $(PPM) 11 | md5sum *.ppm 12 | md5sum *.ppm | md5sum 13 | 14 | bench: main14.elf 15 | time ./main14.elf 1024 768 10 main14.ppm && md5sum main14.ppm 16 | 17 | NIMOPT:= 18 | NIMOPT+=--hints:off 19 | 20 | #DEBUG:=1 21 | ifdef DEBUG 22 | NIMOPT+=--debugger:native 23 | endif 24 | 25 | #PROF:=1 26 | ifdef PROF 27 | NIMOPT+=--profiler:on --stackTrace:on 28 | endif 29 | 30 | OPT:=1 31 | ifdef OPT 32 | NIMOPT+=-d:release 33 | NIMOPT+=-d:danger 34 | #NIMOPT+=--gc:orc 35 | # NIMOPT+=--passC:"-O3" 36 | # NIMOPT+=--passC:"-Ofast -fno-plt -flto -march=native -DNDEBUG" 37 | # NIMOPT+=--passC:"-Ofast -fno-plt -flto -DNDEBUG" 38 | NIMOPT+=--passC:"-O3 -fno-plt -flto -DNDEBUG" 39 | NIMOPT+=--gc:arc 40 | NIMOPT+=-d:lto 41 | endif 42 | 43 | %.elf: %.nim 44 | $(NIM) c $(NIMOPT) -o:$@ $^ 45 | 46 | %.ppm: %.elf 47 | ./$^ $(ARGS) > $@ 48 | 49 | clean: 50 | $(RM) *.elf *.elf.o *.ppm 51 | -------------------------------------------------------------------------------- /rtiow/Nim/main02.nim: -------------------------------------------------------------------------------- 1 | import strformat 2 | var nx = 200 3 | var ny = 100 4 | echo("P3") 5 | echo(fmt"{nx} {ny}") 6 | echo(255) 7 | for j in countdown(ny - 1, 0): 8 | for i in countup(0, nx - 1): 9 | var r = i / nx 10 | var g = j / ny 11 | var b = 0.2 12 | var ir = int(255.99 * r) 13 | var ig = int(255.99 * g) 14 | var ib = int(255.99 * b) 15 | echo(fmt"{ir} {ig} {ib}") 16 | -------------------------------------------------------------------------------- /rtiow/Nim/main03.nim: -------------------------------------------------------------------------------- 1 | import strformat 2 | import vec3 3 | var nx = 200 4 | var ny = 100 5 | echo("P3") 6 | echo(fmt"{nx} {ny}") 7 | echo(255) 8 | for j in countdown(ny - 1, 0): 9 | for i in countup(0, nx - 1): 10 | var col = vec3(i / nx, j / ny, 0.2) 11 | var ir = int(255.99 * col.x) 12 | var ig = int(255.99 * col.y) 13 | var ib = int(255.99 * col.z) 14 | echo(fmt"{ir} {ig} {ib}") 15 | -------------------------------------------------------------------------------- /rtiow/Nim/main04.nim: -------------------------------------------------------------------------------- 1 | import strformat 2 | import vec3 3 | import ray 4 | 5 | func color(r: Ray): Vec3 = 6 | var unit_direction = unit_vector(r.direction) 7 | var t = 0.5 * (unit_direction.y + 1) 8 | result = (1 - t) * vec3(1, 1, 1) + t * vec3(0.5, 0.7, 1) 9 | 10 | var nx = 200 11 | var ny = 100 12 | echo("P3") 13 | echo(fmt"{nx} {ny}") 14 | echo(255) 15 | var lower_left_corner = vec3(-2, -1, -1) 16 | var horizontal = vec3(4, 0, 0) 17 | var vertical = vec3(0, 2, 0) 18 | var origin = vec3(0, 0, 0) 19 | for j in countdown(ny - 1, 0): 20 | for i in countup(0, nx - 1): 21 | var u = float32(i) / float32(nx) 22 | var v = float32(j) / float32(ny) 23 | var r = ray(origin, lower_left_corner + u*horizontal + v*vertical) 24 | var col = color(r) 25 | var ir = int(255.99 * col.x) 26 | var ig = int(255.99 * col.y) 27 | var ib = int(255.99 * col.z) 28 | echo(fmt"{ir} {ig} {ib}") 29 | -------------------------------------------------------------------------------- /rtiow/Nim/main05.nim: -------------------------------------------------------------------------------- 1 | import strformat 2 | import vec3 3 | import ray 4 | 5 | func hit_sphere(center: Vec3, radius: float32, r: Ray): bool = 6 | var oc = r.origin - center 7 | var a = vdot(r.direction, r.direction) 8 | var b = 2 * vdot(oc, r.direction) 9 | var c = vdot(oc, oc) - radius * radius 10 | var discriminant = b*b - 4*a*c 11 | result = discriminant > 0 12 | 13 | func color(r: Ray): Vec3 = 14 | if hit_sphere(vec3(0, 0, -1), 0.5, r): 15 | return vec3(1, 0, 0) 16 | var unit_direction = unit_vector(r.direction) 17 | var t = 0.5 * (unit_direction.y + 1) 18 | result = (1 - t) * vec3(1, 1, 1) + t * vec3(0.5, 0.7, 1) 19 | 20 | var nx = 200 21 | var ny = 100 22 | echo("P3") 23 | echo(fmt"{nx} {ny}") 24 | echo(255) 25 | var lower_left_corner = vec3(-2, -1, -1) 26 | var horizontal = vec3(4, 0, 0) 27 | var vertical = vec3(0, 2, 0) 28 | var origin = vec3(0, 0, 0) 29 | for j in countdown(ny - 1, 0): 30 | for i in countup(0, nx - 1): 31 | var u = float32(i) / float32(nx) 32 | var v = float32(j) / float32(ny) 33 | var r = ray(origin, lower_left_corner + u*horizontal + v*vertical) 34 | var col = color(r) 35 | var ir = int(255.99 * col.x) 36 | var ig = int(255.99 * col.y) 37 | var ib = int(255.99 * col.z) 38 | echo(fmt"{ir} {ig} {ib}") 39 | -------------------------------------------------------------------------------- /rtiow/Nim/main06_1.nim: -------------------------------------------------------------------------------- 1 | import strformat 2 | import math 3 | import vec3 4 | import ray 5 | 6 | func hit_sphere(center: Vec3, radius: float32, r: Ray): float32 = 7 | var oc = r.origin - center 8 | var a = vdot(r.direction, r.direction) 9 | var b = 2 * vdot(oc, r.direction) 10 | var c = vdot(oc, oc) - radius * radius 11 | var discriminant = b*b - 4*a*c 12 | if discriminant < 0: 13 | return -1 14 | else: 15 | return (-b - sqrt(discriminant)) / (2*a) 16 | 17 | func color(r: Ray): Vec3 = 18 | var t = hit_sphere(vec3(0, 0, -1), 0.5, r) 19 | if t > 0: 20 | var N = unit_vector(r.point_at_parameter(t) - vec3(0, 0, -1)) 21 | return 0.5*vec3(N.x+1, N.y+1, N.z+1) 22 | var unit_direction = unit_vector(r.direction) 23 | t = 0.5 * (unit_direction.y + 1) 24 | result = (1 - t) * vec3(1, 1, 1) + t * vec3(0.5, 0.7, 1) 25 | 26 | var (nx, ny) = (200, 100) 27 | echo("P3") 28 | echo(fmt"{nx} {ny}") 29 | echo(255) 30 | var lower_left_corner = vec3(-2, -1, -1) 31 | var horizontal = vec3(4, 0, 0) 32 | var vertical = vec3(0, 2, 0) 33 | var origin = vec3(0, 0, 0) 34 | for j in countdown(ny - 1, 0): 35 | for i in countup(0, nx - 1): 36 | var u = float32(i) / float32(nx) 37 | var v = float32(j) / float32(ny) 38 | var r = ray(origin, lower_left_corner + u*horizontal + v*vertical) 39 | var col = color(r) 40 | var ir = int(255.99 * col.x) 41 | var ig = int(255.99 * col.y) 42 | var ib = int(255.99 * col.z) 43 | echo(fmt"{ir} {ig} {ib}") 44 | -------------------------------------------------------------------------------- /rtiow/Nim/main06_2.nim: -------------------------------------------------------------------------------- 1 | import strformat 2 | import math 3 | import vec3 4 | import ray 5 | 6 | type HitRec = object 7 | t: float32 8 | p: Vec3 9 | normal: Vec3 10 | 11 | type HSphere = object 12 | center: Vec3 13 | radius: float32 14 | 15 | func hsphere(center: Vec3, radius: float32): HSphere = 16 | HSphere(center: center, radius: radius) 17 | 18 | func hit_sphere(s: HSphere, r: Ray, t_min, t_max: float32, 19 | rec: var HitRec): bool = 20 | var oc = r.origin - s.center 21 | var a = vdot(r.direction, r.direction) 22 | var b = vdot(oc, r.direction) 23 | var c = vdot(oc, oc) - s.radius * s.radius 24 | var discriminant = b*b - a*c 25 | if discriminant > 0: 26 | var temp = (-b - sqrt(discriminant)) / a 27 | if temp < t_max and temp > t_min: 28 | rec.t = temp 29 | rec.p = r.point_at_parameter(rec.t) 30 | rec.normal = (rec.p - s.center) / s.radius 31 | return true 32 | temp = (-b + sqrt(discriminant)) / a 33 | if temp < t_max and temp > t_min: 34 | rec.t = temp 35 | rec.p = r.point_at_parameter(rec.t) 36 | rec.normal = (rec.p - s.center) / s.radius 37 | return true 38 | return false 39 | 40 | func hit(hh: openArray[HSphere], r: Ray, t_min, t_max: float32, 41 | rec: var HitRec): bool = 42 | var temp_rec: HitRec 43 | var hit_anything = false 44 | var closest_so_far = t_max 45 | for h in hh: 46 | if hit_sphere(h, r, t_min, closest_so_far, temp_rec): 47 | hit_anything = true 48 | closest_so_far = temp_rec.t 49 | rec = temp_rec 50 | return hit_anything 51 | 52 | func color(r: Ray, world: openArray[HSphere]): Vec3 = 53 | var rec: HitRec 54 | if hit(world, r, 0, 99999, rec): 55 | return 0.5*(rec.normal + vec3(1, 1, 1)) 56 | var unit_direction = unit_vector(r.direction) 57 | var t = 0.5 * (unit_direction.y + 1) 58 | result = (1 - t) * vec3(1, 1, 1) + t * vec3(0.5, 0.7, 1) 59 | 60 | var (nx, ny) = (200, 100) 61 | echo(&"P3\n{nx} {ny}\n255") 62 | var lower_left_corner = vec3(-2, -1, -1) 63 | var horizontal = vec3(4, 0, 0) 64 | var vertical = vec3(0, 2, 0) 65 | var origin = vec3(0, 0, 0) 66 | var world: seq[HSphere] = @[ 67 | hsphere(vec3(0, 0, -1), 0.5), 68 | hsphere(vec3(0, -100.5, -1), 100) 69 | ] 70 | for j in countdown(ny - 1, 0): 71 | for i in countup(0, nx - 1): 72 | var u = float32(i) / float32(nx) 73 | var v = float32(j) / float32(ny) 74 | var r = ray(origin, lower_left_corner + u*horizontal + v*vertical) 75 | var col = color(r, world) 76 | var ir = int(255.99 * col.x) 77 | var ig = int(255.99 * col.y) 78 | var ib = int(255.99 * col.z) 79 | stdout.write(&"{ir} {ig} {ib}\n") 80 | -------------------------------------------------------------------------------- /rtiow/Nim/main07.nim: -------------------------------------------------------------------------------- 1 | import strformat, math 2 | import vec3, ray, pcg 3 | 4 | type HitRec = object 5 | t: float32 6 | p: Vec3 7 | normal: Vec3 8 | 9 | type HSphere = object 10 | center: Vec3 11 | radius: float32 12 | 13 | type Camera = object 14 | origin: Vec3 15 | lower_left_corner: Vec3 16 | horizontal: Vec3 17 | vertical: Vec3 18 | 19 | func get_ray(cam: Camera, u, v: float32): Ray = 20 | result = ray(cam.origin, cam.lower_left_corner + u*cam.horizontal + 21 | v*cam.vertical) 22 | 23 | func hsphere(center: Vec3, radius: float32): HSphere = 24 | HSphere(center: center, radius: radius) 25 | 26 | func hit_sphere(s: HSphere, r: Ray, t_min, t_max: float32, 27 | rec: var HitRec): bool = 28 | var oc = r.origin - s.center 29 | var a = vdot(r.direction, r.direction) 30 | var b = vdot(oc, r.direction) 31 | var c = vdot(oc, oc) - s.radius * s.radius 32 | var discriminant = b*b - a*c 33 | if discriminant > 0: 34 | var temp = (-b - sqrt(discriminant)) / a 35 | if temp < t_max and temp > t_min: 36 | rec.t = temp 37 | rec.p = r.point_at_parameter(rec.t) 38 | rec.normal = (rec.p - s.center) / s.radius 39 | return true 40 | temp = (-b + sqrt(discriminant)) / a 41 | if temp < t_max and temp > t_min: 42 | rec.t = temp 43 | rec.p = r.point_at_parameter(rec.t) 44 | rec.normal = (rec.p - s.center) / s.radius 45 | return true 46 | return false 47 | 48 | func hit(hh: openArray[HSphere], r: Ray, t_min, t_max: float32, 49 | rec: var HitRec): bool = 50 | var temp_rec: HitRec 51 | var hit_anything = false 52 | var closest_so_far = t_max 53 | for h in hh: 54 | if hit_sphere(h, r, t_min, closest_so_far, temp_rec): 55 | hit_anything = true 56 | closest_so_far = temp_rec.t 57 | rec = temp_rec 58 | return hit_anything 59 | 60 | func color(r: Ray, world: openArray[HSphere]): Vec3 = 61 | var rec: HitRec 62 | if hit(world, r, 0, 99999, rec): 63 | return 0.5*(rec.normal + vec3(1, 1, 1)) 64 | var unit_direction = unit_vector(r.direction) 65 | var t = 0.5 * (unit_direction.y + 1) 66 | result = (1 - t) * vec3(1, 1, 1) + t * vec3(0.5, 0.7, 1) 67 | 68 | pcg.srand(0) 69 | var (nx, ny, ns) = (200, 100, 100) 70 | echo(&"P3\n{nx} {ny}\n255") 71 | var world: seq[HSphere] = @[ 72 | hsphere(vec3(0, 0, -1), 0.5), 73 | hsphere(vec3(0, -100.5, -1), 100)] 74 | var cam = Camera( 75 | lower_left_corner: vec3(-2, -1, -1), 76 | horizontal: vec3(4, 0, 0), 77 | vertical: vec3(0, 2, 0), 78 | origin: vec3(0, 0, 0), 79 | ) 80 | for j in countdown(ny - 1, 0): 81 | for i in countup(0, nx - 1): 82 | var col = vec3(0, 0, 0) 83 | for s in countup(0, ns-1): 84 | var u = (float32(i) + random_f()) / float32(nx) 85 | var v = (float32(j) + random_f()) / float32(ny) 86 | var r = cam.get_ray(u, v) 87 | col = col + color(r, world) 88 | col = col / float32(ns) 89 | var ir = int(255.99 * col.x) 90 | var ig = int(255.99 * col.y) 91 | var ib = int(255.99 * col.z) 92 | stdout.write(&"{ir} {ig} {ib}\n") 93 | -------------------------------------------------------------------------------- /rtiow/Nim/pcg.nim: -------------------------------------------------------------------------------- 1 | # PCG random implementation - credits to Cieric for original Odin/C version 2 | const RAND_MAX* = uint32(4294967295) 3 | type Pcg32RandomT* = object 4 | state: uint64 5 | inc: uint64 6 | 7 | var SEED = Pcg32RandomT(state: 0, inc: 0) 8 | 9 | {.push inline.} 10 | 11 | proc srand*(val: uint32) = 12 | SEED.state = val 13 | SEED.inc = 0 14 | 15 | proc rand*(): uint32 = 16 | var oldstate = SEED.state 17 | SEED.state = oldstate * uint64(6364136223846793005) + (SEED.inc or 1) 18 | var xorshifted = uint32(((oldstate shr 18) xor oldstate) shr 27) 19 | var rot = uint32(oldstate shr 59) 20 | return (xorshifted shr rot) or (xorshifted shl ((-int32(rot)) and 31)) 21 | 22 | proc random_f*(): float32 = 23 | float32(rand()) / (float32(RAND_MAX) + 1f) 24 | 25 | {.pop.} 26 | -------------------------------------------------------------------------------- /rtiow/Nim/ray.nim: -------------------------------------------------------------------------------- 1 | import vec3 2 | type Ray* = object 3 | origin*: Vec3 4 | direction*: Vec3 5 | 6 | {.push inline.} 7 | 8 | func ray*(origin: Vec3, direction: Vec3): Ray = 9 | result.origin = origin 10 | result.direction = direction 11 | 12 | func point_at_parameter*(r: Ray, t: float32): Vec3 = 13 | r.origin + t * r.direction 14 | 15 | {.pop.} 16 | -------------------------------------------------------------------------------- /rtiow/Nim/vec3.nim: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | type Vec3* = object 4 | x*, y*, z*: float32 5 | 6 | {.push inline.} 7 | 8 | func vec3*(x, y, z: float32): Vec3 = 9 | Vec3(x: x, y: y, z: z) 10 | 11 | func squared_length*(v: Vec3): float32 = 12 | v.x * v.x + v.y * v.y + v.z * v.z 13 | 14 | func length*(v: Vec3): float32 = 15 | sqrt(v.squared_length()) 16 | 17 | func vdot*(v1, v2: Vec3): float32 = 18 | v1.x * v2.x + v1.y * v2.y + v1.z * v2.z 19 | 20 | func vcross*(v1: Vec3, v2: Vec3): Vec3 = 21 | result.x = v1.y * v2.z - v1.z * v2.y 22 | result.y = v1.z * v2.x - v1.x * v2.z 23 | result.z = v1.x * v2.y - v1.y * v2.x 24 | 25 | func `-`*(v: Vec3): Vec3 = 26 | result.x = -v.x 27 | result.y = -v.y 28 | result.z = -v.z 29 | 30 | func `/`*(v: Vec3, t: float32): Vec3 = 31 | result.x = v.x / t 32 | result.y = v.y / t 33 | result.z = v.z / t 34 | 35 | func `*`*(t: float32, v: Vec3): Vec3 = 36 | result.x = t * v.x 37 | result.y = t * v.y 38 | result.z = t * v.z 39 | 40 | func `+`*(v1: Vec3, v2: Vec3): Vec3 = 41 | result.x = v1.x + v2.x 42 | result.y = v1.y + v2.y 43 | result.z = v1.z + v2.z 44 | 45 | func `-`*(v1: Vec3, v2: Vec3): Vec3 = 46 | result.x = v1.x - v2.x 47 | result.y = v1.y - v2.y 48 | result.z = v1.z - v2.z 49 | 50 | func `*`*(v1: Vec3, v2: Vec3): Vec3 = 51 | result.x = v1.x * v2.x 52 | result.y = v1.y * v2.y 53 | result.z = v1.z * v2.z 54 | 55 | func unit_vector*(v: Vec3): Vec3 = 56 | v / v.length() 57 | 58 | func vreflect*(v: Vec3, n: Vec3): Vec3 = 59 | v - 2f * vdot(v, n) * n 60 | 61 | {.pop.} 62 | -------------------------------------------------------------------------------- /rtiow/Odin/Makefile: -------------------------------------------------------------------------------- 1 | SRC:=$(wildcard main*.odin) 2 | EXE:=$(patsubst %.odin,%.elf,$(SRC)) 3 | PPM:=$(patsubst %.odin,%.ppm,$(SRC)) 4 | 5 | _SYS:=$(shell uname -o) 6 | ifeq ($(_SYS),Msys) 7 | WIN32:=1 8 | EXEXT:=exe 9 | ODIN=odin.exe 10 | else 11 | EXEXT:=elf 12 | ODIN=odin 13 | endif 14 | 15 | all: $(EXE) 16 | du -sh . 17 | 18 | check: $(PPM) 19 | md5sum *.ppm 20 | md5sum *.ppm | md5sum 21 | 22 | bench: main14.elf 23 | time ./main14.elf 1024 768 10 main14.ppm && md5sum main14.ppm 24 | 25 | #OPT=-llvm-api 26 | OPT=-opt:3 -no-bounds-check 27 | #OPT=-O0 -g 28 | #DEBUG:=1 29 | ifdef DEBUG 30 | OPT+=-define:DEBUG=1 31 | endif 32 | #OPT+=-debug 33 | 34 | %.$(EXEXT): %.odin pcg/pcg.odin 35 | $(ODIN) build $< -out:$@ $(OPT) 36 | 37 | %.ppm: %.$(EXEXT) 38 | ./$^ $(ARGS) > $@ 39 | 40 | clean: 41 | $(RM) *.$(EXEXT) *.ppm 42 | -------------------------------------------------------------------------------- /rtiow/Odin/main02.odin: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "core:fmt" 4 | 5 | main :: proc() { 6 | nx := 200; 7 | ny := 100; 8 | fmt.printf("P3\n"); 9 | fmt.printf("%d %d\n", nx, ny); 10 | fmt.printf("%d\n", 255); 11 | for j := ny - 1; j >= 0; j -= 1 { 12 | for i := 0; i < nx; i += 1 { 13 | r := f32(i) / f32(nx); 14 | g := f32(j) / f32(ny); 15 | b := 0.2; 16 | ir := int(255.99 * r); 17 | ig := int(255.99 * g); 18 | ib := int(255.99 * b); 19 | fmt.printf("%d %d %d\n", ir, ig, ib); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /rtiow/Odin/main03.odin: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "core:fmt" 4 | 5 | Vec3 :: [3]f32; 6 | 7 | main :: proc() { 8 | nx := 200; 9 | ny := 100; 10 | fmt.printf("P3\n"); 11 | fmt.printf("%d %d\n", nx, ny); 12 | fmt.printf("%d\n", 255); 13 | for j := ny - 1; j >= 0; j -= 1 { 14 | for i := 0; i < nx; i += 1 { 15 | col := Vec3{f32(i) / f32(nx), f32(j) / f32(ny), 0.2}; 16 | ir := int(255.99 * col[0]); 17 | ig := int(255.99 * col[1]); 18 | ib := int(255.99 * col[2]); 19 | fmt.printf("%d %d %d\n", ir, ig, ib); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /rtiow/Odin/main04.odin: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "core:fmt" 4 | import "core:math" 5 | 6 | Vec3 :: [3]f32; 7 | 8 | Ray :: struct { 9 | origin: Vec3, 10 | direction: Vec3 11 | } 12 | 13 | vlen :: proc(v: Vec3) -> f32 { 14 | return math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); 15 | } 16 | 17 | unit_vector :: proc(v: Vec3) -> Vec3 { 18 | return v / vlen(v); 19 | } 20 | 21 | color :: proc(r: Ray) -> Vec3 { 22 | unit_direction := unit_vector(r.direction); 23 | t := 0.5 * (unit_direction[1] + 1.0); 24 | return (1.0 - t) * Vec3{1.0, 1.0, 1.0} + t * Vec3{0.5, 0.7, 1.0}; 25 | } 26 | 27 | main :: proc() { 28 | nx := 200; 29 | ny := 100; 30 | fmt.printf("P3\n"); 31 | fmt.printf("%d %d\n", nx, ny); 32 | fmt.printf("%d\n", 255); 33 | lower_left_corner := Vec3{-2.0, -1.0, -1.0}; 34 | horizontal := Vec3{4.0, 0.0, 0.0}; 35 | vertical := Vec3{0.0, 2.0, 0.0}; 36 | origin := Vec3{0.0, 0.0, 0.0}; 37 | for j := ny - 1; j >= 0; j -= 1 { 38 | for i := 0; i < nx; i += 1 { 39 | u := f32(i) / f32(nx); 40 | v := f32(j) / f32(ny); 41 | r := Ray{origin, lower_left_corner + u * horizontal + v * vertical}; 42 | col := color(r); 43 | ir := int(255.99 * col[0]); 44 | ig := int(255.99 * col[1]); 45 | ib := int(255.99 * col[2]); 46 | fmt.printf("%d %d %d\n", ir, ig, ib); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /rtiow/Odin/main05.odin: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "core:fmt" 4 | import "core:math" 5 | 6 | Vec3 :: [3]f32; 7 | 8 | Ray :: struct { 9 | origin: Vec3, 10 | direction: Vec3 11 | } 12 | 13 | vlen :: proc(v: Vec3) -> f32 { 14 | return math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); 15 | } 16 | 17 | unit_vector :: proc(v: Vec3) -> Vec3 { 18 | return v / vlen(v); 19 | } 20 | 21 | vdot :: proc(v1: Vec3, v2: Vec3) -> f32 { 22 | return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; 23 | } 24 | 25 | hit_sphere :: proc(center: Vec3, radius: f32, r: Ray) -> bool { 26 | oc := r.origin - center; 27 | a := vdot(r.direction, r.direction); 28 | b := 2.0 * vdot(oc, r.direction); 29 | c := vdot(oc, oc) - radius * radius; 30 | discriminant := b * b - 4 * a * c; 31 | return discriminant > 0; 32 | } 33 | 34 | color :: proc(r: Ray) -> Vec3 { 35 | if hit_sphere(Vec3{0, 0, -1}, 0.5, r) { 36 | return Vec3{1, 0, 0}; 37 | } 38 | unit_direction := unit_vector(r.direction); 39 | t := 0.5 * (unit_direction[1] + 1.0); 40 | return (1.0 - t) * Vec3{1.0, 1.0, 1.0} + t * Vec3{0.5, 0.7, 1.0}; 41 | } 42 | 43 | main :: proc() { 44 | nx := 200; 45 | ny := 100; 46 | fmt.printf("P3\n"); 47 | fmt.printf("%d %d\n", nx, ny); 48 | fmt.printf("%d\n", 255); 49 | lower_left_corner := Vec3{-2.0, -1.0, -1.0}; 50 | horizontal := Vec3{4.0, 0.0, 0.0}; 51 | vertical := Vec3{0.0, 2.0, 0.0}; 52 | origin := Vec3{0.0, 0.0, 0.0}; 53 | for j := ny - 1; j >= 0; j -= 1 { 54 | for i := 0; i < nx; i += 1 { 55 | u := f32(i) / f32(nx); 56 | v := f32(j) / f32(ny); 57 | r := Ray{origin, lower_left_corner + u * horizontal + v * vertical}; 58 | col := color(r); 59 | ir := int(255.99 * col[0]); 60 | ig := int(255.99 * col[1]); 61 | ib := int(255.99 * col[2]); 62 | fmt.printf("%d %d %d\n", ir, ig, ib); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /rtiow/Odin/main06_1.odin: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "core:fmt" 4 | import "core:math" 5 | 6 | Vec3 :: [3]f32; 7 | 8 | Ray :: struct { 9 | origin: Vec3, 10 | direction: Vec3 11 | } 12 | 13 | vlen :: proc(v: Vec3) -> f32 { 14 | return math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); 15 | } 16 | 17 | unit_vector :: proc(v: Vec3) -> Vec3 { 18 | return v / vlen(v); 19 | } 20 | 21 | vdot :: proc(v1: Vec3, v2: Vec3) -> f32 { 22 | return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; 23 | } 24 | 25 | hit_sphere :: proc(center: Vec3, radius: f32, r: Ray) -> f32 { 26 | oc := r.origin - center; 27 | a := vdot(r.direction, r.direction); 28 | b := 2.0 * vdot(oc, r.direction); 29 | c := vdot(oc, oc) - radius * radius; 30 | discriminant := b * b - 4 * a * c; 31 | if discriminant < 0 { 32 | return -1.0; 33 | } else { 34 | return (-b - math.sqrt(discriminant)) / (2.0 * a); 35 | } 36 | } 37 | 38 | point_at_parameter :: proc(r: Ray, t: f32) -> Vec3 { 39 | return r.origin + t * r.direction; 40 | } 41 | 42 | color :: proc(r: Ray) -> Vec3 { 43 | t := hit_sphere(Vec3{0, 0, -1}, 0.5, r); 44 | if t > 0.0 { 45 | N := unit_vector(point_at_parameter(r, t) - Vec3{0, 0, -1}); 46 | return 0.5 * (N + Vec3{1, 1, 1}); 47 | } 48 | unit_direction := unit_vector(r.direction); 49 | t = 0.5 * (unit_direction[1] + 1.0); 50 | return (1.0 - t) * Vec3{1.0, 1.0, 1.0} + t * Vec3{0.5, 0.7, 1.0}; 51 | } 52 | 53 | main :: proc() { 54 | nx := 200; 55 | ny := 100; 56 | fmt.printf("P3\n"); 57 | fmt.printf("%d %d\n", nx, ny); 58 | fmt.printf("%d\n", 255); 59 | lower_left_corner := Vec3{-2.0, -1.0, -1.0}; 60 | horizontal := Vec3{4.0, 0.0, 0.0}; 61 | vertical := Vec3{0.0, 2.0, 0.0}; 62 | origin := Vec3{0.0, 0.0, 0.0}; 63 | for j := ny - 1; j >= 0; j -= 1 { 64 | for i := 0; i < nx; i += 1 { 65 | u := f32(i) / f32(nx); 66 | v := f32(j) / f32(ny); 67 | r := Ray{origin, lower_left_corner + u * horizontal + v * vertical}; 68 | col := color(r); 69 | ir := int(255.99 * col[0]); 70 | ig := int(255.99 * col[1]); 71 | ib := int(255.99 * col[2]); 72 | fmt.printf("%d %d %d\n", ir, ig, ib); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /rtiow/Odin/main06_2.odin: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "core:fmt" 4 | import "core:math" 5 | 6 | Vec3 :: [3]f32; 7 | 8 | Ray :: struct { 9 | origin: Vec3, 10 | direction: Vec3 11 | } 12 | 13 | HSphere :: struct { 14 | center: Vec3, 15 | radius: f32 16 | } 17 | 18 | HitRec :: struct { 19 | t: f32, 20 | p: Vec3, 21 | normal: Vec3 22 | } 23 | 24 | vlen :: proc(v: Vec3) -> f32 { 25 | return math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); 26 | } 27 | 28 | unit_vector :: proc(v: Vec3) -> Vec3 { 29 | return v / vlen(v); 30 | } 31 | 32 | point_at_parameter :: proc(r: Ray, t: f32) -> Vec3 { 33 | return r.origin + t * r.direction; 34 | } 35 | 36 | vdot :: proc(v1: Vec3, v2: Vec3) -> f32 { 37 | return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; 38 | } 39 | 40 | hit_sphere :: proc(s: HSphere, r: Ray, t_min: f32, t_max: f32, rec: ^HitRec) -> bool { 41 | oc := r.origin - s.center; 42 | a := vdot(r.direction, r.direction); 43 | b := vdot(oc, r.direction); 44 | c := vdot(oc, oc) - s.radius * s.radius; 45 | discriminant := b * b - a * c; 46 | if discriminant > 0 { 47 | temp := (-b - math.sqrt(discriminant)) / a; 48 | if temp < t_max && temp > t_min { 49 | rec.t = temp; 50 | rec.p = point_at_parameter(r, rec.t); 51 | rec.normal = (rec.p - s.center) / s.radius; 52 | return true; 53 | } 54 | temp = (-b + math.sqrt(discriminant)) / a; 55 | if temp < t_max && temp > t_min { 56 | rec.t = temp; 57 | rec.p = point_at_parameter(r, rec.t); 58 | rec.normal = (rec.p - s.center) / s.radius; 59 | return true; 60 | } 61 | } 62 | return false; 63 | } 64 | 65 | hit :: proc(hh: []HSphere, r: Ray, t_min: f32, t_max: f32, rec: ^HitRec) -> bool { 66 | temp_rec := HitRec{}; 67 | hit_anything := false; 68 | closest_so_far := t_max; 69 | for h in hh { 70 | if hit_sphere(h, r, t_min, closest_so_far, &temp_rec) { 71 | hit_anything = true; 72 | closest_so_far = temp_rec.t; 73 | rec^ = temp_rec; 74 | } 75 | } 76 | return hit_anything; 77 | } 78 | 79 | color :: proc(world: []HSphere, r: Ray) -> Vec3 { 80 | rec := HitRec{}; 81 | if hit(world, r, 0., 99999., &rec) { 82 | return 0.5 * (rec.normal + Vec3{1, 1, 1}); 83 | } 84 | unit_direction := unit_vector(r.direction); 85 | t := 0.5 * (unit_direction[1] + 1.0); 86 | return (1.0 - t) * Vec3{1.0, 1.0, 1.0} + t * Vec3{0.5, 0.7, 1.0}; 87 | } 88 | 89 | main :: proc() { 90 | nx := 200; 91 | ny := 100; 92 | fmt.printf("P3\n"); 93 | fmt.printf("%d %d\n", nx, ny); 94 | fmt.printf("%d\n", 255); 95 | lower_left_corner := Vec3{-2.0, -1.0, -1.0}; 96 | horizontal := Vec3{4.0, 0.0, 0.0}; 97 | vertical := Vec3{0.0, 2.0, 0.0}; 98 | origin := Vec3{0.0, 0.0, 0.0}; 99 | world := []HSphere{ 100 | HSphere{Vec3{0.0, 0.0, -1.0}, 0.5}, 101 | HSphere{Vec3{0.0, -100.5, -1.0}, 100}, 102 | }; 103 | for j := ny - 1; j >= 0; j -= 1 { 104 | for i := 0; i < nx; i += 1 { 105 | u := f32(i) / f32(nx); 106 | v := f32(j) / f32(ny); 107 | r := Ray{origin, lower_left_corner + u * horizontal + v * vertical}; 108 | col := color(world, r); 109 | ir := int(255.99 * col[0]); 110 | ig := int(255.99 * col[1]); 111 | ib := int(255.99 * col[2]); 112 | fmt.printf("%d %d %d\n", ir, ig, ib); 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /rtiow/Odin/pcg/pcg.odin: -------------------------------------------------------------------------------- 1 | package pcg 2 | 3 | /********************************************** 4 | PCG random implementation - credits to Cieric 5 | */ 6 | RAND_MAX : u32 = 4294967295; 7 | pcg32_random_t :: struct { state, inc : u64, }; 8 | seed : pcg32_random_t = {0, 0}; 9 | srand :: proc(val : u32) { 10 | seed.state = cast(u64)(val); 11 | seed.inc = 0; 12 | } 13 | 14 | rand :: proc() -> u32 { 15 | oldstate : u64 = seed.state; 16 | seed.state = oldstate * cast(u64)(6364136223846793005) + (seed.inc | 1); 17 | xorshifted : u32 = cast(u32)(((oldstate >> 18) ~ oldstate) >> 27); 18 | rot : u32 = cast(u32)(oldstate >> 59); 19 | return (xorshifted >> rot) | (xorshifted << ((-rot) & 31)); 20 | } 21 | /* 22 | **********************************************/ 23 | -------------------------------------------------------------------------------- /rtiow/README.md: -------------------------------------------------------------------------------- 1 | # Ray tracing in one weekend 2 | See here : https://raytracing.github.io 3 | This repo contains my experiments following the excellent book above, 4 | implemented in Rust, Nelua, Nim, C, V, C++, Odin ~~and Go~~. (sorted by runtime perf) 5 | 6 | Note : the current C perf is poor, probably because it's mostly a dirty port of the C++ design, 7 | with vtables to simulates OOP constructs. A rework in underway to try and get decent perfs. 8 | 9 | Note : now that I added superfine support and its 10 runs, I removed Go from the benchmark as it 10 | takes 5x longer than the other slowest lang, until I (or someone) can fix its impl to get decent speed. 11 | 12 | # rtiow 13 | Benchmark : 14 | ------------- 15 | `$ make mrproper bench` 16 | 17 | ``` 18 | make[1]: Entering directory '/home/nico/perso/git/realist/rtiow/Rust' 19 | time ./main14.elf 1024 768 10 main14.ppm && md5sum main14.ppm 20 | 34.56user 0.00system 0:34.57elapsed 99%CPU (0avgtext+0avgdata 4624maxresident)k 21 | make[1]: Entering directory '/home/nico/perso/git/realist/rtiow/Nelua' 22 | time ./main14.elf 1024 768 10 main14.ppm && md5sum main14.ppm 23 | 35.82user 0.00system 0:35.83elapsed 99%CPU (0avgtext+0avgdata 4292maxresident)k 24 | make[1]: Entering directory '/home/nico/perso/git/realist/rtiow/Nim' 25 | time ./main14.elf 1024 768 10 main14.ppm && md5sum main14.ppm 26 | 41.66user 0.00system 0:41.67elapsed 99%CPU (0avgtext+0avgdata 4164maxresident)k 27 | make[1]: Entering directory '/home/nico/perso/git/realist/rtiow/C' 28 | time ./main14.elf 1024 768 10 main14.ppm && md5sum main14.ppm 29 | 50.40user 0.00system 0:50.42elapsed 99%CPU (0avgtext+0avgdata 4340maxresident)k 30 | make[1]: Entering directory '/home/nico/perso/git/realist/rtiow/V' 31 | time ./main14.elf 1024 768 10 main14.ppm && md5sum main14.ppm 32 | 55.69user 0.09system 0:55.80elapsed 99%CPU (0avgtext+0avgdata 250048maxresident)k 33 | make[1]: Entering directory '/home/nico/perso/git/realist/rtiow/CPP' 34 | time ./main14.elf 1024 768 10 main14.ppm && md5sum main14.ppm 35 | 56.94user 0.00system 0:56.95elapsed 99%CPU (0avgtext+0avgdata 5592maxresident)k 36 | make[1]: Entering directory '/home/nico/perso/git/realist/rtiow/Odin' 37 | time ./main14.elf 1024 768 10 main14.ppm && md5sum main14.ppm 38 | 69.75user 0.00system 1:09.77elapsed 99%CPU (0avgtext+0avgdata 4204maxresident)k 39 | make[1]: Entering directory '/home/nico/perso/git/realist/rtiow/Go' 40 | time ./main14.elf 1024 768 10 main14.ppm && md5sum main14.ppm 41 | 329.23user 2.03system 5:28.69elapsed 100%CPU (0avgtext+0avgdata 10104maxresident)k 42 | ``` 43 | 44 | It can help to first do: 45 | ``` 46 | sudo cpupower frequency-set -g performance 47 | ``` 48 | -------------------------------------------------------------------------------- /rtiow/Rust/Makefile: -------------------------------------------------------------------------------- 1 | SRC:=$(wildcard main*.rs) 2 | EXE:=$(patsubst %.rs,%.elf,$(SRC)) 3 | PPM:=$(patsubst %.rs,%.ppm,$(SRC)) 4 | 5 | RSC=rustc 6 | 7 | all: $(EXE) 8 | du -sh . 9 | 10 | check: $(PPM) 11 | md5sum *.ppm 12 | md5sum *.ppm | md5sum 13 | 14 | bench: main14.elf 15 | time ./main14.elf 1024 768 10 main14.ppm && md5sum main14.ppm 16 | 17 | OPT=-C opt-level=3 18 | #DEBUG:=1 19 | ifdef DEBUG 20 | OPT+=--cfg 'DEBUG' 21 | endif 22 | 23 | %.elf: %.rs pcg.rs 24 | $(RSC) -o $@ $< $(OPT) -lm 25 | 26 | %.ppm: %.elf 27 | ./$^ $(ARGS) > $@ 28 | 29 | clean: 30 | $(RM) *.elf *.ppm 31 | -------------------------------------------------------------------------------- /rtiow/Rust/main02.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let nx = 200; 3 | let ny = 100; 4 | println!("P3"); 5 | println!("{} {}", nx, ny); 6 | println!("255"); 7 | for j in (0..ny).rev() { 8 | for i in 0..nx { 9 | let r = i as f32 / nx as f32; 10 | let g = j as f32 / ny as f32; 11 | let b = 0.2; 12 | let ir = (255.99*r) as i32; 13 | let ig = (255.99*g) as i32; 14 | let ib = (255.99*b) as i32; 15 | println!("{} {} {}", ir, ig, ib); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /rtiow/Rust/main03.rs: -------------------------------------------------------------------------------- 1 | type Vec3 = [f32; 3]; 2 | 3 | fn main() { 4 | let nx = 200; 5 | let ny = 100; 6 | println!("P3"); 7 | println!("{} {}", nx, ny); 8 | println!("255"); 9 | for j in (0..ny).rev() { 10 | for i in 0..nx { 11 | let col : Vec3 = [i as f32 / nx as f32, j as f32 / ny as f32, 0.2]; 12 | let ir = (255.99*col[0]) as i32; 13 | let ig = (255.99*col[1]) as i32; 14 | let ib = (255.99*col[2]) as i32; 15 | println!("{} {} {}", ir, ig, ib); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /rtiow/Rust/main04.rs: -------------------------------------------------------------------------------- 1 | use std::ops::Div; 2 | use std::ops::Mul; 3 | 4 | #[derive(Debug)] 5 | #[derive(Copy, Clone)] 6 | struct Vec3([f32; 3]); 7 | 8 | #[derive(Debug)] 9 | struct Ray { 10 | origin: Vec3, 11 | direction: Vec3 12 | } 13 | 14 | impl Vec3 { 15 | fn squared_length(self) -> f32 { 16 | let Self([x1, y1, z1]) = self; 17 | x1 * x1 + y1 * y1 + z1 * z1 18 | } 19 | fn length(self) -> f32 { 20 | f32::sqrt(self.squared_length()) 21 | } 22 | } 23 | 24 | impl std::ops::Div for Vec3 { 25 | type Output = Vec3; 26 | 27 | fn div(self, rhs: Vec3) -> Self::Output { 28 | let Self([x1, y1, z1]) = self; 29 | let Self([x2, y2, z2]) = rhs; 30 | 31 | Self([x1 / x2, y1 / y2, z1 / z2]) 32 | } 33 | } 34 | 35 | impl std::ops::Add for Vec3 { 36 | type Output = Vec3; 37 | 38 | fn add(self, rhs: Vec3) -> Self::Output { 39 | let Self([x1, y1, z1]) = self; 40 | let Self([x2, y2, z2]) = rhs; 41 | 42 | Self([x1 + x2, y1 + y2, z1 + z2]) 43 | } 44 | } 45 | 46 | impl Div for Vec3 { 47 | type Output = Self; 48 | 49 | fn div(self, rhs: f32) -> Self::Output { 50 | let Self([x1, y1, z1]) = self; 51 | Self([x1 / rhs, y1 / rhs, z1 / rhs]) 52 | } 53 | } 54 | 55 | impl Mul for Vec3 { 56 | type Output = Self; 57 | 58 | fn mul(self, rhs: f32) -> Self::Output { 59 | let Self([x1, y1, z1]) = self; 60 | Self([x1 * rhs, y1 * rhs, z1 * rhs]) 61 | } 62 | } 63 | 64 | //let v = Vec3([0., 0., 0.]); 65 | //v.0[1] 66 | 67 | fn unit_vector(v: Vec3) -> Vec3 { 68 | v / v.length() 69 | } 70 | 71 | fn color(r: Ray) -> Vec3 { 72 | // println!("r={:?}", r); 73 | let unit_direction = unit_vector(r.direction); 74 | // println!("ud={:?}", unit_direction); 75 | let t = 0.5 * (unit_direction.0[1] + 1.); 76 | // println!("t={}", t); 77 | Vec3([1., 1., 1.]) * (1. - t) + Vec3([0.5, 0.7, 1.]) * t 78 | } 79 | 80 | fn main() { 81 | let nx = 200; 82 | let ny = 100; 83 | println!("P3"); 84 | println!("{} {}", nx, ny); 85 | println!("255"); 86 | let lower_left_corner = Vec3([-2.0, -1.0, -1.0]); 87 | let horizontal = Vec3([4., 0., 0.]); 88 | let vertical = Vec3([0., 2., 0.]); 89 | let origin = Vec3([0., 0., 0.]); 90 | for j in (0..ny).rev() { 91 | for i in 0..nx { 92 | let u = i as f32 / nx as f32; 93 | let v = j as f32 / ny as f32; 94 | // println!("u={} v={}", u, v); 95 | let r = Ray { 96 | origin: origin, 97 | direction: lower_left_corner + horizontal * u + vertical * v 98 | }; 99 | let col = color(r); 100 | // println!("col={:?}", col); 101 | let ir = (255.99*col.0[0]) as i32; 102 | let ig = (255.99*col.0[1]) as i32; 103 | let ib = (255.99*col.0[2]) as i32; 104 | println!("{} {} {}", ir, ig, ib); 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /rtiow/Rust/main05.rs: -------------------------------------------------------------------------------- 1 | use std::ops::Div; 2 | use std::ops::Mul; 3 | 4 | #[derive(Debug)] 5 | #[derive(Copy, Clone)] 6 | struct Vec3([f32; 3]); 7 | 8 | #[derive(Debug)] 9 | #[derive(Copy, Clone)] 10 | struct Ray { 11 | origin: Vec3, 12 | direction: Vec3 13 | } 14 | 15 | impl Vec3 { 16 | fn squared_length(self) -> f32 { 17 | let Self([x1, y1, z1]) = self; 18 | x1 * x1 + y1 * y1 + z1 * z1 19 | } 20 | fn length(self) -> f32 { 21 | f32::sqrt(self.squared_length()) 22 | } 23 | } 24 | 25 | impl std::ops::Rem for Vec3 { 26 | type Output = f32; 27 | 28 | fn rem(self, rhs: Vec3) -> f32 { 29 | let Self([x1, y1, z1]) = self; 30 | let Self([x2, y2, z2]) = rhs; 31 | 32 | x1 * x2 + y1 * y2 + z1 * z2 33 | } 34 | } 35 | 36 | impl std::ops::Div for Vec3 { 37 | type Output = Vec3; 38 | 39 | fn div(self, rhs: Vec3) -> Self::Output { 40 | let Self([x1, y1, z1]) = self; 41 | let Self([x2, y2, z2]) = rhs; 42 | 43 | Self([x1 / x2, y1 / y2, z1 / z2]) 44 | } 45 | } 46 | 47 | impl std::ops::Add for Vec3 { 48 | type Output = Vec3; 49 | 50 | fn add(self, rhs: Vec3) -> Self::Output { 51 | let Self([x1, y1, z1]) = self; 52 | let Self([x2, y2, z2]) = rhs; 53 | 54 | Self([x1 + x2, y1 + y2, z1 + z2]) 55 | } 56 | } 57 | 58 | impl std::ops::Sub for Vec3 { 59 | type Output = Vec3; 60 | 61 | fn sub(self, rhs: Vec3) -> Self::Output { 62 | let Self([x1, y1, z1]) = self; 63 | let Self([x2, y2, z2]) = rhs; 64 | 65 | Self([x1 - x2, y1 - y2, z1 - z2]) 66 | } 67 | } 68 | 69 | impl Div for Vec3 { 70 | type Output = Self; 71 | 72 | fn div(self, rhs: f32) -> Self::Output { 73 | let Self([x1, y1, z1]) = self; 74 | Self([x1 / rhs, y1 / rhs, z1 / rhs]) 75 | } 76 | } 77 | 78 | impl Mul for Vec3 { 79 | type Output = Self; 80 | 81 | fn mul(self, rhs: f32) -> Self::Output { 82 | let Self([x1, y1, z1]) = self; 83 | Self([x1 * rhs, y1 * rhs, z1 * rhs]) 84 | } 85 | } 86 | 87 | fn unit_vector(v: Vec3) -> Vec3 { 88 | v / v.length() 89 | } 90 | 91 | fn hit_sphere(center: Vec3, radius: f32, r: Ray) -> bool { 92 | let oc = r.origin - center; 93 | // println!("oc={:?}", oc); 94 | let a = r.direction % r.direction; 95 | let b = 2. * (oc % r.direction); 96 | let c = (oc % oc) - radius * radius; 97 | let discriminant = b * b - 4. * a * c; 98 | // println!("a={} b={} c={} d={}", a, b, c, discriminant); 99 | discriminant > 0. 100 | } 101 | 102 | fn color(r: Ray) -> Vec3 { 103 | if hit_sphere(Vec3([0., 0., -1.]), 0.5, r) { 104 | Vec3([1., 0., 0.]) 105 | } else { 106 | let unit_direction = unit_vector(r.direction); 107 | let t = 0.5 * (unit_direction.0[1] + 1.); 108 | Vec3([1., 1., 1.]) * (1. - t) + Vec3([0.5, 0.7, 1.]) * t 109 | } 110 | } 111 | 112 | fn main() { 113 | let nx = 200; 114 | let ny = 100; 115 | println!("P3"); 116 | println!("{} {}", nx, ny); 117 | println!("255"); 118 | let lower_left_corner = Vec3([-2.0, -1.0, -1.0]); 119 | let horizontal = Vec3([4., 0., 0.]); 120 | let vertical = Vec3([0., 2., 0.]); 121 | let origin = Vec3([0., 0., 0.]); 122 | for j in (0..ny).rev() { 123 | for i in 0..nx { 124 | let u = i as f32 / nx as f32; 125 | let v = j as f32 / ny as f32; 126 | let r = Ray { 127 | origin: origin, 128 | direction: lower_left_corner + horizontal * u + vertical * v 129 | }; 130 | let col = color(r); 131 | let ir = (255.99*col.0[0]) as i32; 132 | let ig = (255.99*col.0[1]) as i32; 133 | let ib = (255.99*col.0[2]) as i32; 134 | println!("{} {} {}", ir, ig, ib); 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /rtiow/Rust/pcg.rs: -------------------------------------------------------------------------------- 1 | /********************************************** 2 | PCG random implementation - credits to Cieric for original Odin/C version 3 | */ 4 | 5 | pub const RAND_MAX: u32 = 4294967295; 6 | 7 | struct Pcg32RandomT { 8 | state: u64, 9 | inc: u64 10 | } 11 | 12 | static mut SEED: Pcg32RandomT = Pcg32RandomT { 13 | state: 0, 14 | inc: 0 15 | }; 16 | 17 | pub fn srand(val: u32) { 18 | unsafe { 19 | SEED.state = val as u64; 20 | SEED.inc = 0; 21 | } 22 | } 23 | 24 | pub fn rand() -> u32 { 25 | unsafe { 26 | let oldstate = SEED.state as u64; 27 | SEED.state = oldstate * 6364136223846793005 as u64 + (SEED.inc | 1); 28 | let xorshifted = (((oldstate >> 18) ^ oldstate) >> 27) as u32; 29 | let rot = (oldstate >> 59) as u32; 30 | return (xorshifted >> rot) | (xorshifted << ((-(rot as i32)) & 31)); 31 | } 32 | } 33 | 34 | /* 35 | **********************************************/ 36 | -------------------------------------------------------------------------------- /rtiow/V/Makefile: -------------------------------------------------------------------------------- 1 | SRC:=$(wildcard main*.v) 2 | EXE:=$(patsubst %.v,%.elf,$(SRC)) 3 | PPM:=$(patsubst %.v,%.ppm,$(SRC)) 4 | 5 | V:=v 6 | 7 | all: $(EXE) 8 | du -sh . 9 | 10 | check: $(PPM) 11 | md5sum *.ppm 12 | md5sum *.ppm | md5sum 13 | 14 | bench: main14.elf 15 | time ./main14.elf 1024 768 10 main14.ppm && md5sum main14.ppm 16 | 17 | VFLAGS+=--enable-globals 18 | #DEBUG:=1 19 | ifdef DEBUG 20 | VFLAGS+=-d dbg 21 | #VFLAGS+=-profile profile.txt 22 | else 23 | # OPT:=-O3 24 | # OPT:=-Ofast -fno-plt -flto -DNDEBUG 25 | OPT:=-O3 -fno-plt -flto -DNDEBUG 26 | endif 27 | 28 | #PROF:=1 29 | ifdef PROF 30 | OPT+=-pg 31 | endif 32 | 33 | %_v.c: %.v 34 | $(V) $(VFLAGS) -o $@ $^ 35 | 36 | %.elf: %_v.c 37 | $(CC) -o $@ $^ $(OPT) -lm 38 | 39 | %.ppm: %.elf 40 | ./$^ > $@ 41 | 42 | clean: 43 | $(RM) *_v.c *.elf *.ppm 44 | -------------------------------------------------------------------------------- /rtiow/V/main02.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn main() { 4 | nx := 200 5 | ny := 100 6 | println('P3') 7 | println('$nx $ny') 8 | println(255) 9 | for j := ny - 1; j >= 0; j-- { 10 | for i := 0; i < nx; i++ { 11 | r := f32(i) / f32(nx) 12 | g := f32(j) / f32(ny) 13 | b := 0.2 14 | ir := int(f32(255.99) * r) 15 | ig := int(f32(255.99) * g) 16 | ib := int(f32(255.99) * b) 17 | println('$ir $ig $ib') 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /rtiow/V/main03.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import vec 4 | 5 | fn main() { 6 | nx := 200 7 | ny := 100 8 | println('P3') 9 | println('$nx $ny') 10 | println(255) 11 | for j := ny - 1; j >= 0; j-- { 12 | for i := 0; i < nx; i++ { 13 | col := vec.Vec3{f32(i) / f32(nx), f32(j) / f32(ny), 0.2} 14 | ir := int(f32(255.99) * col.x) 15 | ig := int(f32(255.99) * col.y) 16 | ib := int(f32(255.99) * col.z) 17 | println('$ir $ig $ib') 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /rtiow/V/main04.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import vec 4 | import ray 5 | 6 | fn color(r ray.Ray) vec.Vec3 { 7 | // println('r=$r') 8 | unit_direction := r.direction.unit_vector() 9 | // println('ud=$unit_direction') 10 | t := .5 * (unit_direction.y + 1.0) 11 | // println('t=$t') 12 | return vec.mult(1.0 - t, vec.Vec3{1.0, 1.0, 1.0}) + vec.mult(t, vec.Vec3{.5, .7, 1}) 13 | } 14 | 15 | fn main() { 16 | nx := 200 17 | ny := 100 18 | println('P3') 19 | println('$nx $ny') 20 | println(255) 21 | lower_left_corner := vec.Vec3{-2, -1, -1} 22 | horizontal := vec.Vec3{4, 0, 0} 23 | vertical := vec.Vec3{0, 2, 0} 24 | origin := vec.Vec3{0, 0, 0} 25 | for j := ny - 1; j >= 0; j-- { 26 | for i := 0; i < nx; i++ { 27 | u := f32(i) / f32(nx) 28 | v := f32(j) / f32(ny) 29 | // println('u=$u v=$v') 30 | r := ray.Ray{origin, lower_left_corner + vec.mult(u, horizontal) + vec.mult(v, vertical)} 31 | col := color(r) 32 | // println('col=$col') 33 | ir := int(f32(255.99) * col.x) 34 | ig := int(f32(255.99) * col.y) 35 | ib := int(f32(255.99) * col.z) 36 | println('$ir $ig $ib') 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /rtiow/V/main05.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import vec 4 | import ray 5 | 6 | fn hit_sphere(center vec.Vec3, radius f32, r ray.Ray) bool { 7 | oc := r.origin - center 8 | // println('oc=$oc') 9 | a := r.direction.dot(r.direction) 10 | b := 2.0 * oc.dot(r.direction) 11 | c := oc.dot(oc) - radius * radius 12 | discriminant := b * b - 4.0 * a * c 13 | // println('a=$a b=$b c=$c d=$discriminant') 14 | return discriminant > 0 15 | } 16 | 17 | fn color(r ray.Ray) vec.Vec3 { 18 | // next 2 lines to workaround buggy AST v2 compiler 19 | x := vec.Vec3{0, 0, -1} 20 | if hit_sphere(x, 0.5, r) { 21 | // if hit_sphere(vec.Vec3{0, 0, -1}, 0.5, r) { 22 | return vec.Vec3{1, 0, 0} 23 | } 24 | unit_direction := r.direction.unit_vector() 25 | t := .5 * (unit_direction.y + 1.0) 26 | return vec.mult(1.0 - t, vec.Vec3{1, 1, 1}) + vec.mult(t, vec.Vec3{.5, .7, 1}) 27 | } 28 | 29 | fn main() { 30 | nx := 200 31 | ny := 100 32 | println('P3') 33 | println('$nx $ny') 34 | println(255) 35 | lower_left_corner := vec.Vec3{-2, -1, -1} 36 | horizontal := vec.Vec3{4, 0, 0} 37 | vertical := vec.Vec3{0, 2, 0} 38 | origin := vec.Vec3{0, 0, 0} 39 | for j := ny - 1; j >= 0; j-- { 40 | for i := 0; i < nx; i++ { 41 | u := f32(i) / f32(nx) 42 | v := f32(j) / f32(ny) 43 | r := ray.Ray{origin, lower_left_corner + vec.mult(u, horizontal) + vec.mult(v, vertical)} 44 | col := color(r) 45 | ir := int(f32(255.99) * col.x) 46 | ig := int(f32(255.99) * col.y) 47 | ib := int(f32(255.99) * col.z) 48 | println('$ir $ig $ib') 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /rtiow/V/main06_1.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import vec 4 | import ray 5 | import math 6 | 7 | fn hit_sphere(center vec.Vec3, radius f32, r ray.Ray) f32 { 8 | oc := r.origin - center 9 | a := r.direction.dot(r.direction) 10 | b := 2.0 * oc.dot(r.direction) 11 | c := oc.dot(oc) - radius * radius 12 | discriminant := b * b - 4.0 * a * c 13 | // println('a=$a b=$b c=$c d=$discriminant') 14 | if discriminant < 0 { 15 | return -1.0 16 | } else { 17 | return (-b - math.sqrtf(discriminant)) / (2.0 * a) 18 | } 19 | } 20 | 21 | fn color(r ray.Ray) vec.Vec3 { 22 | mut t := hit_sphere(vec.Vec3{0, 0, -1}, .5, r) 23 | if t > 0 { 24 | // println('t=$t') 25 | n := (r.point_at_parameter(t) - vec.Vec3{0, 0, -1}).unit_vector() 26 | return vec.mult(.5, n + vec.Vec3{1, 1, 1}) 27 | } 28 | unit_direction := r.direction.unit_vector() 29 | t = .5 * (unit_direction.y + 1.0) 30 | return vec.mult(1.0 - t, vec.Vec3{1, 1, 1}) + vec.mult(t, vec.Vec3{.5, .7, 1}) 31 | } 32 | 33 | fn main() { 34 | nx := 200 35 | ny := 100 36 | println('P3') 37 | println('$nx $ny') 38 | println(255) 39 | lower_left_corner := vec.Vec3{-2, -1, -1} 40 | horizontal := vec.Vec3{4, 0, 0} 41 | vertical := vec.Vec3{0, 2, 0} 42 | origin := vec.Vec3{0, 0, 0} 43 | for j := ny - 1; j >= 0; j-- { 44 | for i := 0; i < nx; i++ { 45 | u := f32(i) / f32(nx) 46 | v := f32(j) / f32(ny) 47 | r := ray.Ray{origin, lower_left_corner + vec.mult(u, horizontal) + vec.mult(v, vertical)} 48 | col := color(r) 49 | ir := int(f32(255.99) * col.x) 50 | ig := int(f32(255.99) * col.y) 51 | ib := int(f32(255.99) * col.z) 52 | println('$ir $ig $ib') 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /rtiow/V/main06_2.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import vec 4 | import ray 5 | import math 6 | 7 | struct Sphere { 8 | center vec.Vec3 9 | radius f32 10 | } 11 | 12 | struct NullHittable {} 13 | 14 | type Hittable = NullHittable | Sphere 15 | 16 | struct HitRec { 17 | mut: 18 | t f32 // hit time 19 | p vec.Vec3 // hit point coords 20 | normal vec.Vec3 // normal at hit point 21 | } 22 | 23 | fn (s Sphere) hit(r ray.Ray, t_min f32, t_max f32, mut rec HitRec) bool { 24 | oc := r.origin - s.center 25 | a := r.direction.dot(r.direction) 26 | b := oc.dot(r.direction) 27 | c := oc.dot(oc) - s.radius * s.radius 28 | discriminant := b * b - a * c 29 | if discriminant > 0 { 30 | mut temp := (-b - math.sqrtf(discriminant)) / a 31 | if temp < t_max && temp > t_min { 32 | rec.t = temp 33 | rec.p = r.point_at_parameter(rec.t) 34 | rec.normal = vec.div(rec.p - s.center, s.radius) 35 | return true 36 | } 37 | temp = (-b + math.sqrtf(discriminant)) / a 38 | if temp < t_max && temp > t_min { 39 | rec.t = temp 40 | rec.p = r.point_at_parameter(rec.t) 41 | rec.normal = vec.div(rec.p - s.center, s.radius) 42 | return true 43 | } 44 | } 45 | return false 46 | } 47 | 48 | [inline] 49 | fn (h Hittable) hit(r ray.Ray, t_min f32, t_max f32, mut rec HitRec) bool { 50 | match h { 51 | Sphere { 52 | return h.hit(r, t_min, t_max, mut rec) 53 | } 54 | NullHittable {} 55 | } 56 | return false 57 | } 58 | 59 | fn (hh []Hittable) hit(r ray.Ray, t_min f32, t_max f32, mut rec HitRec) bool { 60 | mut hit_anything := false 61 | mut closest_so_far := t_max 62 | for h in hh { 63 | if h.hit(r, t_min, closest_so_far, mut rec) { 64 | hit_anything = true 65 | closest_so_far = rec.t 66 | // println('t=$temp_rec.t') 67 | } 68 | } 69 | return hit_anything 70 | } 71 | 72 | fn color(r ray.Ray) vec.Vec3 { 73 | mut rec := HitRec{} 74 | hittables := [ 75 | Hittable(Sphere{ 76 | center: vec.Vec3{0, 0, -1} 77 | radius: .5 78 | }), 79 | Sphere{ 80 | center: vec.Vec3{0, -100.5, -1} 81 | radius: 100 82 | }, 83 | ] 84 | if hittables.hit(r, 0, 99999, mut rec) { 85 | // println('t=$rec.t') 86 | return vec.mult(0.5, rec.normal + vec.Vec3{1, 1, 1}) 87 | } else { 88 | unit_direction := r.direction.unit_vector() 89 | t := .5 * (unit_direction.y + 1.0) 90 | return vec.mult(1.0 - t, vec.Vec3{1, 1, 1}) + vec.mult(t, vec.Vec3{.5, .7, 1}) 91 | } 92 | } 93 | 94 | fn main() { 95 | nx := 200 96 | ny := 100 97 | println('P3') 98 | println('$nx $ny') 99 | println(255) 100 | lower_left_corner := vec.Vec3{-2, -1, -1} 101 | horizontal := vec.Vec3{4, 0, 0} 102 | vertical := vec.Vec3{0, 2, 0} 103 | origin := vec.Vec3{0, 0, 0} 104 | for j := ny - 1; j >= 0; j-- { 105 | for i := 0; i < nx; i++ { 106 | u := f32(i) / f32(nx) 107 | v := f32(j) / f32(ny) 108 | r := ray.Ray{origin, lower_left_corner + vec.mult(u, horizontal) + vec.mult(v, vertical)} 109 | col := color(r) 110 | ir := int(f32(255.99) * col.x) 111 | ig := int(f32(255.99) * col.y) 112 | ib := int(f32(255.99) * col.z) 113 | println('$ir $ig $ib') 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /rtiow/V/pcg/pcg.v: -------------------------------------------------------------------------------- 1 | module pcg 2 | 3 | struct PCG32Random { 4 | mut: 5 | state u64 6 | inc u64 7 | } 8 | 9 | __global ( 10 | rfcnt int 11 | riuscnt int 12 | riudcnt int 13 | seed PCG32Random 14 | ) 15 | 16 | pub const ( 17 | pcg_rand_max = 4294967295 18 | ) 19 | 20 | pub fn pcg_srand(val u32) { 21 | seed.state = val 22 | seed.inc = 0 23 | } 24 | 25 | pub fn pcg_rand() u32 { 26 | oldstate := seed.state 27 | seed.state = oldstate * u64(6364136223846793005) + (seed.inc | 1) 28 | xorshifted := u32(((oldstate >> 18) ^ oldstate) >> 27) 29 | rot := u32(oldstate >> 59) 30 | return (xorshifted >> rot) | (xorshifted << ((-rot) & 31)) 31 | } 32 | -------------------------------------------------------------------------------- /rtiow/V/ray/ray.v: -------------------------------------------------------------------------------- 1 | module ray 2 | 3 | import vec 4 | 5 | pub struct Ray { 6 | pub: 7 | origin vec.Vec3 8 | direction vec.Vec3 9 | } 10 | 11 | pub fn (r &Ray) str() string { 12 | return '{${r.origin.str()}, ${r.direction.str()}}' 13 | } 14 | 15 | [inline] 16 | pub fn (r &Ray) point_at_parameter(t f32) vec.Vec3 { 17 | return r.origin + vec.mult(t, r.direction) 18 | } 19 | -------------------------------------------------------------------------------- /rtiow/V/vec/vec.v: -------------------------------------------------------------------------------- 1 | module vec 2 | 3 | import math 4 | 5 | //[typedef]pub type Scalar f32 6 | pub struct Vec3 { 7 | pub: 8 | // x Scalar y Scalar z Scalar 9 | x f32 y f32 z f32 10 | } 11 | 12 | union U0 { 13 | mut: 14 | v [3]f32 15 | i [3]u32 16 | } 17 | 18 | struct S0 { 19 | u U0 20 | } 21 | 22 | pub fn (a Vec3) str() string { 23 | // return '{$a.x, $a.y, $a.z}' 24 | mut u0 := U0{} 25 | mut p1 := '' 26 | mut p2 := '' 27 | mut p3 := '' 28 | unsafe{ 29 | u0.v[0] = a.x 30 | u0.v[1] = a.y 31 | u0.v[2] = a.z 32 | p1 = u0.i[0].hex() 33 | p2 = u0.i[1].hex() 34 | p3 = u0.i[2].hex() 35 | if u0.i[0] == 0 { 36 | p1 = '0' 37 | } 38 | if u0.i[1] == 0 { 39 | p2 = '0' 40 | } 41 | if u0.i[2] == 0 { 42 | p3 = '0' 43 | } 44 | } 45 | return '{${a.x:.6f}, ${a.y:.6f}, ${a.z:.6f};$p1, $p2, $p3}' 46 | } 47 | 48 | [inline] 49 | pub fn (a Vec3) +(b Vec3) Vec3 { 50 | return Vec3 { 51 | a.x + b.x, 52 | a.y + b.y, 53 | a.z + b.z 54 | } 55 | } 56 | 57 | [inline] 58 | pub fn (a Vec3) *(b Vec3) Vec3 { 59 | return Vec3 { 60 | a.x * b.x, 61 | a.y * b.y, 62 | a.z * b.z 63 | } 64 | } 65 | 66 | [inline] 67 | pub fn (v Vec3) cross(ov Vec3) Vec3 { 68 | return Vec3 { 69 | v.y * ov.z - v.z * ov.y, 70 | v.z * ov.x - v.x * ov.z, 71 | v.x * ov.y - v.y * ov.x 72 | } 73 | } 74 | 75 | [inline] 76 | pub fn (a Vec3) -(b Vec3) Vec3 { 77 | return Vec3 { 78 | a.x - b.x, 79 | a.y - b.y, 80 | a.z - b.z 81 | } 82 | } 83 | 84 | [inline] 85 | pub fn mult(k f32, v Vec3) Vec3 { 86 | return Vec3 { 87 | k * v.x, 88 | k * v.y, 89 | k * v.z 90 | } 91 | } 92 | 93 | [inline] 94 | pub fn div(v Vec3, k f32) Vec3 { 95 | return Vec3 { 96 | v.x / k, 97 | v.y / k, 98 | v.z / k 99 | } 100 | } 101 | 102 | [inline] 103 | pub fn (v Vec3) reflect(n Vec3) Vec3 { 104 | return v - mult(2.0 * v.dot(n), n) 105 | } 106 | 107 | pub fn (v Vec3) refract(n Vec3, ni_over_nt f32, mut refracted Vec3) bool { 108 | uv := v.unit_vector() 109 | // println('refuv=$uv') 110 | // println('refn=$n') 111 | dt := uv.dot(n) 112 | discriminant := 1.0 - ni_over_nt * ni_over_nt * (1.0 - dt * dt) 113 | // ddn := vec.Vec3{dt, discriminant, ni_over_nt} 114 | // println('ddn=$ddn') 115 | if discriminant > 0 { 116 | unsafe{*refracted = mult(ni_over_nt, uv - mult(dt, n)) - mult(math.sqrtf(discriminant), n)} 117 | // println('refrac=${*refracted}') 118 | return true 119 | } else { 120 | return false 121 | } 122 | } 123 | 124 | [inline] 125 | pub fn (v Vec3) squared_length() f32 { 126 | return v.x * v.x + v.y * v.y + v.z * v.z 127 | } 128 | 129 | [inline] 130 | pub fn (v Vec3) length() f32 { 131 | // return math.sqrtf(v.x * v.x + v.y * v.y + v.z * v.z) 132 | return math.sqrtf(v.squared_length()) 133 | } 134 | 135 | [inline] 136 | pub fn (v Vec3) unit_vector() Vec3 { 137 | return div(v, v.length()) 138 | } 139 | 140 | [inline] 141 | pub fn (a Vec3) dot(b Vec3) f32 { 142 | return a.x * b.x + 143 | a.y * b.y + 144 | a.z * b.z 145 | /* 146 | print('DOT $a.x,$a.y,$a.z;$b.x,$b.y,$b.z') 147 | ret := a.x * b.x + 148 | a.y * b.y + 149 | a.z * b.z 150 | println(' => $ret') 151 | return ret 152 | */ 153 | } 154 | -------------------------------------------------------------------------------- /rtiow/V_old/Makefile: -------------------------------------------------------------------------------- 1 | SRC:=$(wildcard main*.v) 2 | EXE:=$(patsubst %.v,%.elf,$(SRC)) 3 | PPM:=$(patsubst %.v,%.ppm,$(SRC)) 4 | 5 | V:=v 6 | 7 | all: $(EXE) 8 | du -sh . 9 | 10 | check: $(PPM) 11 | md5sum *.ppm 12 | md5sum *.ppm | md5sum 13 | 14 | bench: main14.elf 15 | time ./main14.elf 1024 768 10 main14.ppm && md5sum main14.ppm 16 | 17 | #DEBUG:=1 18 | VFLAGS+=--enable-globals 19 | #VFLAGS+=-profile profile.txt 20 | ifdef DEBUG 21 | VFLAGS+=-d dbg 22 | else 23 | # OPT:=-O3 24 | # OPT:=-Ofast -fno-plt -flto -DNDEBUG 25 | OPT:=-O3 -fno-plt -flto -DNDEBUG 26 | endif 27 | 28 | #PROF:=1 29 | ifdef PROF 30 | OPT+=-pg 31 | endif 32 | 33 | %_v.c: %.v 34 | $(V) $(VFLAGS) -o $@ $^ 35 | 36 | %.elf: %_v.c 37 | $(CC) -o $@ $^ $(OPT) -lm 38 | 39 | %.ppm: %.elf 40 | ./$^ > $@ 41 | 42 | clean: 43 | $(RM) *_v.c *.elf *.ppm 44 | -------------------------------------------------------------------------------- /rtiow/V_old/main02.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn main() { 4 | nx := 200 5 | ny := 100 6 | println('P3') 7 | println('$nx $ny') 8 | println(255) 9 | for j := ny - 1; j >= 0; j-- { 10 | for i := 0; i < nx; i++ { 11 | r := f32(i) / f32(nx) 12 | g := f32(j) / f32(ny) 13 | b := 0.2 14 | ir := int(f32(255.99) * r) 15 | ig := int(f32(255.99) * g) 16 | ib := int(f32(255.99) * b) 17 | println('$ir $ig $ib') 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /rtiow/V_old/main03.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import vec 4 | 5 | fn main() { 6 | nx := 200 7 | ny := 100 8 | println('P3') 9 | println('$nx $ny') 10 | println(255) 11 | for j := ny - 1; j >= 0; j-- { 12 | for i := 0; i < nx; i++ { 13 | col := vec.Vec3{f32(i) / f32(nx), f32(j) / f32(ny), 0.2} 14 | ir := int(f32(255.99) * col.x) 15 | ig := int(f32(255.99) * col.y) 16 | ib := int(f32(255.99) * col.z) 17 | println('$ir $ig $ib') 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /rtiow/V_old/main04.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import vec 4 | import ray 5 | 6 | fn color(r ray.Ray) vec.Vec3 { 7 | // println('r=$r') 8 | unit_direction := r.direction().unit_vector() 9 | // println('ud=$unit_direction') 10 | t := .5 * (unit_direction.y + 1.0) 11 | // println('t=$t') 12 | return vec.mult(1.0 - t, vec.Vec3{1.0, 1.0, 1.0}) + vec.mult(t, vec.Vec3{.5, .7, 1}) 13 | } 14 | 15 | fn main() { 16 | nx := 200 17 | ny := 100 18 | println('P3') 19 | println('$nx $ny') 20 | println(255) 21 | lower_left_corner := vec.Vec3{-2, -1, -1} 22 | horizontal := vec.Vec3{4, 0, 0} 23 | vertical := vec.Vec3{0, 2, 0} 24 | origin := vec.Vec3{0, 0, 0} 25 | for j := ny - 1; j >= 0; j-- { 26 | for i := 0; i < nx; i++ { 27 | u := f32(i) / f32(nx) 28 | v := f32(j) / f32(ny) 29 | // println('u=$u v=$v') 30 | r := ray.Ray{origin, lower_left_corner + vec.mult(u, horizontal) + vec.mult(v, vertical)} 31 | col := color(r) 32 | // println('col=$col') 33 | ir := int(f32(255.99) * col.x) 34 | ig := int(f32(255.99) * col.y) 35 | ib := int(f32(255.99) * col.z) 36 | println('$ir $ig $ib') 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /rtiow/V_old/main05.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import vec 4 | import ray 5 | 6 | fn hit_sphere(center vec.Vec3, radius f32, r ray.Ray) bool { 7 | oc := r.origin() - center 8 | // println('oc=$oc') 9 | a := r.direction().dot(r.direction()) 10 | b := 2.0 * oc.dot(r.direction()) 11 | c := oc.dot(oc) - radius * radius 12 | discriminant := b * b - 4.0 * a * c 13 | // println('a=$a b=$b c=$c d=$discriminant') 14 | return discriminant > 0 15 | } 16 | 17 | fn color(r ray.Ray) vec.Vec3 { 18 | // next 2 lines to workaround buggy AST v2 compiler 19 | x := vec.Vec3{0, 0, -1} 20 | if hit_sphere(x, 0.5, r) { 21 | // if hit_sphere(vec.Vec3{0, 0, -1}, 0.5, r) { 22 | return vec.Vec3{1, 0, 0} 23 | } 24 | unit_direction := r.direction().unit_vector() 25 | t := .5 * (unit_direction.y + 1.0) 26 | return vec.mult(1.0 - t, vec.Vec3{1, 1, 1}) + vec.mult(t, vec.Vec3{.5, .7, 1}) 27 | } 28 | 29 | fn main() { 30 | nx := 200 31 | ny := 100 32 | println('P3') 33 | println('$nx $ny') 34 | println(255) 35 | lower_left_corner := vec.Vec3{-2, -1, -1} 36 | horizontal := vec.Vec3{4, 0, 0} 37 | vertical := vec.Vec3{0, 2, 0} 38 | origin := vec.Vec3{0, 0, 0} 39 | for j := ny - 1; j >= 0; j-- { 40 | for i := 0; i < nx; i++ { 41 | u := f32(i) / f32(nx) 42 | v := f32(j) / f32(ny) 43 | r := ray.Ray{origin, lower_left_corner + vec.mult(u, horizontal) + vec.mult(v, vertical)} 44 | col := color(r) 45 | ir := int(f32(255.99) * col.x) 46 | ig := int(f32(255.99) * col.y) 47 | ib := int(f32(255.99) * col.z) 48 | println('$ir $ig $ib') 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /rtiow/V_old/main06_1.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import vec 4 | import ray 5 | import math 6 | 7 | fn hit_sphere(center vec.Vec3, radius f32, r ray.Ray) f32 { 8 | oc := r.origin() - center 9 | a := r.direction().dot(r.direction()) 10 | b := 2.0 * oc.dot(r.direction()) 11 | c := oc.dot(oc) - radius * radius 12 | discriminant := b * b - 4.0 * a * c 13 | // println('a=$a b=$b c=$c d=$discriminant') 14 | if discriminant < 0 { 15 | return -1.0 16 | } else { 17 | return (-b - math.sqrtf(discriminant)) / (2.0 * a) 18 | } 19 | } 20 | 21 | fn color(r ray.Ray) vec.Vec3 { 22 | mut t := hit_sphere(vec.Vec3{0, 0, -1}, .5, r) 23 | if t > 0 { 24 | // println('t=$t') 25 | n := (r.point_at_parameter(t) - vec.Vec3{0, 0, -1}).unit_vector() 26 | return vec.mult(.5, n + vec.Vec3{1, 1, 1}) 27 | } 28 | unit_direction := r.direction().unit_vector() 29 | t = .5 * (unit_direction.y + 1.0) 30 | return vec.mult(1.0 - t, vec.Vec3{1, 1, 1}) + vec.mult(t, vec.Vec3{.5, .7, 1}) 31 | } 32 | 33 | fn main() { 34 | nx := 200 35 | ny := 100 36 | println('P3') 37 | println('$nx $ny') 38 | println(255) 39 | lower_left_corner := vec.Vec3{-2, -1, -1} 40 | horizontal := vec.Vec3{4, 0, 0} 41 | vertical := vec.Vec3{0, 2, 0} 42 | origin := vec.Vec3{0, 0, 0} 43 | for j := ny - 1; j >= 0; j-- { 44 | for i := 0; i < nx; i++ { 45 | u := f32(i) / f32(nx) 46 | v := f32(j) / f32(ny) 47 | r := ray.Ray{origin, lower_left_corner + vec.mult(u, horizontal) + vec.mult(v, vertical)} 48 | col := color(r) 49 | ir := int(f32(255.99) * col.x) 50 | ig := int(f32(255.99) * col.y) 51 | ib := int(f32(255.99) * col.z) 52 | println('$ir $ig $ib') 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /rtiow/V_old/main06_2.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import vec 4 | import ray 5 | import math 6 | 7 | enum HType { 8 | sphere 9 | } 10 | 11 | struct HSphere { 12 | center vec.Vec3 13 | radius f32 14 | } 15 | 16 | union HData { 17 | sphere HSphere 18 | } 19 | 20 | struct Hittable { 21 | htype HType 22 | data HData 23 | } 24 | 25 | struct HitRec { 26 | mut: 27 | t f32 // hit time 28 | p vec.Vec3 // hit point coords 29 | normal vec.Vec3 // normal at hit point 30 | } 31 | 32 | fn (s HSphere) hit(r ray.Ray, t_min f32, t_max f32, mut rec HitRec) bool { 33 | oc := r.origin() - s.center 34 | a := r.direction().dot(r.direction()) 35 | b := oc.dot(r.direction()) 36 | c := oc.dot(oc) - s.radius * s.radius 37 | discriminant := b * b - a * c 38 | if discriminant > 0 { 39 | mut temp := (-b - math.sqrtf(discriminant)) / a 40 | if temp < t_max && temp > t_min { 41 | rec.t = temp 42 | rec.p = r.point_at_parameter(rec.t) 43 | rec.normal = vec.div(rec.p - s.center, s.radius) 44 | return true 45 | } 46 | temp = (-b + math.sqrtf(discriminant)) / a 47 | if temp < t_max && temp > t_min { 48 | rec.t = temp 49 | rec.p = r.point_at_parameter(rec.t) 50 | rec.normal = vec.div(rec.p - s.center, s.radius) 51 | return true 52 | } 53 | } 54 | return false 55 | } 56 | 57 | fn (h Hittable) hit(r ray.Ray, t_min f32, t_max f32, mut rec HitRec) bool { 58 | if h.htype == .sphere { 59 | return h.data.sphere.hit(r, t_min, t_max, mut rec) 60 | } 61 | return false 62 | } 63 | 64 | fn (hh []Hittable) hit(r ray.Ray, t_min f32, t_max f32, mut rec HitRec) bool { 65 | mut hit_anything := false 66 | mut closest_so_far := t_max 67 | for h in hh { 68 | if h.hit(r, t_min, closest_so_far, mut rec) { 69 | hit_anything = true 70 | closest_so_far = rec.t 71 | // println('t=$temp_rec.t') 72 | } 73 | } 74 | return hit_anything 75 | } 76 | 77 | fn color(r ray.Ray) vec.Vec3 { 78 | mut rec := HitRec{} 79 | hittables := [ 80 | Hittable{ 81 | htype: .sphere 82 | data: HData{ 83 | sphere: HSphere{ 84 | center: vec.Vec3{0, 0, -1} 85 | radius: .5 86 | } 87 | } 88 | }, 89 | Hittable{ 90 | htype: .sphere 91 | data: HData{ 92 | sphere: HSphere{ 93 | center: vec.Vec3{0, -100.5, -1} 94 | radius: 100 95 | } 96 | } 97 | }, 98 | ] 99 | if hittables.hit(r, 0, 99999, mut rec) { 100 | // println('t=$rec.t') 101 | return vec.mult(0.5, rec.normal + vec.Vec3{1, 1, 1}) 102 | } else { 103 | unit_direction := r.direction().unit_vector() 104 | t := .5 * (unit_direction.y + 1.0) 105 | return vec.mult(1.0 - t, vec.Vec3{1, 1, 1}) + vec.mult(t, vec.Vec3{.5, .7, 1}) 106 | } 107 | } 108 | 109 | fn main() { 110 | nx := 200 111 | ny := 100 112 | println('P3') 113 | println('$nx $ny') 114 | println(255) 115 | lower_left_corner := vec.Vec3{-2, -1, -1} 116 | horizontal := vec.Vec3{4, 0, 0} 117 | vertical := vec.Vec3{0, 2, 0} 118 | origin := vec.Vec3{0, 0, 0} 119 | for j := ny - 1; j >= 0; j-- { 120 | for i := 0; i < nx; i++ { 121 | u := f32(i) / f32(nx) 122 | v := f32(j) / f32(ny) 123 | r := ray.Ray{origin, lower_left_corner + vec.mult(u, horizontal) + vec.mult(v, vertical)} 124 | col := color(r) 125 | ir := int(f32(255.99) * col.x) 126 | ig := int(f32(255.99) * col.y) 127 | ib := int(f32(255.99) * col.z) 128 | println('$ir $ig $ib') 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /rtiow/V_old/pcg/pcg.v: -------------------------------------------------------------------------------- 1 | module pcg 2 | 3 | struct PCG32Random { 4 | mut: 5 | state u64 6 | inc u64 7 | } 8 | 9 | __global ( 10 | rfcnt int 11 | riuscnt int 12 | riudcnt int 13 | seed PCG32Random 14 | ) 15 | 16 | pub const ( 17 | pcg_rand_max = 4294967295 18 | ) 19 | 20 | pub fn pcg_srand(val u32) { 21 | seed.state = val 22 | seed.inc = 0 23 | } 24 | 25 | pub fn pcg_rand() u32 { 26 | oldstate := seed.state 27 | seed.state = oldstate * u64(6364136223846793005) + (seed.inc | 1) 28 | xorshifted := u32(((oldstate >> 18) ^ oldstate) >> 27) 29 | rot := u32(oldstate >> 59) 30 | return (xorshifted >> rot) | (xorshifted << ((-rot) & 31)) 31 | } 32 | -------------------------------------------------------------------------------- /rtiow/V_old/ray/ray.v: -------------------------------------------------------------------------------- 1 | module ray 2 | 3 | import vec 4 | 5 | pub struct Ray { 6 | a vec.Vec3 7 | b vec.Vec3 8 | } 9 | 10 | pub fn (r Ray) str() string { 11 | return '{${r.a.str()}, ${r.b.str()}}' 12 | } 13 | 14 | [inline] 15 | pub fn (r Ray) origin() vec.Vec3 { 16 | return r.a 17 | } 18 | 19 | [inline] 20 | pub fn (r Ray) direction() vec.Vec3 { 21 | return r.b 22 | } 23 | 24 | [inline] 25 | pub fn (r Ray) point_at_parameter(t f32) vec.Vec3 { 26 | return r.a + vec.mult(t, r.b) 27 | } 28 | -------------------------------------------------------------------------------- /rtiow/V_old/vec/vec.v: -------------------------------------------------------------------------------- 1 | module vec 2 | 3 | import math 4 | 5 | //[typedef]pub type Scalar f32 6 | pub struct Vec3 { 7 | pub: 8 | // x Scalar y Scalar z Scalar 9 | x f32 y f32 z f32 10 | } 11 | 12 | union U0 { 13 | mut: 14 | v [3]f32 15 | i [3]u32 16 | } 17 | 18 | struct S0 { 19 | u U0 20 | } 21 | 22 | pub fn (a Vec3) str() string { 23 | // return '{$a.x, $a.y, $a.z}' 24 | mut u0 := U0{} 25 | u0.v[0] = a.x 26 | u0.v[1] = a.y 27 | u0.v[2] = a.z 28 | mut p1 := u0.i[0].hex() 29 | mut p2 := u0.i[1].hex() 30 | mut p3 := u0.i[2].hex() 31 | if u0.i[0] == 0 { 32 | p1 = '0' 33 | } 34 | if u0.i[1] == 0 { 35 | p2 = '0' 36 | } 37 | if u0.i[2] == 0 { 38 | p3 = '0' 39 | } 40 | return '{$a.x, $a.y, $a.z;$p1, $p2, $p3}' 41 | } 42 | 43 | [inline] 44 | pub fn (a Vec3) +(b Vec3) Vec3 { 45 | return Vec3 { 46 | a.x + b.x, 47 | a.y + b.y, 48 | a.z + b.z 49 | } 50 | } 51 | 52 | [inline] 53 | pub fn (a Vec3) *(b Vec3) Vec3 { 54 | return Vec3 { 55 | a.x * b.x, 56 | a.y * b.y, 57 | a.z * b.z 58 | } 59 | } 60 | 61 | [inline] 62 | pub fn (v Vec3) cross(ov Vec3) Vec3 { 63 | return Vec3 { 64 | v.y * ov.z - v.z * ov.y, 65 | v.z * ov.x - v.x * ov.z, 66 | v.x * ov.y - v.y * ov.x 67 | } 68 | } 69 | 70 | [inline] 71 | pub fn (a Vec3) -(b Vec3) Vec3 { 72 | return Vec3 { 73 | a.x - b.x, 74 | a.y - b.y, 75 | a.z - b.z 76 | } 77 | } 78 | 79 | [inline] 80 | pub fn mult(k f32, v Vec3) Vec3 { 81 | return Vec3 { 82 | k * v.x, 83 | k * v.y, 84 | k * v.z 85 | } 86 | } 87 | 88 | [inline] 89 | pub fn div(v Vec3, k f32) Vec3 { 90 | return Vec3 { 91 | v.x / k, 92 | v.y / k, 93 | v.z / k 94 | } 95 | } 96 | 97 | pub fn (v Vec3) reflect(n Vec3) Vec3 { 98 | return v - mult(2.0 * v.dot(n), n) 99 | } 100 | 101 | pub fn (v Vec3) refract(n Vec3, ni_over_nt f32, mut refracted Vec3) bool { 102 | uv := v.unit_vector() 103 | // println('refuv=$uv') 104 | // println('refn=$n') 105 | dt := uv.dot(n) 106 | discriminant := 1.0 - ni_over_nt * ni_over_nt * (1.0 - dt * dt) 107 | // ddn := vec.Vec3{dt, discriminant, ni_over_nt} 108 | // println('ddn=$ddn') 109 | if discriminant > 0 { 110 | unsafe{*refracted = mult(ni_over_nt, uv - mult(dt, n)) - mult(math.sqrtf(discriminant), n)} 111 | // println('refrac=${*refracted}') 112 | return true 113 | } else { 114 | return false 115 | } 116 | } 117 | 118 | [inline] 119 | pub fn (v Vec3) squared_length() f32 { 120 | return v.x * v.x + v.y * v.y + v.z * v.z 121 | } 122 | 123 | pub fn (v Vec3) length() f32 { 124 | // return math.sqrtf(v.x * v.x + v.y * v.y + v.z * v.z) 125 | return math.sqrtf(v.squared_length()) 126 | } 127 | 128 | pub fn (v Vec3) unit_vector() Vec3 { 129 | return div(v, v.length()) 130 | } 131 | 132 | [inline] 133 | pub fn (a Vec3) dot(b Vec3) f32 { 134 | return a.x * b.x + 135 | a.y * b.y + 136 | a.z * b.z 137 | /* 138 | print('DOT $a.x,$a.y,$a.z;$b.x,$b.y,$b.z') 139 | ret := a.x * b.x + 140 | a.y * b.y + 141 | a.z * b.z 142 | println(' => $ret') 143 | return ret 144 | */ 145 | } 146 | -------------------------------------------------------------------------------- /rtiow/Zig/Makefile: -------------------------------------------------------------------------------- 1 | SRC:=$(wildcard main*.zig) 2 | EXE:=$(patsubst %.zig,%.elf,$(SRC)) 3 | PPM:=$(patsubst %.zig,%.ppm,$(SRC)) 4 | 5 | ZIG=zig 6 | 7 | all: $(EXE) 8 | du -sh . 9 | 10 | check: $(PPM) 11 | md5sum *.ppm 12 | md5sum *.ppm | md5sum 13 | 14 | bench: main14.elf 15 | time ./main14.elf 1024 768 10 main14.ppm && md5sum main14.ppm 16 | 17 | #OPT=-O 18 | #OPT=-O0 -g 19 | #DEBUG:=1 20 | ifdef DEBUG 21 | OPT+=-DDEBUG 22 | endif 23 | 24 | #PROF:=1 25 | ifdef PROF 26 | OPT+=-pg 27 | endif 28 | 29 | %.elf: %.zig 30 | $(ZIG) build-exe --name $@ $^ $(OPT) 31 | 32 | %.ppm: %.elf 33 | ./$^ $(ARGS) > $@ 34 | 35 | clean: 36 | $(RM) *.elf *.elf.o *.ppm 37 | -------------------------------------------------------------------------------- /rtiow/Zig/main02.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn main() !void { 4 | const nx = 200; 5 | const ny = 100; 6 | const stdout = std.io.getStdOut().writer(); 7 | try stdout.print("P3\n", .{}); 8 | try stdout.print("{} {}\n", .{ nx, ny }); 9 | try stdout.print("{}\n", .{255}); 10 | var j: i32 = ny - 1; 11 | while (j >= 0) { 12 | var i: i32 = 0; 13 | while (i < nx) { 14 | var r: f32 = @intToFloat(f32, i) / nx; 15 | var g: f32 = @intToFloat(f32, j) / ny; 16 | var b: f32 = 0.2; 17 | var ir: i32 = @floatToInt(i32, 255.99 * r); 18 | var ig: i32 = @floatToInt(i32, 255.99 * g); 19 | var ib: i32 = @floatToInt(i32, 255.99 * b); 20 | // printf("%d %d %d\n", ir, ig, ib); 21 | try stdout.print("{} {} {}\n", .{ ir, ig, ib }); 22 | i += 1; 23 | } 24 | j -= 1; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /rtiow/rttnw/CPP/Makefile: -------------------------------------------------------------------------------- 1 | 2 | all: 3 | 4 | mrproper: 5 | $(RM) *.ppm 6 | -------------------------------------------------------------------------------- /rtiow/rttnw/CPP/camera.h: -------------------------------------------------------------------------------- 1 | #ifndef CAMERAH 2 | #define CAMERAH 3 | 4 | #include "random.h" 5 | #include "ray.h" 6 | 7 | vec3 random_in_unit_disk() { 8 | vec3 p; 9 | do { 10 | p = 2.0*vec3(random_double(),random_double(),0) - vec3(1,1,0); 11 | } while (dot(p,p) >= 1.0); 12 | return p; 13 | } 14 | 15 | class camera { 16 | public: 17 | camera(vec3 lookfrom, vec3 lookat, vec3 vup, 18 | float vfov /* vfov is top to bottom in degrees */, 19 | float aspect, float aperture, float focus_dist, 20 | float t0, float t1) { 21 | 22 | time0 = t0; 23 | time1 = t1; 24 | lens_radius = aperture / 2; 25 | float theta = vfov*M_PI/180; 26 | float half_height = tanf(theta/2); 27 | float half_width = aspect * half_height; 28 | origin = lookfrom; 29 | w = unit_vector(lookfrom - lookat); 30 | u = unit_vector(cross(vup, w)); 31 | v = cross(w, u); 32 | lower_left_corner = origin 33 | - half_width*focus_dist*u 34 | - half_height*focus_dist*v 35 | - focus_dist*w; 36 | horizontal = 2*half_width*focus_dist*u; 37 | vertical = 2*half_height*focus_dist*v; 38 | } 39 | 40 | ray get_ray(float s, float t) { 41 | vec3 rd = lens_radius*random_in_unit_disk(); 42 | vec3 offset = u * rd.x() + v * rd.y(); 43 | float time = time0 + random_double()*(time1-time0); 44 | return ray( 45 | origin + offset, 46 | lower_left_corner + s*horizontal + t*vertical - origin - offset, 47 | time); 48 | } 49 | 50 | vec3 origin; 51 | vec3 lower_left_corner; 52 | vec3 horizontal; 53 | vec3 vertical; 54 | vec3 u, v, w; 55 | float time0, time1; 56 | float lens_radius; 57 | }; 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /rtiow/rttnw/CPP/earthmap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsauzede/realist/c1a62019d55c3f7abed7f7c3f06ae3b2778cf47f/rtiow/rttnw/CPP/earthmap.jpg -------------------------------------------------------------------------------- /rtiow/rttnw/CPP/hittable_list.h: -------------------------------------------------------------------------------- 1 | #ifndef HITTABLELISTH 2 | #define HITTABLELISTH 3 | 4 | #include "hittable.h" 5 | 6 | class hittable_list: public hittable { 7 | public: 8 | hittable_list() {} 9 | hittable_list(hittable **l, int n) {list = l; list_size = n; } 10 | virtual bool hit( 11 | const ray& r, float tmin, float tmax, hit_record& rec) const; 12 | virtual bool bounding_box(float t0, float t1, aabb& box) const; 13 | hittable **list; 14 | int list_size; 15 | }; 16 | 17 | bool hittable_list::hit( 18 | const ray& r, float t_min, float t_max, hit_record& rec) const { 19 | 20 | hit_record temp_rec; 21 | bool hit_anything = false; 22 | double closest_so_far = t_max; 23 | for (int i = 0; i < list_size; i++) { 24 | if (list[i]->hit(r, t_min, closest_so_far, temp_rec)) { 25 | hit_anything = true; 26 | closest_so_far = temp_rec.t; 27 | rec = temp_rec; 28 | } 29 | } 30 | return hit_anything; 31 | } 32 | 33 | bool hittable_list::bounding_box(float t0, float t1, aabb& box) const { 34 | if (list_size < 1) return false; 35 | aabb temp_box; 36 | bool first_true = list[0]->bounding_box(t0, t1, temp_box); 37 | if (!first_true) 38 | return false; 39 | else 40 | box = temp_box; 41 | for (int i = 1; i < list_size; i++) { 42 | if(list[i]->bounding_box(t0, t1, temp_box)) { 43 | box = surrounding_box(box, temp_box); 44 | } 45 | else 46 | return false; 47 | } 48 | return true; 49 | } 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /rtiow/rttnw/CPP/random.h: -------------------------------------------------------------------------------- 1 | #ifndef RANDOMH 2 | #define RANDOMH 3 | 4 | #include 5 | 6 | #include "vec3.h" 7 | 8 | inline double random_double() { 9 | return rand() / (RAND_MAX + 1.0); 10 | } 11 | vec3 random_in_unit_sphere() { 12 | vec3 p; 13 | do { 14 | p = 2.0*vec3(random_double(), random_double(), random_double()) - vec3(1,1,1); 15 | } while (p.squared_length() >= 1.0); 16 | return p; 17 | } 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /rtiow/rttnw/CPP/ray.h: -------------------------------------------------------------------------------- 1 | #ifndef RAYH 2 | #define RAYH 3 | #include "vec3.h" 4 | 5 | class ray 6 | { 7 | public: 8 | ray() {} 9 | ray(const vec3& a, const vec3& b, float ti = 0.0) { A = a; B = b; _time = ti;} 10 | vec3 origin() const { return A; } 11 | vec3 direction() const { return B; } 12 | float time() const { return _time; } 13 | vec3 point_at_parameter(float t) const { return A + t * B; } 14 | 15 | vec3 A; 16 | vec3 B; 17 | float _time; 18 | }; 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /rtiow/rttroyl/main02_1.py: -------------------------------------------------------------------------------- 1 | import math 2 | import random 3 | def random_double():return random.random()*2-1 4 | 5 | N=1000 6 | inside=0 7 | for i in range(N): 8 | x=random_double() 9 | y=random_double() 10 | if x*x+y*y<1:inside+=1 11 | print(f'Estimate of Pi = {4*inside/N:.10f}') 12 | -------------------------------------------------------------------------------- /rtiow/rttroyl/main02_2.py: -------------------------------------------------------------------------------- 1 | import math 2 | import random 3 | def random_double():return random.random()*2-1 4 | 5 | runs=0 6 | inside=0 7 | while True: 8 | runs+=1 9 | x=random_double() 10 | y=random_double() 11 | if x*x+y*y<1:inside+=1 12 | print(f'run {runs}: Estimate of Pi = {4*inside/runs:.10f}') 13 | -------------------------------------------------------------------------------- /rtiow/rttroyl/main02_3.py: -------------------------------------------------------------------------------- 1 | import math 2 | import random 3 | def random_double(a=0,b=1): 4 | return (b-a)*random.random()+a 5 | 6 | sqrt_N=10000 7 | inside=0 8 | inside_strat=0 9 | for i in range(sqrt_N): 10 | for j in range(sqrt_N): 11 | x=random_double(-1,1) 12 | y=random_double(-1,1) 13 | if x*x+y*y<1:inside+=1 14 | x=2*((i+random_double()) / sqrt_N)-1 15 | y=2*((j+random_double()) / sqrt_N)-1 16 | if x*x+y*y<1:inside_strat+=1 17 | print(f'Regular Estimate of Pi = {4*inside/sqrt_N/sqrt_N:.12f}') 18 | print(f'Stratified Estimate of Pi = {4*inside_strat/sqrt_N/sqrt_N:.12f}') 19 | -------------------------------------------------------------------------------- /rtiow/rttroyl/random.h: -------------------------------------------------------------------------------- 1 | #ifndef RANDOMH 2 | #define RANDOMH 3 | 4 | #include 5 | 6 | #include "vec3.h" 7 | 8 | inline double random_double() { 9 | return rand() / (RAND_MAX + 1.0); 10 | } 11 | inline double random_double(double min, double max) { 12 | // Returns a random real in [min,max). 13 | return min + (max-min)*random_double(); 14 | } 15 | 16 | vec3 random_in_unit_sphere() { 17 | vec3 p; 18 | do { 19 | p = 2.0*vec3(random_double(), random_double(), random_double()) - vec3(1,1,1); 20 | } while (p.squared_length() >= 1.0); 21 | return p; 22 | } 23 | 24 | vec3 random_on_unit_sphere() { 25 | vec3 p; 26 | do { 27 | p = 2.0*vec3(random_double(),random_double(),random_double()) - vec3(1,1,1); 28 | } while (dot(p,p) >= 1.0); 29 | return unit_vector(p); 30 | } 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /rtiow/rttroyl/rttroyl2.cpp: -------------------------------------------------------------------------------- 1 | #include "random.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int main0() { 9 | int N = 1000; 10 | int inside_circle = 0; 11 | for (int i = 0; i < N; i++) { 12 | float x = 2*random_double() - 1; 13 | float y = 2*random_double() - 1; 14 | if(x*x + y*y < 1) 15 | inside_circle++; 16 | } 17 | std::cout << "Estimate of Pi = " << 4*float(inside_circle) / N << "\n"; 18 | return 0; 19 | } 20 | 21 | int main1() { 22 | long inside_circle = 0; 23 | long runs = 0; 24 | while (true) { 25 | runs++; 26 | float x = 2*random_double() - 1; 27 | float y = 2*random_double() - 1; 28 | if(x*x + y*y < 1) 29 | inside_circle++; 30 | 31 | if(runs% 100000 == 0) 32 | std::cout << "Estimate of Pi = " << 4*float(inside_circle) / runs << "\n"; 33 | 34 | } 35 | return 0; 36 | } 37 | 38 | int main() { 39 | int inside_circle = 0; 40 | int inside_circle_stratified = 0; 41 | int sqrt_N = 10000; 42 | for (int i = 0; i < sqrt_N; i++) { 43 | for (int j = 0; j < sqrt_N; j++) { 44 | double x = random_double(-1,1); 45 | double y = random_double(-1,1); 46 | if (x*x + y*y < 1) 47 | inside_circle++; 48 | x = 2*((i + random_double()) / sqrt_N) - 1; 49 | y = 2*((j + random_double()) / sqrt_N) - 1; 50 | if (x*x + y*y < 1) 51 | inside_circle_stratified++; 52 | } 53 | } 54 | std::cout << std::fixed << std::setprecision(12); 55 | std::cout << "Regular Estimate of Pi = " << 56 | 4*double(inside_circle) / (sqrt_N*sqrt_N) << "\n"; 57 | std::cout << "Stratified Estimate of Pi = " << 58 | 4*double(inside_circle_stratified) / (sqrt_N*sqrt_N) << "\n"; 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /rtiow/rttroyl/rttroyl3.cpp: -------------------------------------------------------------------------------- 1 | #include "random.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int main0() { 8 | int N = 1000000; 9 | float sum; 10 | for (int i = 0; i < N; i++) { 11 | float x = 2*random_double(); 12 | sum += x*x; 13 | } 14 | std::cout << "I =" << 2*sum/N << "\n"; 15 | } 16 | 17 | inline float pdf0(float x) { 18 | return 0.5*x; 19 | } 20 | 21 | int main1() { 22 | int N = 1000000; 23 | float sum; 24 | for (int i = 0; i < N; i++) { 25 | float x = sqrt(4*random_double()); 26 | sum += x*x / pdf0(x); 27 | } 28 | std::cout << "I =" << sum/N << "\n"; 29 | } 30 | 31 | int main2() { 32 | int N = 1000000; 33 | float sum; 34 | for (int i = 0; i < N; i++) { 35 | float x = 2*random_double(); 36 | sum += x*x / pdf0(x); 37 | } 38 | std::cout << "I =" << sum/N << "\n"; 39 | } 40 | 41 | inline float pdf(float x) { 42 | return 3*x*x/8; 43 | } 44 | 45 | int main() { 46 | int N = 1; 47 | float sum; 48 | for (int i = 0; i < N; i++) { 49 | float x = pow(8*random_double(), 1./3.); 50 | sum += x*x / pdf(x); 51 | } 52 | std::cout << "I =" << sum/N << "\n"; 53 | } 54 | -------------------------------------------------------------------------------- /rtiow/rttroyl/rttroyl4.cpp: -------------------------------------------------------------------------------- 1 | #include "random.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | inline float pdf(const vec3& p) { 8 | return 1 / (4*M_PI); 9 | } 10 | 11 | int main() { 12 | int N = 1000000; 13 | float sum; 14 | for (int i = 0; i < N; i++) { 15 | vec3 d = random_on_unit_sphere(); 16 | float cosine_squared = d.z()*d.z(); 17 | sum += cosine_squared / pdf(d); 18 | } 19 | std::cout << "I =" << sum/N << "\n"; 20 | printf("PI=%.20f\n", M_PI); 21 | } 22 | -------------------------------------------------------------------------------- /rttnw11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsauzede/realist/c1a62019d55c3f7abed7f7c3f06ae3b2778cf47f/rttnw11.png -------------------------------------------------------------------------------- /sdl.mak: -------------------------------------------------------------------------------- 1 | 2 | ifndef SDLCONFIG 3 | 4 | SDL1CONFIG=sdl-config 5 | ifneq ($(shell a=`which $(SDL1CONFIG) 2>&1`;echo $$?),0) 6 | SDL1CONFIG= 7 | endif 8 | 9 | SDL2CONFIG=sdl2-config 10 | ifneq ($(shell a=`which $(SDL2CONFIG) 2>&1`;echo $$?),0) 11 | SDL2CONFIG= 12 | endif 13 | 14 | ifdef SDL2CONFIG 15 | SDLCONFIG=$(SDL2CONFIG) 16 | else 17 | ifdef SDL1CONFIG 18 | SDLCONFIG=$(SDL1CONFIG) 19 | endif 20 | endif 21 | 22 | ifndef SDLCONFIG 23 | SDLCONFIG=NO_SDL_INSTALLED 24 | SDL_CHECK: 25 | @echo "No SDL installed.\nTry : $$ sudo apt-get install libsdl2-dev";false 26 | else 27 | SDL_CHECK: 28 | @echo "Using detected SDLCONFIG=$(SDLCONFIG)" 29 | endif 30 | 31 | else 32 | 33 | SDL_CHECK: 34 | @echo "Using forced SDLCONFIG=$(SDLCONFIG)" 35 | 36 | endif 37 | 38 | ifdef SDLCONFIG 39 | SDL_FLAGS+=$(shell $(SDLCONFIG) --cflags) 40 | endif 41 | 42 | OP_SYS=$(shell uname -o) 43 | ifeq ($(OP_SYS),Msys) 44 | WINDOWS=1 45 | endif 46 | 47 | ifdef WINDOWS 48 | SDL_STATIC=1 49 | endif 50 | 51 | SDL_VER=$(shell $(SDLCONFIG) --version | cut -f 1 -d ".") 52 | ifeq ($(SDL_VER),1) 53 | USE_SDL1=1 54 | else 55 | USE_SDL1= 56 | endif 57 | 58 | ifdef SDL_STATIC 59 | SDL_LIBS+=$(shell $(SDLCONFIG) --static-libs) -static 60 | else 61 | SDL_LIBS+=$(shell $(SDLCONFIG) --libs) 62 | endif 63 | ifdef WINDOWS 64 | # this one to get text console output 65 | SDL_LIBS+=-mno-windows 66 | endif 67 | -------------------------------------------------------------------------------- /sph.pov: -------------------------------------------------------------------------------- 1 | //EXAMPLE OF SPHERE 2 | 3 | //Files with predefined colors and textures 4 | #include "colors.inc" 5 | #include "glass.inc" 6 | #include "golds.inc" 7 | #include "metals.inc" 8 | #include "stones.inc" 9 | #include "woods.inc" 10 | 11 | //Place the camera 12 | camera { 13 | sky <0,0,1> //Don't change this 14 | direction <-1,0,0> //Don't change this 15 | right <-4/3,0,0> //Don't change this 16 | location <30,10,1.5> //Camera location 17 | look_at <0,0,0> //Where camera is pointing 18 | angle 15 //Angle of the view--increase to see more, decrease to see less 19 | } 20 | 21 | //Ambient light to "brighten up" darker pictures 22 | global_settings { ambient_light White } 23 | 24 | //Place a light--you can have more than one! 25 | light_source { 26 | <10,-10,20> //Change this if you want to put the light at a different point 27 | color White*2 //Multiplying by 2 doubles the brightness 28 | } 29 | 30 | //Set a background color 31 | background { color White } 32 | 33 | //Create a "floor" 34 | plane { 35 | <0,0,1>, 0 //This represents the plane 0x+0y+z=0 36 | texture { T_Silver_3A } //The texture comes from the file "metals.inc" 37 | } 38 | 39 | //Sphere with specified center point and radius 40 | //The texture comes from the file "stones.inc" 41 | sphere { <0,0,1.5>, 1 texture {T_Stone1} } 42 | 43 | -------------------------------------------------------------------------------- /sph.real: -------------------------------------------------------------------------------- 1 | 30.0 10.0 1.5 2 | -30.0 -10 -1.5 3 | 0.0 0.0 1.0 4 | 5 | 0.0 0.0 1.5 6 | 1.0 7 | 1.0 0.0 0.0 8 | 0 0 0 0 0 0 9 | 10 | 10 -10 20 11 | 1 12 | 1 1 1 13 | 0 0 0 0 0 0 14 | -------------------------------------------------------------------------------- /sphs.real: -------------------------------------------------------------------------------- 1 | -15.0 +11.0 -12 2 | 19.0 -7.468027 14.309401 3 | 0.0 0.5 0.0 4 | 5 | 0.0 1.0 0.0 1.0 1.0 0.0 0.0 0 0 0 0 0 0 6 | 2.0 1.0 0.0 1.0 1.0 0.0 0.0 0 0 0 0 0 0 7 | 1.0 1.0 1.732051 1.0 1.0 0.0 0.0 0 0 0 0 0 0 8 | 4.0 1.0 0.0 1.0 1.0 0.0 0.0 0 0 0 0 0 0 9 | 3.0 1.0 1.732051 1.0 1.0 0.0 0.0 0 0 0 0 0 0 10 | 2.000000 1.000000 3.464102 1.0 1.0 0.0 0.0 0 0 0 0 0 0 11 | 6.000000 1.000000 0.000000 1.0 1.0 0.0 0.0 0 0 0 0 0 0 12 | 5.000000 1.000000 1.732051 1.0 1.0 0.0 0.0 0 0 0 0 0 0 13 | 4.000000 1.000000 3.464102 1.0 1.0 0.0 0.0 0 0 0 0 0 0 14 | 3.000000 1.000000 5.196152 1.0 1.0 0.0 0.0 0 0 0 0 0 0 15 | 8.000000 1.000000 0.000000 1.0 1.0 0.0 0.0 0 0 0 0 0 0 16 | 7.000000 1.000000 1.732051 1.0 1.0 0.0 0.0 0 0 0 0 0 0 17 | 6.000000 1.000000 3.464102 1.0 1.0 0.0 0.0 0 0 0 0 0 0 18 | 5.000000 1.000000 5.196152 1.0 1.0 0.0 0.0 0 0 0 0 0 0 19 | 4.000000 1.000000 6.928203 1.0 1.0 0.0 0.0 0 0 0 0 0 0 20 | -------------------------------------------------------------------------------- /spyr.json: -------------------------------------------------------------------------------- 1 | # initial #objects: 0 2 | { 3 | 'screen': { 'w':100, 'h':80, 'ratiox':1, 'ratioy':1 }, 4 | 'camera': { 'loc':[0.4, 0, 0.4], 'front':[-1, 0, -1], 'up':[-0.707107, 0, 0.707107]}, 5 | 'objects': [ 6 | {'type':'sphere', 'data': [0, -0.1, 0, 0.05, 0.8, 0.8, 0.8]}, 7 | {'type':'sphere', 'data': [0, 0, 0, 0.05, 0.8, 0.8, 0.8]}, 8 | {'type':'sphere', 'data': [0, 0.1, 0, 0.05, 0.8, 0.8, 0.8]}, 9 | {'type':'sphere', 'data': [0.1, -0.05, 0, 0.05, 0.8, 0, 0]}, 10 | {'type':'sphere', 'data': [0.1, 0.05, 0, 0.05, 0, 0, 0.8]}, 11 | {'type':'sphere', 'data': [0.2, 0, 0, 0.05, 0, 0.8, 0]}, 12 | {'type':'sphere', 'data': [0.05, -0.05, 0.1, 0.05, 0.8, 0.8, 0.8]}, 13 | {'type':'sphere', 'data': [0.05, 0.05, 0.1, 0.05, 0.8, 0.8, 0.8]}, 14 | {'type':'sphere', 'data': [0, -0.5, 0.5, 0.02, 1, 1, 0]} 15 | ] 16 | } 17 | #e={0.400000,0.000000,0.400000} 18 | #f={-1.000000,0.000000,-1.000000} 19 | #u={-0.707107,0.000000,0.707107} 20 | #r={0.000000,1.000000,0.000000} 21 | 22 | # using OPT 23 | # ww=1.000000 hh=0.750000 24 | # found 10 objects 25 | -------------------------------------------------------------------------------- /spyr.real: -------------------------------------------------------------------------------- 1 | 0.4 0 0.4 2 | -1 0 -1 3 | -0.707107 0 0.707107 4 | 5 | 0 8 6 | 0 7 | 0.8 0.8 0.8 8 | 0 -0.1 0 9 | 0.05 10 | 11 | 12 | 0 8 13 | 0 14 | 0.8 0.8 0.8 15 | 0 0 0 16 | 0.05 17 | 18 | 19 | 0 8 20 | 0 21 | 0.8 0.8 0.8 22 | 0 0.1 0 23 | 0.05 24 | 25 | 26 | 0 8 27 | 1 28 | 0.8 0 0 29 | 0.1 -0.05 0 30 | 0.05 31 | 32 | 33 | 0 8 34 | 0 35 | 0 0 0.8 36 | 0.1 0.05 0 37 | 0.05 38 | 39 | 40 | 0 8 41 | 0 42 | 0 0.8 0 43 | 0.2 0 0 44 | 0.05 45 | 46 | 47 | 0 8 48 | 0 49 | 0.8 0.8 0.8 50 | 0.05 -0.05 0.1 51 | 0.05 52 | 53 | 54 | 0 8 55 | 0 56 | 0.8 0.8 0.8 57 | 0.05 0.05 0.1 58 | 0.05 59 | -------------------------------------------------------------------------------- /vec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016-2019 Nicolas Sauzede (nsauzede@laposte.net) 3 | * SPDX-License-Identifier: GPL-3.0-or-later 4 | */ 5 | #include 6 | 7 | int solvetri( const double a, const double b, const double c, double *t1, double *t2) { 8 | int result; 9 | double d = b * b - 4 * a * c; 10 | if (d > 0) { 11 | double sd = sqrt( d); 12 | *t1 = (-b - sd) / 2 / a; 13 | *t2 = (-b + sd) / 2 / a; 14 | result = 2; 15 | } 16 | else if (d == 0) { 17 | *t1 = -b / 2 / a; 18 | result = 1; 19 | } 20 | else { 21 | result = 0; 22 | } 23 | return result; 24 | } 25 | -------------------------------------------------------------------------------- /vecc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2016-2019 Nicolas Sauzede (nsauzede@laposte.net) 3 | * SPDX-License-Identifier: GPL-3.0-or-later 4 | */ 5 | #include 6 | #include 7 | 8 | typedef double v3[3]; 9 | 10 | void vcross( v3 l, const v3 r1, const v3 r2) { 11 | l[0] = r1[1] * r2[2] - r1[2] * r2[1]; 12 | l[1] = r1[2] * r2[0] - r1[0] * r2[2]; 13 | l[2] = r1[0] * r2[1] - r1[1] * r2[0]; 14 | } 15 | 16 | void vadd( v3 l, const v3 r1, const v3 r2) { 17 | l[0] = r1[0] + r2[0]; 18 | l[1] = r1[1] + r2[1]; 19 | l[2] = r1[2] + r2[2]; 20 | } 21 | 22 | void vsub( v3 l, const v3 r1, const v3 r2) { 23 | l[0] = r1[0] - r2[0]; 24 | l[1] = r1[1] - r2[1]; 25 | l[2] = r1[2] - r2[2]; 26 | } 27 | 28 | void vcopy( v3 l, const double *r) { 29 | l[0] = r[0]; 30 | l[1] = r[1]; 31 | l[2] = r[2]; 32 | } 33 | 34 | void vset( v3 l, const double r1, const double r2, const double r3) { 35 | l[0] = r1; 36 | l[1] = r2; 37 | l[2] = r3; 38 | } 39 | 40 | void vmult( v3 l, const v3 r1, const double r2) { 41 | l[0] = r1[0] * r2; 42 | l[1] = r1[1] * r2; 43 | l[2] = r1[2] * r2; 44 | } 45 | 46 | double vdot( const v3 v1, const v3 v2) { 47 | return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; 48 | } 49 | 50 | void vnormalize( v3 l) { 51 | double norm; 52 | norm = sqrt( vdot( l, l)); 53 | l[0] /= norm; 54 | l[1] /= norm; 55 | l[2] /= norm; 56 | } 57 | 58 | //inline void vprint( const v3 v) { 59 | // printf( "%f,%f,%f\n", v[0], v[1], v[2]); 60 | //} 61 | 62 | inline void vprintn( const char *t, const v3 v) { 63 | printf( "%s={%f,%f,%f}\n", t, v[0], v[1], v[2]); 64 | } 65 | --------------------------------------------------------------------------------