-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmaterials.lua
More file actions
74 lines (56 loc) · 2.25 KB
/
materials.lua
File metadata and controls
74 lines (56 loc) · 2.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
hittable = require("hittable")
function Material()
local material = {}
return material
end
function Lambertian(albedo)
local lambertian = Material()
lambertian.scatter = function (ray, hitmemory)
local scatterdirection = hitmemory.normal.addvec(randomunitvec3())
if scatterdirection.nearzero() then
scatterdirection = hitmemory.normal
end
local scattered = instanceray(hitmemory.p, scatterdirection)
local attenuation = albedo
return true, scattered, attenuation
end
return lambertian
end
function Metal(albedo, glossiness)
local metal = Material()
metal.finish = 1 - math.max(math.min(glossiness, 1), 0)
metal.scatter = function (ray, hitmemory)
local reflected = reflectvector(ray.direction, hitmemory.normal)
reflected = reflected.unit().addvec(randomunitvec3().multnum(metal.finish))
local scattered = instanceray(hitmemory.p, reflected)
local attenuation = albedo
return (hitmemory.normal.dot(scattered.direction)) > 0, scattered, attenuation
end
return metal
end
function Dielectric(refractionindex, albedo)
local dielectric = Material()
dielectric.refractionindex = refractionindex
dielectric.findside = function (hitmemory) if hitmemory.front_face then return dielectric.refractionindex else return 1/dielectric.refractionindex end end
if albedo ~= nil then
dielectric.albedo = instancevec3(1,1,1)
else
dielectric.albedo = albedo
end
dielectric.scatter = function (ray, hitmemory)
local attenuation = dielectric.albedo
local memoryi = dielectric.findside(hitmemory)
local unitdirection = ray.direction.unit()
local costheta = math.min(hitmemory.normal.dot(unitdirection.negative()), 1.0)
local sintheta = math.sqrt(1 - costheta*costheta)
local result
if (memoryi * sintheta) > 1 then -- critical angle reached
result = reflectvector(unitdirection, hitmemory.normal)
else
result = refractvector(unitdirection, hitmemory.normal, memoryi, costheta)
end
local scattered = instanceray(hitmemory.p, result)
return true, scattered, attenuation
end
return dielectric
end