forked from Shirakumo/trial
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathssao.lisp
62 lines (55 loc) · 2.55 KB
/
ssao.lisp
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
#|
This file is a part of trial
(c) 2019 Shirakumo http://tymoon.eu ([email protected])
Author: Nicolas Hafner <[email protected]>
|#
(in-package #:org.shirakumo.fraf.trial)
(defun generate-ssao-noise (&optional (samples 16))
(let ((array (make-array (* samples 3) :element-type 'single-float)))
(dotimes (i samples array)
(setf (aref array (+ 0 (* 3 i))) (1- (* 2 (random 1.0))))
(setf (aref array (+ 1 (* 3 i))) (1- (* 2 (random 1.0))))
(setf (aref array (+ 2 (* 3 i))) 0.0))))
(defun generate-ssao-kernel (&optional (samples 64))
(let ((array (make-array samples)))
(flet ((lerp (a b f)
(+ a (* f (- b a)))))
(dotimes (i samples array)
(let* ((scale (lerp 0.1 1.0 (expt (/ i samples) 2)))
(sample (vec3 (1- (* 2 (random 1.0)))
(1- (* 2 (random 1.0)))
(random 1.0)))
(sample (nv* (nvunit sample) (random 1.0) scale)))
(setf (aref array i) sample))))))
(define-shader-pass ssao-pass (post-effect-pass)
((position-map :port-type input)
(normal-map :port-type input)
(noise-map :port-type buffer
:texspec (:width 4
:height 4
:min-filter :nearest
:mag-filter :nearest
:wrapping :repeat
:internal-format :rgb32f
:pixel-format :rgb
:pixel-type :float))
(occlusion :port-type output
:attachment :color-attachment0
:texspec (:internal-format :rgb
:min-filter :nearest
:mag-filter :nearest))
(kernel :initform (generate-ssao-kernel) :accessor kernel))
(:inhibit-shaders (shader-entity :fragment-shader (generate-ssao-noise))))
(defmethod initialize-instance :after ((pass ssao-pass) &key)
(setf (getf (texspec (port pass 'noise-map)) :pixel-data) (generate-ssao-noise)))
(defmethod render :before ((pass ssao-pass) (program shader-program))
(let ((kernel (kernel pass)))
(loop for i from 0 below (length kernel)
for vec of-type vec3 = (aref kernel i)
do (setf (uniform program (format NIL "samples[~d]" i)) vec))
(setf (uniform program "projection_matrix") *projection-matrix*)
(setf (uniform program "view_matrix") *view-matrix*)
(setf (uniform program "viewport_size") (vec2 (width *context*) (height *context*)))))
(define-class-shader (ssao-pass :fragment-shader)
;; KLUDGE
(asdf:system-relative-pathname :trial "data/ssao.frag"))