@@ -6,30 +6,27 @@ struct WhittedIntegrator{C<: Camera, S <: AbstractSampler} <: SamplerIntegrator
6
6
max_depth:: Int64
7
7
end
8
8
9
-
10
9
function sample_kernel_inner (i:: A , scene:: B , t_sampler:: C , film:: D , film_tile:: E , camera:: F , pixel:: G , spp_sqr:: H ) where {A, B, C, D, E, F, G, H}
11
- while has_next_sample ( t_sampler)
10
+ for _ in 1 : t_sampler. samples_per_pixel
12
11
camera_sample = get_camera_sample (t_sampler, pixel)
13
12
ray, ω = generate_ray_differential (camera, camera_sample)
14
13
ray = scale_differentials (ray, spp_sqr)
15
14
l = RGBSpectrum (0f0 )
16
15
if ω > 0.0f0
17
- l = li (i , ray, scene, 1 )
16
+ l = li (t_sampler, i . max_depth , ray, scene, 1 )
18
17
end
19
18
# TODO check l for invalid values
20
19
if isnan (l)
21
20
l = RGBSpectrum (0f0 )
22
21
end
23
22
add_sample! (film, film_tile, camera_sample. film, l, ω)
24
- start_next_sample! (t_sampler)
25
23
end
26
24
end
27
25
28
26
@noinline function sample_kernel (i, camera, scene, film, film_tile, tile_bounds)
29
27
t_sampler = deepcopy (i. sampler)
30
28
spp_sqr = 1f0 / √ Float32 (t_sampler. samples_per_pixel)
31
29
for pixel in tile_bounds
32
- start_pixel! (t_sampler, pixel)
33
30
sample_kernel_inner (i, scene, t_sampler, film, film_tile, camera, pixel, spp_sqr)
34
31
end
35
32
merge_film_tile! (film, film_tile)
@@ -73,18 +70,19 @@ function (i::SamplerIntegrator)(scene::Scene, film)
73
70
end
74
71
75
72
function get_material (bvh:: BVHAccel , shape:: Triangle )
73
+ materials = bvh. materials
76
74
@inbounds if shape. material_idx == 0
77
- return bvh . materials[1 ]
75
+ return materials[1 ]
78
76
else
79
- return bvh . materials[shape. material_idx]
77
+ return materials[shape. material_idx]
80
78
end
81
79
end
82
80
function get_material (scene:: Scene , shape:: Triangle )
83
81
get_material (scene. aggregate, shape)
84
82
end
85
83
86
84
function li (
87
- i :: WhittedIntegrator , ray:: RayDifferentials , scene:: Scene , depth:: Int64 ,
85
+ sampler, max_depth , ray:: RayDifferentials , scene:: Scene , depth:: Int64 ,
88
86
):: RGBSpectrum
89
87
90
88
l = RGBSpectrum (0f0 )
@@ -106,64 +104,69 @@ function li(
106
104
m = get_material (scene, shape)
107
105
if m. type === NO_MATERIAL
108
106
return li (
109
- i , RayDifferentials (spawn_ray (si, ray. d)),
107
+ sampler, max_depth , RayDifferentials (spawn_ray (si, ray. d)),
110
108
scene, depth,
111
109
)
112
110
end
113
111
bsdf = m (si, false , Radiance)
114
112
# Compute emitted light if ray hit an area light source.
115
113
l += le (si, wo)
116
114
# Add contribution of each light source.
117
- for light in scene. lights
118
- sampled_li, wi, pdf, visibility_tester = sample_li (
119
- light, core, get_2d (i. sampler),
120
- )
121
- (is_black (sampled_li) || pdf ≈ 0f0 ) && continue
122
- f = bsdf (wo, wi)
123
- if ! is_black (f) && unoccluded (visibility_tester, scene)
124
- l += f * sampled_li * abs (wi ⋅ n) / pdf
115
+ lights = scene. lights
116
+ Base. Cartesian. @nexprs 8 i -> begin
117
+ if i <= length (lights)
118
+ light = lights[i]
119
+ sampled_li, wi, pdf, visibility_tester = sample_li (
120
+ light, core, get_2d (sampler),
121
+ )
122
+ if ! (is_black (sampled_li) || pdf ≈ 0f0 )
123
+ f = bsdf (wo, wi)
124
+ if ! is_black (f) && unoccluded (visibility_tester, scene)
125
+ l += f * sampled_li * abs (wi ⋅ n) / pdf
126
+ end
127
+ end
125
128
end
126
129
end
127
- if depth + 1 ≤ i . max_depth
130
+ if depth + 1 ≤ max_depth
128
131
# Trace rays for specular reflection & refraction.
129
- l += specular_reflect (bsdf, i , ray, si, scene, depth)
130
- l += specular_transmit (bsdf, i , ray, si, scene, depth)
132
+ l += specular_reflect (bsdf, sampler, max_depth , ray, si, scene, depth)
133
+ l += specular_transmit (bsdf, sampler, max_depth , ray, si, scene, depth)
131
134
end
132
135
l
133
136
end
134
137
135
- function specular_reflect (
136
- bsdf, i :: I , ray:: RayDifferentials ,
137
- surface_intersect :: SurfaceInteraction , scene:: Scene , depth:: Int64 ,
138
- ) where I <: SamplerIntegrator
138
+ @inline function specular_reflect (
139
+ bsdf, sampler, max_depth , ray:: RayDifferentials ,
140
+ si :: SurfaceInteraction , scene:: Scene , depth:: Int64 ,
141
+ )
139
142
140
143
# Compute specular reflection direction `wi` and BSDF value.
141
144
142
- wo = surface_intersect . core. wo
145
+ wo = si . core. wo
143
146
type = BSDF_REFLECTION | BSDF_SPECULAR
144
147
wi, f, pdf, sampled_type = sample_f (
145
- bsdf, wo, get_2d (i . sampler), type,
148
+ bsdf, wo, get_2d (sampler), type,
146
149
)
147
150
# Return contribution of specular reflection.
148
- ns = surface_intersect . shading. n
151
+ ns = si . shading. n
149
152
if ! (pdf > 0f0 && ! is_black (f) && abs (wi ⋅ ns) != 0f0 )
150
153
return RGBSpectrum (0f0 )
151
154
end
152
155
# Compute ray differential for specular reflection.
153
- rd = RayDifferentials (spawn_ray (surface_intersect , wi))
156
+ rd = RayDifferentials (spawn_ray (si , wi))
154
157
if ray. has_differentials
155
- rx_origin = surface_intersect . core. p + surface_intersect .∂p∂x
156
- ry_origin = surface_intersect . core. p + surface_intersect .∂p∂y
158
+ rx_origin = si . core. p + si .∂p∂x
159
+ ry_origin = si . core. p + si .∂p∂y
157
160
# Compute differential reflected directions.
158
161
∂n∂x = (
159
- surface_intersect . shading.∂n∂u * surface_intersect .∂u∂x
162
+ si . shading.∂n∂u * si .∂u∂x
160
163
+
161
- surface_intersect . shading.∂n∂v * surface_intersect .∂v∂x
164
+ si . shading.∂n∂v * si .∂v∂x
162
165
)
163
166
∂n∂y = (
164
- surface_intersect . shading.∂n∂u * surface_intersect .∂u∂y
167
+ si . shading.∂n∂u * si .∂u∂y
165
168
+
166
- surface_intersect . shading.∂n∂v * surface_intersect .∂v∂y
169
+ si . shading.∂n∂v * si .∂v∂y
167
170
)
168
171
∂wo∂x = - ray. rx_direction - wo
169
172
∂wo∂y = - ray. ry_direction - wo
@@ -173,19 +176,19 @@ function specular_reflect(
173
176
ry_direction = wi - ∂wo∂y + 2f0 * (wo ⋅ ns) * ∂n∂y + ∂dn∂y * ns
174
177
rd = RayDifferentials (rd, rx_origin= rx_origin, ry_origin= ry_origin, rx_direction= rx_direction, ry_direction= ry_direction)
175
178
end
176
- return f * li (i , rd, scene, depth + 1 ) * abs (wi ⋅ ns) / pdf
179
+ return f * li (sampler, max_depth , rd, scene, depth + 1 ) * abs (wi ⋅ ns) / pdf
177
180
end
178
181
179
- function specular_transmit (
180
- bsdf, i :: S , ray:: RayDifferentials ,
182
+ @inline function specular_transmit (
183
+ bsdf, sampler, max_depth , ray:: RayDifferentials ,
181
184
surface_intersect:: SurfaceInteraction , scene:: Scene , depth:: Int64 ,
182
- ) where S <: SamplerIntegrator
185
+ )
183
186
184
187
# Compute specular reflection direction `wi` and BSDF value.
185
188
wo = surface_intersect. core. wo
186
189
type = BSDF_TRANSMISSION | BSDF_SPECULAR
187
190
wi, f, pdf, sampled_type = sample_f (
188
- bsdf, wo, get_2d (i . sampler), type,
191
+ bsdf, wo, get_2d (sampler), type,
189
192
)
190
193
191
194
ns = surface_intersect. shading. n
@@ -223,12 +226,12 @@ function specular_transmit(
223
226
∂dn∂x = ∂wo∂x ⋅ ns + wo ⋅ ∂n∂x
224
227
∂dn∂y = ∂wo∂y ⋅ ns + wo ⋅ ∂n∂y
225
228
μ = η * (wo ⋅ ns) - abs (wi ⋅ ns)
226
- ν = η - (η^ 2 * (wo ⋅ ns)) / abs (wi ⋅ ns)
229
+ ν = η - (η * η * (wo ⋅ ns)) / abs (wi ⋅ ns)
227
230
∂μ∂x = ν * ∂dn∂x
228
231
∂μ∂y = ν * ∂dn∂y
229
232
rx_direction = wi - η * ∂wo∂x + μ * ∂n∂x + ∂μ∂x * ns
230
233
ry_direction = wi - η * ∂wo∂y + μ * ∂n∂y + ∂μ∂y * ns
231
234
rd = RayDifferentials (rd, rx_origin= rx_origin, ry_origin= ry_origin, rx_direction= rx_direction, ry_direction= ry_direction)
232
235
end
233
- f * li (i , rd, scene, depth + 1 ) * abs (wi ⋅ ns) / pdf
236
+ f * li (sampler, max_depth , rd, scene, depth + 1 ) * abs (wi ⋅ ns) / pdf
234
237
end
0 commit comments