Add fresnel in raytracer example
This commit is contained in:
parent
028895ce7f
commit
bd9425ebec
2 changed files with 21 additions and 10 deletions
Binary file not shown.
|
Before Width: | Height: | Size: 423 KiB After Width: | Height: | Size: 423 KiB |
|
|
@ -211,6 +211,9 @@ func log(x: f32) -> f32:
|
||||||
func abs(x: f32) -> f32:
|
func abs(x: f32) -> f32:
|
||||||
return if x >= 0.0 then x else -x
|
return if x >= 0.0 then x else -x
|
||||||
|
|
||||||
|
func sqr(x: f32) -> f32:
|
||||||
|
return x * x
|
||||||
|
|
||||||
func min(x: f32, y: f32) -> f32:
|
func min(x: f32, y: f32) -> f32:
|
||||||
return if x <= y then x else y
|
return if x <= y then x else y
|
||||||
|
|
||||||
|
|
@ -598,21 +601,29 @@ func raytrace(scene: scene*, camera_ray: ray, rng: rng mut*) -> vec3:
|
||||||
new_direction = normalized(add(new_direction, mults(next_vec3_normal(rng), cosine * intersection.material.roughness)))
|
new_direction = normalized(add(new_direction, mults(next_vec3_normal(rng), cosine * intersection.material.roughness)))
|
||||||
|
|
||||||
else if intersection.material.type == glass_tag:
|
else if intersection.material.type == glass_tag:
|
||||||
// This should also contain multiplication by brdf and division by direction pdf,
|
|
||||||
// but we'll just pretend that the random refracted ray pdf coincides with brdf and thus cancels out
|
|
||||||
factor = multv(factor, intersection.material.color)
|
|
||||||
|
|
||||||
mut ior = intersection.material.ior
|
mut ior = intersection.material.ior
|
||||||
if inside:
|
if inside:
|
||||||
ior = 1.0 / ior
|
ior = 1.0 / ior
|
||||||
|
|
||||||
// Compute perfect refracted ray
|
// Schlick's approximation for Fresnel term
|
||||||
let k = 1.0 - ior * ior * (1.0 - cosine * cosine)
|
let r0 = sqr((1.0 - ior) / (1.0 + ior))
|
||||||
if k >= 0.0:
|
let reflectance = r0 + (1.0 - r0) * pow(max(0.0, 1.0 - abs(cosine)), 5.0)
|
||||||
new_direction = add(mults(current_ray.direction, ior), mults(intersection.normal, ior * abs(cosine) - sqrt(k)))
|
|
||||||
else:
|
if next_f32(rng) < reflectance:
|
||||||
// Total internal reflection
|
// Compute perfect-mirror reflected direction
|
||||||
new_direction = add(current_ray.direction, mults(intersection.normal, 2.0 * cosine))
|
new_direction = add(current_ray.direction, mults(intersection.normal, 2.0 * cosine))
|
||||||
|
else:
|
||||||
|
// This should also contain multiplication by brdf and division by direction pdf,
|
||||||
|
// but we'll just pretend that the random refracted ray pdf coincides with brdf and thus cancels out
|
||||||
|
factor = multv(factor, intersection.material.color)
|
||||||
|
|
||||||
|
// Compute perfect refracted ray
|
||||||
|
let k = 1.0 - ior * ior * (1.0 - cosine * cosine)
|
||||||
|
if k >= 0.0:
|
||||||
|
new_direction = add(mults(current_ray.direction, ior), mults(intersection.normal, ior * abs(cosine) - sqrt(k)))
|
||||||
|
else:
|
||||||
|
// Total internal reflection
|
||||||
|
new_direction = add(current_ray.direction, mults(intersection.normal, 2.0 * cosine))
|
||||||
|
|
||||||
// Alter the direction based on roughness
|
// Alter the direction based on roughness
|
||||||
new_direction = normalized(add(new_direction, mults(next_vec3_normal(rng), intersection.material.roughness)))
|
new_direction = normalized(add(new_direction, mults(next_vec3_normal(rng), intersection.material.roughness)))
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue