@@ -13,24 +13,7 @@ export Camera, Dielectric, Hittable, HittableList, HitRecord, Lambertian, Materi
13
13
export scene_2_spheres, scene_4_spheres, scene_blue_red_spheres, scene_diel_spheres, scene_random_spheres
14
14
export TRNG
15
15
16
- const Vec3{T<: AbstractFloat } = SVector{3 , T}
17
-
18
- # Adapted from @Christ_Foster's: https://discourse.julialang.org/t/ray-tracing-in-a-week-end-julia-vs-simd-optimized-c/72958/40
19
- @inline @inbounds function Base. getproperty (v:: SVector{3} , name:: Symbol )
20
- name === :x || name === :r ? getfield (v, :data )[1 ] :
21
- name === :y || name === :g ? getfield (v, :data )[2 ] :
22
- name === :z || name === :b ? getfield (v, :data )[3 ] : getfield (v, name)
23
- end
24
-
25
- @inline @inbounds function Base. getproperty (v:: SVector{2} , name:: Symbol )
26
- name === :x || name === :r ? getfield (v, :data )[1 ] :
27
- name === :y || name === :g ? getfield (v, :data )[2 ] : getfield (v, name)
28
- end
29
-
30
- @inline squared_length (v:: Vec3 ) = v ⋅ v
31
- @inline near_zero (v:: Vec3 ) = squared_length (v) < 1e-5
32
- @inline rgb (v:: Vec3 ) = RGB (v... )
33
- @inline rgb_gamma2 (v:: Vec3 ) = RGB (sqrt .(v)... )
16
+ include (" vec.jl" )
34
17
35
18
struct Ray{T}
36
19
origin:: Vec3{T} # Point
@@ -105,33 +88,11 @@ struct Scatter{T<: AbstractFloat}
105
88
@inline Scatter (r:: Ray{T} ,a:: Vec3{T} ,reflected= true ) where T = new {T} (r,a,reflected)
106
89
end
107
90
108
- struct Lambertian{T} <: Material{T}
109
- albedo:: Vec3{T}
110
- end
111
-
112
91
""" Compute reflection vector for v (pointing to surface) and normal n⃗.
113
92
114
93
See [diagram](https://raytracing.github.io/books/RayTracingInOneWeekend.html#metal/mirroredlightreflection)"""
115
94
@inline @fastmath reflect (v:: Vec3{T} , n⃗:: Vec3{T} ) where T = v - (2 v⋅ n⃗)* n⃗
116
95
117
- """ Create a scattered ray emitted by `mat` from incident Ray `r`.
118
-
119
- Args:
120
- rec: the HitRecord of the surface from which to scatter the ray.
121
-
122
- Return `nothing`` if it's fully absorbed. """
123
- @inline @fastmath function scatter (mat:: Lambertian{T} , r:: Ray{T} , rec:: HitRecord{T} ):: Scatter{T} where T
124
- scatter_dir = rec. n⃗ + random_vec3_on_sphere (T)
125
- if near_zero (scatter_dir) # Catch degenerate scatter direction
126
- scatter_dir = rec. n⃗
127
- else
128
- scatter_dir = normalize (scatter_dir)
129
- end
130
- scattered_r = Ray {T} (rec. p, scatter_dir)
131
- attenuation = mat. albedo
132
- return Scatter (scattered_r, attenuation)
133
- end
134
-
135
96
@inline @fastmath function hit (s:: Sphere{T} , r:: Ray{T} , tmin:: T , tmax:: T ):: Union{HitRecord,Nothing} where T
136
97
oc = r. origin - s. center
137
98
# a = r.dir ⋅ r.dir # unnecessary since `r.dir` is normalized
176
137
177
138
@inline color_vec3_in_rgb (v:: Vec3{T} ) where T = 0.5 normalize (v) + SA{T}[0.5 ,0.5 ,0.5 ]
178
139
179
- struct Metal{T} <: Material{T}
180
- albedo:: Vec3{T}
181
- fuzz:: T # how big the sphere used to generate fuzzy reflection rays. 0=none
182
- @inline Metal (a:: Vec3{T} , f:: T = 0.0 ) where T = new {T} (a,f)
183
- end
184
- @inline @fastmath function scatter (mat:: Metal{T} , r_in:: Ray{T} , rec:: HitRecord ):: Scatter{T} where T
185
- reflected = normalize (reflect (r_in. dir, rec. n⃗) + mat. fuzz* random_vec3_on_sphere (T))
186
- Scatter (Ray (rec. p, reflected), mat. albedo)
187
- end
188
140
189
141
""" Compute color for a ray, recursively
190
142
274
226
normalize (r_out_perp + r_out_parallel)
275
227
end
276
228
277
- struct Dielectric{T} <: Material{T}
278
- ir:: T # index of refraction, i.e. η.
279
- end
280
-
281
229
@inline @fastmath function reflectance (cosθ, refraction_ratio)
282
230
# Use Schlick's approximation for reflectance.
283
231
# claforte: may be buggy? I'm getting black pixels in the Hollow Glass Sphere...
286
234
r0 + (1 - r0)* ((1 - cosθ)^ 5 )
287
235
end
288
236
289
- @inline @fastmath function scatter (mat:: Dielectric{T} , r_in:: Ray{T} , rec:: HitRecord{T} ) where T
290
- attenuation = SA{T}[1 ,1 ,1 ]
291
- refraction_ratio = rec. front_face ? (one (T)/ mat. ir) : mat. ir # i.e. ηᵢ/ηₜ
292
- cosθ = min (- r_in. dir⋅ rec. n⃗, one (T))
293
- sinθ = √ (one (T) - cosθ^ 2 )
294
- cannot_refract = refraction_ratio * sinθ > one (T)
295
- if cannot_refract || reflectance (cosθ, refraction_ratio) > trand (T)
296
- dir = reflect (r_in. dir, rec. n⃗)
297
- else
298
- dir = refract (r_in. dir, rec. n⃗, refraction_ratio)
299
- end
300
- Scatter (Ray {T} (rec. p, dir), attenuation) # TODO : rename reflected -> !absorbed?
301
- end
237
+ include (" material.jl" )
302
238
303
239
include (" scenes.jl" )
304
240
0 commit comments