forked from pritzza/Rodent-Raytracer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Design.txt
190 lines (136 loc) · 3.76 KB
/
Design.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
So I'd like to make a simple ray tracer with these features:
- CPU
- "Interactive"
- Controllable Camera
- Sphere & Triangle intersections
- Emissive Materials / Area Lights
- Shadows
- Can easily plug in different diffuse models
- Light scattering
- Anti-Aliasing
- Specular highlights
- Refraction
- Metal & NonMetal materials
(for the next ray tracer):
- Accelerated spacial structures
- GPU/CUDA/RTX
- Realtime
Renderer
render()
traceRay()
checkRayIntersection()
Scene
geometry[]
Geometry
position ]
scale | transform matrix to transform primitives to world space
rotation ]
primatives[]
bounding box
Primitive
material
virtual getNormal()
Box : Primitive
bottom corner
top corner
Sphere : Primitive
scale ]
position ] transform matrix to transform unit sphere to local space
Triangle : Primitive
vertices[3]
Material
color
rougness // controls solid angle of reflection andis used in brdf
emissonColor
emissionStrength
abstract redirect(direction, normal) => Direction
abstract reflectionCoeff() => vec3
Metal : Material
base reflectivity // for Schlick(rgb)
redirect()
reflect
reflectionCoeff()
return base reflectivity
Dielectric : Material
opacity // controls probability of ray being reflected vs refracted
index of refraction // uses Schlick(ior1, ior2) (ideally)
redirect()
if rng < opacity // use opacity as probability of light refracting
refract
else
reflect
reflectionCoeff()
return Schlick(ior) // actually dont know how to implement use of an ior2
Ray Intersection
ray*
t
intersection position
surface normal
Math
raySphereIntersection(Ray, Sphere) => Ray Intersection
rayIntersection(Ray, Sphere) => Ray Intersection
Intersection
ray intersection*
material*
bool transmissive // rays that transmitted don't reflect light for us to see
Camera
pos ]
rotation ] view matrix
up-dir
forward-dir
fov
Window
buffer
Image
width
height
pixels[]
render(Camera, Scene, Image) // renders scene to Image
for pixels in Image
for rays per pixel
calculate ray position and direction
send it out // traceRay()
average colors
// cast ray out into scene, see where it goes, and determin color off that
traceRay(Ray, Scene) => Color
hits[]
for maxNumBounces
check for intersection // checkRayIntersection
if ray hit
append hit to hits
position ray at intersection
redirect based off material // reflect or refract
else
break
return evaluateLightPath from hits
// evaluates a path that light that did (or didnt) make it to the eye
evaluateLightPath(hits[]) => Color
incoming light = black (0)
if reached environment // if ray bounced off a surface and never hit anything after
incoming light += environment light
// start from last hit (whether there is any light there or not)
// forward trace light ray, computing how light reflects and accumulates
// off it bounces off each surface until making its way to eye
reverse iterating hits
if hit wasn't refractive
incoming light += emitted light + incoming light * BRDF * cos(theta)
return incoming light
BRDF(view dir, light dir, normal, material) => Color
R0 = get reflectivity from material
Ks = SchlickApprox(R0)
diffuse = Lambert()
specular = CookTorrance()
// normal distribution function = GGX/Trowbridge-Reitz
// geometry shading function = Schlick-GGX (uses Smith model's G and Schlick-Beckmann G1)
return Kd * diffuse + Ks * specular
checkRayIntersection(Ray, Scene) => Ray Intersection
intersection = null
for objects in geometry
for primitive in object
transform primitive into world space
if sphere
test = do ray-sphere intersection test
if triangle
test = do ray-triangle intersection test
if test result is valid and closer than intersection
intersection = test