├── 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 | 
7 |
8 | 
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 | Canvas |
36 | Zoomed |
37 | Hovered color |
38 | Selected color |
39 |
40 |
41 |
42 |
43 |
44 |
45 | |
46 |
47 |
48 | |
49 | |
50 | |
51 |
52 |
53 |
54 |
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 |
--------------------------------------------------------------------------------