From 9187edcd45e97efd5b4d699c071bc1530f298d54 Mon Sep 17 00:00:00 2001 From: David Thompson Date: Sat, 8 May 2021 09:00:26 -0400 Subject: graphics: model: Add basic alpha mode support for glTF models. --- chickadee/graphics/model.scm | 11 +++++++---- chickadee/graphics/pbr.scm | 14 +++++++++----- data/shaders/pbr-frag.glsl | 22 ++++++++++++++++++++++ 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/chickadee/graphics/model.scm b/chickadee/graphics/model.scm index caec045..5228db8 100644 --- a/chickadee/graphics/model.scm +++ b/chickadee/graphics/model.scm @@ -905,11 +905,14 @@ (let ((v (or (array-ref/optional obj "emissiveFactor") #(1.0 1.0 1.0)))) (vec3 (vector-ref v 0) (vector-ref v 1) (vector-ref v 2)))) + ;; TODO: Sort primitives such that all OPAQUE and MASK + ;; objects are drawn first, then draw primitives with + ;; BLEND. (alpha-mode (match (or (string-ref/optional obj "alphaMode") - "BLEND") - ("OPAQUE" 'opaque) - ("MASK" 'mask) - ("BLEND" 'blend))) + "OPAQUE") + ("OPAQUE" 0) + ("MASK" 1) + ("BLEND" 2))) (alpha-cutoff (or (number-ref/optional obj "alphaCutoff") 0.5)) (double-sided? (boolean-ref/optional obj "doubleSided")) (extensions (object-ref/optional obj "extensions")) diff --git a/chickadee/graphics/pbr.scm b/chickadee/graphics/pbr.scm index 4b5b192..1f9853f 100644 --- a/chickadee/graphics/pbr.scm +++ b/chickadee/graphics/pbr.scm @@ -24,6 +24,7 @@ (define-module (chickadee graphics pbr) #:use-module (chickadee config) #:use-module (chickadee math vector) + #:use-module (chickadee graphics blend) #:use-module (chickadee graphics buffer) #:use-module (chickadee graphics color) #:use-module (chickadee graphics engine) @@ -77,7 +78,7 @@ (local-field emissive-texture pbr-material-emissive-texture) (bool emissive-texture-enabled pbr-material-emissive-texture-enabled) (int emissive-texcoord pbr-material-emissive-texcoord) - (local-field alpha-mode pbr-material-alpha-mode) + (int alpha-mode pbr-material-alpha-mode) (float alpha-cutoff pbr-material-alpha-cutoff) (local-field double-sided? pbr-material-double-sided?)) @@ -101,7 +102,7 @@ #:emissive-texture null-texture #:emissive-texture-enabled #f #:emissive-texcoord 0 - #:alpha-mode 'opaque + #:alpha-mode 0 #:alpha-cutoff 1.0 #:double-sided? #f)) @@ -113,9 +114,12 @@ (let* ((shader (graphics-variable-ref pbr-shader)) (vattrs (vertex-array-attributes vertex-array)) (sattrs (shader-attributes shader))) - (with-graphics-state ((g:cull-face-mode (if (pbr-material-double-sided? material) - no-cull-face-mode - back-cull-face-mode)) + (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-normal-texture material)) (g:texture-2 (pbr-material-occlusion-texture material)) diff --git a/data/shaders/pbr-frag.glsl b/data/shaders/pbr-frag.glsl index ce252ab..5b21fe1 100644 --- a/data/shaders/pbr-frag.glsl +++ b/data/shaders/pbr-frag.glsl @@ -15,6 +15,7 @@ struct Material { vec3 emissiveFactor; bool emissiveTextureEnabled; int emissiveTexcoord; + int alphaMode; float alphaCutoff; }; @@ -49,6 +50,25 @@ vec4 sampleTexture(sampler2D tex, bool enabled, int texcoord, vec3 factor, vec4 } } +vec4 applyAlpha(vec4 color) { + // Apply alpha mode. + if(material.alphaMode == 0) { + return vec4(color.xyz, 1.0); + } else if(material.alphaMode == 1) { + if(color.a >= material.alphaCutoff) { + return vec4(color.xyz, 1.0); + } else { + discard; + } + } else if(material.alphaMode == 2) { + if(color.a <= 0.005) { + discard; + } else { + return color; + } + } +} + void main(void) { vec4 finalColor = sampleTexture(baseColorTexture, material.baseColorTextureEnabled, @@ -77,6 +97,8 @@ void main(void) { material.emissiveTexcoord, material.emissiveFactor, vec4(0.0, 0.0, 0.0, 0.0)); + finalColor = applyAlpha(finalColor); + #ifdef GLSL330 fragColor = finalColor; #else -- cgit v1.2.3