-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathshaders.scm
More file actions
173 lines (154 loc) · 6.63 KB
/
shaders.scm
File metadata and controls
173 lines (154 loc) · 6.63 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
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
;;;; shaders.scm
;;;; glls shaders and pipelines for common mesh types
(module hypergiant-shaders
(phong-lighting
calc-bone-matrix
set-max-lights!
color-conversion)
(import chicken scheme)
(use hypergiant-render-pipeline
(prefix glls-render glls:) (prefix hyperscene scene:))
(import-for-syntax glls-compiler)
(export-pipeline
mesh-pipeline
color-pipeline
texture-pipeline
sprite-pipeline
text-pipeline)
(glls:define-shader calc-bone-matrix
(#:vertex uniform: ((bone-matrices (#:array #:mat4 100))) ;; TODO solve magic number
export: (calc-bone-matrix))
(define (calc-bone-matrix (bindices #:vec4) (bweights #:vec4))
#:mat4
(let ((m #:mat4 (* (array-ref bone-matrices (int bindices.x))
bweights.x)))
(+= m (* (array-ref bone-matrices (int bindices.y)) bweights.y))
(+= m (* (array-ref bone-matrices (int bindices.z)) bweights.z))
(+= m (* (array-ref bone-matrices (int bindices.w)) bweights.w))
m)))
(cond-expand
(gles (include "es-pipelines"))
(else (include "pipelines")))
;; Via: http://www.chilliant.com/rgb2hsv.html
(glls:define-shader color-conversion
(#:fragment export: (hue->rgb
hsv->rgb
hsl->rgb
rgb->hsl
rgb->hsv))
(define epsilon #:float 0.0000000001)
(define (hue->rgb (h #:float)) #:vec3
(let ((r #:float (- (abs (- (* h 6) 3)) 1))
(g #:float (- 2 (abs (- (* h 6) 2))))
(b #:float (- 2 (abs (- (* h 6) 4)))))
(clamp (vec3 r g b) 0 1)))
(define (hsv->rgb (hsv #:vec3)) #:vec3
(* (+ (* (- (hue->rgb hsv.x)
1)
hsv.y)
1)
hsv.z))
(define (hsl->rgb (hsl #:vec3)) #:vec3
(let ((c #:float (* (- 1
(abs (- (* 2 hsl.z)
1)))
hsl.y)))
(+ (* (- (hue->rgb hsl.x)
0.5)
c)
hsl.z)))
(define (rgb->hcv (rgb #:vec3)) #:vec3
(let* ((p #:vec4 (if (< rgb.g rgb.b)
(vec4 rgb.bg -1.0 (/ 2.0 3.0))
(vec4 rgb.gb 0.0 (/ -1.0 3.0))))
(q #:vec4 (if (< rgb.r p.x)
(vec4 p.xyw rgb.r)
(vec4 rgb.r p.yzx)))
(c #:float (- q.x (min q.w q.y)))
(h #:float (abs (+ (/ (- q.w q.y)
(+ (* 6 c)
epsilon))
q.z))))
(vec3 h c q.x)))
(define (rgb->hsv (rgb #:vec3)) #:vec3
(let ((hcv #:vec3 (rgb->hcv rgb)))
(vec3 hcv.x
(/ hcv.y
(+ hcv.z epsilon))
hcv.z)))
(define (rgb->hsl (rgb #:vec3)) #:vec3
(let* ((hcv #:vec3 (rgb->hcv rgb))
(l #:float (- hcv.z
(* hcv.y 0.5)))
(s #:float (/ hcv.y
(+ (+ 1 (- (abs (- (* l 2)
1)))
epsilon)))))
(vec3 hcv.x s l)))
)
;; TODO light direction
(define-syntax phong-light-n
(er-macro-transformer
(lambda (expr r c)
(let ((name (cadr expr))
(n (caddr expr)))
`(glls:define-shader ,name
(#:fragment uniform: ((camera-position #:vec3)
(inverse-transpose-model #:mat4)
(ambient #:vec3)
(n-lights #:int)
(light-positions (#:array #:vec3 ,n))
(light-colors (#:array #:vec3 ,n))
(light-intensities (#:array #:float ,n))
(material #:vec4))
export: (light))
(define gamma #:vec3 (vec3 (/ 1 2.2)))
(define (light (surface-color #:vec4) (position #:vec3) (normal #:vec3))
#:vec4
(set! normal (* (mat3 inverse-transpose-model)
(normalize normal)))
(let ((linear-color #:vec3 (* ambient surface-color.rgb)))
(do-times (i n-lights)
(let* ((light-position #:vec3 (array-ref light-positions i))
(light-color #:vec3 (array-ref light-colors i))
(light-intensity #:float (array-ref light-intensities i))
(surface-specular #:vec3 (vec3 material))
(specular-exponent #:float material.a)
(distance #:vec3 (- light-position position))
(intensity #:float (clamp (/ light-intensity
(pow (+ 0.001
(* distance.x distance.x)
(* distance.y distance.y)
(* distance.z distance.z))
2))
0.0 1.0))
(to-light #:vec3 (normalize distance))
(to-camera #:vec3 (normalize (- camera-position position)))
(diffuse-intensity #:float (max (dot normal to-light) 0.0))
(diffuse #:vec3 (* surface-color.rgb light-color
diffuse-intensity))
(specular-intensity
#:float (if (> diffuse-intensity 0.0)
(max (dot to-camera
(reflect (- to-light) normal))
0.0)
0.0))
(specular #:vec3 (* light-color surface-specular
(expt specular-intensity
specular-exponent))))
(+= linear-color (* intensity (+ diffuse specular)))))
(vec4 (pow linear-color gamma) surface-color.a))))))))
(phong-light-n phong-lighting-8 8)
(phong-light-n phong-lighting-16 16)
(phong-light-n phong-lighting-32 32)
(phong-light-n phong-lighting-64 64)
(define phong-lighting phong-lighting-8)
(define (set-max-lights! n)
(scene:set-max-lights! n)
(set! phong-lighting (cond
((<= n 8) phong-lighting-8)
((<= n 16) phong-lighting-16)
((<= n 32) phong-lighting-32)
((<= n 64) phong-lighting-64)
(else (error 'set-max-lights! "Too many lights" n)))))
) ; end module hypergiant-shaders