diff options
author | David Thompson <dthompson2@worcester.edu> | 2021-08-12 07:42:22 -0400 |
---|---|---|
committer | David Thompson <dthompson2@worcester.edu> | 2021-08-12 07:42:22 -0400 |
commit | caf243c60f84850a9a70c94db577dd2322a782fa (patch) | |
tree | 967f4d410359d3ba67d51afd6f8bdf171185ad9a | |
parent | d6b38a8357a5e7151e38c96047ff8d7f32c4b958 (diff) |
graphics: Refactor model/phong/pbr modules to use new mesh module.
-rw-r--r-- | chickadee/graphics/model.scm | 244 | ||||
-rw-r--r-- | chickadee/graphics/pbr.scm | 152 | ||||
-rw-r--r-- | chickadee/graphics/phong.scm | 107 | ||||
-rw-r--r-- | data/shaders/pbr-frag.glsl | 4 | ||||
-rw-r--r-- | data/shaders/phong-frag.glsl | 45 |
5 files changed, 206 insertions, 346 deletions
diff --git a/chickadee/graphics/model.scm b/chickadee/graphics/model.scm index 9afa91c..77d67b8 100644 --- a/chickadee/graphics/model.scm +++ b/chickadee/graphics/model.scm @@ -29,13 +29,16 @@ #:use-module (chickadee math quaternion) #:use-module (chickadee math vector) #:use-module (chickadee graphics buffer) + #:use-module (chickadee graphics blend) #:use-module (chickadee graphics color) #:use-module (chickadee graphics depth) #:use-module (chickadee graphics engine) #:use-module (chickadee graphics light) + #:use-module (chickadee graphics mesh) #:use-module (chickadee graphics multisample) #:use-module (chickadee graphics pbr) #:use-module (chickadee graphics phong) + #:use-module (chickadee graphics polygon) #:use-module (chickadee graphics shader) #:use-module (chickadee graphics texture) #:use-module (chickadee utils) @@ -67,37 +70,18 @@ ;;; (define-record-type <render-state> - (%make-render-state renderer view-matrix model-matrix world-model-matrix - camera-position lights ambient-light-color) + (%make-render-state model-matrix world-model-matrix) render-state? - (renderer render-state-renderer) - (view-matrix render-state-view-matrix) (model-matrix render-state-model-matrix) - (world-model-matrix render-state-world-model-matrix) - (camera-position render-state-camera-position) - (lights render-state-lights) - (ambient-light-color render-state-ambient-light-color - set-render-state-ambient-light-color!)) + (world-model-matrix render-state-world-model-matrix)) -(define %default-ambient-light-color (make-color 0.03 0.03 0.03 1.0)) - -(define (make-render-state renderer) - (%make-render-state renderer - (make-identity-matrix4) - (make-identity-matrix4) - (make-identity-matrix4) - (vec3 0.0 0.0 0.0) - (make-vector %max-lights %disabled-light) - %default-ambient-light-color)) +(define (make-render-state) + (%make-render-state (make-identity-matrix4) + (make-identity-matrix4))) (define (render-state-reset! state) - (matrix4-identity! (render-state-view-matrix state)) (matrix4-identity! (render-state-model-matrix state))) -(define (render-state-view-matrix-mult! state matrix) - (let ((view (render-state-view-matrix state))) - (matrix4-mult! view view matrix))) - (define (render-state-model-matrix-mult! state matrix) (let ((model (render-state-model-matrix state))) (matrix4-mult! model model matrix))) @@ -107,70 +91,6 @@ matrix (render-state-model-matrix state))) -(define (set-render-state-camera-position! state position) - (vec3-copy! position (render-state-camera-position state))) - -(define (set-render-state-lights! state lights) - (let ((lv (render-state-lights state))) - (let loop ((i 0) - (lights lights)) - (when (< i %max-lights) - (match lights - (() - (vector-set! lv i %disabled-light) - (loop (+ i 1) '())) - ((light . rest) - (vector-set! lv i light) - (loop (+ i 1) rest))))))) - - -;;; -;;; Primitive -;;; - -;; A piece of a mesh. Represents a single draw call. -(define-record-type <primitive> - (make-primitive name vertex-array material) - primitive? - (name primitive-name) - (vertex-array primitive-vertex-array) - (material primitive-material)) - -(define (draw-primitive/phong primitive state) - (shader-apply/phong (primitive-vertex-array primitive) - (primitive-material primitive) - (render-state-world-model-matrix state) - (render-state-view-matrix state) - (render-state-camera-position state) - (render-state-lights state) - (render-state-ambient-light-color state))) - -(define (draw-primitive/pbr primitive state) - (shader-apply/pbr (primitive-vertex-array primitive) - (primitive-material primitive) - (render-state-world-model-matrix state) - (render-state-view-matrix state) - (render-state-camera-position state) - (render-state-lights state) - (render-state-ambient-light-color state))) - - -;;; -;;; Mesh -;;; - -;; A complete 3D model composed of many primitives. -(define-record-type <mesh> - (make-mesh name primitives) - mesh? - (name mesh-name) - (primitives mesh-primitives)) - -(define (draw-mesh mesh state) - (let ((render (render-state-renderer state))) - (for-each (lambda (primitive) (render primitive state)) - (mesh-primitives mesh)))) - ;;; ;;; Model Node @@ -194,15 +114,22 @@ (children '())) (%make-model-node name mesh matrix world-matrix children)) -(define (draw-model-node node state) +(define (draw-model-node node state view-matrix camera-position ambient-light + lights) (for-each (lambda (child) - (draw-model-node child state)) + (draw-model-node child state view-matrix camera-position + ambient-light lights)) (model-node-children node)) (let ((mesh (model-node-mesh node))) (when mesh (render-state-world-model-matrix-mult! state (model-node-world-matrix node)) - (draw-mesh mesh state)))) + (draw-mesh mesh + #:model-matrix (render-state-world-model-matrix state) + #:view-matrix view-matrix + #:camera-position camera-position + #:ambient-light ambient-light + #:lights lights)))) ;;; @@ -225,19 +152,16 @@ (define %depth-test (make-depth-test)) (define* (draw-model model model-matrix view-matrix camera-position #:key - (lights '()) - (ambient-light-color %default-ambient-light-color)) + (ambient-light black) + (lights '())) (with-graphics-state ((g:depth-test %depth-test) (g:multisample? #t)) (let ((state (model-render-state model))) (render-state-reset! state) - (render-state-view-matrix-mult! state view-matrix) (render-state-model-matrix-mult! state model-matrix) - (set-render-state-camera-position! state camera-position) - (set-render-state-lights! state lights) - (set-render-state-ambient-light-color! state ambient-light-color) ;; TODO: Support drawing non-default scenes. - (draw-model-node (model-default-scene model) state)))) + (draw-model-node (model-default-scene model) state view-matrix + camera-position ambient-light lights)))) ;;; @@ -283,26 +207,32 @@ (define (maybe-add-material) (let ((name (assq-ref opts 'name))) (when name - (hash-set! material-map - name - (make-phong-material - #:name name - #:ambient (assq-ref opts 'ambient) - #:ambient-map (assq-ref opts 'ambient-map) - #:use-ambient-map - (assq-ref opts 'use-ambient-map?) - #:diffuse (assq-ref opts 'diffuse) - #:diffuse-map (assq-ref opts 'diffuse-map) - #:use-diffuse-map - (assq-ref opts 'use-diffuse-map?) - #:specular (assq-ref opts 'specular) - #:specular-map (assq-ref opts 'specular-map) - #:use-specular-map - (assq-ref opts 'use-specular-map?) - #:shininess (assq-ref opts 'shininess) - #:bump-map (assq-ref opts 'bump-map) - #:use-bump-map - (assq-ref opts 'use-bump-map?)))))) + (let* ((ambient (assq-ref opts 'ambient-map)) + (diffuse (assq-ref opts 'diffuse-map)) + (specular (assq-ref opts 'specular-map)) + (normals (assq-ref opts 'normal-map)) + (properties (make-phong-properties + #:ambient (assq-ref opts 'ambient) + #:use-ambient-map + (assq-ref opts 'use-ambient-map?) + #:diffuse (assq-ref opts 'diffuse) + #:use-diffuse-map + (assq-ref opts 'use-diffuse-map?) + #:specular (assq-ref opts 'specular) + #:use-specular-map + (assq-ref opts 'use-specular-map?) + #:shininess (assq-ref opts 'shininess) + #:use-normal-map + (assq-ref opts 'use-normal-map?))) + (material + (make-material #:name name + #:shader (phong-shader) + #:texture-0 ambient + #:texture-1 diffuse + #:texture-2 specular + #:texture-3 normals + #:properties properties))) + (hash-set! material-map name material))))) (match (read-line port) ((? eof-object?) (maybe-add-material)) @@ -384,15 +314,15 @@ (cons 'use-specular-map? #t) opts)))) (((or "map_Bump" "map_bump" "bump") . args) ; normal map - (let* ((bump-opts (parse-map-args args)) - (file (scope-file (assq-ref bump-opts + (let* ((normal-opts (parse-map-args args)) + (file (scope-file (assq-ref normal-opts 'file-name))) (texture (load-image file #:min-filter 'linear #:mag-filter 'linear #:flip? #f))) - (loop (cons* (cons 'bump-map texture) - (cons 'use-bump-map? #t) + (loop (cons* (cons 'normal-map texture) + (cons 'use-normal-map? #t) opts)))) (("newmtl" new-name) ;; Begin new material @@ -408,8 +338,8 @@ (specular-map . ,null-texture) (use-specular-map? . #f) (shininess . 1.0) - (bump-map . ,null-texture) - (use-bump-map? . #f)))) + (normal-map . ,null-texture) + (use-normal-map? . #f)))) (data (format (current-error-port) "warning: ~a:~d: unsupported MTL data: ~s~%" @@ -626,7 +556,7 @@ (or (hash-ref material-map material) (hash-ref material-map "default")))))) ;; Register default material - (hash-set! material-map "default" default-phong-material) + (hash-set! material-map "default" default-phong-properties) ;; Parse file. (let loop ((material "default")) (match (read-line port) @@ -684,8 +614,7 @@ #:mesh mesh))) (make-model #:name model-name #:scenes (list scene) - #:render-state - (make-render-state draw-primitive/phong))))))) + #:render-state (make-render-state))))))) ;;; @@ -962,32 +891,38 @@ (parse-texture obj "occlusionTexture")) ((emissive-texture emissive-texcoord) (parse-texture obj "emissiveTexture"))) - (make-pbr-material #:name name - #:base-color-factor base-color-factor - #:base-color-texture base-color-texture - #:base-color-texture-enabled (non-null-texture? base-color-texture) - #:base-color-texcoord base-color-texcoord - #:metallic-factor metallic-factor - #:roughness-factor roughness-factor - #:metallic-roughness-texture metal-rough-texture - #:metallic-roughness-texture-enabled (non-null-texture? metal-rough-texture) - #:metallic-roughness-texcoord metal-rough-texcoord - #:normal-factor normal-factor - #:normal-texture normal-texture - #:normal-texture-enabled (non-null-texture? normal-texture) - #:normal-texcoord normal-texcoord - #:occlusion-texture occlusion-texture - #:occlusion-texture-enabled (non-null-texture? occlusion-texture) - #:occlusion-texcoord occlusion-texcoord - #:emissive-factor emissive-factor - #:emissive-texture emissive-texture - #:emissive-texture-enabled (non-null-texture? emissive-texture) - #:emissive-texcoord emissive-texcoord - #:alpha-mode alpha-mode - #:alpha-cutoff alpha-cutoff - #:double-sided? double-sided?)))) + (make-material + #:name name + #:shader (pbr-shader) + #:blend-mode (if (= alpha-mode 2) blend:alpha blend:replace) + #:cull-face-mode (if double-sided? + no-cull-face-mode + back-cull-face-mode) + #:texture-0 base-color-texture + #:texture-1 metal-rough-texture + #:texture-2 normal-texture + #:texture-3 occlusion-texture + #:texture-4 emissive-texture + #:properties (make-pbr-properties + #:base-color-factor base-color-factor + #:base-color-texture-enabled (non-null-texture? base-color-texture) + #:base-color-texcoord base-color-texcoord + #:metallic-factor metallic-factor + #:roughness-factor roughness-factor + #:metallic-roughness-texture-enabled (non-null-texture? metal-rough-texture) + #:metallic-roughness-texcoord metal-rough-texcoord + #:normal-factor normal-factor + #:normal-texture-enabled (non-null-texture? normal-texture) + #:normal-texcoord normal-texcoord + #:occlusion-texture-enabled (non-null-texture? occlusion-texture) + #:occlusion-texcoord occlusion-texcoord + #:emissive-factor emissive-factor + #:emissive-texture-enabled (non-null-texture? emissive-texture) + #:emissive-texcoord emissive-texcoord + #:alpha-mode alpha-mode + #:alpha-cutoff alpha-cutoff))))) (define (attribute-name->index name) - (let ((shader (graphics-variable-ref pbr-shader))) + (let ((shader (pbr-shader))) (match name ("POSITION" (attribute-location @@ -1026,7 +961,7 @@ (#f #f) (n (vector-ref accessors n)))) (material (match (number-ref/optional obj "material") - (#f default-pbr-material) + (#f default-pbr-properties) (n (vector-ref materials n)))) (mode (match (or (number-ref/optional obj "mode") 4) (0 'points) @@ -1173,5 +1108,4 @@ (error "unsupported glTF version" version)) (make-model #:name (basename file-name) #:scenes (list default-scene) - #:render-state - (make-render-state draw-primitive/pbr)))))) + #:render-state (make-render-state)))))) diff --git a/chickadee/graphics/pbr.scm b/chickadee/graphics/pbr.scm index 0977579..16b5878 100644 --- a/chickadee/graphics/pbr.scm +++ b/chickadee/graphics/pbr.scm @@ -32,119 +32,77 @@ #:use-module (chickadee graphics shader) #:use-module (chickadee graphics texture) #:use-module (srfi srfi-9) - #:export (make-pbr-material - pbr-material? - pbr-material-name - pbr-material-base-color-factor - pbr-material-base-color-texture - pbr-material-base-color-texture-enabled? - pbr-material-base-color-texcoord - pbr-material-metallic-factor - pbr-material-roughness-factor - pbr-material-metallic-roughness-texture - pbr-material-metallic-roughness-texture-enabled? - pbr-material-metallic-roughness-texcoord - pbr-material-normal-factor - pbr-material-normal-texture - pbr-material-normal-texture-enabled? - pbr-material-normal-texcoord - pbr-material-occlusion-texture - pbr-material-occlusion-texture-enabled? - pbr-material-occlusion-texcoord - pbr-material-emissive-factor - pbr-material-emissive-texture - pbr-material-emissive-texture-enabled? - pbr-material-emissive-texcoord - pbr-material-alpha-mode - pbr-material-alpha-cutoff - pbr-material-double-sided? - default-pbr-material - pbr-shader - shader-apply/pbr)) + #:export (make-pbr-properties + pbr-properties? + pbr-properties-base-color-factor + pbr-properties-base-color-texture-enabled? + pbr-properties-base-color-texcoord + pbr-properties-metallic-factor + pbr-properties-roughness-factor + pbr-properties-metallic-roughness-texture-enabled? + pbr-properties-metallic-roughness-texcoord + pbr-properties-normal-factor + pbr-properties-normal-texture-enabled? + pbr-properties-normal-texcoord + pbr-properties-occlusion-texture-enabled? + pbr-properties-occlusion-texcoord + pbr-properties-emissive-factor + pbr-properties-emissive-texture-enabled? + pbr-properties-emissive-texcoord + pbr-properties-alpha-mode + pbr-properties-alpha-cutoff + default-pbr-properties + pbr-shader)) -(define-shader-type <pbr-material> - make-pbr-material - pbr-material? - (local-field name pbr-material-name) - (float-vec3 base-color-factor pbr-material-base-color-factor) - (local-field base-color-texture pbr-material-base-color-texture) - (bool base-color-texture-enabled pbr-material-base-color-texture-enabled?) - (int base-color-texcoord pbr-material-base-color-texcoord) - (float metallic-factor pbr-material-metallic-factor) - (float roughness-factor pbr-material-roughness-factor) - (local-field metallic-roughness-texture pbr-material-metallic-roughness-texture) - (bool metallic-roughness-texture-enabled pbr-material-metallic-roughness-texture-enabled?) - (int metallic-roughness-texcoord pbr-material-metallic-roughness-texcoord) - (float-vec3 normal-factor pbr-material-normal-factor) - (local-field normal-texture pbr-material-normal-texture) - (bool normal-texture-enabled pbr-material-normal-texture-enabled) - (int normal-texcoord pbr-material-normal-texcoord) - (local-field occlusion-texture pbr-material-occlusion-texture) - (bool occlusion-texture-enabled pbr-material-occlusion-texture-enabled) - (int occlusion-texcoord pbr-material-occlusion-texcoord) - (float-vec3 emissive-factor pbr-material-emissive-factor) - (local-field emissive-texture pbr-material-emissive-texture) - (bool emissive-texture-enabled pbr-material-emissive-texture-enabled) - (int emissive-texcoord pbr-material-emissive-texcoord) - (int alpha-mode pbr-material-alpha-mode) - (float alpha-cutoff pbr-material-alpha-cutoff) - (local-field double-sided? pbr-material-double-sided?)) +(define-shader-type <pbr-properties> + make-pbr-properties + pbr-properties? + (float-vec3 base-color-factor pbr-properties-base-color-factor) + (bool base-color-texture-enabled pbr-properties-base-color-texture-enabled?) + (int base-color-texcoord pbr-properties-base-color-texcoord) + (float metallic-factor pbr-properties-metallic-factor) + (float roughness-factor pbr-properties-roughness-factor) + (bool metallic-roughness-texture-enabled pbr-properties-metallic-roughness-texture-enabled?) + (int metallic-roughness-texcoord pbr-properties-metallic-roughness-texcoord) + (float-vec3 normal-factor pbr-properties-normal-factor) + (bool normal-texture-enabled pbr-properties-normal-texture-enabled) + (int normal-texcoord pbr-properties-normal-texcoord) + (bool occlusion-texture-enabled pbr-properties-occlusion-texture-enabled) + (int occlusion-texcoord pbr-properties-occlusion-texcoord) + (float-vec3 emissive-factor pbr-properties-emissive-factor) + (bool emissive-texture-enabled pbr-properties-emissive-texture-enabled) + (int emissive-texcoord pbr-properties-emissive-texcoord) + (int alpha-mode pbr-properties-alpha-mode) + (float alpha-cutoff pbr-properties-alpha-cutoff)) -(define default-pbr-material - (make-pbr-material #:name "default" - #:base-color-factor #v(1.0 1.0 1.0) - #:base-color-texture null-texture +(define default-pbr-properties + (make-pbr-properties #:base-color-factor #v(1.0 1.0 1.0) #:base-color-texture-enabled #f #:base-color-texcoord 0 #:metallic-factor 1.0 #:roughness-factor 1.0 - #:metallic-roughness-texture null-texture #:metallic-roughness-texture-enabled #f #:metallic-roughness-texcoord 0 #:normal-factor #v(1.0 1.0 1.0) - #:normal-texture null-texture #:normal-texture-enabled #f #:normal-texcoord 0 - #:occlusion-texture null-texture #:occlusion-texture-enabled #f #:occlusion-texcoord 0 #:emissive-factor #v(1.0 1.0 1.0) - #:emissive-texture null-texture #:emissive-texture-enabled #f #:emissive-texcoord 0 #:alpha-mode 0 - #:alpha-cutoff 0.5 - #:double-sided? #f)) + #:alpha-cutoff 0.5)) -(define-graphics-variable pbr-shader - (load-shader (scope-datadir "shaders/pbr-vert.glsl") - (scope-datadir "shaders/pbr-frag.glsl"))) +(define %pbr-shader + (delay (load-shader (scope-datadir "shaders/pbr-vert.glsl") + (scope-datadir "shaders/pbr-frag.glsl")))) -(define (shader-apply/pbr vertex-array material model-matrix view-matrix - camera-position lights ambient-light-color) - (let* ((shader (graphics-variable-ref pbr-shader)) - (vattrs (vertex-array-attributes vertex-array)) - (sattrs (shader-attributes shader))) - (with-graphics-state ((g:blend-mode (if (= (pbr-material-alpha-mode material) 2) - blend:alpha - blend:replace)) - (g:cull-face-mode (if (pbr-material-double-sided? material) - no-cull-face-mode - back-cull-face-mode)) - (g:texture-0 (pbr-material-base-color-texture material)) - (g:texture-1 (pbr-material-metallic-roughness-texture material)) - (g:texture-2 (pbr-material-normal-texture material)) - (g:texture-3 (pbr-material-occlusion-texture material)) - (g:texture-4 (pbr-material-emissive-texture material))) - (shader-apply shader vertex-array - #:model model-matrix - #:view view-matrix - #:projection (current-projection) - #:vertex-colored (buffer-view? - (assv-ref vattrs - (attribute-location - (hash-ref sattrs "color0")))) - #:camera-position camera-position - #:material material - #:ambient-light-color ambient-light-color - #:lights lights)))) +(define (pbr-shader) + (force %pbr-shader)) + +;; TODO: Handle vertex colors +;; (buffer-view? +;; (assv-ref vattrs +;; (attribute-location +;; (hash-ref sattrs "color0")))) diff --git a/chickadee/graphics/phong.scm b/chickadee/graphics/phong.scm index 5288075..edb8686 100644 --- a/chickadee/graphics/phong.scm +++ b/chickadee/graphics/phong.scm @@ -30,83 +30,56 @@ #:use-module (chickadee graphics shader) #:use-module (chickadee graphics texture) #:use-module (srfi srfi-9) - #:export (make-phong-material - phong-material? - phong-material-name - phong-material-ambient - phong-material-ambient-map - phong-material-use-ambient-map? - phong-material-diffuse - phong-material-diffuse-map - phong-material-use-diffuse-map? - phong-material-specular - phong-material-specular-map? - phong-material-use-specular-map? - phong-material-specular-exponent - phong-material-bump-map - phong-material-use-bump-map? - default-phong-material - load-phong-shader - shader-apply/phong)) + #:export (make-phong-properties + phong-properties? + phong-properties-name + phong-properties-ambient + phong-properties-use-ambient-map? + phong-properties-diffuse + phong-properties-use-diffuse-map? + phong-properties-specular + phong-properties-specular-map? + phong-properties-use-specular-map? + phong-properties-specular-exponent + phong-properties-use-normal-map? + default-phong-properties + phong-shader)) ;;; -;;; Phong Material +;;; Phong Properties ;;; -(define-shader-type <phong-material> - make-phong-material - phong-material? - (local-field name phong-material-name) - (float-vec3 ambient phong-material-ambient) - (local-field ambient-map phong-material-ambient-map) - (bool use-ambient-map phong-material-use-ambient-map?) - (float-vec3 diffuse phong-material-diffuse) - (local-field diffuse-map phong-material-diffuse-map) - (bool use-diffuse-map phong-material-use-diffuse-map?) - (float-vec3 specular phong-material-specular) - (local-field specular-map phong-material-specular-map) - (bool use-specular-map phong-material-use-specular-map?) - (float shininess phong-material-shininess) - (local-field bump-map phong-material-bump-map) - (bool use-bump-map phong-material-use-bump-map?)) +(define-shader-type <phong-properties> + make-phong-properties + phong-properties? + (float-vec3 ambient phong-properties-ambient) + (bool use-ambient-map phong-properties-use-ambient-map?) + (float-vec3 diffuse phong-properties-diffuse) + (bool use-diffuse-map phong-properties-use-diffuse-map?) + (float-vec3 specular phong-properties-specular) + (bool use-specular-map phong-properties-use-specular-map?) + (float shininess phong-properties-shininess) + (bool use-normal-map phong-properties-use-normal-map?)) -(define default-phong-material - (make-phong-material #:name "default" - #:ambient (vec3 0.5 0.5 0.5) - #:ambient-map null-texture - #:use-ambient-map #f - #:diffuse (vec3 0.8 0.8 0.8) - #:diffuse-map null-texture - #:use-diffuse-map #f - #:specular (vec3 0.3 0.3 0.3) - #:specular-map null-texture - #:use-specular-map #f - #:shininess 32.0 - #:bump-map null-texture - #:use-bump-map #f)) +(define default-phong-properties + (make-phong-properties #:ambient (vec3 0.5 0.5 0.5) + #:use-ambient-map #f + #:diffuse (vec3 0.8 0.8 0.8) + #:use-diffuse-map #f + #:specular (vec3 1.0 1.0 1.0) + #:use-specular-map #f + #:shininess 32.0 + #:use-normal-map #f)) ;;; ;;; Phong Shader ;;; -(define-graphics-variable phong-shader - (load-shader (scope-datadir "shaders/phong-vert.glsl") - (scope-datadir "shaders/phong-frag.glsl"))) +(define %phong-shader + (delay (load-shader (scope-datadir "shaders/phong-vert.glsl") + (scope-datadir "shaders/phong-frag.glsl")))) -(define (shader-apply/phong vertex-array material model-matrix view-matrix - camera-position lights ambient-light-color) - (let ((shader (graphics-variable-ref phong-shader))) - (with-graphics-state ((g:texture-0 (phong-material-ambient-map material)) - (g:texture-1 (phong-material-diffuse-map material)) - (g:texture-2 (phong-material-specular-map material)) - (g:texture-3 (phong-material-bump-map material))) - (shader-apply shader vertex-array - #:model model-matrix - #:view view-matrix - #:projection (current-projection) - #:material material - #:camera-position camera-position - #:ambient-light-color ambient-light-color - #:lights lights)))) +(define (phong-shader) + (force %phong-shader)) diff --git a/data/shaders/pbr-frag.glsl b/data/shaders/pbr-frag.glsl index a941a29..478c40a 100644 --- a/data/shaders/pbr-frag.glsl +++ b/data/shaders/pbr-frag.glsl @@ -53,7 +53,7 @@ out vec4 fragColor; uniform Material material; uniform Light lights[MAX_LIGHTS]; -uniform vec4 ambientLightColor; +uniform vec4 ambientLight; uniform bool vertexColored; uniform vec3 cameraPosition; uniform sampler2D baseColorTexture; @@ -386,7 +386,7 @@ void main(void) { // is dampened by the ambient occlusion factor. // // TODO: Use image based lighting. - color += ambientLightColor.rgb * albedo * ambientOcclusion; + color += ambientLight.rgb * albedo * ambientOcclusion; // Apply Reinhard tone mapping to convert our high dynamic range // color value to low dynamic range. All of the lighting // calculations stacked on top of each other is likely to create diff --git a/data/shaders/phong-frag.glsl b/data/shaders/phong-frag.glsl index 7cab3f8..363c4e7 100644 --- a/data/shaders/phong-frag.glsl +++ b/data/shaders/phong-frag.glsl @@ -2,17 +2,13 @@ struct Material { vec3 ambient; - sampler2D ambientMap; bool useAmbientMap; vec3 diffuse; - sampler2D diffuseMap; bool useDiffuseMap; vec3 specular; - sampler2D specularMap; bool useSpecularMap; float shininess; - sampler2D bumpMap; - bool useBumpMap; + bool useNormalMap; }; struct Light { @@ -40,10 +36,14 @@ in vec2 fragTex; out vec4 fragColor; #endif +uniform sampler2D ambientMap; +uniform sampler2D diffuseMap; +uniform sampler2D specularMap; +uniform sampler2D normalMap; uniform Material material; uniform Light lights[MAX_LIGHTS]; uniform vec3 cameraPosition; -uniform vec4 ambientLightColor; +uniform vec4 ambientLight; const float GAMMA = 2.2; @@ -54,10 +54,6 @@ vec2 texture(sampler2D tex, vec2 coord) { } #endif -float posDot(vec3 v1, vec3 v2) { - return max(dot(v1, v2), 0.0); -} - vec3 gammaCorrect(vec3 color) { return pow(color, vec3(1.0 / GAMMA)); } @@ -105,7 +101,7 @@ vec3 lightRadiance(Light light, vec3 direction) { vec3 materialAmbient() { if(material.useAmbientMap) { - return texture(material.ambientMap, fragTex).rgb; + return texture(ambientMap, fragTex).rgb; } else { return material.ambient; } @@ -113,7 +109,7 @@ vec3 materialAmbient() { vec3 materialDiffuse() { if(material.useDiffuseMap) { - vec4 color = texture(material.diffuseMap, fragTex); + vec4 color = texture(diffuseMap, fragTex); // discard transparent fragments. if(color.a == 0.0) { discard; @@ -126,18 +122,18 @@ vec3 materialDiffuse() { vec3 materialSpecular() { if(material.useSpecularMap) { - return texture(material.specularMap, fragTex).rgb; + return texture(specularMap, fragTex).rgb; } else { return material.specular; } } vec3 materialNormal() { - if(material.useBumpMap) { + if(material.useNormalMap) { // Compute tangent space using fragment data rather than relying // on tangent attributes. See: // http://www.thetenthplanet.de/archives/1180 - vec3 tangentNormal = normalize(texture(material.bumpMap, fragTex).xyz * 2.0 - 1.0); + vec3 tangentNormal = normalize(texture(normalMap, fragTex).xyz * 2.0 - 1.0); vec3 q1 = dFdx(fragWorldPos); vec3 q2 = dFdy(fragWorldPos); vec2 st1 = dFdx(fragTex); @@ -156,8 +152,8 @@ vec3 materialNormal() { void main() { vec3 viewDir = normalize(cameraPosition - fragWorldPos); vec3 ambientOcclusion = materialAmbient(); - vec3 baseDiffuseColor = materialDiffuse(); - vec3 baseSpecularColor = materialSpecular(); + vec3 diffuseColor = materialDiffuse(); + vec3 specularColor = materialSpecular(); vec3 normal = materialNormal(); vec3 color = vec3(0.0); @@ -170,18 +166,17 @@ void main() { } vec3 lightDir = lightDirection(light); - vec3 radiance = lightRadiance(light, lightDir); - float diffuseFactor = posDot(lightDir, normal); - vec3 reflectDir = reflect(-lightDir, normal); - vec3 diffuseColor = baseDiffuseColor * diffuseFactor; vec3 halfVector = normalize(lightDir + viewDir); - float specularFactor = pow(posDot(halfVector, normal), material.shininess); - vec3 specularColor = baseSpecularColor * specularFactor; - color += (diffuseColor + specularColor) * radiance; + vec3 radiance = lightRadiance(light, lightDir); + float lambert = clamp(dot(normal, lightDir), 0.0, 1.0); + vec3 diffuseLight = radiance * lambert; + float specularFactor = clamp(dot(halfVector, normal), 0.0, 1.0) * float(lambert > 0.0); + vec3 specularLight = radiance * pow(specularFactor, material.shininess); + color += diffuseLight * diffuseColor + specularLight * specularColor; } // Apply ambient lighting. - vec3 ambientColor = baseDiffuseColor * ambientLightColor.rgb * ambientOcclusion; + vec3 ambientColor = diffuseColor * ambientLight.rgb * ambientOcclusion; color += ambientColor; // Apply gamma correction and HDR tone mapping to get the final |