summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chickadee/graphics/model.scm244
-rw-r--r--chickadee/graphics/pbr.scm152
-rw-r--r--chickadee/graphics/phong.scm107
-rw-r--r--data/shaders/pbr-frag.glsl4
-rw-r--r--data/shaders/phong-frag.glsl45
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