-
Notifications
You must be signed in to change notification settings - Fork 3
/
cray.clj
61 lines (55 loc) · 2.22 KB
/
cray.clj
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
(ns cray
(:use color image vectr sphere ray light material))
(if (< (count *command-line-args*) 2 )
(do
(println "Usage:\nclj cray.clj <outfile>")
(System/exit 0) ) )
(defn compute-reflection-ray
[ray point normal]
(make-ray point
(vectr-subtract
(:d ray)
(vectr-scale normal (* (vectr-dot (:d ray)
normal) 2)))))
(defn phong-compose
[point ray normal material light]
(let [reflection (compute-reflection-ray ray point normal)
light-vectr (vectr-normalize (vectr-subtract point
(:pos light)))
half-vectr (vectr-normalize (vectr-add light-vectr (:d ray)))
diffuse (max 0.0 (vectr-dot light-vectr
(vectr-scale normal -1) ) )
specular (Math/pow (max 0.0
(vectr-dot half-vectr
(vectr-scale normal -1)))
(:phong material))
color (:col material)]
(color-add (color-scale color (:amb material) )
(color-scale color (* diffuse (:diff material)))
(color-scale (:col light) (* specular
(:spec material))))))
(defn compute-color
[sphere light ray]
(let [intersects (sphere-intersect sphere ray)
material (:material sphere)]
(if (nil? intersects)
black-color
(let [point (ray-point-at ray (first intersects))
normal (sphere-surface-normal sphere point)]
(phong-compose point ray normal material light)))))
(let [img (make-image 400 400)
eye (make-vectr 200 200 -500)
sphere (make-sphere (make-vectr 200 200 300)
100
material-blue-plastic)
light (make-light (make-vectr 0 800 0) white-color) ]
(image-every-pixel
img
(fn [img x y w h]
(let [pixel (make-vectr x (- h 1 y) 0 )
ray (make-ray eye pixel)]
(image-set-pixel!
img
x y
(compute-color sphere light ray)))))
(image-save img (second *command-line-args* )))