zigrtiow: some refraction with dielectric.
This commit is contained in:
parent
aea437785a
commit
8adf1bcadb
@ -90,11 +90,9 @@ pub fn main() anyerror!void {
|
||||
var tmp_world = HittableList.init();
|
||||
|
||||
const material_ground = Material{ .labertian = Labertian{ .albedo = Color.init(0.8, 0.8, 0.0) } };
|
||||
const material_center = Material{ .dielectric = Dielectric{ .ir = 1.5 } };
|
||||
//const material_center = Material{ .labertian = Labertian{ .albedo = Color.init(0.7, 0.3, 0.3) } };
|
||||
const material_center = Material{ .labertian = Labertian{ .albedo = Color.init(0.1, 0.2, 0.5) } };
|
||||
const material_left = Material{ .dielectric = Dielectric{ .ir = 1.5 } };
|
||||
//const material_left = Material{ .metal = Metal{ .albedo = Color.init(0.8, 0.8, 0.8), .fuzz = 0.3 } };
|
||||
const material_right = Material{ .metal = Metal{ .albedo = Color.init(0.8, 0.6, 0.2), .fuzz = 1.0 } };
|
||||
const material_right = Material{ .metal = Metal{ .albedo = Color.init(0.8, 0.6, 0.2), .fuzz = 0.0 } };
|
||||
|
||||
try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(0, -100.5, -1), 100, material_ground) });
|
||||
try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(0, 0, -1), 0.5, material_center) });
|
||||
|
||||
@ -23,6 +23,17 @@ pub const Material = union(enum) {
|
||||
|
||||
pub const ScatterRec = struct { attenuation: Color, scattered: Ray };
|
||||
|
||||
fn reflect(v: Vec3, n: Vec3) Vec3 {
|
||||
return v.sub(n.scale(v.dot(n) * 2));
|
||||
}
|
||||
fn refract(uv: Vec3, n: Vec3, etai_over_etat: f32) Vec3 {
|
||||
const cos_theta = @minimum(-uv.dot(n), 1.0);
|
||||
|
||||
const r_out_perp = uv.add(n.scale(cos_theta)).scale(etai_over_etat);
|
||||
const r_out_parallel = n.scale(-@sqrt(@fabs(1.0 - r_out_perp.length_squared())));
|
||||
return r_out_perp.add(r_out_parallel);
|
||||
}
|
||||
|
||||
pub const Labertian = struct {
|
||||
albedo: Vec3,
|
||||
pub fn scatter(labertian: Labertian, r_in: Ray, rec: HitRecord) ?ScatterRec {
|
||||
@ -55,9 +66,6 @@ pub const Metal = struct {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
fn reflect(v: Vec3, n: Vec3) Vec3 {
|
||||
return v.sub(n.scale(v.dot(n) * 2));
|
||||
}
|
||||
};
|
||||
|
||||
pub const Dielectric = struct {
|
||||
@ -68,18 +76,19 @@ pub const Dielectric = struct {
|
||||
const refraction_ratio = if (rec.front_face) 1.0 / dielectric.ir else dielectric.ir;
|
||||
|
||||
const unit_direction = r_in.direction().unit();
|
||||
const refracted = refract(unit_direction, rec.normal, refraction_ratio);
|
||||
const cos_theta = @minimum(-unit_direction.dot(rec.normal), 1.0);
|
||||
const sin_theta = @sqrt(1 - cos_theta * cos_theta);
|
||||
|
||||
const scattered = Ray.init(rec.p, refracted);
|
||||
const cannot_refract = refraction_ratio * sin_theta > 1;
|
||||
const direction = if (cannot_refract)
|
||||
reflect(unit_direction, rec.normal)
|
||||
else
|
||||
refract(unit_direction, rec.normal, refraction_ratio);
|
||||
|
||||
const scattered = Ray.init(rec.p, direction);
|
||||
return ScatterRec{
|
||||
.attenuation = attenuation,
|
||||
.scattered = scattered,
|
||||
};
|
||||
}
|
||||
fn refract(uv: Vec3, n: Vec3, etai_over_etat: f32) Vec3 {
|
||||
const cos_theta = @minimum(-uv.dot(n), 1.0);
|
||||
const r_out_perp = uv.add(n.scale(cos_theta)).scale(etai_over_etat);
|
||||
const r_out_parallel = n.scale(-@sqrt(@fabs(1.0 - r_out_perp.length_squared())));
|
||||
return r_out_perp.add(r_out_parallel);
|
||||
}
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user