diff --git a/app.scm b/app.scm index c199738..079f035 100755 --- a/app.scm +++ b/app.scm @@ -6,20 +6,20 @@ ;; (export run)) (import (chezscheme) (vulkan) - (matchable)) + (matchable) + (prelude)) + ;; (define run ;; (lambda ())) (let ((state (setup-vulkan)) (shaders (make-shaders "shaders/shader.vert" "shaders/shader.frag"))) - (match-let* (((vertex-input-metadata . pipeline) - (create-pipeline state - shaders - "models/sampleroom.dae")) - ((uniform-buffers . command-buffers) (create-buffers state - vertex-input-metadata - pipeline))) - (run-draw-loop state uniform-buffers command-buffers))) + (displayln "creating pipeline") + (match-let* (((pipeline vertex-input-metadata render-pass) + (create-pipeline state shaders "models/sampleroom.dae")) + ((command-buffers uniform-buffers camera-matrix) + (create-buffers state pipeline vertex-input-metadata render-pass))) + (run-draw-loop state uniform-buffers command-buffers camera-matrix))) ;; (parameterize ([optimize-level 3] ;; [debug-level 0]) diff --git a/assimp.scm b/assimp.scm index de9934e..9cce61b 100644 --- a/assimp.scm +++ b/assimp.scm @@ -1,4 +1,3 @@ -;; ;; ffi bindings for assimp ;; @@ -106,10 +105,10 @@ (define-ftype aabb (struct (min vector3) - (max vector3))) + (max vector3))) ;; // ------------------------------------------------------------------------------- -;; /** +;; /** ;; * A node in the imported hierarchy. ;; * ;; * Each node has name, a parent node (except for the root node), @@ -201,8 +200,9 @@ ;; load library - -(define o (load-shared-object "libassimp.so.5.0.0")) +(define o (load-shared-library (make-library-detail #f + "libassimp.so.5.0.0" + "phoenix-libs/assimp-vc142-mtd.dll"))) ;; define native functions @@ -223,29 +223,29 @@ (define (mesh-ptr->vertex-buffer-data mesh-ptr) (let* ((num-vertices (mesh-num-vertices mesh-ptr)) - (vertices - (map flip-vertices - (vector3-array-ptr->list (make-array-pointer num-vertices - (mesh-vertices mesh-ptr) - 'vector3)))) - (normals - (vector3-array-ptr->list (make-array-pointer num-vertices - (mesh-normals mesh-ptr) - 'vector3))) - - ;; Texture coordinates may have multiple channels, we only use the first we find - (texture-coords-channel - (find (lambda (ptr) - (not (ftype-pointer-null? ptr))) (mesh-texture-coords mesh-ptr))) - - (texture-coords - (map (lambda (uv-coords) - (cond - ((list? uv-coords) (list (car uv-coords) (cadr uv-coords))) - (else (error "uv channels are missing" mesh-ptr)))) - (vector3-array-ptr->list (make-array-pointer num-vertices - texture-coords-channel - 'vector3))))) + (vertices + (map flip-vertices + (vector3-array-ptr->list (make-array-pointer num-vertices + (mesh-vertices mesh-ptr) + 'vector3)))) + (normals + (vector3-array-ptr->list (make-array-pointer num-vertices + (mesh-normals mesh-ptr) + 'vector3))) + + ;; Texture coordinates may have multiple channels, we only use the first we find + (texture-coords-channel + (find (lambda (ptr) + (not (ftype-pointer-null? ptr))) (mesh-texture-coords mesh-ptr))) + + (texture-coords + (map (lambda (uv-coords) + (cond + ((list? uv-coords) (list (car uv-coords) (cadr uv-coords))) + (else (error "uv channels are missing" mesh-ptr)))) + (vector3-array-ptr->list (make-array-pointer num-vertices + texture-coords-channel + 'vector3))))) (displayln "vertices are number: " num-vertices) (make-vertex-buffer-data vertices normals texture-coords #f))) @@ -253,17 +253,17 @@ ;; data for index buffer (define mesh-ptr->indices - (lambda (mesh-ptr vertex-offset) + (lambda (mesh-ptr vertex-offset) (displayln "num of faces is " (mesh-num-faces mesh-ptr)) (concatenate (face-pointer-map - (lambda (face-ptr) - (unsigned-pointer-map (lambda (x) (+ vertex-offset (read-unsigned x))) - (make-array-pointer (face-num-indices face-ptr) - (face-indices face-ptr) - 'unsigned))) - (make-array-pointer (mesh-num-faces mesh-ptr) - (mesh-faces mesh-ptr) - 'face))))) + (lambda (face-ptr) + (unsigned-pointer-map (lambda (x) (+ vertex-offset (read-unsigned x))) + (make-array-pointer (face-num-indices face-ptr) + (face-indices face-ptr) + 'unsigned))) + (make-array-pointer (mesh-num-faces mesh-ptr) + (mesh-faces mesh-ptr) + 'face))))) ;; record to collect the data required from assimp @@ -287,47 +287,47 @@ (define mesh-ptr->model-data (lambda (mesh-ptr vertex-offset) - (let ((vertex-data (mesh-ptr->vertex-buffer-data mesh-ptr)) - (indices (mesh-ptr->indices mesh-ptr vertex-offset))) - (make-model-data vertex-data indices)))) + (let ((vertex-data (mesh-ptr->vertex-buffer-data mesh-ptr)) + (indices (mesh-ptr->indices mesh-ptr vertex-offset))) + (make-model-data vertex-data indices)))) (define mesh-indices->model-data (lambda (mesh-indices mesh-list vertex-offset) - (unsigned-pointer-map (lambda (mesh-index) - (mesh-ptr->model-data (list-ref mesh-list - (read-unsigned mesh-index)) - vertex-offset)) - mesh-indices))) + (unsigned-pointer-map (lambda (mesh-index) + (mesh-ptr->model-data (list-ref mesh-list + (read-unsigned mesh-index)) + vertex-offset)) + mesh-indices))) (define process-node (lambda (node-ptr meshes-list collected-mesh-data) - (let* ((num-meshes (node-num-meshes node-ptr)) - (mesh-indices (make-array-pointer num-meshes (node-meshes node-ptr) 'unsigned)) - (num-children (node-num-children node-ptr)) - (child-nodes (double-pointer->list (node-children node-ptr) - node - num-children)) - (vertex-offset (fold-left (lambda (offset model-data) - (+ offset - (length (vertex-buffer-data-vertices - (model-data-vertex-data model-data))))) - 0 - collected-mesh-data))) - (let ((current-mesh-data (mesh-indices->model-data mesh-indices - meshes-list - vertex-offset))) - (fold-left (lambda (data child-node-ptr) - (process-node child-node-ptr meshes-list data)) - (append collected-mesh-data current-mesh-data) - child-nodes))))) - + (let* ((num-meshes (node-num-meshes node-ptr)) + (mesh-indices (make-array-pointer num-meshes (node-meshes node-ptr) 'unsigned)) + (num-children (node-num-children node-ptr)) + (child-nodes (double-pointer->list (node-children node-ptr) + node + num-children)) + (vertex-offset (fold-left (lambda (offset model-data) + (+ offset + (length (vertex-buffer-data-vertices + (model-data-vertex-data model-data))))) + 0 + collected-mesh-data))) + (let ((current-mesh-data (mesh-indices->model-data mesh-indices + meshes-list + vertex-offset))) + (fold-left (lambda (data child-node-ptr) + (process-node child-node-ptr meshes-list data)) + (append collected-mesh-data current-mesh-data) + child-nodes))))) + (let* ((scene-ptr (import_file model - (bitwise-ior pretransform-vertices - triangulate - gen-normals))) - (meshes-list (double-pointer->list (scene-meshes scene-ptr) - mesh - (scene-num-meshes scene-ptr)))) + (bitwise-ior pretransform-vertices + triangulate + gen-normals))) + (meshes-list (double-pointer->list (scene-meshes scene-ptr) + mesh + (scene-num-meshes scene-ptr)))) (displayln "scene meshes " (scene-num-meshes scene-ptr)) (process-node (scene-root-node scene-ptr) meshes-list (list))))) @@ -335,7 +335,7 @@ ;; > (load "assimp.scm") ;; > (import (assimp)) -(define model-file "models/sampleroom.dae") +(define model-file "models/cube.dae") (define model-data-obj (import-model model-file)) ;; (define model-data-obj (import-model "models/cube.obj")) ;; (define model-data-obj (import-model "models/Sponza-master/sponza.obj")) diff --git a/assimp.sls b/assimp.sls index 195ef4e..bd44af6 100644 --- a/assimp.sls +++ b/assimp.sls @@ -11,7 +11,7 @@ model-data-vertex-data model-data-indices) (import (chezscheme) - (ffi) - (prelude)) + (ffi) + (prelude)) (include "assimp.scm")) diff --git a/camera.scm b/camera.scm index 470823a..cb9ab89 100644 --- a/camera.scm +++ b/camera.scm @@ -32,7 +32,8 @@ (define vector->list (lambda (vector) (match vector - (($ vector4 x y z w) (list x y z w))))) + (($ vector4 x y z w) (list x y z w)) + (($ vector3 x y z) (list x y z))))) (define matrix->list (lambda (matrix) @@ -149,15 +150,15 @@ (make-vector4 0.0 0.0 1.0 0.0) (make-vector4 0.0 0.0 0.0 1.0)))) - (define test-matrix (make-matrix4 (make-vector4 1 2 3 4) - (make-vector4 1 2 3 4) - (make-vector4 1 2 3 4) - (make-vector4 1 2 3 4))) + (define test-matrix (make-matrix4 (make-vector4 1.0 2.0 3.0 4.0) + (make-vector4 1.0 2.0 3.0 4.0) + (make-vector4 1.0 2.0 3.0 4.0) + (make-vector4 1.0 2.0 3.0 4.0))) - ;; (define matrix4-identity (make-matrix4 (make-vector4 1 0 0 0) - ;; (make-vector4 0 1 0 0) - ;; (make-vector4 0 0 1 0) - ;; (make-vector4 0 0 0 1))) + (define matrix4-identity (make-matrix4 (make-vector4 1 0 0 0) + (make-vector4 0 1 0 0) + (make-vector4 0 0 1 0) + (make-vector4 0 0 0 1))) ;; (display-matrix test-matrix) @@ -293,8 +294,9 @@ (define mvp-matrix->list (lambda (mvp-matrix-obj) (match mvp-matrix-obj - (($ mvp-matrix model view projection) - (apply append (map matrix->list (list model view projection))))))) + (($ mvp-matrix model view projection eye) + (append (apply append (map matrix->list (list model view projection))) + (vector->list eye)))))) (define up (make-vector3 0.0 1.0 0.0)) @@ -369,13 +371,10 @@ (match current-matrix (($ mvp-matrix model view projection eye center) - (let ((eye (car (update-eye-center eye-position center)))) - (let ((view (update-view-matrix eye camera-rotation))) - (cons (make-mvp-matrix model - view - projection - eye - center) eye)))))))) + (let* ((eye (car (update-eye-center eye-position center))) + (view (update-view-matrix eye camera-rotation))) + (cons (make-mvp-matrix model view projection eye center) + eye))))))) #| diff --git a/ffi.scm b/ffi.scm index 75cd189..6cfdba9 100644 --- a/ffi.scm +++ b/ffi.scm @@ -27,6 +27,7 @@ array-pointer-raw-ptr array-pointer-empty? array-pointer? + new-array-pointer with-new-array-pointer pointer-ref-value pointer-ref-ftype @@ -34,9 +35,9 @@ double-pointer->list) (import (chezscheme) - (prelude)) + (prelude)) - (define libc (load-shared-object "libc.so.6")) + (define libc (load-shared-library (make-library-detail #f "libc.so.6" "msvcrt.dll"))) (define memcpy (foreign-procedure "memcpy" (uptr uptr size_t) void)) @@ -150,7 +151,11 @@ strs))))))))) - (define strdup (foreign-procedure "strdup" (string) string)) + (define strdup + (let ((proc-name (cond + ((foreign-entry? "strdup") "strdup") + ((foreign-entry? "_strdup") "_strdup")))) + (foreign-procedure proc-name (string) string))) (define-syntax write-cstring (syntax-rules () @@ -177,8 +182,11 @@ (define-syntax make-foreign-array (syntax-rules () - ((_ struct size) (make-ftype-pointer struct (unbox (malloc (* size - (ftype-sizeof struct)))))))) + ((_ struct size) (make-ftype-pointer struct + (if (equal? size 0) + 0 + (unbox (malloc (* size + (ftype-sizeof struct))))))))) (define-syntax pointer-ref-value (syntax-rules () @@ -234,6 +242,15 @@ (define-record-type array-pointer (fields length raw-ptr type) (nongenerative)) + + (define-syntax new-array-pointer + (syntax-rules () + ((_ pointer-type count) + (make-array-pointer count + (make-foreign-array pointer-type count) + pointer-type)))) + + ;; notice: this should not be here belongs somewhere inside vulkan library ;; this function covers a general pattern for vulkan functions to return an array ;; the f provided will be called two times: ;; once for the value of count and then @@ -282,10 +299,10 @@ (else (lp (fx+ 1 i) (cons (and (array-pointer-raw-ptr arr-ptr) - (f (ftype-&ref pointer-type - () - (array-pointer-raw-ptr arr-ptr) - i))) + (f (ftype-&ref pointer-type + () + (array-pointer-raw-ptr arr-ptr) + i))) xs))))))) (define find-lambda diff --git a/glfw.scm b/glfw.scm index 35554dc..35814d8 100644 --- a/glfw.scm +++ b/glfw.scm @@ -10,13 +10,20 @@ movement-data-forward movement-data-back movement-data-right - movement-data-left) + movement-data-left + load-glfw) (import (chezscheme) + (prelude) (ffi) (glfw glfw)) - ;; (define glfw (load-shared-object "libglfw.so")) + (define load-glfw (lambda () + (display "loading glfw") (newline) + (load-shared-library (make-library-detail #f + "libglfw.so" + "phoenix-libs/glfw3.dll")))) + (define lib (load-glfw)) (define glfw-init (foreign-procedure "glfwInit" () boolean)) diff --git a/image.scm b/image.scm index 1938c3f..5eefb1f 100644 --- a/image.scm +++ b/image.scm @@ -6,9 +6,12 @@ image-data-size image-data?) (import (scheme) + (prelude) (ffi)) - (define o (load-shared-object "../phoenix-libs/libstb_image.so")) + (define o (load-shared-library (make-library-detail #f + "phoenix-libs/libstb_image.so" + "phoenix-libs/libstb_image.dll"))) (define-enum-ftype desired-channels stbi-default stbi-grey stbi-grey-alpha stbi-rgb stbi-rgb-alpha) @@ -28,16 +31,16 @@ ;; image is image-data (let ((image #f)) (dynamic-wind - (lambda () - (let ((width (make-foreign-object int)) - (height (make-foreign-object int)) - (channels (make-foreign-object int))) - (set! image - (make-image-data (stbi_load image-path width height channels stbi-rgb-alpha) - (read-int width) - (read-int height) - (fx* (read-int height) (read-int width) 4))))) - (lambda () (f image)) - (lambda () - (display "free image") (newline) - (stbi_free (image-data-pointer image)))))))) + (lambda () + (let ((width (make-foreign-object int)) + (height (make-foreign-object int)) + (channels (make-foreign-object int))) + (set! image + (make-image-data (stbi_load image-path width height channels stbi-rgb-alpha) + (read-int width) + (read-int height) + (fx* (read-int height) (read-int width) 4))))) + (lambda () (f image)) + (lambda () + (display "free image") (newline) + (stbi_free (image-data-pointer image)))))))) diff --git a/prelude.scm b/prelude.scm index f3cf0e6..a4ecfb4 100644 --- a/prelude.scm +++ b/prelude.scm @@ -1,59 +1,86 @@ (library (prelude) (export identity - construct-name - displayln - map-indexed - take - kebab-case->camel-case - - define-interface - define-module - abstract-module - implement) - - (import (chezscheme)) + construct-name + displayln + map-indexed + take + kebab-case->camel-case + + define-interface + define-module + abstract-module + implement + make-library-detail + load-shared-library) + + (import (chezscheme) + (matchable)) (define identity (lambda (x) x)) (define construct-name (lambda (template-identifier . args) (datum->syntax template-identifier - (string->symbol (apply string-append - (map (lambda (x) - (if (string? x) - x - (symbol->string (syntax->datum x)))) - args)))))) + (string->symbol (apply string-append + (map (lambda (x) + (if (string? x) + x + (symbol->string (syntax->datum x)))) + args)))))) (define map-indexed (lambda (f arr) (let lp ((i 0) - (xs arr) - (coll '())) - (cond - ((null? xs) (reverse coll)) - (else (lp (+ i 1) - (cdr xs) - (cons (f (car xs) i) coll))))))) + (xs arr) + (coll '())) + (cond + ((null? xs) (reverse coll)) + (else (lp (+ i 1) + (cdr xs) + (cons (f (car xs) i) coll))))))) (define take (lambda (list pos) (let ((vec (list->vector list))) - (map (lambda (i) (vector-ref vec i)) (iota pos))))) + (map (lambda (i) (vector-ref vec i)) (iota pos))))) (define kebab-case->camel-case (lambda (str) (let lp ((str (string->list str)) - (dest '())) - (cond - ((null? str) (list->string (reverse dest))) - - ((char=? (car str) #\-) (lp (cddr str) - (cons (char-upcase (cadr str)) dest))) - - (else (lp (cdr str) - (cons (car str) dest))))))) + (dest '())) + (cond + ((null? str) (list->string (reverse dest))) + + ((char=? (car str) #\-) (lp (cddr str) + (cons (char-upcase (cadr str)) dest))) + + (else (lp (cdr str) + (cons (car str) dest))))))) + + (define-record-type library-detail (fields osx linux windows)) + + (define load-shared-library + (lambda (lib-detail) + + (define with-defaults + (lambda (lib) + "if lib is not a pair then create a pair with the passed lib" + (if (pair? lib) lib (cons lib lib)))) + + (match-let* ((($ library-detail osx linux windows) lib-detail) + ((osx-32 . osx-64) (with-defaults osx)) + ((linux-32 . linux-64) (with-defaults linux)) + ((win-32 . win-64) (with-defaults windows))) + (case (machine-type) + ((i3osx ti3osx) (load-shared-object osx-32)) + ((a6osx ta6osx) (load-shared-object osx-64)) + ((i3le ti3le) (load-shared-object linux-32)) + ((a6le ta6le) (load-shared-object linux-64)) + ((i3nt ti3nt) (load-shared-object win-32)) + ((a6nt ta6nt) (load-shared-object win-64)))))) + + ;; Modules @@ -87,12 +114,12 @@ (syntax-rules () [(_ name (export ...)) (define-syntax name - (lambda (x) - (syntax-case x () - [(_ n defs) - (with-implicit (n export ...) - #'(module n (export ...) . - defs))])))])) + (lambda (x) + (syntax-case x () + [(_ n defs) + (with-implicit (n export ...) + #'(module n (export ...) . + defs))])))])) (define-syntax define-module (syntax-rules () @@ -166,8 +193,8 @@ (syntax-rules () [(_ name (ex ...) (kwd ...) defn ...) (module name (ex ... kwd ...) - (declare ex) ... - defn ...)])) + (declare ex) ... + defn ...)])) (define-syntax implement (syntax-rules () diff --git a/shaderc.scm b/shaderc.scm index 5aa3781..2249011 100644 --- a/shaderc.scm +++ b/shaderc.scm @@ -10,10 +10,13 @@ compile-shaders) (import (chezscheme) + (prelude) (ffi) (only (srfi s13 strings) string-join)) - (define s (load-shared-object "libshaderc_shared.so")) + (define s (load-shared-library (make-library-detail #f + "libshaderc_shared.so" + "phoenix-libs/libshaderc_shared.dll"))) ;;;;;;;;;;;;;;;;;;;;;;; ;; low level wrapper ;; @@ -57,6 +60,15 @@ shaderc-compilation-status-validation-error shaderc-compilation-status-configuration-error) + (define _get-error-message + (foreign-procedure "shaderc_result_get_error_message" ((* shaderc-compilation-result)) string)) + + (define _get-num-warnings + (foreign-procedure "shaderc_result_get_num_warnings" ((* shaderc-compilation-result)) size_t)) + + (define _get-num-errors + (foreign-procedure "shaderc_result_get_num_errors" ((* shaderc-compilation-result)) size_t)) + (define _get-compilation-status (foreign-procedure "shaderc_result_get_compilation_status" ((* shaderc-compilation-result)) shaderc-compilation-status)) @@ -112,10 +124,16 @@ (make-array-pointer (_get-result-length result) (_get-result-bytes result) 'unsigned-32)) - (else (error "shader compilation failed: " (_get-compilation-status result)))))))) + (else (let ((num-errors (_get-num-errors result)) + (num-warnings (_get-num-warnings result)) + (error-message (_get-error-message result))) + (display "Num errors: ") (display num-errors) (newline) + (display "Num warnings: ") (display num-warnings) (newline) + (display "Error message: ") (display error-message) (newline) + (error "shader compilation failed: " (_get-compilation-status result))))))))) ;; (load "shaderc.scm") ;; (import (shaderc)) -;; (compile-shaders "shaders/shader.vert" shaderc-vertex-shader) +;; (define x (compile-shaders "shaders/shader.vert" shaderc-vertex-shader)) ;; (compile-shaders "shaders/shader.frag" shaderc-fragment-shader) diff --git a/shaders/brdf.frag b/shaders/brdf.frag new file mode 100644 index 0000000..c571492 --- /dev/null +++ b/shaders/brdf.frag @@ -0,0 +1,97 @@ +#version 450 + +layout (location = 0) in vec2 inUV; + +layout (location = 0) out vec4 outColor; + +layout (constant_id = 0) const uint NUM_SAMPLES = 1024u; + +#define PI 3.1415926535897932384626433832795 + +// Based on +// http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/ +float random(vec2 co) +{ + float a = 12.9898; + float b = 78.233; + float c = 43758.5453; + float dt= dot(co.xy ,vec2(a,b)); + float sn= mod(dt,3.14); + return fract(sin(sn) * c); +} + + +vec2 hammersley2d(uint i, uint N) +{ + // Radical inverse based on + // http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html + + uint bits = (i << 16u) | (i >> 16u); + bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); + bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); + bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); + bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); + float rdi = float(bits) * 2.3283064365386963e-10; + return vec2(float(i) /float(N), rdi); +} + +// Based on +// http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf +vec3 importanceSample_GGX(vec2 Xi, float roughness, vec3 normal) +{ + // Maps a 2D point to a hemisphere with spread based on roughness + float alpha = roughness * roughness; + float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1; + float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y)); + float sinTheta = sqrt(1.0 - cosTheta * cosTheta); + vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta); + + // Tangent space + vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); + vec3 tangentX = normalize(cross(up, normal)); + vec3 tangentY = normalize(cross(normal, tangentX)); + + // Convert to world Space + return normalize(tangentX * H.x + tangentY * H.y + normal * H.z); +} + +// Geometric Shadowing function +float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness) +{ + float k = (roughness * roughness) / 2.0; + float GL = dotNL / (dotNL * (1.0 - k) + k); + float GV = dotNV / (dotNV * (1.0 - k) + k); + return GL * GV; +} + +vec2 BRDF(float NoV, float roughness) +{ + // Normal always points along z-axis for the 2D lookup + const vec3 N = vec3(0.0, 0.0, 1.0); + vec3 V = vec3(sqrt(1.0 - NoV*NoV), 0.0, NoV); + + vec2 LUT = vec2(0.0); + for(uint i = 0u; i < NUM_SAMPLES; i++) { + vec2 Xi = hammersley2d(i, NUM_SAMPLES); + vec3 H = importanceSample_GGX(Xi, roughness, N); + vec3 L = 2.0 * dot(V, H) * H - V; + + float dotNL = max(dot(N, L), 0.0); + float dotNV = max(dot(N, V), 0.0); + float dotVH = max(dot(V, H), 0.0); + float dotNH = max(dot(H, N), 0.0); + + if (dotNL > 0.0) { + float G = G_SchlicksmithGGX(dotNL, dotNV, roughness); + float G_Vis = (G * dotVH) / (dotNH * dotNV); + float Fc = pow(1.0 - dotVH, 5.0); + LUT += vec2((1.0 - Fc) * G_Vis, Fc * G_Vis); + } + } + return LUT / float(NUM_SAMPLES); +} + +void main() +{ + outColor = vec4(BRDF(inUV.s, 1.0-inUV.t), 0.0, 1.0); +} diff --git a/shaders/brdf.vert b/shaders/brdf.vert new file mode 100644 index 0000000..1138358 --- /dev/null +++ b/shaders/brdf.vert @@ -0,0 +1,8 @@ +#version 450 + +layout (location = 0) out vec2 outUV; + +void main() { + outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + gl_Position = vec4(outUV * 2.0f - 1.0f, 0.0f, 1.0f); +} diff --git a/shaders/shader.frag b/shaders/shader.frag index 2f86a4e..a5f6033 100644 --- a/shaders/shader.frag +++ b/shaders/shader.frag @@ -1,14 +1,191 @@ #version 450 #extension GL_ARB_separate_shader_objects : enable -layout(binding = 1) uniform sampler2D texSampler; +layout(location = 0) in vec3 inWorldPos; +layout(location = 1) in vec3 inNormal; +layout(location = 2) in vec2 inTexCoord; -layout(location = 0) in vec3 fragColor; -layout(location = 1) in vec2 fragTexCoord; +layout (binding = 0) uniform UBO { + mat4 model; + mat4 view; + mat4 proj; + vec3 camPos; +} ubo; + +layout (binding = 1) uniform UBOParams { + vec4 lights[4]; + float exposure; + float gamma; +} uboParams; + +// layout (binding = 2) uniform samplerCube samplerIrradiance; +layout (binding = 2) uniform sampler2D samplerBRDFLUT; +// layout (binding = 4) uniform samplerCube prefilteredMap; +layout (binding = 3) uniform sampler2D albedoMap; +layout (binding = 4) uniform sampler2D normalMap; +layout (binding = 5) uniform sampler2D aoMap; +layout (binding = 6) uniform sampler2D metallicMap; +layout (binding = 7) uniform sampler2D roughnessMap; layout(location = 0) out vec4 outColor; -void main() { - outColor = texture(texSampler, fragTexCoord) * vec4(fragColor, 1.0); - // outColor = vec4(fragColor, 1.0); +#define PI 3.1415926535897932384626433832795 +#define ALBEDO pow(texture(albedoMap, inTexCoord).rgb, vec3(2.2)) + +vec3 Uncharted2Tonemap(vec3 x) { + float A = 0.15; + float B = 0.50; + float C = 0.10; + float D = 0.20; + float E = 0.02; + float F = 0.30; + + return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F; +} + +// Normal Distribution Function +float Distribution_GGX(float NdotH, float roughness) { + float alpha = roughness * roughness; + float alpha2 = alpha * alpha; + + float denom = NdotH * NdotH * (alpha2 - 1.0) + 1.0; + + return (alpha2) / (PI * denom * denom); +} + +// Geometric Shadowing function +float GeometricSchlicksmithGGX(float NdotL, float NdotV, float roughness) { + float r = (roughness + 1.0); + float k = (r * r) / 8.0; + + float GL = NdotL / (NdotL * (1.0 - k) + k); + float GV = NdotV / (NdotV * (1.0 - k) + k); + return GL * GV; +} + +// Fresnel functions + +vec3 FresnelSchlick(float cos_theta, vec3 F0) { + return F0 + (1.0 - F0) * pow(1.0 - cos_theta, 5.0); +} + +vec3 FresnelSchlickRoughness(float cos_theta, vec3 F0, float roughness) { + return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - cos_theta, 5.0); +} + +// ibl + +// vec3 prefilteredReflection(vec3 R, float roughness) { +// const float MAX_REFLECTION_LOD = 9.0; + +// float lod = roughness * MAX_REFLECTION_LOD; +// float lodFloor = floor(lod); +// float lodCeil = ceil(lod); + +// vec3 a = textureLod(prefilteredMap, R, lodFloor).rgb; +// vec3 b = textureLod(prefilteredMap, R, lodCeil).rgb; + +// return mix(a, b, lodFloor - lodCeil); +// } + +// Lighting calculations + +vec3 specularContribution(vec3 L, vec3 V, vec3 N, vec3 F0, float metallic, + float roughness) { + // precalculate vectors and dot products + vec3 H = normalize(V + L); + + float NdotH = clamp(dot(N, H), 0.0, 1.0); + float NdotV = clamp(dot(N, V), 0.0, 1.0); + float NdotL = clamp(dot(N, L), 0.0, 1.0); + + // Light color + vec3 lightColor = vec3(1.0); + + vec3 color = vec3(0.0); + + if (NdotL > 0.0) { + // D = Normal distribution (Distribution of the microfacets) + float D = Distribution_GGX(NdotH, roughness); + + // G = Geometric Shadowing term (Microfacets shadowing) + float G = GeometricSchlicksmithGGX(NdotL, NdotV, roughness); + + // F = Fresnel factor (reflectance depending on angle of incidence) + vec3 F = FresnelSchlick(NdotV, F0); + + vec3 spec = D * F * G / (4.0 * NdotL * NdotV + 0.001); + vec3 KD = (vec3(1.0) - F) * (1.0 - metallic); + color += (KD * ALBEDO / PI + spec) * NdotL; + } + + return color; +} + +// Normal mapping +// See http://www.thetenthplanet.de/archives/1180 +vec3 perturbNormal() { + vec3 tangentNormal = texture(normalMap, inTexCoord).xyz * 2.0 - 1.0; + vec3 q1 = dFdx(inWorldPos); + vec3 q2 = dFdy(inWorldPos); + vec2 st1 = dFdx(inTexCoord); + vec2 st2 = dFdy(inTexCoord); + + vec3 N = normalize(inNormal); + vec3 T = normalize(q1 * st2.t - q2 * st1.t); + vec3 B = -normalize(cross(N, T)); + mat3 TBN = mat3(T, B, N); + + return normalize(TBN * tangentNormal); +} + + +void main () { + + vec3 N = perturbNormal(); + vec3 V = normalize(ubo.camPos - inWorldPos); + vec3 R = reflect(- V, N); + + float metallic = texture(metallicMap, inTexCoord).r; + float roughness = texture(roughnessMap, inTexCoord).r; + + vec3 F0 = vec3(0.04); + F0 = mix(F0, ALBEDO, metallic); + + vec3 Lo = vec3(0.0); + for(int i = 0; i < uboParams.lights[i].length(); i++) { + vec3 L = normalize(uboParams.lights[i].xyz - inWorldPos); + Lo += specularContribution(L, V, N, F0, metallic, roughness); + } + + vec2 brdf = texture(samplerBRDFLUT, vec2(max(dot(N, V), 0.0), roughness)).rg; + // vec3 reflection = prefilteredReflection(R, roughness).rgb; + // vec3 irradiance = texture(samplerIrradiance, N).rgb; + + // Diffuse based on irradiance + // vec3 diffuse = irradiance * ALBEDO; + vec3 diffuse = ALBEDO; + + vec3 F = FresnelSchlickRoughness(max(dot(N, V), 0.0), F0, roughness); + + // Specular reflectance + // vec3 specular = reflection * (F * brdf.x + brdf.y); + + vec3 specular = (F * brdf.x + brdf.y); + + // Ambient part + vec3 kD = 1.0 - F; + kD *= 1.0 - metallic; + vec3 ambient = (kD * diffuse + specular) * texture(aoMap, inTexCoord).rrr; + + vec3 color = ambient + Lo; + + // Tone mapping + color = Uncharted2Tonemap(color * uboParams.exposure); + color = color * (1.0f / Uncharted2Tonemap(vec3(11.2f))); + + // gamma correction + color = pow(color, vec3(1.0f / uboParams.gamma)); + + outColor = vec4(color, 1.0); } diff --git a/shaders/shader.vert b/shaders/shader.vert index f87b52c..1512e9f 100644 --- a/shaders/shader.vert +++ b/shaders/shader.vert @@ -5,20 +5,23 @@ layout(binding = 0) uniform UniformBufferObject { mat4 model; mat4 view; mat4 proj; + vec3 camPos; } ubo; layout(location = 0) in vec3 inPosition; -layout(location = 1) in vec3 inColor; +layout(location = 1) in vec3 inNormal; layout(location = 2) in vec2 inTexCoord; -layout(location = 0) out vec3 fragColor; -layout(location = 1) out vec2 fragTexCoord; +layout(location = 0) out vec3 outWorldPos; +layout(location = 1) out vec3 outNormal; +layout(location = 2) out vec2 outTexCoord; void main() { - gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 1.0); - - fragColor = inColor; - fragTexCoord = inTexCoord; + outWorldPos = vec3(ubo.model * vec4(inPosition, 1.0)); + outNormal = mat3(ubo.model) * inNormal; + outTexCoord = inTexCoord; + outTexCoord.t = 1.0 - inTexCoord.t; + gl_Position = ubo.proj * ubo.view * vec4(outWorldPos, 1.0); } diff --git a/textures/tile/Tile_Pavestone_ugznfcyo_surface_Preview.png b/textures/tile/Tile_Pavestone_ugznfcyo_surface_Preview.png new file mode 100644 index 0000000..e6053a3 Binary files /dev/null and b/textures/tile/Tile_Pavestone_ugznfcyo_surface_Preview.png differ diff --git a/textures/tile/ugznfcyo.json b/textures/tile/ugznfcyo.json new file mode 100644 index 0000000..5fc721d --- /dev/null +++ b/textures/tile/ugznfcyo.json @@ -0,0 +1,1529 @@ +{ + "pack": null, + "semanticTags": { + "subject_matter": "manmade", + "name": "Sidewalk Tiles", + "asset_type": "surface", + "contains": [ + "tiles", + "stone", + "sidewalk" + ], + "theme": [ + "sidewalks", + "pathways", + "walkways", + "urban", + "pedastrian", + "city", + "street", + "downtown", + "urban" + ], + "descriptive": [ + "rough", + "worn" + ], + "environment": [ + "urban" + ], + "orientation": [ + "floor" + ], + "state": [ + "old" + ], + "city": "San Francisco", + "country": "United States", + "region": "Americas", + "color": [ + "Gray" + ], + "industry": [ + "archviz", + "games", + "VFX" + ] + }, + "tags": [ + "gray", + "rough", + "dirty", + "worn", + "old" + ], + "previews": { + "images": [ + { + "contentLength": 243597, + "resolution": "360x360", + "uri": "ugznfcyo_Grid_360.png", + "tags": [ + "thumb" + ] + }, + { + "contentLength": 333633, + "resolution": "420x420", + "uri": "ugznfcyo_Grid_420.png", + "tags": [ + "thumb" + ] + }, + { + "contentLength": 1029053, + "resolution": "720x720", + "uri": "ugznfcyo_Grid_720.png", + "tags": [ + "thumb", + "retina" + ] + }, + { + "contentLength": 1417517, + "resolution": "840x840", + "uri": "ugznfcyo_Grid_840.png", + "tags": [ + "thumb", + "retina" + ] + }, + { + "contentLength": 2741453, + "resolution": "1440x768", + "uri": "ugznfcyo_PopupClay_1440.png", + "tags": [ + "preview", + "clay" + ] + }, + { + "contentLength": 5276363, + "resolution": "1920x1080", + "uri": "ugznfcyo_PopupClay_1920.png", + "tags": [ + "preview", + "clay" + ] + }, + { + "contentLength": 11641135, + "resolution": "2880x1536", + "uri": "ugznfcyo_PopupClay_2880.png", + "tags": [ + "preview", + "clay", + "retina" + ] + }, + { + "contentLength": 22845871, + "resolution": "3840x2160", + "uri": "ugznfcyo_PopupClay_3840.png", + "tags": [ + "preview", + "clay", + "retina" + ] + }, + { + "contentLength": 3153343, + "resolution": "1440x768", + "uri": "ugznfcyo_PopupTiled_1440.png", + "tags": [ + "preview", + "tiled" + ] + }, + { + "contentLength": 5915407, + "resolution": "1920x1080", + "uri": "ugznfcyo_PopupTiled_1920.png", + "tags": [ + "preview", + "tiled" + ] + }, + { + "contentLength": 12699189, + "resolution": "2880x1536", + "uri": "ugznfcyo_PopupTiled_2880.png", + "tags": [ + "preview", + "tiled", + "retina" + ] + }, + { + "contentLength": 24385307, + "resolution": "3840x2160", + "uri": "ugznfcyo_PopupTiled_3840.png", + "tags": [ + "preview", + "tiled", + "retina" + ] + }, + { + "contentLength": 3171371, + "resolution": "1440x768", + "uri": "ugznfcyo_Popup_1440.png", + "tags": [ + "preview" + ] + }, + { + "contentLength": 6026302, + "resolution": "1920x1080", + "uri": "ugznfcyo_Popup_1920.png", + "tags": [ + "preview" + ] + }, + { + "contentLength": 13063655, + "resolution": "2880x1536", + "uri": "ugznfcyo_Popup_2880.png", + "tags": [ + "preview", + "retina" + ] + }, + { + "contentLength": 25249709, + "resolution": "3840x2160", + "uri": "ugznfcyo_Popup_3840.png", + "tags": [ + "preview", + "retina" + ] + }, + { + "contentLength": 702, + "resolution": "24x24", + "uri": "EkFaxLnr33PS6vGX/wnZvgAAAQtJREFUKM9l0mlzhCAMBmC1KOLV3ZnlkEPU+v9/Y5Mgy2ybjzzzknBUVa5eMCb66k/1bLQ22nOe2g8TY1RQ0drz5yHK+ndUzjnlkny1ZZ0bYzgQyFlEKC6hjDMpAkK79SOXWmtpuDTqlgdO0F5Gb9sGAiGlLAptNkUZvA8gGhqpSJkJdpqV9sfhA4A02AbEzn0lLh72dccINqLRYDYBLaRfXytEtkCdOE3NMuwgGJLpPADiMgAkHgIZBDTnCChHIEFa4CCTCggogQRDI5yDwVSvW/wtjuGVLBmS4AQLPUqXIU2AIZaut37DutNwdX6Qmrq/96vLE3ZNkab7+AxD88TlZzP8/yjdMHRl9RetRCZffkeXGQAAAABJRU5ErkJggg==", + "tags": [ + "thumb", + "tiny" + ] + }, + { + "contentLength": 40728, + "resolution": "360x360", + "uri": "ugznfcyo_Grid_360_thumb.jpg", + "tags": [ + "thumb", + "jpeg" + ] + }, + { + "contentLength": 56791, + "resolution": "420x420", + "uri": "ugznfcyo_Grid_420_thumb.jpg", + "tags": [ + "thumb", + "jpeg" + ] + }, + { + "contentLength": 183093, + "resolution": "720x720", + "uri": "ugznfcyo_Grid_720_thumb.jpg", + "tags": [ + "thumb", + "retina", + "jpeg" + ] + }, + { + "contentLength": 255904, + "resolution": "840x840", + "uri": "ugznfcyo_Grid_840_thumb.jpg", + "tags": [ + "thumb", + "retina", + "jpeg" + ] + }, + { + "contentLength": 510790, + "resolution": "1440x768", + "uri": "ugznfcyo_PopupClay_1440_preview.jpg", + "tags": [ + "preview", + "clay", + "jpeg" + ] + }, + { + "contentLength": 1016027, + "resolution": "1920x1080", + "uri": "ugznfcyo_PopupClay_1920_preview.jpg", + "tags": [ + "preview", + "clay", + "jpeg" + ] + }, + { + "contentLength": 2326193, + "resolution": "2880x1536", + "uri": "ugznfcyo_PopupClay_2880_preview.jpg", + "tags": [ + "preview", + "clay", + "retina", + "jpeg" + ] + }, + { + "contentLength": 4774426, + "resolution": "3840x2160", + "uri": "ugznfcyo_PopupClay_3840_preview.jpg", + "tags": [ + "preview", + "clay", + "retina", + "jpeg" + ] + }, + { + "contentLength": 549029, + "resolution": "1440x768", + "uri": "ugznfcyo_PopupTiled_1440_preview.jpg", + "tags": [ + "preview", + "tiled", + "jpeg" + ] + }, + { + "contentLength": 1040413, + "resolution": "1920x1080", + "uri": "ugznfcyo_PopupTiled_1920_preview.jpg", + "tags": [ + "preview", + "tiled", + "jpeg" + ] + }, + { + "contentLength": 2257863, + "resolution": "2880x1536", + "uri": "ugznfcyo_PopupTiled_2880_preview.jpg", + "tags": [ + "preview", + "tiled", + "retina", + "jpeg" + ] + }, + { + "contentLength": 4571202, + "resolution": "3840x2160", + "uri": "ugznfcyo_PopupTiled_3840_preview.jpg", + "tags": [ + "preview", + "tiled", + "retina", + "jpeg" + ] + }, + { + "contentLength": 561527, + "resolution": "1440x768", + "uri": "ugznfcyo_Popup_1440_preview.jpg", + "tags": [ + "preview", + "jpeg" + ] + }, + { + "contentLength": 1098682, + "resolution": "1920x1080", + "uri": "ugznfcyo_Popup_1920_preview.jpg", + "tags": [ + "preview", + "jpeg" + ] + }, + { + "contentLength": 2459752, + "resolution": "2880x1536", + "uri": "ugznfcyo_Popup_2880_preview.jpg", + "tags": [ + "preview", + "retina", + "jpeg" + ] + }, + { + "contentLength": 4970991, + "resolution": "3840x2160", + "uri": "ugznfcyo_Popup_3840_preview.jpg", + "tags": [ + "preview", + "retina", + "jpeg" + ] + }, + { + "contentLength": 382360, + "resolution": "1280x720", + "uri": "ugznfcyo_Popup_3840_sp.jpg", + "tags": [ + "jpeg", + "sidepanel" + ] + } + ], + "scaleReferences": [], + "relativeSize": "1x1" + }, + "environment": { + "biome": "undefined", + "region": "Americas" + }, + "maps": [ + { + "mimeType": "image/x-exr", + "minIntensity": 188, + "bitDepth": 32, + "name": "AO", + "resolution": "1024x1024", + "contentLength": 3944113, + "colorSpace": "sRGB", + "uri": "ugznfcyo_1K_AO.exr", + "physicalSize": "1x1", + "maxIntensity": 236, + "type": "ao", + "averageColor": "#DDDDDD" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 188, + "bitDepth": 8, + "name": "AO", + "resolution": "1024x1024", + "contentLength": 538699, + "colorSpace": "sRGB", + "uri": "ugznfcyo_1K_AO.jpg", + "physicalSize": "1x1", + "maxIntensity": 236, + "type": "ao", + "averageColor": "#DDDDDD" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 0, + "bitDepth": 16, + "name": "Albedo", + "resolution": "1024x1024", + "contentLength": 4735139, + "colorSpace": "sRGB", + "uri": "ugznfcyo_1K_Albedo.exr", + "physicalSize": "1x1", + "maxIntensity": 131, + "type": "albedo", + "averageColor": "#645C52" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 0, + "bitDepth": 8, + "name": "Albedo", + "resolution": "1024x1024", + "contentLength": 1431100, + "colorSpace": "sRGB", + "uri": "ugznfcyo_1K_Albedo.jpg", + "physicalSize": "1x1", + "maxIntensity": 131, + "type": "albedo", + "averageColor": "#645C52" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 0, + "bitDepth": 32, + "name": "Bump", + "resolution": "1024x1024", + "contentLength": 4194153, + "colorSpace": "Linear", + "uri": "ugznfcyo_1K_Bump.exr", + "physicalSize": "1x1", + "maxIntensity": 255, + "type": "bump", + "averageColor": "#808080" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 0, + "bitDepth": 8, + "name": "Bump", + "resolution": "1024x1024", + "contentLength": 717611, + "colorSpace": "Linear", + "uri": "ugznfcyo_1K_Bump.jpg", + "physicalSize": "1x1", + "maxIntensity": 255, + "type": "bump", + "averageColor": "#808080" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 255, + "bitDepth": 32, + "name": "Cavity", + "resolution": "1024x1024", + "contentLength": 4089745, + "colorSpace": "sRGB", + "uri": "ugznfcyo_1K_Cavity.exr", + "physicalSize": "1x1", + "maxIntensity": 255, + "type": "cavity", + "averageColor": "#FFFFFF" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 255, + "bitDepth": 8, + "name": "Cavity", + "resolution": "1024x1024", + "contentLength": 656419, + "colorSpace": "sRGB", + "uri": "ugznfcyo_1K_Cavity.jpg", + "physicalSize": "1x1", + "maxIntensity": 255, + "type": "cavity", + "averageColor": "#FFFFFF" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 121, + "bitDepth": 32, + "name": "Displacement", + "resolution": "1024x1024", + "contentLength": 3541209, + "colorSpace": "Linear", + "uri": "ugznfcyo_1K_Displacement.exr", + "physicalSize": "1x1", + "maxIntensity": 130, + "type": "displacement", + "averageColor": "#818181" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 121, + "bitDepth": 8, + "name": "Displacement", + "resolution": "1024x1024", + "contentLength": 130487, + "colorSpace": "Linear", + "uri": "ugznfcyo_1K_Displacement.jpg", + "physicalSize": "1x1", + "maxIntensity": 130, + "type": "displacement", + "averageColor": "#818181" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 43, + "bitDepth": 32, + "name": "Gloss", + "resolution": "1024x1024", + "contentLength": 3521019, + "colorSpace": "Linear", + "uri": "ugznfcyo_1K_Gloss.exr", + "physicalSize": "1x1", + "maxIntensity": 46, + "type": "gloss", + "averageColor": "#2D2D2D" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 43, + "bitDepth": 8, + "name": "Gloss", + "resolution": "1024x1024", + "contentLength": 159515, + "colorSpace": "Linear", + "uri": "ugznfcyo_1K_Gloss.jpg", + "physicalSize": "1x1", + "maxIntensity": 46, + "type": "gloss", + "averageColor": "#2D2D2D" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 115, + "bitDepth": 16, + "name": "Normal", + "resolution": "1024x1024", + "contentLength": 3731496, + "colorSpace": "Linear", + "uri": "ugznfcyo_1K_Normal.exr", + "physicalSize": "1x1", + "maxIntensity": 171, + "type": "normal", + "averageColor": "#8282FA" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 115, + "bitDepth": 8, + "name": "Normal", + "resolution": "1024x1024", + "contentLength": 1710182, + "colorSpace": "Linear", + "uri": "ugznfcyo_1K_Normal.jpg", + "physicalSize": "1x1", + "maxIntensity": 171, + "type": "normal", + "averageColor": "#8282FA" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 209, + "bitDepth": 32, + "name": "Roughness", + "resolution": "1024x1024", + "contentLength": 3003319, + "colorSpace": "Linear", + "uri": "ugznfcyo_1K_Roughness.exr", + "physicalSize": "1x1", + "maxIntensity": 212, + "type": "roughness", + "averageColor": "#D2D2D2" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 209, + "bitDepth": 8, + "name": "Roughness", + "resolution": "1024x1024", + "contentLength": 154968, + "colorSpace": "Linear", + "uri": "ugznfcyo_1K_Roughness.jpg", + "physicalSize": "1x1", + "maxIntensity": 212, + "type": "roughness", + "averageColor": "#D2D2D2" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 56, + "bitDepth": 16, + "name": "Specular", + "resolution": "1024x1024", + "contentLength": 3597101, + "colorSpace": "sRGB", + "uri": "ugznfcyo_1K_Specular.exr", + "physicalSize": "1x1", + "maxIntensity": 56, + "type": "specular", + "averageColor": "#383838" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 56, + "bitDepth": 8, + "name": "Specular", + "resolution": "1024x1024", + "contentLength": 381601, + "colorSpace": "sRGB", + "uri": "ugznfcyo_1K_Specular.jpg", + "physicalSize": "1x1", + "maxIntensity": 56, + "type": "specular", + "averageColor": "#383838" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 188, + "bitDepth": 32, + "name": "AO", + "resolution": "2048x2048", + "contentLength": 14714554, + "colorSpace": "sRGB", + "uri": "ugznfcyo_2K_AO.exr", + "physicalSize": "1x1", + "maxIntensity": 236, + "type": "ao", + "averageColor": "#DDDDDD" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 188, + "bitDepth": 8, + "name": "AO", + "resolution": "2048x2048", + "contentLength": 2074471, + "colorSpace": "sRGB", + "uri": "ugznfcyo_2K_AO.jpg", + "physicalSize": "1x1", + "maxIntensity": 236, + "type": "ao", + "averageColor": "#DDDDDD" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 0, + "bitDepth": 16, + "name": "Albedo", + "resolution": "2048x2048", + "contentLength": 19027050, + "colorSpace": "sRGB", + "uri": "ugznfcyo_2K_Albedo.exr", + "physicalSize": "1x1", + "maxIntensity": 131, + "type": "albedo", + "averageColor": "#645C52" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 0, + "bitDepth": 8, + "name": "Albedo", + "resolution": "2048x2048", + "contentLength": 5982206, + "colorSpace": "sRGB", + "uri": "ugznfcyo_2K_Albedo.jpg", + "physicalSize": "1x1", + "maxIntensity": 131, + "type": "albedo", + "averageColor": "#645C52" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 0, + "bitDepth": 32, + "name": "Bump", + "resolution": "2048x2048", + "contentLength": 15962759, + "colorSpace": "Linear", + "uri": "ugznfcyo_2K_Bump.exr", + "physicalSize": "1x1", + "maxIntensity": 255, + "type": "bump", + "averageColor": "#808080" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 0, + "bitDepth": 8, + "name": "Bump", + "resolution": "2048x2048", + "contentLength": 2961067, + "colorSpace": "Linear", + "uri": "ugznfcyo_2K_Bump.jpg", + "physicalSize": "1x1", + "maxIntensity": 255, + "type": "bump", + "averageColor": "#808080" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 255, + "bitDepth": 32, + "name": "Cavity", + "resolution": "2048x2048", + "contentLength": 15869293, + "colorSpace": "sRGB", + "uri": "ugznfcyo_2K_Cavity.exr", + "physicalSize": "1x1", + "maxIntensity": 255, + "type": "cavity", + "averageColor": "#FFFFFF" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 255, + "bitDepth": 8, + "name": "Cavity", + "resolution": "2048x2048", + "contentLength": 3038636, + "colorSpace": "sRGB", + "uri": "ugznfcyo_2K_Cavity.jpg", + "physicalSize": "1x1", + "maxIntensity": 255, + "type": "cavity", + "averageColor": "#FFFFFF" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 121, + "bitDepth": 32, + "name": "Displacement", + "resolution": "2048x2048", + "contentLength": 13035230, + "colorSpace": "Linear", + "uri": "ugznfcyo_2K_Displacement.exr", + "physicalSize": "1x1", + "maxIntensity": 130, + "type": "displacement", + "averageColor": "#818181" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 121, + "bitDepth": 8, + "name": "Displacement", + "resolution": "2048x2048", + "contentLength": 408934, + "colorSpace": "Linear", + "uri": "ugznfcyo_2K_Displacement.jpg", + "physicalSize": "1x1", + "maxIntensity": 130, + "type": "displacement", + "averageColor": "#818181" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 43, + "bitDepth": 32, + "name": "Gloss", + "resolution": "2048x2048", + "contentLength": 13191343, + "colorSpace": "Linear", + "uri": "ugznfcyo_2K_Gloss.exr", + "physicalSize": "1x1", + "maxIntensity": 46, + "type": "gloss", + "averageColor": "#2D2D2D" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 43, + "bitDepth": 8, + "name": "Gloss", + "resolution": "2048x2048", + "contentLength": 515312, + "colorSpace": "Linear", + "uri": "ugznfcyo_2K_Gloss.jpg", + "physicalSize": "1x1", + "maxIntensity": 46, + "type": "gloss", + "averageColor": "#2D2D2D" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 115, + "bitDepth": 16, + "name": "Normal", + "resolution": "2048x2048", + "contentLength": 15630722, + "colorSpace": "Linear", + "uri": "ugznfcyo_2K_Normal.exr", + "physicalSize": "1x1", + "maxIntensity": 171, + "type": "normal", + "averageColor": "#8282FA" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 115, + "bitDepth": 8, + "name": "Normal", + "resolution": "2048x2048", + "contentLength": 7765810, + "colorSpace": "Linear", + "uri": "ugznfcyo_2K_Normal.jpg", + "physicalSize": "1x1", + "maxIntensity": 171, + "type": "normal", + "averageColor": "#8282FA" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 209, + "bitDepth": 32, + "name": "Roughness", + "resolution": "2048x2048", + "contentLength": 12378498, + "colorSpace": "Linear", + "uri": "ugznfcyo_2K_Roughness.exr", + "physicalSize": "1x1", + "maxIntensity": 212, + "type": "roughness", + "averageColor": "#D2D2D2" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 209, + "bitDepth": 8, + "name": "Roughness", + "resolution": "2048x2048", + "contentLength": 496853, + "colorSpace": "Linear", + "uri": "ugznfcyo_2K_Roughness.jpg", + "physicalSize": "1x1", + "maxIntensity": 212, + "type": "roughness", + "averageColor": "#D2D2D2" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 56, + "bitDepth": 16, + "name": "Specular", + "resolution": "2048x2048", + "contentLength": 16071730, + "colorSpace": "sRGB", + "uri": "ugznfcyo_2K_Specular.exr", + "physicalSize": "1x1", + "maxIntensity": 56, + "type": "specular", + "averageColor": "#383838" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 56, + "bitDepth": 8, + "name": "Specular", + "resolution": "2048x2048", + "contentLength": 1994097, + "colorSpace": "sRGB", + "uri": "ugznfcyo_2K_Specular.jpg", + "physicalSize": "1x1", + "maxIntensity": 56, + "type": "specular", + "averageColor": "#383838" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 188, + "bitDepth": 32, + "name": "AO", + "resolution": "4096x4096", + "contentLength": 53749908, + "colorSpace": "sRGB", + "uri": "ugznfcyo_4K_AO.exr", + "physicalSize": "1x1", + "maxIntensity": 236, + "type": "ao", + "averageColor": "#DDDDDD" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 188, + "bitDepth": 8, + "name": "AO", + "resolution": "4096x4096", + "contentLength": 7643401, + "colorSpace": "sRGB", + "uri": "ugznfcyo_4K_AO.jpg", + "physicalSize": "1x1", + "maxIntensity": 236, + "type": "ao", + "averageColor": "#DDDDDD" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 0, + "bitDepth": 16, + "name": "Albedo", + "resolution": "4096x4096", + "contentLength": 73970643, + "colorSpace": "sRGB", + "uri": "ugznfcyo_4K_Albedo.exr", + "physicalSize": "1x1", + "maxIntensity": 131, + "type": "albedo", + "averageColor": "#645C52" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 0, + "bitDepth": 8, + "name": "Albedo", + "resolution": "4096x4096", + "contentLength": 22143130, + "colorSpace": "sRGB", + "uri": "ugznfcyo_4K_Albedo.jpg", + "physicalSize": "1x1", + "maxIntensity": 131, + "type": "albedo", + "averageColor": "#645C52" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 0, + "bitDepth": 32, + "name": "Bump", + "resolution": "4096x4096", + "contentLength": 58255335, + "colorSpace": "Linear", + "uri": "ugznfcyo_4K_Bump.exr", + "physicalSize": "1x1", + "maxIntensity": 255, + "type": "bump", + "averageColor": "#808080" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 0, + "bitDepth": 8, + "name": "Bump", + "resolution": "4096x4096", + "contentLength": 9998979, + "colorSpace": "Linear", + "uri": "ugznfcyo_4K_Bump.jpg", + "physicalSize": "1x1", + "maxIntensity": 255, + "type": "bump", + "averageColor": "#808080" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 255, + "bitDepth": 32, + "name": "Cavity", + "resolution": "4096x4096", + "contentLength": 60087462, + "colorSpace": "sRGB", + "uri": "ugznfcyo_4K_Cavity.exr", + "physicalSize": "1x1", + "maxIntensity": 255, + "type": "cavity", + "averageColor": "#FFFFFF" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 255, + "bitDepth": 8, + "name": "Cavity", + "resolution": "4096x4096", + "contentLength": 13395456, + "colorSpace": "sRGB", + "uri": "ugznfcyo_4K_Cavity.jpg", + "physicalSize": "1x1", + "maxIntensity": 255, + "type": "cavity", + "averageColor": "#FFFFFF" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 121, + "bitDepth": 32, + "name": "Displacement", + "resolution": "4096x4096", + "contentLength": 46900301, + "colorSpace": "Linear", + "uri": "ugznfcyo_4K_Displacement.exr", + "physicalSize": "1x1", + "maxIntensity": 130, + "type": "displacement", + "averageColor": "#818181" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 121, + "bitDepth": 8, + "name": "Displacement", + "resolution": "4096x4096", + "contentLength": 1525084, + "colorSpace": "Linear", + "uri": "ugznfcyo_4K_Displacement.jpg", + "physicalSize": "1x1", + "maxIntensity": 130, + "type": "displacement", + "averageColor": "#818181" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 43, + "bitDepth": 32, + "name": "Gloss", + "resolution": "4096x4096", + "contentLength": 48319953, + "colorSpace": "Linear", + "uri": "ugznfcyo_4K_Gloss.exr", + "physicalSize": "1x1", + "maxIntensity": 46, + "type": "gloss", + "averageColor": "#2D2D2D" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 43, + "bitDepth": 8, + "name": "Gloss", + "resolution": "4096x4096", + "contentLength": 1996007, + "colorSpace": "Linear", + "uri": "ugznfcyo_4K_Gloss.jpg", + "physicalSize": "1x1", + "maxIntensity": 46, + "type": "gloss", + "averageColor": "#2D2D2D" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 115, + "bitDepth": 16, + "name": "Normal", + "resolution": "4096x4096", + "contentLength": 61080601, + "colorSpace": "Linear", + "uri": "ugznfcyo_4K_Normal.exr", + "physicalSize": "1x1", + "maxIntensity": 171, + "type": "normal", + "averageColor": "#8282FA" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 115, + "bitDepth": 8, + "name": "Normal", + "resolution": "4096x4096", + "contentLength": 30693143, + "colorSpace": "Linear", + "uri": "ugznfcyo_4K_Normal.jpg", + "physicalSize": "1x1", + "maxIntensity": 171, + "type": "normal", + "averageColor": "#8282FA" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 209, + "bitDepth": 32, + "name": "Roughness", + "resolution": "4096x4096", + "contentLength": 46060610, + "colorSpace": "Linear", + "uri": "ugznfcyo_4K_Roughness.exr", + "physicalSize": "1x1", + "maxIntensity": 212, + "type": "roughness", + "averageColor": "#D2D2D2" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 209, + "bitDepth": 8, + "name": "Roughness", + "resolution": "4096x4096", + "contentLength": 1922190, + "colorSpace": "Linear", + "uri": "ugznfcyo_4K_Roughness.jpg", + "physicalSize": "1x1", + "maxIntensity": 212, + "type": "roughness", + "averageColor": "#D2D2D2" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 56, + "bitDepth": 16, + "name": "Specular", + "resolution": "4096x4096", + "contentLength": 68069724, + "colorSpace": "sRGB", + "uri": "ugznfcyo_4K_Specular.exr", + "physicalSize": "1x1", + "maxIntensity": 56, + "type": "specular", + "averageColor": "#383838" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 56, + "bitDepth": 8, + "name": "Specular", + "resolution": "4096x4096", + "contentLength": 9364987, + "colorSpace": "sRGB", + "uri": "ugznfcyo_4K_Specular.jpg", + "physicalSize": "1x1", + "maxIntensity": 56, + "type": "specular", + "averageColor": "#383838" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 188, + "bitDepth": 32, + "name": "AO", + "resolution": "8192x8192", + "contentLength": 179247432, + "colorSpace": "sRGB", + "uri": "ugznfcyo_8K_AO.exr", + "physicalSize": "1x1", + "maxIntensity": 236, + "type": "ao", + "averageColor": "#DDDDDD" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 188, + "bitDepth": 8, + "name": "AO", + "resolution": "8192x8192", + "contentLength": 25776966, + "colorSpace": "sRGB", + "uri": "ugznfcyo_8K_AO.jpg", + "physicalSize": "1x1", + "maxIntensity": 236, + "type": "ao", + "averageColor": "#DDDDDD" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 0, + "bitDepth": 16, + "name": "Albedo", + "resolution": "8192x8192", + "contentLength": 272640158, + "colorSpace": "sRGB", + "uri": "ugznfcyo_8K_Albedo.exr", + "physicalSize": "1x1", + "maxIntensity": 131, + "type": "albedo", + "averageColor": "#645C52" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 0, + "bitDepth": 8, + "name": "Albedo", + "resolution": "8192x8192", + "contentLength": 66090800, + "colorSpace": "sRGB", + "uri": "ugznfcyo_8K_Albedo.jpg", + "physicalSize": "1x1", + "maxIntensity": 131, + "type": "albedo", + "averageColor": "#645C52" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 0, + "bitDepth": 32, + "name": "Bump", + "resolution": "8192x8192", + "contentLength": 209937283, + "colorSpace": "Linear", + "uri": "ugznfcyo_8K_Bump.exr", + "physicalSize": "1x1", + "maxIntensity": 255, + "type": "bump", + "averageColor": "#808080" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 0, + "bitDepth": 8, + "name": "Bump", + "resolution": "8192x8192", + "contentLength": 26967308, + "colorSpace": "Linear", + "uri": "ugznfcyo_8K_Bump.jpg", + "physicalSize": "1x1", + "maxIntensity": 255, + "type": "bump", + "averageColor": "#808080" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 255, + "bitDepth": 32, + "name": "Cavity", + "resolution": "8192x8192", + "contentLength": 211202706, + "colorSpace": "sRGB", + "uri": "ugznfcyo_8K_Cavity.exr", + "physicalSize": "1x1", + "maxIntensity": 255, + "type": "cavity", + "averageColor": "#FFFFFF" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 255, + "bitDepth": 8, + "name": "Cavity", + "resolution": "8192x8192", + "contentLength": 51570732, + "colorSpace": "sRGB", + "uri": "ugznfcyo_8K_Cavity.jpg", + "physicalSize": "1x1", + "maxIntensity": 255, + "type": "cavity", + "averageColor": "#FFFFFF" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 121, + "bitDepth": 32, + "name": "Displacement", + "resolution": "8192x8192", + "contentLength": 167397663, + "colorSpace": "Linear", + "uri": "ugznfcyo_8K_Displacement.exr", + "physicalSize": "1x1", + "maxIntensity": 130, + "type": "displacement", + "averageColor": "#818181" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 121, + "bitDepth": 8, + "name": "Displacement", + "resolution": "8192x8192", + "contentLength": 5672316, + "colorSpace": "Linear", + "uri": "ugznfcyo_8K_Displacement.jpg", + "physicalSize": "1x1", + "maxIntensity": 130, + "type": "displacement", + "averageColor": "#818181" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 43, + "bitDepth": 32, + "name": "Gloss", + "resolution": "8192x8192", + "contentLength": 89984856, + "colorSpace": "Linear", + "uri": "ugznfcyo_8K_Gloss.exr", + "physicalSize": "1x1", + "maxIntensity": 46, + "type": "gloss", + "averageColor": "#2D2D2D" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 43, + "bitDepth": 8, + "name": "Gloss", + "resolution": "8192x8192", + "contentLength": 7800500, + "colorSpace": "Linear", + "uri": "ugznfcyo_8K_Gloss.jpg", + "physicalSize": "1x1", + "maxIntensity": 46, + "type": "gloss", + "averageColor": "#2D2D2D" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 115, + "bitDepth": 16, + "name": "Normal", + "resolution": "8192x8192", + "contentLength": 222403239, + "colorSpace": "Linear", + "uri": "ugznfcyo_8K_Normal.exr", + "physicalSize": "1x1", + "maxIntensity": 171, + "type": "normal", + "averageColor": "#8282FA" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 115, + "bitDepth": 8, + "name": "Normal", + "resolution": "8192x8192", + "contentLength": 99558267, + "colorSpace": "Linear", + "uri": "ugznfcyo_8K_Normal.jpg", + "physicalSize": "1x1", + "maxIntensity": 171, + "type": "normal", + "averageColor": "#8282FA" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 209, + "bitDepth": 32, + "name": "Roughness", + "resolution": "8192x8192", + "contentLength": 80323976, + "colorSpace": "Linear", + "uri": "ugznfcyo_8K_Roughness.exr", + "physicalSize": "1x1", + "maxIntensity": 212, + "type": "roughness", + "averageColor": "#D2D2D2" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 209, + "bitDepth": 8, + "name": "Roughness", + "resolution": "8192x8192", + "contentLength": 7542230, + "colorSpace": "Linear", + "uri": "ugznfcyo_8K_Roughness.jpg", + "physicalSize": "1x1", + "maxIntensity": 212, + "type": "roughness", + "averageColor": "#D2D2D2" + }, + { + "mimeType": "image/x-exr", + "minIntensity": 56, + "bitDepth": 16, + "name": "Specular", + "resolution": "8192x8192", + "contentLength": 245200264, + "colorSpace": "sRGB", + "uri": "ugznfcyo_8K_Specular.exr", + "physicalSize": "1x1", + "maxIntensity": 56, + "type": "specular", + "averageColor": "#383838" + }, + { + "mimeType": "image/jpeg", + "minIntensity": 56, + "bitDepth": 8, + "name": "Specular", + "resolution": "8192x8192", + "contentLength": 33882733, + "colorSpace": "sRGB", + "uri": "ugznfcyo_8K_Specular.jpg", + "physicalSize": "1x1", + "maxIntensity": 56, + "type": "specular", + "averageColor": "#383838" + } + ], + "json": { + "contentLength": 30236, + "uri": "ugznfcyo.json" + }, + "points": 2, + "meta": [ + { + "key": "scanArea", + "name": "Scan Area", + "value": "1x1 m" + }, + { + "key": "height", + "name": "Height", + "value": "0.007 m" + }, + { + "key": "tileable", + "name": "Tileable", + "value": true + }, + { + "key": "tiling_directions", + "name": "Tiling Directions", + "value": [ + "x", + "y" + ] + }, + { + "key": "texelDensity", + "name": "Texel Density", + "value": "8192 px/m" + }, + { + "key": "calibration", + "name": "Calibration", + "value": "GretagMacbeth ColorChecker Color Rendition Chart" + }, + { + "key": "scanner", + "name": "Scanner", + "value": "MKX" + } + ], + "categories": [ + "surface", + "tile", + "pavestone" + ], + "version": 2, + "references": [], + "referencePreviews": { + "maps": [ + { + "mimeType": "image/jpeg", + "resolution": "1024x1024", + "contentLength": 538699, + "type": "ao", + "uri": "" + }, + { + "mimeType": "image/jpeg", + "resolution": "1024x1024", + "contentLength": 1431100, + "type": "albedo", + "uri": "" + }, + { + "mimeType": "image/jpeg", + "resolution": "1024x1024", + "contentLength": 717611, + "type": "bump", + "uri": "" + }, + { + "mimeType": "image/jpeg", + "resolution": "1024x1024", + "contentLength": 656419, + "type": "cavity", + "uri": "" + }, + { + "mimeType": "image/jpeg", + "resolution": "1024x1024", + "contentLength": 130487, + "type": "displacement", + "uri": "" + }, + { + "mimeType": "image/jpeg", + "resolution": "1024x1024", + "contentLength": 159515, + "type": "gloss", + "uri": "" + }, + { + "mimeType": "image/jpeg", + "resolution": "1024x1024", + "contentLength": 1710182, + "type": "normal", + "uri": "" + }, + { + "mimeType": "image/jpeg", + "resolution": "1024x1024", + "contentLength": 154968, + "type": "roughness", + "uri": "" + }, + { + "mimeType": "image/jpeg", + "resolution": "1024x1024", + "contentLength": 381601, + "type": "specular", + "uri": "" + } + ] + }, + "properties": [], + "averageColor": "#000000", + "name": "Sidewalk Tiles", + "assetCategories": { + "surface": { + "tile": { + "sidewalk": {} + } + } + }, + "revision": 0, + "id": "ugznfcyo", + "physicalSize": null +} \ No newline at end of file diff --git a/textures/tile/ugznfcyo_4K_AO.jpg b/textures/tile/ugznfcyo_4K_AO.jpg new file mode 100644 index 0000000..0d54d95 Binary files /dev/null and b/textures/tile/ugznfcyo_4K_AO.jpg differ diff --git a/textures/tile/ugznfcyo_4K_Albedo.jpg b/textures/tile/ugznfcyo_4K_Albedo.jpg new file mode 100644 index 0000000..83aa75b Binary files /dev/null and b/textures/tile/ugznfcyo_4K_Albedo.jpg differ diff --git a/textures/tile/ugznfcyo_4K_Bump.jpg b/textures/tile/ugznfcyo_4K_Bump.jpg new file mode 100644 index 0000000..656dcd9 Binary files /dev/null and b/textures/tile/ugznfcyo_4K_Bump.jpg differ diff --git a/textures/tile/ugznfcyo_4K_Cavity.jpg b/textures/tile/ugznfcyo_4K_Cavity.jpg new file mode 100644 index 0000000..22f43ac Binary files /dev/null and b/textures/tile/ugznfcyo_4K_Cavity.jpg differ diff --git a/textures/tile/ugznfcyo_4K_Displacement.exr b/textures/tile/ugznfcyo_4K_Displacement.exr new file mode 100644 index 0000000..4e83536 Binary files /dev/null and b/textures/tile/ugznfcyo_4K_Displacement.exr differ diff --git a/textures/tile/ugznfcyo_4K_Displacement.jpg b/textures/tile/ugznfcyo_4K_Displacement.jpg new file mode 100644 index 0000000..9684309 Binary files /dev/null and b/textures/tile/ugznfcyo_4K_Displacement.jpg differ diff --git a/textures/tile/ugznfcyo_4K_Gloss.jpg b/textures/tile/ugznfcyo_4K_Gloss.jpg new file mode 100644 index 0000000..6ef0634 Binary files /dev/null and b/textures/tile/ugznfcyo_4K_Gloss.jpg differ diff --git a/textures/tile/ugznfcyo_4K_Normal.jpg b/textures/tile/ugznfcyo_4K_Normal.jpg new file mode 100644 index 0000000..c5ca89f Binary files /dev/null and b/textures/tile/ugznfcyo_4K_Normal.jpg differ diff --git a/textures/tile/ugznfcyo_4K_Roughness.jpg b/textures/tile/ugznfcyo_4K_Roughness.jpg new file mode 100644 index 0000000..d1e9b9a Binary files /dev/null and b/textures/tile/ugznfcyo_4K_Roughness.jpg differ diff --git a/textures/tile/ugznfcyo_4K_Specular.jpg b/textures/tile/ugznfcyo_4K_Specular.jpg new file mode 100644 index 0000000..6244d69 Binary files /dev/null and b/textures/tile/ugznfcyo_4K_Specular.jpg differ diff --git a/vulkan.scm b/vulkan.scm index 318ec85..a33e7d5 100644 --- a/vulkan.scm +++ b/vulkan.scm @@ -1,160 +1,218 @@ -#!chezscheme -(library (vulkan) - - (export setup-vulkan - make-shaders - create-pipeline - create-buffers - run-draw-loop) - - (import (chezscheme) - (prelude) - (ffi) - (glfw) - (assimp) - (glfw) - (shaderc) - (camera) - (image) - (matchable) - - (vulkan structure-types)) - - (define v (load-shared-object "libvulkan.so.1")) - - (include "vulkan/enums.scm") - (include "vulkan/ftype.scm") - - (include "vulkan/instance.scm") - (include "vulkan/surface.scm") - - (include "vulkan/queues.scm") - (include "vulkan/devices.scm") - (include "vulkan/swapchain.scm") - - (include "vulkan/images.scm") - (include "vulkan/pipeline.scm") - (include "vulkan/mesh.scm") - (include "vulkan/texture.scm") - (include "vulkan/buffers.scm") - - (include "vulkan/sync.scm") - - (define-record-type vulkan-state - (fields window surface physical-device queue-index device queues swapchain)) - - (define setup-vulkan - (lambda () - (let* ((instance (init-vulkan)) - (_ (glfw-init)) - (window (setup-window instance 3840 2160)) - (surface (window-details-surface window)) - (physical-device (array-pointer-raw-ptr (get-physical-devices instance))) - (queue-index (find-queue-family physical-device surface)) - (device (create-logical-device physical-device queue-index)) - (queues (create-queue-handles device)) - (swapchain-details (create-swapchain physical-device device surface queue-index))) - (make-vulkan-state window surface physical-device queue-index device queues - swapchain-details)))) - - ;; returns a cons cell of (vertex-input-metadata . graphics-pipeline) - (define create-pipeline - (lambda (state shaders model-filename) - (match-let (((@ vulkan-state (physical-device physical-device) - (device device) - (swapchain swapchain)) state)) - (let* ((vertex-input-metadata (model->vertex-input-metadata model-filename)) - (pipeline-data (make-pipeline-data shaders - (vertex-input->details vertex-input-metadata)))) - (cons vertex-input-metadata - (create-graphics-pipeline physical-device device swapchain pipeline-data)))))) - - ;; returns a cons cell of (uniform-buffers . command-buffers) - (define create-buffers - (lambda (state vertex-input-metadata-obj pipeline) - (match-let* (((@ vulkan-state (physical-device physical-device) - (device device) - (swapchain swapchain-obj) - (queue-index queue-index) - (queues queues)) state) - ((@ vertex-input-metadata (vertices-list vertices) - (indices indices) - (components components)) vertex-input-metadata-obj) - ((@ swapchain (image-views swapchain-image-views) - (extent extent)) swapchain-obj) - ((graphics-queue . present-queue) queues)) - (displayln "indices length " (length indices) - "vertices length" (length vertices)) - (let* ((command-pool (create-command-pool device queue-index)) - (vertex-buffer (create-gpu-local-buffer physical-device +(define-record-type vulkan-state + (fields window surface physical-device queue-index device queues swapchain command-pool)) + +(define setup-vulkan + (lambda () + (let* ((instance (init-vulkan)) + (_ (glfw-init)) + (window (setup-window instance 3840 2160)) + (surface (window-details-surface window)) + (physical-device (array-pointer-raw-ptr (get-physical-devices instance))) + (queue-index (find-queue-family physical-device surface)) + (device (create-logical-device physical-device queue-index)) + (queues (create-queue-handles device)) + (swapchain-details (create-swapchain physical-device device surface queue-index)) + (command-pool (create-command-pool device queue-index))) + (make-vulkan-state window surface physical-device queue-index device queues + swapchain-details command-pool)))) + +(define configure-descriptor-layout + (lambda (device) + + (define fragment-sampler-binding + (lambda (binding-index) + (make-vk-descriptor-set-layout-binding binding-index + vk-descriptor-type-combined-image-sampler + 1 + vk-shader-stage-fragment-bit + (null-pointer vk-sampler)))) + + (define make-uniform-buffer-binding + (lambda (binding-index stage) + (make-vk-descriptor-set-layout-binding binding-index + vk-descriptor-type-uniform-buffer + 1 + stage + (null-pointer vk-sampler)))) + + (let* ((uniform-buffer-binding + (make-uniform-buffer-binding 0 + (bitwise-ior vk-shader-stage-vertex-bit + vk-shader-stage-fragment-bit))) + (light-info-binding (make-uniform-buffer-binding 1 vk-shader-stage-fragment-bit)) + (texture-sampler-bindings (map fragment-sampler-binding (cddr (iota 10)))) + (bindings (list->vk-descriptor-set-layout-binding-pointer-array + (append (list uniform-buffer-binding light-info-binding) + texture-sampler-bindings)))) + (create-descriptor-layout device bindings)))) + +;; returns a cons cell of (vertex-input-metadata . graphics-pipeline) +(define create-pipeline + (lambda (state shaders model-filename) + (displayln "creating pipeline") + (match-let (((@ vulkan-state (physical-device physical-device) + (device device) + (swapchain swapchain)) state)) + (let* ((vertex-input-metadata (model->vertex-input-metadata model-filename)) + (render-pass (configure-render-pass physical-device device swapchain)) + (descriptor-layout (configure-descriptor-layout device)) + (rasterization-state (make-rasterization-state vk-polygon-mode-fill + vk-cull-mode-back-bit + vk-front-face-clockwise)) + (depth-state (make-depth-stencil-state #t #t vk-compare-op-less)) + (pipeline-data (make-pipeline-data shaders + (vertex-input->details vertex-input-metadata) + render-pass + descriptor-layout + rasterization-state + depth-state + (swapchain-extent swapchain)))) + (list (create-graphics-pipeline physical-device device pipeline-data) + vertex-input-metadata + render-pass))))) + +;; descriptor data + + + +;; returns a list of ( command-pool command-buffers uniform-buffers) +(define create-buffers + (lambda (state pipeline vertex-input-metadata-obj render-pass) + (displayln "creating buffer") + (match-let* (((@ vulkan-state (physical-device physical-device) + (device device) + (swapchain swapchain-obj) + (queue-index queue-index) + (queues queues) + (command-pool command-pool)) state) + ((@ vertex-input-metadata (vertices-list vertices) + (indices indices) + (components components)) vertex-input-metadata-obj) + ((@ swapchain (image-views swapchain-image-views) + (extent extent)) swapchain-obj) + ((graphics-queue . present-queue) queues)) + (displayln "indices length " (length indices) + "vertices length" (length vertices)) + (let* ((vertex-buffer (create-gpu-local-buffer physical-device + device + graphics-queue + command-pool + vertices + vk-buffer-usage-vertex-buffer-bit)) + (index-buffer (create-gpu-local-buffer physical-device + device + graphics-queue + command-pool + indices + vk-buffer-usage-index-buffer-bit)) + (framebuffers (create-framebuffers-for-swapchain physical-device + device + command-pool + graphics-queue + swapchain-obj + pipeline + render-pass)) + (framebuffer-size (length framebuffers)) + + (camera-matrix (extent->uniform-buffer-data extent)) + + (camera-uniform-buffers + (create-uniform-buffers physical-device + device + (uniform-buffer-data->list camera-matrix) + framebuffer-size)) + (lights-uniform-buffers + (create-uniform-buffers physical-device + device + (lights-data->list default-light-data) + framebuffer-size)) + + (albedo-texture-data (create-texture-data physical-device device + command-pool graphics-queue + swapchain-obj + "textures/tile/ugznfcyo_4K_Albedo.jpg")) + (normal-texture-data (create-texture-data physical-device + device command-pool - vertices - vk-buffer-usage-vertex-buffer-bit)) - (index-buffer (create-gpu-local-buffer physical-device - device - graphics-queue - command-pool - indices - vk-buffer-usage-index-buffer-bit)) - (framebuffers (create-framebuffers physical-device - device - command-pool - graphics-queue - swapchain-obj - pipeline)) - (framebuffer-size (length framebuffers)) - (uniform-buffers (create-uniform-buffers physical-device - device - (extent->uniform-buffer-data extent) - framebuffer-size)) - (texture-data (create-texture-data physical-device - device - command-pool - graphics-queue - swapchain-obj)) - (descriptor-sets (create-descriptor-sets device - (create-descriptor-pool device - framebuffer-size) - (pipeline-descriptor-set-layout pipeline) - uniform-buffers - texture-data))) - (cons uniform-buffers (create-command-buffers device - swapchain-obj - command-pool - pipeline - vertex-buffer - index-buffer - framebuffers - descriptor-sets - (length indices) - components)))))) - - (define sync-objects (lambda (device) (init-sync-objects device))) - - (define initial-state - (lambda (cmd-buffers) - (make-frame-state 1 - (list->vector (map (lambda (_) #f) - (iota (array-pointer-length cmd-buffers))))))) - - - (define run-draw-loop - (lambda (state uniform-buffers command-buffers) - (match state - ((@ vulkan-state (window window) - (device device) - (swapchain swapchain) - (queues queues)) - (draw-next-frame (window-details-window window) - device - swapchain - queues - uniform-buffers - command-buffers - (sync-objects device) - (initial-state command-buffers))))))) + graphics-queue + swapchain-obj + "textures/tile/ugznfcyo_4K_Normal.jpg")) + (ao-texture-data (create-texture-data physical-device + device + command-pool + graphics-queue + swapchain-obj + "textures/tile/ugznfcyo_4K_AO.jpg")) + (metallic-texture-data (create-texture-data physical-device + device + command-pool + graphics-queue + swapchain-obj + "textures/tile/ugznfcyo_4K_Gloss.jpg")) + + (roughness-texture-data (create-texture-data physical-device + device + command-pool + graphics-queue + swapchain-obj + "textures/tile/ugznfcyo_4K_Roughness.jpg")) + + (pbr-texture-data (brdf-data physical-device device command-pool graphics-queue)) + + (descriptor-sets (create-descriptor-sets device + (create-descriptor-pool device + framebuffer-size) + (pipeline-descriptor-set-layout pipeline) + (map cons + camera-uniform-buffers + lights-uniform-buffers) + (list pbr-texture-data + albedo-texture-data + normal-texture-data + ao-texture-data + metallic-texture-data + roughness-texture-data)))) + (list (create-command-buffers device + swapchain-obj + command-pool + pipeline + vertex-buffer + index-buffer + framebuffers + descriptor-sets + (length indices) + components) + camera-uniform-buffers + camera-matrix))))) + +(define sync-objects (lambda (device) (init-sync-objects device))) + +(define initial-state + (lambda (cmd-buffers) + (make-frame-state 1 + (list->vector (map (lambda (_) #f) + (iota (array-pointer-length cmd-buffers))))))) + + +(define run-draw-loop + (lambda (state uniform-buffers command-buffers camera-matrix) + (match state + ((@ vulkan-state (window window) + (device device) + (swapchain swapchain) + (queues queues)) + (draw-next-frame (window-details-window window) + device + swapchain + queues + uniform-buffers + command-buffers + (sync-objects device) + (initial-state command-buffers) + camera-matrix))))) + ;;; (load "vulkan.scm") diff --git a/vulkan.sls b/vulkan.sls new file mode 100644 index 0000000..713973e --- /dev/null +++ b/vulkan.sls @@ -0,0 +1,46 @@ +#!chezscheme +(library (vulkan) + + (export setup-vulkan + make-shaders + create-pipeline + create-buffers + run-draw-loop) + + (import (chezscheme) + (prelude) + (ffi) + (glfw) + (assimp) + (glfw) + (shaderc) + (camera) + (image) + (matchable) + + (vulkan structure-types)) + + (define g (load-glfw)) + (define v (load-shared-library (make-library-detail #f + "libvulkan.so.1" + "vulkan-1.dll"))) + + (include "vulkan/enums.scm") + (include "vulkan/ftype.scm") + + (include "vulkan/instance.scm") + (include "vulkan/surface.scm") + + (include "vulkan/queues.scm") + (include "vulkan/devices.scm") + (include "vulkan/swapchain.scm") + + (include "vulkan/images.scm") + (include "vulkan/pipeline.scm") + (include "vulkan/mesh.scm") + (include "vulkan/texture.scm") + (include "vulkan/buffers.scm") + + (include "vulkan/sync.scm") + (include "vulkan/pbr.scm") + (include "vulkan.scm")) diff --git a/vulkan/buffers.scm b/vulkan/buffers.scm index 6ba0d3c..e744270 100644 --- a/vulkan/buffers.scm +++ b/vulkan/buffers.scm @@ -1,31 +1,38 @@ ;; Framebuffers +(define (framebuffer-info render-pass extent . image-views) + (displayln "image views" image-views) + (let ((views (list->vk-image-view-pointer-array image-views))) + (make-vk-frame-buffer-create-info framebuffer-create-info 0 0 + (pointer-ref-value render-pass) + (array-pointer-length views) + (array-pointer-raw-ptr views) + (vk-extent-2d-width extent) + (vk-extent-2d-height extent) + 1))) + +(define (create-framebuffer device render-pass extent . image-views) + (let ((info (apply framebuffer-info (append (list render-pass extent) image-views))) + (framebuffer (make-foreign-object vk-frame-buffer))) + (vk-create-framebuffer device info 0 framebuffer) + framebuffer)) + ;; returns a list of framebuffers created for each of the swapchain image views -(define create-framebuffers - (lambda (physical-device device command-pool graphics-queue swapchain pipeline) - - (define (framebuffer-info . image-views) - (let ((views (list->vk-image-view-pointer-array image-views))) - (displayln "views" views) - (make-vk-frame-buffer-create-info framebuffer-create-info 0 0 - (pointer-ref-value (pipeline-render-pass pipeline)) - (array-pointer-length views) - (array-pointer-raw-ptr views) - (vk-extent-2d-width (swapchain-extent swapchain)) - (vk-extent-2d-height (swapchain-extent swapchain)) - 1))) - +(define create-framebuffers-for-swapchain + (lambda (physical-device device command-pool graphics-queue swapchain pipeline render-pass) (let ((depth-image-view (create-depth-buffer-image physical-device device command-pool graphics-queue - swapchain))) + swapchain)) + (extent (swapchain-extent swapchain))) (map (lambda (image-view) - (let ((info (framebuffer-info image-view (gpu-image-view depth-image-view))) - (framebuffer (make-foreign-object vk-frame-buffer))) - (vk-create-framebuffer device info 0 framebuffer) - framebuffer)) + (create-framebuffer device + render-pass + extent + image-view + (gpu-image-view depth-image-view))) (swapchain-image-views swapchain))))) @@ -57,23 +64,26 @@ (define start-command-buffer-recording (case-lambda - ((command-buffer) (start-command-buffer-recording command-buffer #f)) - ((command-buffer one-time-submit?) - (let ((begin-info (make-vk-command-buffer-begin-info - command-buffer-begin-info - 0 - (if one-time-submit? - vk-command-buffer-usage-one-time-submit-bit - 0) - (null-pointer vk-command-buffer-inheritance-info)))) - (vk-begin-command-buffer command-buffer begin-info) - command-buffer)))) + ((command-buffer) (start-command-buffer-recording command-buffer #f)) + ((command-buffer one-time-submit?) + (let ((begin-info (make-vk-command-buffer-begin-info + command-buffer-begin-info + 0 + (if one-time-submit? + vk-command-buffer-usage-one-time-submit-bit + 0) + (null-pointer vk-command-buffer-inheritance-info)))) + (vk-begin-command-buffer command-buffer begin-info) + command-buffer)))) + +;; timeout in nanosecs + (define end-command-buffer-recording (case-lambda ((command-buffer) (vk-end-command-buffer command-buffer)) - ((command-buffer graphics-queue) + ((command-buffer device graphics-queue wait?) (vk-end-command-buffer command-buffer) (let ((submit-info (make-vk-submit-info submit-info 0 0 @@ -82,8 +92,20 @@ 1 command-buffer 0 - (null-pointer vk-semaphore)))) - (vk-queue-submit graphics-queue 1 submit-info 0) + (null-pointer vk-semaphore))) + (fence (and wait? + (let ((fence (make-foreign-object vk-fence))) + (vk-create-fence device + (make-vk-fence-create-info fence-create-info 0 0) + 0 + fence) + fence)))) + (vk-queue-submit graphics-queue 1 submit-info (if wait? + (pointer-ref-value fence) + 0)) + (if wait? + (begin (vk-wait-for-fences device 1 fence vk-true +timeout+) + (vk-destroy-fence device fence 0))) (vk-queue-wait-idle graphics-queue))))) ;; creates and submits a single command buffer @@ -91,20 +113,24 @@ ;; once f returns the command buffer is submitted to the queue and ;; we wait for device idle (define execute-command-buffer - (lambda (device command-pool graphics-queue f) + (case-lambda + ((device command-pool graphics-queue f) + (execute-command-buffer device command-pool graphics-queue #f f)) + ((device command-pool graphics-queue wait? f) (let ((command-buffer #f)) (dynamic-wind - (lambda () - (set! command-buffer - (start-command-buffer-recording (allocate-command-buffers device command-pool) - #t))) - (lambda () - (begin (f command-buffer) - (end-command-buffer-recording command-buffer graphics-queue))) - (lambda () - ;; (vk-free-command-buffers device command-pool 1 command-buffer) - #f - ))))) + (lambda () + (set! command-buffer + (start-command-buffer-recording (allocate-command-buffers device + command-pool) + #t))) + (lambda () + (f command-buffer) + (end-command-buffer-recording command-buffer device graphics-queue wait?)) + (lambda () + ;; (vk-free-command-buffers device command-pool 1 command-buffer) + #f + )))))) ;; allocate 'num-buffers' command-buffers and record the command as passed in f ;; to all of them @@ -125,6 +151,26 @@ descriptor-sets) cmd-buffers-ptr))) +(define-record-type render-pass-data + (fields command-buffer framebuffer render-area clear-values pipeline)) + +(define perform-render-pass + (lambda (render-pass-info draw-lambda) + (match render-pass-info + (($ render-pass-data cmd-buffer framebuffer render-area clear-values pipeline) + (let ((info (make-vk-render-pass-begin-info (pipeline-render-pass pipeline) + framebuffer + render-area + clear-values))) + (vk-cmd-begin-render-pass cmd-buffer + info + vk-subpass-contents-inline) + (vk-cmd-bind-pipeline cmd-buffer + vk-pipeline-bind-point-graphics + (pipeline-handle pipeline)) + (draw-lambda) + (vk-cmd-end-render-pass cmd-buffer)))))) + (define create-command-buffers (lambda (device swapchain command-pool pipeline vertex-buffer index-buffer framebuffers @@ -139,14 +185,10 @@ (list->vk-clear-value-pointer-array (list (make-vk-clear-value clear-values) (make-vk-clear-value depth-clear)))))) - (define perform-render-pass + (define render-pass (lambda (cmd-buffer framebuffer descriptor-set vertex-buffer index-buffer render-area clear-values) - (let ((info (make-vk-render-pass-begin-info (pipeline-render-pass pipeline) - framebuffer - render-area - clear-values)) - (vertex-buffers (array-pointer-raw-ptr (list->vk-buffer-pointer-array + (let ((vertex-buffers (array-pointer-raw-ptr (list->vk-buffer-pointer-array (list (buffer-handle vertex-buffer))))) (offsets (array-pointer-raw-ptr (list->u64-pointer-array (map (lambda (v) @@ -154,38 +196,30 @@ (ftype-set! u64 () ptr v) ptr)) (list 0)))))) - (vk-cmd-begin-render-pass cmd-buffer - info - vk-subpass-contents-inline) - (vk-cmd-bind-pipeline cmd-buffer - vk-pipeline-bind-point-graphics - (pipeline-handle pipeline)) - (vk-cmd-bind-vertex-buffers cmd-buffer - 0 - 1 - vertex-buffers - offsets) - (vk-cmd-bind-index-buffer cmd-buffer - (buffer-handle index-buffer) - 0 - vk-index-type-uint32) - (vk-cmd-bind-descriptor-sets cmd-buffer - vk-pipeline-bind-point-graphics - (pipeline-layout pipeline) - 0 - 1 - descriptor-set - 0 - (null-pointer u32)) - (for-each (lambda (component) - (vk-cmd-draw-indexed cmd-buffer - (mesh-component-index-count component) - 1 - 0 - (mesh-component-index-base component) - 0)) - components) - (vk-cmd-end-render-pass cmd-buffer) + (perform-render-pass + (make-render-pass-data cmd-buffer framebuffer render-area clear-values pipeline) + (lambda () + (vk-cmd-bind-vertex-buffers cmd-buffer 0 1 vertex-buffers offsets) + (vk-cmd-bind-index-buffer cmd-buffer + (buffer-handle index-buffer) + 0 + vk-index-type-uint32) + (vk-cmd-bind-descriptor-sets cmd-buffer + vk-pipeline-bind-point-graphics + (pipeline-layout pipeline) + 0 + 1 + descriptor-set + 0 + (null-pointer u32)) + (for-each (lambda (component) + (vk-cmd-draw-indexed cmd-buffer + (mesh-component-index-count component) + 1 + 0 + (mesh-component-index-base component) + 0)) + components))) cmd-buffer))) (let ((clear-values (clear-values-ptr)) @@ -198,13 +232,13 @@ framebuffers descriptor-sets (lambda (cmd-buffer framebuffer descriptor-set) - (perform-render-pass cmd-buffer - framebuffer - descriptor-set - vertex-buffer - index-buffer - render-area - clear-values)))))) + (render-pass cmd-buffer + framebuffer + descriptor-set + vertex-buffer + index-buffer + render-area + clear-values)))))) ;; Buffers @@ -286,6 +320,7 @@ (execute-command-buffer device command-pool graphics-queue + #f (lambda (command-buffer) (displayln "command-buffer is" command-buffer) (vk-cmd-copy-buffer command-buffer @@ -346,10 +381,13 @@ data))) ((number? (car data)) - (list->u32-pointer-array + ;; todo shouldn;t do this + (list->float-pointer-array (map-indexed (lambda (value i) - (let ((ptr (make-foreign-object u32))) - (ftype-set! u32 () ptr value) + (let ((ptr (make-foreign-object float))) + (ftype-set! float () ptr (if (exact? value) + (exact->inexact value) + value)) ptr)) data)))))))) @@ -394,6 +432,10 @@ (make-buffer gpu-buffer-ptr memory size)))) +;; descriptor state data +;; buffer data for writing descriptor sets +(define-record-type descriptor-set-data (fields uniform-buffers textures)) + ;; Uniform buffers (define-record-type uniform-buffer-data (fields model view projection)) @@ -406,22 +448,18 @@ (calculate-mvp-matrix width height))) - (define create-uniform-buffers (lambda (physical-device device data num-buffers) (map (lambda (i) - (cons (create-host-buffer physical-device - device - (uniform-buffer-data->list data) - vk-buffer-usage-uniform-buffer-bit) - data)) + (create-host-buffer physical-device device data vk-buffer-usage-uniform-buffer-bit)) (iota num-buffers)))) (define update-uniform-buffer (lambda (device uniform-buffer matrix eye-position movement-direction) - ;; (displayln "uniform buffer" uniform-buffer "matrix" matrix "eye position" eye-position) - (match (car uniform-buffer) + (displayln "uniform buffer" uniform-buffer "matrix" matrix "eye position" eye-position) + (match uniform-buffer (($ buffer handle memory size) + (displayln "updating matrix") (match (update-mvp-matrix matrix eye-position movement-direction) ((matrix . eye) (copy-data-from-scheme device @@ -430,6 +468,16 @@ (cons matrix eye)))) (else (error "unifor buffer not valid" uniform-buffer))))) + +(define-record-type lights-data (fields positions exposure gamma)) + +(define (lights-data->list data) + (match data + (($ lights-data positions exposure gamma) + (append positions (list exposure gamma))))) + +(define default-light-data (make-lights-data '(0 0 0 0 0 0 0 0) 4.5 2.5)) + ;; Descriptor sets and pools ;; used to pass on data like uniform buffers and textures to the shaders @@ -437,10 +485,10 @@ (define create-descriptor-pool (lambda (device descriptor-count) (let* ((uniform-buffer-pool-size (make-vk-descriptor-pool-size vk-descriptor-type-uniform-buffer - descriptor-count)) + (* descriptor-count 2))) (image-sampler-pool-size (make-vk-descriptor-pool-size vk-descriptor-type-combined-image-sampler - descriptor-count)) + (* descriptor-count 8))) (pool-size-ptr (list->vk-descriptor-pool-size-pointer-array (list uniform-buffer-pool-size image-sampler-pool-size))) (info (make-vk-descriptor-pool-create-info descriptor-pool-create-info 0 0 @@ -453,7 +501,7 @@ (define create-descriptor-sets - (lambda (device descriptor-pool descriptor-layout uniform-buffers texture-data) + (lambda (device descriptor-pool descriptor-layout uniform-buffers textures-data) (define allocate-descriptor-sets (lambda (num-sets) @@ -472,44 +520,61 @@ (let* ((num-sets (length uniform-buffers)) ;; todo can be optimized further - (ubo-size (sizeof-scheme-data (uniform-buffer-data->list (cdar uniform-buffers)))) + (camera-ubo-size (buffer-size (caar uniform-buffers))) + (light-ubo-size (buffer-size (cdar uniform-buffers))) (descriptor-sets (allocate-descriptor-sets num-sets))) - (displayln "ubo size is" ubo-size) - (map (lambda (uniform-buffer descriptor-set) - (let* ((buffer-info - (make-vk-descriptor-buffer-info (pointer-ref-value uniform-buffer) + (displayln "ubox isze " camera-ubo-size light-ubo-size) + (map (lambda (camera-uniform-buffer lights-uniform-buffer descriptor-set) + (let* ((camera-buffer-info + (make-vk-descriptor-buffer-info (pointer-ref-value camera-uniform-buffer) + 0 + camera-ubo-size)) + (lights-buffer-info + (make-vk-descriptor-buffer-info (pointer-ref-value lights-uniform-buffer) 0 - ubo-size)) - (image-info - (make-vk-descriptor-image-info - (pointer-ref-value (texture-data-sampler texture-data)) - (pointer-ref-value (texture-data-image-view texture-data)) - vk-image-layout-shader-read-only-optimal)) - (uniform-buffer-write - (make-vk-write-descriptor-set write-descriptor-set - 0 - (pointer-ref-value descriptor-set) - 0 - 0 - 1 - vk-descriptor-type-uniform-buffer - (null-pointer vk-descriptor-image-info) - buffer-info - (null-pointer vk-buffer-view))) - (combined-image-sampler-write - (make-vk-write-descriptor-set write-descriptor-set - 0 - (pointer-ref-value descriptor-set) - 1 - 0 - 1 - vk-descriptor-type-combined-image-sampler - image-info - (null-pointer vk-descriptor-buffer-info) - (null-pointer vk-buffer-view))) - (write - (list->vk-write-descriptor-set-pointer-array - (list uniform-buffer-write combined-image-sampler-write)))) + light-ubo-size)) + (image-infos + (map (lambda (texture-data) + (make-vk-descriptor-image-info (pointer-ref-value + (texture-data-sampler texture-data)) + (pointer-ref-value + (texture-data-image-view texture-data)) + vk-image-layout-shader-read-only-optimal)) + textures-data)) + + (uniform-buffer-writes + (map-indexed (lambda (buffer-info index) + (make-vk-write-descriptor-set write-descriptor-set + 0 + (pointer-ref-value descriptor-set) + index + 0 + 1 + vk-descriptor-type-uniform-buffer + (null-pointer vk-descriptor-image-info) + camera-buffer-info + (null-pointer vk-buffer-view))) + (list camera-buffer-info lights-buffer-info))) + + (combined-image-sampler-writes + (map-indexed + (lambda (image-info index) + (make-vk-write-descriptor-set write-descriptor-set + 0 + (pointer-ref-value descriptor-set) + ;; first two filled by uniform buffer writes + (+ 2 index) + 0 + 1 + vk-descriptor-type-combined-image-sampler + image-info + (null-pointer vk-descriptor-buffer-info) + (null-pointer vk-buffer-view))) + image-infos)) + + (write (list->vk-write-descriptor-set-pointer-array + (append uniform-buffer-writes combined-image-sampler-writes)))) + (vk-update-descriptor-sets device (array-pointer-length write) (array-pointer-raw-ptr write) @@ -517,6 +582,7 @@ 0) descriptor-set)) (map (lambda (buf) (buffer-handle (car buf))) uniform-buffers) + (map (lambda (buf) (buffer-handle (cdr buf))) uniform-buffers) (vk-descriptor-set-pointer-map (lambda (x) x) descriptor-sets))))) diff --git a/vulkan/devices.scm b/vulkan/devices.scm index 54ce6d5..c9d13ee 100644 --- a/vulkan/devices.scm +++ b/vulkan/devices.scm @@ -8,21 +8,21 @@ (lambda (count devices) (vk-enumerate-physical-devices instance count devices))))) -(define find-memory-type-index - (lambda (physical-device required-type required-properties) - (let ((properties (make-foreign-object vk-physical-device-memory-properties))) - (vk-get-physical-device-memory-properties physical-device properties) - (find (lambda (i) - (and (bitwise-and required-type - (bitwise-arithmetic-shift-left i 1)) - (equal? required-properties - (bitwise-and (ftype-ref vk-physical-device-memory-properties - (memory-types i property-flags) - properties) - required-properties)))) - (iota (ftype-ref vk-physical-device-memory-properties - (memory-type-count) - properties)))))) +(trace-define find-memory-type-index + (lambda (physical-device required-type required-properties) + (let ((properties (make-foreign-object vk-physical-device-memory-properties))) + (vk-get-physical-device-memory-properties physical-device properties) + (find (lambda (i) + (and (bitwise-and required-type + (bitwise-arithmetic-shift-left i 1)) + (equal? required-properties + (bitwise-and (ftype-ref vk-physical-device-memory-properties + (memory-types i property-flags) + properties) + required-properties)))) + (iota (ftype-ref vk-physical-device-memory-properties + (memory-type-count) + properties)))))) (define create-logical-device diff --git a/vulkan/ftype.scm b/vulkan/ftype.scm index 7cb89bb..8f033c6 100644 --- a/vulkan/ftype.scm +++ b/vulkan/ftype.scm @@ -1,5 +1,6 @@ + (trace-define-syntax define-vulkan-struct (syntax-rules () ((_ struct-name ((member-name . member-type) ...)) @@ -57,10 +58,25 @@ (cons (list (car str)) dest)))))))) -(trace-define-syntax define-vulkan-command - (lambda (stx) - (syntax-case stx () +(define-syntax vk-result-lambda + (syntax-rules () + ((_ command-name ffi-proc (arg-names ...)) + (lambda (arg-names ...) + (let ((res (ffi-proc arg-names ...))) + (case res + ((0) #t) + (else (error "vulkan command failed" command-name res)))))))) + +(define-syntax void-lambda + (syntax-rules () + ((_ ffi-proc (arg-names ...)) (lambda (arg-names ...) (ffi-proc arg-names ...))))) + +(define-syntax define-vulkan-command + (lambda (stx) + (syntax-case stx () [(_ command (argument-types ...)) + #'(define-vulkan-command command (argument-types ...) int)] + [(_ command (argument-types ...) return-type) (let ((command-string (symbol->string (syntax->datum #'command)))) (with-syntax ((command-name (datum->syntax #'command command-string)) @@ -72,15 +88,15 @@ (camel-case->kebab-case command-string)))) ((arg-names ...) (map (lambda (t) (datum->syntax #'command (gensym))) #'(argument-types ...)))) - #'(begin (define _ffi-proc - (foreign-procedure command-name (argument-types ...) int)) + (with-syntax ((body (case (syntax->datum #'return-type) + ((void) #'(void-lambda _ffi-proc (arg-names ...))) + ((int) #'(vk-result-lambda command-name + _ffi-proc + (arg-names ...)))))) + #'(begin (define _ffi-proc + (foreign-procedure command-name (argument-types ...) return-type)) - (define ffi-proc - (lambda (arg-names ...) - (let ((res (_ffi-proc arg-names ...))) - (case res - ((0) #t) - (else (error "vulkan command failed" command-name res)))))))))]))) + (define ffi-proc body)))))]))) ;;;;;;;;;;;;;;;;;;;;;;; @@ -939,6 +955,8 @@ (dst-access-mask . flags) (dependency-flags . flags))) +(define-collection-lambdas vk-subpass-dependency) + (define-vulkan-struct vk-render-pass-create-info ((flags . flags) (attachment-count . unsigned-32) @@ -1466,7 +1484,7 @@ (define-vulkan-command vkCreateFence ((& vk-device) (* vk-fence-create-info) uptr (* vk-fence))) -(define-vulkan-command vkDestroyFence ((& vk-device) (& vk-fence) uptr)) +(define-vulkan-command vkDestroyFence ((& vk-device) (& vk-fence) uptr) void) (define-vulkan-command vkResetFences ((& vk-device) u32 (* vk-fence))) (define-vulkan-command vkGetFenceStatus ((& vk-device) (& vk-fence))) (define-vulkan-command vkWaitForFences ((& vk-device) u32 (* vk-fence) vk-bool32 u64)) diff --git a/vulkan/images.scm b/vulkan/images.scm index 9d191df..218bf7c 100644 --- a/vulkan/images.scm +++ b/vulkan/images.scm @@ -78,14 +78,22 @@ vk-image-usage-depth-stencil-attachment-bit vk-image-aspect-depth-bit))) -(define create-texture-property - (lambda (texture-width texture-height) +(define create-image-property-for-texture + (case-lambda + ((texture-width texture-height) + (create-image-property-for-texture texture-width texture-height vk-format-r8g8b8a8-unorm)) + ((texture-width texture-height format) + (create-image-property-for-texture texture-width + texture-height + format + vk-image-usage-transfer-dst-bit)) + ((texture-width texture-height format usage) (make-image-properties texture-width texture-height - vk-format-r8g8b8a8-unorm - (bitwise-ior vk-image-usage-transfer-dst-bit + format + (bitwise-ior usage vk-image-usage-sampled-bit) - vk-image-aspect-color-bit))) + vk-image-aspect-color-bit)))) (define allocate-image-memory (lambda (physical-device device image-handle) @@ -248,14 +256,19 @@ vk-image-tiling-optimal vk-format-feature-depth-stencil-attachment-bit))) +(define allocate-memory-for-image + (lambda (physical-device device image-handle) + (let ((memory (allocate-image-memory physical-device device image-handle))) + (bind-image-memory device image-handle memory) + memory))) + (define create-depth-buffer-image (lambda (physical-device device command-pool graphics-queue swapchain) (define create-gpu-image (lambda (property) (let* ((image-handle (create-image-handle device property)) - (memory (allocate-image-memory physical-device device image-handle))) - (bind-image-memory device image-handle memory) + (memory (allocate-memory-for-image physical-device device image-handle))) (transition-image-layout device command-pool graphics-queue @@ -297,10 +310,9 @@ (lambda (image-buffer image-data) (let* ((width (image-data-width image-data)) (height (image-data-height image-data)) - (property (create-texture-property width height)) + (property (create-image-property-for-texture width height)) (image-handle (create-image-handle device property)) - (memory (allocate-image-memory physical-device device image-handle))) - (bind-image-memory device image-handle memory) + (memory (allocate-memory-for-image physical-device device image-handle))) (transition-image-layout device command-pool graphics-queue diff --git a/vulkan/mesh.scm b/vulkan/mesh.scm index 6e7776b..26ce26a 100644 --- a/vulkan/mesh.scm +++ b/vulkan/mesh.scm @@ -31,8 +31,8 @@ (lambda () (fx* 4 (length vertices) - ;; (length normals) - (length (or colors (list white-color))) + (length normals) + ;; (length (or colors (list white-color))) (length uvs)))) (define vertex-input->list @@ -42,17 +42,17 @@ "uvs" (length uvs)) (apply append (map append vertices - ;; normals + normals ;; todo colors not being captured - (or (map (lambda (_) white-color) vertices)) + ;; (or (map (lambda (_) white-color) vertices)) uvs)))) (define vertex-input-stride (lambda () (fx* 4 (+ (length (car vertices)) - ;; (length (car normals)) - (length (or (and colors (car colors)) white-color)) + (length (car normals)) + ;; (length (or (and colors (car colors)) white-color)) (length (car uvs)))))) (make-vertex-input-metadata (sizeof-vertex-input) @@ -60,8 +60,8 @@ (vertex-input-stride) indices-data (vector->attr (list (car vertices) - ;; (car normals) - (or (and colors (car colors)) white-color) + (car normals) + ;; (or (and colors (car colors)) white-color) (car uvs))) (reverse components))))) diff --git a/vulkan/pbr.scm b/vulkan/pbr.scm new file mode 100644 index 0000000..4337be6 --- /dev/null +++ b/vulkan/pbr.scm @@ -0,0 +1,126 @@ +;; BRDF integration map + +;; (define-record-type vulkan-data (fields )) + +;; brdf material pipeline +(define brdf-data + (lambda (physical-device device command-pool graphics-queue) + (define +dimension+ 512) + (define +format+ vk-format-r16g16-sfloat) + + (define +dimension-extent+ (make-vk-extent-2d +dimension+ +dimension+)) + + (define create-image + (lambda () + (let* ((image-property + (create-image-property-for-texture +dimension+ + +dimension+ + +format+ + vk-image-usage-color-attachment-bit)) + (image-handle (create-image-handle device image-property)) + (image-memory (allocate-memory-for-image physical-device device image-handle))) + (make-gpu-image image-handle + (create-image-view device image-handle image-property) + image-memory)))) + + (define create-pbr-texture + (lambda () + (let ((image (create-image)) + (sampler (create-texture-sampler device + (make-texture-property + vk-sampler-address-mode-clamp-to-edge + 0.0 + 1.0 + vk-border-color-float-opaque-white)))) + (make-texture-data (gpu-image-view image) sampler)))) + + + (define brdf-render-pass + (lambda () + + ;; subpass dependency for layout transition + (define subpass-dependencies + (list + (make-vk-subpass-dependency vk-subpass-external + 0 + vk-pipeline-stage-bottom-of-pipe-bit + vk-pipeline-stage-color-attachment-output-bit + vk-access-memory-read-bit + (bitwise-ior vk-access-color-attachment-read-bit + vk-access-color-attachment-write-bit) + vk-dependency-by-region-bit) + (make-vk-subpass-dependency 0 + vk-subpass-external + vk-pipeline-stage-color-attachment-output-bit + vk-pipeline-stage-bottom-of-pipe-bit + (bitwise-ior vk-access-color-attachment-read-bit + vk-access-color-attachment-write-bit) + vk-access-memory-read-bit + vk-dependency-by-region-bit))) + + (let* ((attachment-description + (create-color-attachment-description +format+ + vk-image-layout-shader-read-only-optimal)) + (color-attachment-ref + (create-color-attachment-reference vk-image-layout-color-attachment-optimal)) + + (subpass-description (create-subpass-description color-attachment-ref))) + (create-render-pass device + (make-array-pointer 1 + attachment-description + 'vk-attachment-description) + (make-array-pointer 1 subpass-description 'vk-subpass-description) + (list->vk-subpass-dependency-pointer-array subpass-dependencies))))) + + + (define generate-brdf-pipeline + (lambda (render-pass) + (let ((descriptor-layout + (create-descriptor-layout device + (make-array-pointer 0 + (null-pointer + vk-descriptor-set-layout-binding) + 'vk-descriptor-set-layout-binding))) + (rasterization-state (make-rasterization-state vk-polygon-mode-fill + vk-cull-mode-none + vk-front-face-clockwise)) + (depth-stencil-state (make-depth-stencil-state #f #f vk-compare-op-less-or-equal))) + (create-graphics-pipeline physical-device device + (make-pipeline-data (make-shaders "shaders/brdf.vert" + "shaders/brdf.frag") + (make-vertex-input-details '() 0 '()) + render-pass + descriptor-layout + rasterization-state + depth-stencil-state + +dimension-extent+))))) + + (define clear-values (list 0.0 0.0 0.0 1.0)) + (define clear-values-ptr (list->vk-clear-value-pointer-array + (list (make-vk-clear-value clear-values)))) + + (define execute-brdf-pass + (lambda (pbr-texture-data render-pass brdf-pipeline framebuffer) + + (define render-pass + (lambda (command-buffer) + (let ((render-area (make-render-area '(0 . 0) (cons +dimension+ +dimension+)))) + (perform-render-pass (make-render-pass-data command-buffer + framebuffer + render-area + clear-values-ptr + brdf-pipeline) + (lambda () (vk-cmd-draw command-buffer 3 1 0 0)))))) + + (execute-command-buffer device command-pool graphics-queue #t render-pass))) + + (displayln "executing brdf pipeline") + (let* ((pbr-texture-data (create-pbr-texture)) + (render-pass (brdf-render-pass)) + (brdf-pipeline (generate-brdf-pipeline render-pass)) + (framebuffer (create-framebuffer device + render-pass + (make-vk-extent-2d +dimension+ +dimension+) + (texture-data-image-view pbr-texture-data)))) + (execute-brdf-pass pbr-texture-data render-pass brdf-pipeline framebuffer) + pbr-texture-data))) diff --git a/vulkan/pipeline.scm b/vulkan/pipeline.scm index 1a97547..a5b471e 100644 --- a/vulkan/pipeline.scm +++ b/vulkan/pipeline.scm @@ -32,6 +32,9 @@ (create-shader-module frag-spv)))))) + +;; let's capture all the custom information that can be supplied in the pipeline in a record + ;; vertex input ;; this will contain data about mesh component in a model @@ -44,6 +47,18 @@ ;; default vertex input struct (define-record-type vertex-input (fields position color texture-coord)) + + +;; currently supported shaders +(define-record-type shaders (fields vertex fragment)) +(define-record-type vertex-input-details (fields vertex-input-list stride attrs)) +(define-record-type rasterization-state (fields polygon-mode cull-mode front-face)) +(define-record-type depth-stencil-state (fields depth-test? depth-write? depth-compare-op)) + +(define-record-type pipeline-data + (fields shaders vertex-input-details render-pass descriptor-layout rasterization-state + depth-stencil-state viewport)) + ;; takes input a nested list and returns a list of cons cell (format . offset) ;; these are usually saved in the field attrs of vertex-input-metadata (define vector->attr @@ -138,13 +153,17 @@ (cdr attr))) attrs))))) - (make-vk-pipeline-vertex-input-state-create-info pipeline-vertex-input-state-create-info - 0 - 0 - 1 - (make-vertex-binding-description) - (length attrs) - (make-attribute-descriptions)))) + (let ((binding-count (if (null? attrs) 0 1)) + (binding-description (if (null? attrs) + (null-pointer vk-vertex-input-binding-description) + (make-vertex-binding-description)))) + (make-vk-pipeline-vertex-input-state-create-info pipeline-vertex-input-state-create-info + 0 + 0 + binding-count + binding-description + (length attrs) + (make-attribute-descriptions))))) ;; input assembly @@ -158,41 +177,49 @@ ;; viewport -(define (create-viewport-info swapchain-extent) - - (define (create-viewport) - (make-vk-viewport 0.0 - 0.0 - (exact->inexact (vk-extent-2d-width swapchain-extent)) - (exact->inexact (vk-extent-2d-height swapchain-extent)) - 0.0 - 1.0)) - - (define (create-scissor) - (make-vk-rect-2d (make-vk-offset-2d 0 0) swapchain-extent)) - - (make-vk-pipeline-viewport-state-create-info pipeline-viewport-state-create-info 0 0 - 1 - (create-viewport) - 1 - (create-scissor))) +(define create-viewport-info + (case-lambda + (() (create-viewport-info (make-vk-extent-2d 0 0))) + ((swapchain-extent) + + (define (create-viewport) + (let ((width (vk-extent-2d-width swapchain-extent)) + (height (vk-extent-2d-height swapchain-extent))) + (make-vk-viewport 0.0 + 0.0 + (exact->inexact width) + (exact->inexact height) + 0.0 + (if (and (equal? 0 width) + (equal? 0 height)) 0.0 1.0)))) + + (define (create-scissor) + (make-vk-rect-2d (make-vk-offset-2d 0 0) swapchain-extent)) + + (make-vk-pipeline-viewport-state-create-info pipeline-viewport-state-create-info 0 0 + 1 + (create-viewport) + 1 + (create-scissor))))) ;; rasterizer -(define (create-rasterizer-info) - (make-vk-pipeline-rasterization-state-create-info pipeline-rasterization-state-create-info - 0 - 0 - vk-false - vk-false - vk-polygon-mode-fill - vk-cull-mode-back-bit - vk-front-face-clockwise - vk-false - 0.0 - 0.0 - 0.0 - 1.0)) +(define (create-rasterizer-info rasterization-state) + (match rasterization-state + (($ rasterization-state polygon-mode cull-mode front-face) + (make-vk-pipeline-rasterization-state-create-info pipeline-rasterization-state-create-info + 0 + 0 + vk-false + vk-false + polygon-mode + cull-mode + front-face + vk-false + 0.0 + 0.0 + 0.0 + 1.0)))) ;; multisampling @@ -228,39 +255,53 @@ '(0.0 0.0 0.0 0.0)))) +(define-record-type descriptor-layout-detail + (fields descriptor-type shader-stage immutable-sampler descriptor-count)) + ;; descriptor set layout (define create-descriptor-layout - (lambda (device) - (let* ((uniform-buffer-binding - (make-vk-descriptor-set-layout-binding 0 - vk-descriptor-type-uniform-buffer - 1 - vk-shader-stage-vertex-bit - (null-pointer vk-sampler))) - (texture-sampler-binding - (make-vk-descriptor-set-layout-binding 1 - vk-descriptor-type-combined-image-sampler - 1 - vk-shader-stage-fragment-bit - (null-pointer vk-sampler))) - (bindings (list->vk-descriptor-set-layout-binding-pointer-array - (list uniform-buffer-binding texture-sampler-binding))) - (info (make-vk-descriptor-set-layout-create-info descriptor-set-layout-create-info - 0 - 0 - (array-pointer-length bindings) - (array-pointer-raw-ptr bindings))) - (layout (make-foreign-object vk-descriptor-set-layout))) + (lambda (device bindings) + (let ((info (make-vk-descriptor-set-layout-create-info descriptor-set-layout-create-info + 0 + 0 + (array-pointer-length bindings) + (array-pointer-raw-ptr bindings))) + (layout (make-foreign-object vk-descriptor-set-layout))) (vk-create-descriptor-set-layout device info 0 layout) layout))) +(define descriptor-layout-details->descriptor-layout + (lambda (device details) + + (define details->bindings + (lambda () + (list->vk-descriptor-set-layout-binding-pointer-array + (map-indexed (lambda (detail index) + (match detail + (($ descriptor-layout-detail + descriptor-type + shader-stage + sampler + descriptor-count) + (let ((sampler (or sampler (null-pointer vk-sampler)))) + (make-vk-descriptor-set-layout-binding index + descriptor-type + descriptor-count + shader-stage + sampler))))) + details)))) + + (create-descriptor-layout device (details->bindings)))) + + ;; pipeline layout ;; returns (pipeline-layout . descriptor-layout) -(define (create-pipeline-layout device) - (let* ((descriptor-layout (create-descriptor-layout device)) +(define (create-pipeline-layout device descriptor-layout) + (let* ((descriptor-layout (or descriptor-layout + (error "no descriptor layout" #f))) (layout-info (make-vk-pipeline-layout-create-info pipeline-layout-create-info 0 0 1 @@ -271,13 +312,6 @@ (vk-create-pipeline-layout device layout-info 0 layout) (cons layout descriptor-layout))) -;; let's capture all the custom information that can be supplied in the pipeline in a record - -;; currently supported shaders -(define-record-type shaders (fields vertex fragment)) -(define-record-type vertex-input-details (fields vertex-input-list stride attrs)) -(define-record-type pipeline-data (fields shaders vertex-input-details)) - (define vertex-input->details (lambda (input-metadata) (match input-metadata @@ -286,11 +320,55 @@ ;; render pass +(define create-color-attachment-description + (lambda (format final-layout) + (make-vk-attachment-description 0 + format + vk-sample-count-1-bit ;; samples + vk-attachment-load-op-clear ;; load-op + vk-attachment-store-op-store ;; store-op + vk-attachment-load-op-dont-care ;;stencil-load-op + vk-attachment-store-op-dont-care + vk-image-layout-undefined + final-layout))) + +(define create-color-attachment-reference + (lambda (final-layout) (make-vk-attachment-reference 0 final-layout))) + +(define create-subpass-description + (case-lambda + ((color-attachment-ref) (create-subpass-description color-attachment-ref #f)) + ((color-attachment-ref depth-attachment-ref) + (make-vk-subpass-description 0 + vk-pipeline-bind-point-graphics + 0 + (null-pointer vk-attachment-reference) + 1 + color-attachment-ref + (null-pointer vk-attachment-reference) + (or depth-attachment-ref + (null-pointer vk-attachment-reference)) + 0 + (null-pointer unsigned-32))))) + +;; defined as (~0U) +(define vk-subpass-external 0) + (define create-render-pass - (lambda (physical-device device swapchain) + (lambda (device attachments subpasses dependencies) + (let ((info (make-vk-render-pass-create-info render-pass-create-info 0 0 + (array-pointer-length attachments) + (array-pointer-raw-ptr attachments) + (array-pointer-length subpasses) + (array-pointer-raw-ptr subpasses) + (array-pointer-length dependencies) + (array-pointer-raw-ptr dependencies))) + (render-pass (make-foreign-object vk-render-pass))) + (vk-create-render-pass device info 0 render-pass) + render-pass))) - ;; defined as (~0U) - (define vk-subpass-external 0) +(define configure-render-pass + (lambda (physical-device device swapchain) (define create-render-pass-info (lambda () @@ -298,20 +376,12 @@ (vk-surface-format-khr-format (swapchain-format swapchain))) (color-attachment - (make-vk-attachment-description 0 - swapchain-image-format - vk-sample-count-1-bit ;; samples - vk-attachment-load-op-clear ;; load-op - vk-attachment-store-op-store ;; store-op - vk-attachment-load-op-dont-care ;;stencil-load-op - vk-attachment-store-op-dont-care - vk-image-layout-undefined - vk-image-layout-present-src-khr)) + (create-color-attachment-description swapchain-image-format + vk-image-layout-present-src-khr)) + + (color-attachment-ref (create-color-attachment-reference + vk-image-layout-color-attachment-optimal)) - (color-attachment-ref - (make-vk-attachment-reference 0 - vk-image-layout-color-attachment-optimal)) - (depth-attachment (make-vk-attachment-description 0 (find-depth-format physical-device) @@ -330,17 +400,7 @@ (attachments (list->vk-attachment-description-pointer-array (list color-attachment depth-attachment))) - (subpass - (make-vk-subpass-description 0 - vk-pipeline-bind-point-graphics - 0 - (null-pointer vk-attachment-reference) - 1 - color-attachment-ref - (null-pointer vk-attachment-reference) - depth-attachment-ref - 0 - (null-pointer unsigned-32))) + (subpass (create-subpass-description color-attachment-ref depth-attachment-ref)) (dependency (make-vk-subpass-dependency vk-subpass-external @@ -371,25 +431,29 @@ (fields handle layout render-pass descriptor-set-layout)) (define create-depth-stencil-state - (lambda () - (let ((zero-op-state (make-vk-stencil-op-state 0 0 0 0 0 0))) - (make-vk-pipeline-depth-stencil-state-create-info pipeline-depth-stencil-state-create-info - 0 - 0 - vk-true - vk-true - vk-compare-op-less - vk-false - vk-false - zero-op-state - zero-op-state - 0.0 - 1.0)))) + (lambda (depth-stencil) + (define bool->vulkan (lambda (x) (if x vk-true vk-false))) + + (match depth-stencil + (($ depth-stencil-state depth-test? depth-write? depth-compare-op) + (let ((zero-op-state (make-vk-stencil-op-state 0 0 0 0 0 0))) + (make-vk-pipeline-depth-stencil-state-create-info pipeline-depth-stencil-state-create-info + 0 + 0 + (bool->vulkan depth-test?) + (bool->vulkan depth-write?) + depth-compare-op + vk-false + vk-false + zero-op-state + zero-op-state + 0.0 + 1.0)))))) (define create-graphics-pipeline - (lambda (physical-device device swapchain pipeline-data) + (lambda (physical-device device pipeline-data) (let* ((shaders (pipeline-data-shaders pipeline-data)) (shader-stages (list->vk-pipeline-shader-stage-create-info-pointer-array @@ -399,9 +463,8 @@ (vertex-input-data (pipeline-data-vertex-input-details pipeline-data)) - (render-pass (create-render-pass physical-device device swapchain)) - - (layout (create-pipeline-layout device)) + (render-pass (pipeline-data-render-pass pipeline-data)) + (layout (create-pipeline-layout device (pipeline-data-descriptor-layout pipeline-data))) (pipeline-info (make-vk-graphics-pipeline-create-info @@ -421,16 +484,16 @@ (null-pointer vk-pipeline-tessellation-state-create-info) ;; viewport - (create-viewport-info (swapchain-extent swapchain)) + (create-viewport-info (pipeline-data-viewport pipeline-data)) ;; rasterizer - (create-rasterizer-info) + (create-rasterizer-info (pipeline-data-rasterization-state pipeline-data)) ;; multisampling (create-multisampling-info) ;; depth stencil - (create-depth-stencil-state) + (create-depth-stencil-state (pipeline-data-depth-stencil-state pipeline-data)) (create-color-blending-info) diff --git a/vulkan/sync.scm b/vulkan/sync.scm index 6d9321c..62eb93a 100644 --- a/vulkan/sync.scm +++ b/vulkan/sync.scm @@ -15,6 +15,7 @@ (define init-sync-objects (lambda (device) + (displayln "init sync" device) (map (lambda (i) (let ((semaphore-info (make-vk-semaphore-create-info semaphore-create-info 0 0)) (fence-info (make-vk-fence-create-info fence-create-info @@ -44,7 +45,7 @@ (define *run-draw-loop* #f) (define draw-next-frame - (lambda (window device swapchain queues uniform-buffers cmd-buffers sync-objects state) + (lambda (window device swapchain queues uniform-buffers cmd-buffers sync-objects state camera-matrix) (display "starting draw loop") (newline) (let ((image-index (make-foreign-object u32)) (uniform-buffers (list->vector uniform-buffers)) @@ -53,7 +54,7 @@ (graphics-queue (car queues)) (present-queue (cdr queues))) (let lp ((state state) - (eye-position (cons (cdr (vector-ref uniform-buffers 0)) + (eye-position (cons camera-matrix (make-vector3 10.0 13.0 1.8))) (i 0)) (match state diff --git a/vulkan/texture.scm b/vulkan/texture.scm index d05ea8d..a6732f1 100644 --- a/vulkan/texture.scm +++ b/vulkan/texture.scm @@ -5,39 +5,49 @@ (define-record-type texture-data (fields image-view sampler)) -(define create-texture-data - (lambda (physical-device device command-pool graphics-queue swapchain) - - (define create-texture-sampler - (lambda (device) - (let ((info (make-vk-sampler-create-info sampler-create-info - 0 - 0 - vk-filter-linear - vk-filter-linear - vk-sampler-mipmap-mode-linear - vk-sampler-address-mode-repeat - vk-sampler-address-mode-repeat - vk-sampler-address-mode-repeat - 0.0 - vk-true - 16.0 - vk-false - vk-compare-op-always - 0.0 - 0.0 - vk-border-color-int-opaque-black - vk-false)) - (sampler (make-foreign-object vk-sampler))) - (vk-create-sampler device info 0 sampler) - sampler))) +(define-record-type texture-property + (fields sampler-mode min-lod max-lod border-color)) +(define create-texture-sampler + (lambda (device texture-prop) + (match texture-prop + (($ texture-property sampler-mode min-lod max-lod border-color) + (let ((info (make-vk-sampler-create-info sampler-create-info + 0 + 0 + vk-filter-linear + vk-filter-linear + vk-sampler-mipmap-mode-linear + sampler-mode + sampler-mode + sampler-mode + 0.0 + vk-true + 16.0 + vk-false + vk-compare-op-always + min-lod + max-lod + border-color + vk-false)) + (sampler (make-foreign-object vk-sampler))) + (vk-create-sampler device info 0 sampler) + sampler))))) +(define create-texture-data + (case-lambda + ((physical-device device command-pool graphics-queue swapchain) + (create-texture-data physical-device device command-pool graphics-queue swapchain texture-path)) + ((physical-device device command-pool graphics-queue swapchain texture-path) (let ((texture-image (create-texture-image physical-device device command-pool graphics-queue swapchain texture-path)) - (sampler (create-texture-sampler device))) - (make-texture-data (gpu-image-view texture-image) sampler)))) + (sampler (create-texture-sampler device + (make-texture-property vk-sampler-address-mode-repeat + 0.0 + 0.0 + vk-border-color-float-opaque-black)))) + (make-texture-data (gpu-image-view texture-image) sampler)))))