From 08a6e2a06ac113b005aacd68a2aec8984d850a57 Mon Sep 17 00:00:00 2001 From: azimut Date: Tue, 5 Nov 2024 06:10:49 -0300 Subject: [PATCH] fix: properly support skybox in defer --- src/camera/defered.lisp | 2 +- src/postprocess/defer/defer.lisp | 48 ++++++++++++------------- src/postprocess/defer/ibl.lisp | 61 ++++++++++++++++---------------- src/postprocess/postprocess.lisp | 8 ++--- 4 files changed, 58 insertions(+), 61 deletions(-) diff --git a/src/camera/defered.lisp b/src/camera/defered.lisp index b0affd4..4c81453 100644 --- a/src/camera/defered.lisp +++ b/src/camera/defered.lisp @@ -10,7 +10,7 @@ (:default-initargs :fakeambient 0f0 :texture-opts - '((0 :element-type :rgba16f); color roughness + '((0 :element-type :rgba32f); color roughness (32 due I am abusing this as a hdr render for skybox) (1 :element-type :rgba32f); pos ao (2 :element-type :rgba16f); norm specular (3 :element-type :rg16f) ; metallic emissive diff --git a/src/postprocess/defer/defer.lisp b/src/postprocess/defer/defer.lisp index d4510ed..05df373 100644 --- a/src/postprocess/defer/defer.lisp +++ b/src/postprocess/defer/defer.lisp @@ -101,31 +101,31 @@ :fragment (defered-frag :vec2)) (defmethod blit ((scene scene) (postprocess list) (camera defered) time) - "takes defered camera samplers and blits into PREV" + "takes defered camera samplers and blits back into camera (mainly to deal with skybox)" (declare (ignore postprocess)) (destructuring-bind (s1 s2 s3 s4 _) (sam camera) (declare (ignore _)) (with-slots (prev bs) *state* - (with-fbo-bound ((fbo prev)) - (clear-fbo (fbo prev));; needed for scenes with no envmap - (with-blending (blend camera) - (alexandria:when-let - ((actor (find-if #'cube-p (actors scene)))) - (paint scene camera actor time)) - (map-g #'defer-pipe bs - :fakeambient (fakeambient camera) - :cam-pos (pos camera) - :scene (ubo scene) - ;; Samples - :sample1 s1 - :sample2 s2 - :sample3 s3 - :sample4 s4 - ;; Lights - :dirlights (dir-ubo *state*) - :spotlights (spot-ubo *state*) - :pointlights (point-ubo *state*) - ;; Shadows - :dirshadows (dir-sam *state*) - :spotshadows (spot-sam *state*) - :pointshadows (point-sam *state*))))))) + (map-g-into (fbo prev) #'defer-pipe bs + :fakeambient (fakeambient camera) + :cam-pos (pos camera) + :scene (ubo scene) + ;; Samples + :sample1 s1 + :sample2 s2 + :sample3 s3 + :sample4 s4 + ;; Lights + :dirlights (dir-ubo *state*) + :spotlights (spot-ubo *state*) + :pointlights (point-ubo *state*) + ;; Shadows + :dirshadows (dir-sam *state*) + :spotshadows (spot-sam *state*) + :pointshadows (point-sam *state*)) + (with-fbo-bound ((fbo camera)) + (map-g #'pass-pipe bs :sam (first (sam prev))) + (with-setf* ((depth-test-function) #'<=) + (alexandria:when-let ((actor (find-if #'cube-p (actors scene)))) + (paint scene camera actor time)))) + (map-g-into (fbo prev) #'pass-pipe bs :sam (first (sam camera)))))) diff --git a/src/postprocess/defer/ibl.lisp b/src/postprocess/defer/ibl.lisp index fa3feab..fcbde10 100644 --- a/src/postprocess/defer/ibl.lisp +++ b/src/postprocess/defer/ibl.lisp @@ -50,6 +50,7 @@ metallic color ao))) + (incf final-color (* emissive color)) (dotimes (i (scene-data-ndir scene)) (with-slots (colors positions lightspace fudge) dirlights @@ -98,10 +99,7 @@ (* (aref lightspace i) (v! frag-pos 1)) (aref fudge i) i))))) - (v! (+ ambient - final-color) - ;; TODO: this alpha is to blend the possible cubemap - (- 1 (step (y color) 0f0))))) + (v! (+ ambient final-color) 1))) (defpipeline-g defer-ibl-pipe (:points) :fragment (defered-ibl-frag :vec2)) @@ -109,30 +107,31 @@ (defmethod blit ((scene scene-ibl) (postprocess list) (camera defered) time) (destructuring-bind (s1 s2 s3 s4 _) (sam camera) (declare (ignore _)) - (with-blending (blend camera) - (with-slots (prev bs) *state* - (with-fbo-bound ((fbo prev)) - (clear-fbo (fbo prev)) ;; needed for scenes with no envmap - (alexandria:when-let - ((actor (find-if #'cube-p (actors scene)))) - (paint scene camera actor time)) - (map-g #'defer-ibl-pipe bs - :sample1 s1 - :sample2 s2 - :sample3 s3 - :sample4 s4 - :cam-pos (pos (current-camera)) - :scene (ubo scene) - :time time - ;; IBL - :brdf (brdf-sam *state*) - :prefilter (first (sam (prefilter scene))) - :irradiance (first (sam (irradiance scene))) - ;; Shadows - :dirshadows (dir-sam *state*) - :spotshadows (spot-sam *state*) - :pointshadows (point-sam *state*) - ;; Lights - :dirlights (dir-ubo *state*) - :spotlights (spot-ubo *state*) - :pointlights (point-ubo *state*))))))) + (with-slots (prev bs) *state* + (map-g-into (fbo prev) #'defer-ibl-pipe bs + :sample1 s1 + :sample2 s2 + :sample3 s3 + :sample4 s4 + :cam-pos (pos (current-camera)) + :scene (ubo scene) + :time time + ;; IBL + :brdf (brdf-sam *state*) + :prefilter (first (sam (prefilter scene))) + :irradiance (first (sam (irradiance scene))) + ;; Shadows + :dirshadows (dir-sam *state*) + :spotshadows (spot-sam *state*) + :pointshadows (point-sam *state*) + ;; Lights + :dirlights (dir-ubo *state*) + :spotlights (spot-ubo *state*) + :pointlights (point-ubo *state*)) + (with-fbo-bound ((fbo camera)) + (with-blending (blend camera) + (map-g #'pass-pipe bs :sam (first (sam prev))) + (with-setf* ((depth-test-function) #'<=) + (alexandria:when-let ((actor (find-if #'cube-p (actors scene)))) + (paint scene camera actor time))))) + (map-g-into (fbo prev) #'pass-pipe bs :sam (first (sam camera)))))) diff --git a/src/postprocess/postprocess.lisp b/src/postprocess/postprocess.lisp index 6e24ffd..3fdc0a2 100644 --- a/src/postprocess/postprocess.lisp +++ b/src/postprocess/postprocess.lisp @@ -16,21 +16,19 @@ (defpipeline-g pass-pipe (:points) :fragment (pass-frag :vec2)) -(defmethod blit - :around (scene (postprocess list) camera time) +(defmethod blit :AROUND (scene (postprocess list) camera time) (with-setf* ((depth-test-function) NIL (depth-mask) NIL (cull-face) NIL) (call-next-method))) (defmethod blit (scene (postprocess list) (camera renderable) time) - "main blit, puts forward CAMERA into PREV" ; WHY!? due shared logic with defer? + "puts forward CAMERA into PREV" ; WHY!? due shared logic with defer? (declare (ignore scene postprocess time)) (with-slots (prev bs) *state* (map-g-into (fbo prev) #'pass-pipe bs :sam (first (sam camera))))) -(defmethod blit - :after (scene (postprocess list) camera time) +(defmethod blit :AFTER (scene (postprocess list) camera time) ;; 1. ping-pong prev/next (dolist (post (butlast postprocess)) (with-fbo-bound ((fbo (next *state*)))