;;; Chickadee Game Toolkit ;;; Copyright © 2019 David Thompson ;;; ;;; Chickadee is free software: you can redistribute it and/or modify ;;; it under the terms of the GNU General Public License as published ;;; by the Free Software Foundation, either version 3 of the License, ;;; or (at your option) any later version. ;;; ;;; Chickadee is distributed in the hope that it will be useful, but ;;; WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;; General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with this program. If not, see ;;; . ;;; Commentary: ;; ;; Physically based lighting model. ;; ;;; Code: (define-module (chickadee graphics pbr) #:use-module (chickadee math vector) #:use-module (chickadee graphics) #:use-module (chickadee graphics color) #: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-metallic-factor pbr-material-roughness-factor pbr-material-metallic-roughness-texture pbr-material-normal-factor pbr-material-normal-texture pbr-material-occlusion-facgor pbr-material-occlusion-texture pbr-material-emissive-factor pbr-material-emissive-texture pbr-material-alpha-mode pbr-material-alpha-cutoff pbr-material-double-sided? default-pbr-material load-pbr-shader gpu-apply/pbr)) (define-shader-type 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) (float metallic-factor pbr-material-metallic-factor) (float roughness-factor pbr-material-roughness-factor) (local-field metallic-roughness-texture pbr-material-metallic-roughness-texture) (float-vec3 normal-factor pbr-material-normal-factor) (local-field normal-texture pbr-material-normal-texture) (float-vec3 occlusion-factor pbr-material-occlusion-factor) (local-field occlusion-texture pbr-material-occlusion-texture) (float-vec3 emissive-factor pbr-material-emissive-factor) (local-field emissive-texture pbr-material-emissive-texture) (local-field alpha-mode pbr-material-alpha-mode) (float alpha-cutoff pbr-material-alpha-cutoff) (bool double-sided? pbr-material-double-sided?)) (define default-pbr-material (make-pbr-material #:name "default" #:base-color-factor #v(1.0 1.0 1.0) #:base-color-texture null-texture #:metallic-factor 1.0 #:roughness-factor 1.0 #:metallic-roughness-texture null-texture #:normal-factor #v(1.0 1.0 1.0) #:normal-texture null-texture #:occlusion-factor #v(1.0 1.0 1.0) #:occlusion-texture null-texture #:emissive-factor #v(1.0 1.0 1.0) #:emissive-texture null-texture #:alpha-mode 'opaque #:alpha-cutoff 0.5 #:double-sided? #f)) ;; TODO: Actually implement PBR. For now it's just the minimal amount ;; of code needed to render the base texture of a mesh. (define pbr-shader (delay (strings->shader " #ifdef GLSL330 layout (location = 0) in vec3 position; layout (location = 1) in vec2 texcoord0; #elif defined(GLSL130) in vec3 position; in vec2 texcoord0; #elif defined(GLSL120) attribute vec3 position; attribute vec2 texcoord0; #endif #ifdef GLSL120 varying vec2 fragTex; #else out vec2 fragTex; #endif uniform mat4 model; uniform mat4 view; uniform mat4 projection; void main(void) { fragTex = texcoord0; gl_Position = projection * view * model * vec4(position.xyz, 1.0); } " " #ifdef GLSL120 attribute vec2 fragTex; #else in vec2 fragTex; #endif #ifdef GLSL330 out vec4 fragColor; #endif uniform vec3 baseColorFactor; uniform sampler2D baseColorTexture; void main (void) { #ifdef GLSL330 fragColor = texture(baseColorTexture, fragTex) * vec4(baseColorFactor, 1.0); #else gl_FragColor = texture2D(baseColorTexture, fragTex) * vec4(baseColorFactor, 1.0); #endif } "))) (define (load-pbr-shader) (force pbr-shader)) (define (gpu-apply/pbr shader vertex-array material model-matrix view-matrix) (with-texture 0 (pbr-material-base-color-texture material) (gpu-apply shader vertex-array #:model model-matrix #:view view-matrix #:projection (current-projection) #:base-color-factor (pbr-material-base-color-factor material))))