@@ -40,6 +40,17 @@ struct Triangle <: AbstractShape
40
40
end
41
41
end
42
42
43
+ @inline function shading_normal (shape:: Triangle , core_n, shading_n)
44
+ if ! isempty (shape. mesh. normals)
45
+ core_n = face_forward (
46
+ core_n, shading_n,
47
+ )
48
+ elseif shape. core. reverse_orientation ⊻ shape. core. transform_swaps_handedness
49
+ core_n = shading_n = - core_n
50
+ end
51
+ return core_n, shading_n
52
+ end
53
+
43
54
function create_triangle_mesh (
44
55
core:: ShapeCore ,
45
56
indices:: Vector{UInt32} ,
@@ -178,21 +189,21 @@ function ∂n(
178
189
∂n∂u, ∂n∂v
179
190
end
180
191
181
- function _init_triangle_shading_geometry! (
182
- t:: Triangle , interaction :: SurfaceInteraction ,
192
+ function _init_triangle_shading_geometry (
193
+ t:: Triangle , si :: SurfaceInteraction ,
183
194
barycentric:: Point3f , uv:: AbstractVector{Point2f} ,
184
195
)
185
- ! (! isempty (t. mesh. normals) || ! isempty (t. mesh. tangents)) && return
196
+ ! (! isempty (t. mesh. normals) || ! isempty (t. mesh. tangents)) && return si
186
197
# Initialize triangle shading geometry.
187
198
# Compute shading normal, tangent & bitangent.
188
- ns = interaction . core. n
199
+ ns = si . core. n
189
200
if ! isempty (t. mesh. normals)
190
201
ns = normalize (sum_mul (barycentric, normals (t)))
191
202
end
192
203
if ! isempty (t. mesh. tangents)
193
204
ss = normalize (sum_mul (barycentric, tangents (t)))
194
205
else
195
- ss = normalize (interaction .∂p∂u)
206
+ ss = normalize (si .∂p∂u)
196
207
end
197
208
ts = ns × ss
198
209
if (ts ⋅ ts) > 0
@@ -202,9 +213,93 @@ function _init_triangle_shading_geometry!(
202
213
_, ss, ts = coordinate_system (ns)
203
214
end
204
215
∂n∂u, ∂n∂v = ∂n (t, uv)
205
- set_shading_geometry! (t, interaction, ss, ts, ∂n∂u, ∂n∂v, true )
216
+
217
+ return set_shading_geometry (t, si, ss, ts, ∂n∂u, ∂n∂v, true )
218
+ end
219
+
220
+ function create_surface_interaction (
221
+ t, normal, ray, hitpoint, uvs, uv, barycentric, ∂p∂u, ∂p∂v,
222
+ orientation_is_authoritative, reverse_normal)
223
+
224
+ ∂n∂u = Normal3f (0 )
225
+ ∂n∂v = Normal3f (0 )
226
+ time = ray. time
227
+ wo = - ray. d
228
+ core_n = normal
229
+ shading_n = normal
230
+ shading_∂p∂u = ∂p∂u
231
+ shading_∂p∂v = ∂p∂v
232
+ shading_∂n∂u = ∂n∂u
233
+ shading_∂n∂v = ∂n∂v
234
+
235
+ if t. mesh isa Nothing || ! (! isempty (t. mesh. normals) || ! isempty (t. mesh. tangents))
236
+ return SurfaceInteraction (
237
+ Interaction (hitpoint, time, wo, core_n),
238
+ ShadingInteraction (shading_n, shading_∂p∂u, shading_∂p∂v, shading_∂n∂u, shading_∂n∂v),
239
+ uv, ∂p∂u, ∂p∂v, ∂n∂u, ∂n∂v,
240
+ 0.0f0 , 0.0f0 , 0.0f0 , 0.0f0 , Vec3f (0.0f0 ), Vec3f (0.0f0 )
241
+ )
242
+ end
243
+
244
+ # Initialize triangle shading geometry.
245
+ # Compute shading normal, tangent & bitangent.
246
+
247
+ ns = core_n
248
+ if ! isempty (t. mesh. normals)
249
+ ns = normalize (sum_mul (barycentric, normals (t)))
250
+ end
251
+ if ! isempty (t. mesh. tangents)
252
+ ss = normalize (sum_mul (barycentric, tangents (t)))
253
+ else
254
+ ss = normalize (∂p∂u)
255
+ end
256
+ ts = ns × ss
257
+ if (ts ⋅ ts) > 0
258
+ ts = Vec3f (normalize (ts))
259
+ ss = Vec3f (ts × ns)
260
+ else
261
+ _, ss, ts = coordinate_system (ns)
262
+ end
263
+ ∂n∂u, ∂n∂v = ∂n (t, uvs)
264
+
265
+ shading_n = normalize (∂n∂v × ∂n∂v)
266
+ if reverse_normal
267
+ shading_n *= - 1
268
+ end
269
+ if orientation_is_authoritative
270
+ core_n = face_forward (core_n, shading_n)
271
+ else
272
+ shading_n = face_forward (shading_n, core_n)
273
+ end
274
+
275
+ shading_∂p∂u = ∂n∂u
276
+ shading_∂p∂v = ∂n∂v
277
+ shading_∂n∂u = ∂n∂u
278
+ shading_∂n∂v = ∂n∂v
279
+
280
+ # Ensure correct orientation of the geometric normal.
281
+ if ! isempty (t. mesh. normals)
282
+ core_n = face_forward (core_n, shading_n)
283
+ elseif t. core. reverse_orientation ⊻ t. core. transform_swaps_handedness
284
+ core_n = shading_n = - core_n
285
+ end
286
+ return SurfaceInteraction (
287
+
288
+ Interaction (hitpoint, time, wo, core_n),
289
+
290
+ ShadingInteraction (shading_n, shading_∂p∂u, shading_∂p∂v, shading_∂n∂u, shading_∂n∂v),
291
+ uv,
292
+
293
+ ∂p∂u,
294
+ ∂p∂v,
295
+ ∂n∂u,
296
+ ∂n∂v,
297
+
298
+ 0f0 , 0f0 , 0f0 , 0f0 , Vec3f (0f0 ), Vec3f (0f0 )
299
+ )
206
300
end
207
301
302
+
208
303
function intersect (
209
304
pool, t:: Triangle , ray:: Union{Ray,RayDifferentials} , :: Bool = false ,
210
305
):: Tuple{Bool,Float32,SurfaceInteraction}
@@ -213,10 +308,12 @@ function intersect(
213
308
si = SurfaceInteraction ()
214
309
is_degenerate (vs) && return false , 0.0f0 , si
215
310
t_vs, shear = _to_ray_coordinate_space (vs, ray)
311
+
216
312
# Compute edge function coefficients.
313
+
217
314
edges = _edge_function (t_vs)
218
315
if iszero (edges) # Fall-back to double precision.
219
- edges = _edge_function ((x -> x .| > Float64) . (t_vs))
316
+ edges = _edge_function (Float64 .(t_vs))
220
317
end
221
318
# Perform triangle edge & determinant tests.
222
319
# Point is inside a triangle if all edges have the same sign.
@@ -245,31 +342,25 @@ function intersect(
245
342
# Interpolate (u, v) paramteric coordinates and hit point.
246
343
hit_point = sum_mul (barycentric, vs)
247
344
uv_hit = sum_mul (barycentric, uv)
345
+ normal = normalize (δp_13 × δp_23)
248
346
249
- reverse_normal = (t. core. reverse_orientation ⊻ t. core. transform_swaps_handedness)
250
- si = SurfaceInteraction (pool,
251
- hit_point, ray. time, - ray. d, uv_hit,
252
- ∂p∂u, ∂p∂v, Normal3f (0 ), Normal3f (0 ), reverse_normal
347
+ si = SurfaceInteraction (
348
+ normal, hit_point, ray. time, - ray. d, uv_hit,
349
+ ∂p∂u, ∂p∂v, Normal3f (0 ), Normal3f (0 )
253
350
)
254
- si. core. n = si. shading. n = normalize (δp_13 × δp_23)
255
- t. mesh isa Nothing && return true , t_hit, si
256
-
257
- _init_triangle_shading_geometry! (t, si, barycentric, uv)
258
- # Ensure correct orientation of the geometric normal.
259
- if ! isempty (t. mesh. normals)
260
- si. core. n = face_forward (
261
- si. core. n, si. shading. n,
262
- )
263
- elseif t. core. reverse_orientation ⊻ t. core. transform_swaps_handedness
264
- si. core. n = si. shading. n = - si. core. n
351
+ if t. mesh isa Nothing
352
+ return true , t_hit, si
265
353
end
354
+
355
+ si = _init_triangle_shading_geometry (t, si, barycentric, uv)
266
356
# TODO test against alpha texture if present.
267
- true , t_hit, si
357
+ return true , t_hit, si
268
358
end
269
359
270
360
function intersect_p (
271
- pool, t:: Triangle , ray:: Union{Ray,RayDifferentials} , :: Bool = false ,
272
- ):: Bool
361
+ pool, t:: Triangle , ray:: Union{Ray,RayDifferentials} , :: Bool = false ,
362
+ ):: Bool
363
+
273
364
vs = vertices (t)
274
365
is_degenerate (vs) && return false
275
366
t_vs, shear = _to_ray_coordinate_space (vs, ray)
0 commit comments