-
Notifications
You must be signed in to change notification settings - Fork 0
/
shade.go
114 lines (103 loc) · 4.48 KB
/
shade.go
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package gotracer
import (
"math"
"github.com/go-gl/mathgl/mgl64"
)
// func init() {
// parser.RegisterBRDF("lambertian", LambertianBRDF)
// ...
// }
// A bidirectional reflectance distribution function.
// Returns the ratio of reflected radiance exiting along wr to the irradiance
// incident on the surface from direction wi.
// wi - normalized negative incomming light direction (toward light)
// wr - normalized outgoing direction (toward camera)
// type BRDF func(wi, wr mgl64.Vec3, isect Intersection) mgl64.Vec3
type BRDF func(scene *Scene, ray *Ray, isect *Intersection) (color Color64)
// func LambertianBRDF(wi, wr mgl64.Vec3, isect Intersection) mgl64.Vec3 {
// kd := isect.Object.Material.Diffuse.ColorAt(isect.UVCoords)
// return mgl64.Vec3(kd).Mul(wi.Dot(isect.Normal))
// }
func LambertianBRDF(scene *Scene, ray *Ray, isect *Intersection) (color Color64) {
var point mgl64.Vec3 = ray.At(isect.T)
var kd Color64 = isect.Material.Diffuse.ColorAt(isect.UVCoords)
for _, light := range scene.Lights {
var cosTheta float64 = isect.Normal.Dot(light.Direction(point))
if cosTheta > 0 {
var diffuse Color64 = kd.Mul(cosTheta)
var contribution Color64 = diffuse.Product(light.Attenuation(scene, point))
color = color.Add(contribution)
}
}
return
}
// func BlinnPhongBRDF(wi, wr mgl64.Vec3, isect Intersection) mgl64.Vec3 {
// // diffuse := LambertianBRDF(wi, wr, isect)
// // specular := ...
// return mgl64.Vec3{0, 0, 0}
// }
func BlinnPhongBRDF(scene *Scene, ray *Ray, isect *Intersection) (color Color64) {
var point mgl64.Vec3 = ray.At(isect.T)
var mat *Material = isect.Material
var ke Color64 = mat.Emissive.ColorAt(isect.UVCoords)
var ka Color64 = mat.Ambient.ColorAt(isect.UVCoords)
var kd Color64 = mat.Diffuse.ColorAt(isect.UVCoords)
var ks Color64 = mat.Specular.ColorAt(isect.UVCoords)
var shininess float64 = mat.Smoothness.ColorAt(isect.UVCoords).R() * 100
color = ke.Add(ka.Product(scene.AmbientLight))
for _, light := range scene.Lights {
var lightDir mgl64.Vec3 = light.Direction(point)
var cosTheta float64 = isect.Normal.Dot(lightDir)
if cosTheta > 0 {
var h mgl64.Vec3 = lightDir.Sub(ray.Dir).Normalize()
var specular Color64 = ks.Mul(math.Pow(isect.Normal.Dot(h), shininess))
var diffuse Color64 = kd.Mul(cosTheta)
var contribution Color64 = diffuse.Add(specular)
color = color.Add(contribution.Product(light.Attenuation(scene, point)))
}
}
return
}
// func TorranceSparrowBRDF(wi, wr mgl64.Vec3, isect Intersection) mgl64.Vec3 {
// return mgl64.Vec3{0, 0, 0}
// }
// Calculate Lr(wr) = sum for each light i, Li(wi) * BRDF(wi, wr) * (wi . isect.Normal)
// where wr = -ray, wi = direction to light, Li(wi) = radiance from light source,
// func Shade(lights []*Light, ray Ray, isect Intersection) (color Color64) {
// var point mgl64.Vec3 = ray.At(params.isect.T)
// uv := isect.UVCoords
// colorVec := mgl64.Vec3(m.Emissive.ColorAt(uv)).Add(mgl64.Vec3(m.Ambient.ColorAt(uv).Product(scene.AmbientLight)))
// for _, light := range scene.Lights {
// attenuation := light.ShadowAttenuation(point).Mul(light.DistanceAttenuation(point))
// lightDir := light.Direction(point)
// shade := isect.Normal.Dot(lightDir)
// if shade > 0 {
// h := lightDir.Sub(ray.Direction).Normalize()
// s := mgl64.Vec3(m.Specular.ColorAt(uv)).Mul(math.Pow(isect.Normal.Dot(h), m.Gloss.ColorAt(uv)))
// d := mgl64.Vec3(m.Diffuse.ColorAt(uv)).Mul(shade).Add(s)
// a := Color64(attenuation).Product(Color64(d))
// contribution := mgl64.Vec3(light.GetColor().Product(a))
// colorVec = colorVec.Add(contribution)
// }
// }
// return Color64(colorVec)
// return Color64{0, 0, 0}
// }
// func (m *Material) ShadeBlinnPhong(scene *Scene, ray Ray, isect Intersection) (color Color64) {
// point := ray.At(isect.T)
// colorVec := mgl64.Vec3(m.GetEmissiveColor(isect)).Add(mgl64.Vec3(m.GetAmbientColor(isect).Product(scene.AmbientLight)))
// for _, light := range scene.Lights {
// attenuation := light.ShadowAttenuation(point).Mul(light.DistanceAttenuation(point))
// lightDir := light.Direction(point)
// shade := isect.Normal.Dot(lightDir)
// if shade > 0 {
// h := lightDir.Sub(ray.Direction).Normalize()
// s := mgl64.Vec3(m.GetSpecularColor(isect)).Mul(math.Pow(isect.Normal.Dot(h), m.GetShininessValue(isect)))
// d := mgl64.Vec3(m.GetDiffuseColor(isect)).Mul(shade).Add(s)
// a := Color64(attenuation).Product(Color64(d))
// contribution := mgl64.Vec3(light.GetColor().Product(a))
// colorVec = colorVec.Add(contribution)
// }
// }
// return Color64(colorVec)
// }