add Metal material
This commit is contained in:
		
							parent
							
								
									b3c47a914f
								
							
						
					
					
						commit
						bc3fb54991
					
				
					 3 changed files with 45 additions and 11 deletions
				
			
		| 
						 | 
				
			
			@ -94,17 +94,27 @@ pub fn main() anyerror!void {
 | 
			
		|||
 | 
			
		||||
    // World
 | 
			
		||||
    const materialGround = Material{
 | 
			
		||||
        .materialType = MaterialType.Lambertian,
 | 
			
		||||
        .materialType = .Lambertian,
 | 
			
		||||
        .color = Color{ .x = 0.8, .y = 0.8, .z = 0.0 },
 | 
			
		||||
    };
 | 
			
		||||
    const materialCenter = Material{
 | 
			
		||||
        .materialType = MaterialType.Lambertian,
 | 
			
		||||
        .materialType = .Lambertian,
 | 
			
		||||
        .color = Color{ .x = 0.7, .y = 0.3, .z = 0.3 },
 | 
			
		||||
    };
 | 
			
		||||
    const materialLeft = Material{
 | 
			
		||||
        .materialType = .Metal,
 | 
			
		||||
        .color = Color{ .x = 0.8, .y = 0.8, .z = 0.8 },
 | 
			
		||||
    };
 | 
			
		||||
    const materialRight = Material{
 | 
			
		||||
        .materialType = .Metal,
 | 
			
		||||
        .color = Color{ .x = 0.8, .y = 0.6, .z = 0.2 },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const spheres = [_]Sphere{
 | 
			
		||||
        Sphere{ .center = Point3{ .x = 0, .y = 0, .z = -1 }, .radius = 0.5, .material = materialCenter },
 | 
			
		||||
        Sphere{ .center = Point3{ .x = 0, .y = -100.5, .z = -1 }, .radius = 100, .material = materialGround },
 | 
			
		||||
        Sphere{ .center = Point3{ .x = 0, .y = 0, .z = -1 }, .radius = 0.5, .material = materialCenter },
 | 
			
		||||
        Sphere{ .center = Point3{ .x = -1, .y = 0, .z = -1 }, .radius = 0.5, .material = materialLeft },
 | 
			
		||||
        Sphere{ .center = Point3{ .x = 1, .y = 0, .z = -1 }, .radius = 0.5, .material = materialRight },
 | 
			
		||||
     };
 | 
			
		||||
    const world = World{ .spheres = spheres[0..spheres.len] };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ const HitRecord = @import("hittable.zig").HitRecord;
 | 
			
		|||
 | 
			
		||||
pub const MaterialType = enum {
 | 
			
		||||
    Lambertian,
 | 
			
		||||
    Metal,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const Material = struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -21,15 +22,34 @@ pub const ScatteredRay = struct {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
pub fn scatter(ray: Ray, hit: HitRecord, rng: *Random) ?ScatteredRay {
 | 
			
		||||
    var scatterDirection = hit.normal.add(vec3.random_unit_vector(rng));
 | 
			
		||||
    const scatteredDirection = switch (hit.material.materialType) {
 | 
			
		||||
 | 
			
		||||
    // Catch degenerate scatter direction
 | 
			
		||||
    if (scatterDirection.nearZero()) {
 | 
			
		||||
        scatterDirection = hit.normal;
 | 
			
		||||
        .Lambertian => blk: {
 | 
			
		||||
            var scatterDirection = hit.normal.add(vec3.random_unit_vector(rng));
 | 
			
		||||
            // Catch degenerate scatter direction
 | 
			
		||||
            if (scatterDirection.nearZero()) {
 | 
			
		||||
                scatterDirection = hit.normal;
 | 
			
		||||
            }
 | 
			
		||||
            break :blk scatterDirection;
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        .Metal => blk: {
 | 
			
		||||
            const reflected = ray.direction.unit().reflect(hit.normal);
 | 
			
		||||
            const scattered = Ray{ .origin = hit.p, .direction = reflected };
 | 
			
		||||
            if (scattered.direction.dot(hit.normal) <= 0) {
 | 
			
		||||
                break :blk null;
 | 
			
		||||
            }
 | 
			
		||||
            break :blk scattered.direction;
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    if (scatteredDirection) |dir| {
 | 
			
		||||
        return ScatteredRay{
 | 
			
		||||
            .ray = Ray{ .origin = hit.p, .direction = dir},
 | 
			
		||||
            .color = hit.material.color,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ScatteredRay{
 | 
			
		||||
        .ray = Ray{ .origin = hit.p, .direction = scatterDirection},
 | 
			
		||||
        .color = hit.material.color,
 | 
			
		||||
    };
 | 
			
		||||
    return null;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -78,6 +78,10 @@ pub const Vec3 = packed struct {
 | 
			
		|||
            and math.absFloat(self.y) < t
 | 
			
		||||
            and math.absFloat(self.z) < t;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn reflect(self: Vec3, n: Vec3) Vec3 {
 | 
			
		||||
        return self.sub(n.mul_s(self.dot(n) * 2));
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub fn random(rng: *Random, min: f32, max: f32) Vec3 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue