1- use crate :: {
2- hittable:: HitRecord ,
3- math:: { random_in_unit_sphere, reflect} ,
4- Ray , Vec3 ,
5- } ;
1+ use crate :: { hittable:: HitRecord , math:: * , Ray , Vec3 } ;
62use cust_core:: DeviceCopy ;
73use enum_dispatch:: enum_dispatch;
8- use gpu_rand:: DefaultRand ;
4+ use gpu_rand:: { DefaultRand , GpuRand } ;
95
106#[ enum_dispatch]
117pub trait Material {
@@ -18,6 +14,7 @@ pub trait Material {
1814pub enum MaterialKind {
1915 Diffuse ( DiffuseMaterial ) ,
2016 Metallic ( MetallicMaterial ) ,
17+ Dielectric ( DielectricMaterial ) ,
2118}
2219
2320#[ derive( Clone , Copy , PartialEq , DeviceCopy ) ]
@@ -63,3 +60,47 @@ impl Material for MetallicMaterial {
6360 }
6461 }
6562}
63+
64+ #[ derive( Clone , Copy , PartialEq , DeviceCopy ) ]
65+ pub struct DielectricMaterial {
66+ pub ior : f32 ,
67+ pub color : Vec3 ,
68+ }
69+
70+ impl Material for DielectricMaterial {
71+ fn scatter ( & self , incoming : Ray , hit : HitRecord , rng : & mut DefaultRand ) -> ( Vec3 , Option < Ray > ) {
72+ let outward_norm;
73+ let ni_over_nt: f32 ;
74+ let cos: f32 ;
75+
76+ if incoming. dir . dot ( hit. normal ) > 0.0 {
77+ outward_norm = -hit. normal ;
78+ ni_over_nt = self . ior ;
79+ cos = self . ior * incoming. dir . dot ( hit. normal ) / incoming. dir . magnitude ( ) ;
80+ } else {
81+ outward_norm = hit. normal ;
82+ ni_over_nt = 1.0 / self . ior ;
83+ cos = -incoming. dir . dot ( hit. normal ) / incoming. dir . magnitude ( ) ;
84+ }
85+
86+ if let Some ( refracted) = refract ( incoming. dir , outward_norm, ni_over_nt) {
87+ if rng. normal_f32 ( ) > schlick ( cos, self . ior ) {
88+ return (
89+ self . color ,
90+ Some ( Ray {
91+ origin : hit. point ,
92+ dir : refracted,
93+ } ) ,
94+ ) ;
95+ }
96+ }
97+
98+ (
99+ self . color ,
100+ Some ( Ray {
101+ origin : hit. point ,
102+ dir : reflect ( incoming. dir . normalized ( ) , hit. normal ) ,
103+ } ) ,
104+ )
105+ }
106+ }
0 commit comments