summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Thompson <dthompson2@worcester.edu>2021-08-12 20:25:25 -0400
committerDavid Thompson <dthompson2@worcester.edu>2021-08-12 20:25:25 -0400
commit8925bd867e1a8791801698b1abaec4a46180656e (patch)
tree9a7a31445e86952a85b185969bfde2780cfdc5d0
parentf82e5122c2feabb8d92e3d4d1789ee1490b96a90 (diff)
graphics: Always use normal/ambient/etc. maps.
If models don't specify their own textures, use noop textures as appropriate.
-rw-r--r--chickadee/graphics/model.scm102
-rw-r--r--chickadee/graphics/pbr.scm38
-rw-r--r--chickadee/graphics/phong.scm23
-rw-r--r--data/shaders/pbr-frag.glsl80
-rw-r--r--data/shaders/phong-frag.glsl62
5 files changed, 103 insertions, 202 deletions
diff --git a/chickadee/graphics/model.scm b/chickadee/graphics/model.scm
index 77d67b8..8b7cbda 100644
--- a/chickadee/graphics/model.scm
+++ b/chickadee/graphics/model.scm
@@ -207,23 +207,15 @@
(define (maybe-add-material)
(let ((name (assq-ref opts 'name)))
(when name
- (let* ((ambient (assq-ref opts 'ambient-map))
- (diffuse (assq-ref opts 'diffuse-map))
- (specular (assq-ref opts 'specular-map))
- (normals (assq-ref opts 'normal-map))
+ (let* ((ambient (or (assq-ref opts 'ambient-map) (white-texture)))
+ (diffuse (or (assq-ref opts 'diffuse-map) (white-texture)))
+ (specular (or (assq-ref opts 'specular-map) (white-texture)))
+ (normals (or (assq-ref opts 'normal-map) (flat-texture)))
(properties (make-phong-properties
#:ambient (assq-ref opts 'ambient)
- #:use-ambient-map
- (assq-ref opts 'use-ambient-map?)
#:diffuse (assq-ref opts 'diffuse)
- #:use-diffuse-map
- (assq-ref opts 'use-diffuse-map?)
#:specular (assq-ref opts 'specular)
- #:use-specular-map
- (assq-ref opts 'use-specular-map?)
- #:shininess (assq-ref opts 'shininess)
- #:use-normal-map
- (assq-ref opts 'use-normal-map?)))
+ #:shininess (assq-ref opts 'shininess)))
(material
(make-material #:name name
#:shader (phong-shader)
@@ -288,8 +280,7 @@
#:min-filter 'linear
#:mag-filter 'linear
#:flip? #f)))
- (loop (cons* (cons 'ambient-map texture)
- (cons 'use-ambient-map? #t)
+ (loop (cons (cons 'ambient-map texture)
opts))))
(("map_Kd" . args) ; diffuse map
(let* ((diffuse-opts (parse-map-args args))
@@ -299,9 +290,8 @@
#:min-filter 'linear
#:mag-filter 'linear
#:flip? #f)))
- (loop (cons* (cons 'diffuse-map texture)
- (cons 'use-diffuse-map? #t)
- opts))))
+ (loop (cons (cons 'diffuse-map texture)
+ opts))))
(("map_Ks" . args) ; specular map
(let* ((specular-opts (parse-map-args args))
(file (scope-file (assq-ref specular-opts
@@ -310,9 +300,8 @@
#:min-filter 'linear
#:mag-filter 'linear
#:flip? #f)))
- (loop (cons* (cons 'specular-map texture)
- (cons 'use-specular-map? #t)
- opts))))
+ (loop (cons (cons 'specular-map texture)
+ opts))))
(((or "map_Bump" "map_bump" "bump") . args) ; normal map
(let* ((normal-opts (parse-map-args args))
(file (scope-file (assq-ref normal-opts
@@ -321,25 +310,20 @@
#:min-filter 'linear
#:mag-filter 'linear
#:flip? #f)))
- (loop (cons* (cons 'normal-map texture)
- (cons 'use-normal-map? #t)
- opts))))
+ (loop (cons (cons 'normal-map texture)
+ opts))))
(("newmtl" new-name)
;; Begin new material
(maybe-add-material)
(loop `((name . ,new-name)
(ambient . ,(vec3 1.0 1.0 1.0))
(ambient-map . ,null-texture)
- (use-ambient-map? . #f)
(diffuse . ,(vec3 1.0 1.0 1.0))
(diffuse-map . ,null-texture)
- (use-diffuse-map? . #f)
(specular . ,(vec3 1.0 1.0 1.0))
(specular-map . ,null-texture)
- (use-specular-map? . #f)
(shininess . 1.0)
- (normal-map . ,null-texture)
- (use-normal-map? . #f))))
+ (normal-map . ,null-texture))))
(data
(format (current-error-port)
"warning: ~a:~d: unsupported MTL data: ~s~%"
@@ -556,7 +540,14 @@
(or (hash-ref material-map material)
(hash-ref material-map "default"))))))
;; Register default material
- (hash-set! material-map "default" default-phong-properties)
+ (hash-set! material-map "default"
+ (make-material #:name "default"
+ #:shader (phong-shader)
+ #:texture-0 (white-texture)
+ #:texture-1 (white-texture)
+ #:texture-2 (white-texture)
+ #:texture-3 (flat-texture)
+ #:properties default-phong-properties))
;; Parse file.
(let loop ((material "default"))
(match (read-line port)
@@ -853,10 +844,6 @@
(roughness-factor
(or (number-ref/optional pbrmr "roughnessFactor")
1.0))
- (normal-factor
- (let ((v (or (array-ref/optional obj "normalFactor")
- #(1.0 1.0 1.0))))
- (vec3 (vector-ref v 0) (vector-ref v 1) (vector-ref v 2))))
(emissive-factor
(let ((v (or (array-ref/optional obj "emissiveFactor")
#(1.0 1.0 1.0))))
@@ -873,24 +860,22 @@
(double-sided? (boolean-ref/optional obj "doubleSided"))
(extensions (object-ref/optional obj "extensions"))
(extras (assoc-ref obj "extras")))
- (define (parse-texture obj key)
+ (define (parse-texture obj key default)
(match (object-ref/optional obj key)
- (#f (values null-texture 0))
+ (#f (values (default) 0))
(texture
(values (vector-ref textures (number-ref texture "index"))
(or (number-ref/optional texture "texCoord") 0)))))
- (define (non-null-texture? texture)
- (not (eq? texture null-texture)))
(let-values (((base-color-texture base-color-texcoord)
- (parse-texture pbrmr "baseColorTexture"))
+ (parse-texture pbrmr "baseColorTexture" white-texture))
((metal-rough-texture metal-rough-texcoord)
- (parse-texture pbrmr "metallicRoughnessTexture"))
+ (parse-texture pbrmr "metallicRoughnessTexture" white-texture))
((normal-texture normal-texcoord)
- (parse-texture obj "normalTexture"))
+ (parse-texture obj "normalTexture" flat-texture))
((occlusion-texture occlusion-texcoord)
- (parse-texture obj "occlusionTexture"))
+ (parse-texture obj "occlusionTexture" white-texture))
((emissive-texture emissive-texcoord)
- (parse-texture obj "emissiveTexture")))
+ (parse-texture obj "emissiveTexture" black-texture)))
(make-material
#:name name
#:shader (pbr-shader)
@@ -905,19 +890,13 @@
#:texture-4 emissive-texture
#:properties (make-pbr-properties
#:base-color-factor base-color-factor
- #:base-color-texture-enabled (non-null-texture? base-color-texture)
#:base-color-texcoord base-color-texcoord
#:metallic-factor metallic-factor
#:roughness-factor roughness-factor
- #:metallic-roughness-texture-enabled (non-null-texture? metal-rough-texture)
#:metallic-roughness-texcoord metal-rough-texcoord
- #:normal-factor normal-factor
- #:normal-texture-enabled (non-null-texture? normal-texture)
#:normal-texcoord normal-texcoord
- #:occlusion-texture-enabled (non-null-texture? occlusion-texture)
#:occlusion-texcoord occlusion-texcoord
#:emissive-factor emissive-factor
- #:emissive-texture-enabled (non-null-texture? emissive-texture)
#:emissive-texcoord emissive-texcoord
#:alpha-mode alpha-mode
#:alpha-cutoff alpha-cutoff)))))
@@ -930,33 +909,32 @@
("NORMAL"
(attribute-location
(hash-ref (shader-attributes shader) "normal")))
- ("TANGENT" 10)
("TEXCOORD_0"
(attribute-location
(hash-ref (shader-attributes shader) "texcoord0")))
("TEXCOORD_1"
(attribute-location
(hash-ref (shader-attributes shader) "texcoord1")))
- ("TEXCOORD_2" 11)
- ("TEXCOORD_3" 12)
("COLOR_0"
(attribute-location
(hash-ref (shader-attributes shader) "color0")))
- ("JOINTS_0" 13)
- ("WEIGHTS_0" 14))))
+ ;; TODO
+ ("TANGENT" #f)
+ ("JOINTS_0" #f)
+ ("WEIGHTS_0" #f)
+ (_ #f))))
;; TODO: When normals are not specified, generate flat normals.
;;
;; TODO: When positions are not specified, skip the entire
;; primitive.
- ;;
- ;; TODO: When tangents are not specified, calculate them using
- ;; default MikkTSpace algorithms. http://www.mikktspace.com/
(define (parse-primitive obj materials accessors)
- (let ((attributes (map (match-lambda
- ((name . n)
- (cons (attribute-name->index name)
- (vector-ref accessors n))))
- (object-ref obj "attributes")))
+ (let ((attributes (filter-map (match-lambda
+ ((name . n)
+ (let ((attr (attribute-name->index name)))
+ (and attr
+ (cons attr
+ (vector-ref accessors n))))))
+ (object-ref obj "attributes")))
(indices (match (number-ref/optional obj "indices")
(#f #f)
(n (vector-ref accessors n))))
diff --git a/chickadee/graphics/pbr.scm b/chickadee/graphics/pbr.scm
index 16b5878..e1641ec 100644
--- a/chickadee/graphics/pbr.scm
+++ b/chickadee/graphics/pbr.scm
@@ -35,19 +35,13 @@
#:export (make-pbr-properties
pbr-properties?
pbr-properties-base-color-factor
- pbr-properties-base-color-texture-enabled?
pbr-properties-base-color-texcoord
pbr-properties-metallic-factor
pbr-properties-roughness-factor
- pbr-properties-metallic-roughness-texture-enabled?
pbr-properties-metallic-roughness-texcoord
- pbr-properties-normal-factor
- pbr-properties-normal-texture-enabled?
pbr-properties-normal-texcoord
- pbr-properties-occlusion-texture-enabled?
pbr-properties-occlusion-texcoord
pbr-properties-emissive-factor
- pbr-properties-emissive-texture-enabled?
pbr-properties-emissive-texcoord
pbr-properties-alpha-mode
pbr-properties-alpha-cutoff
@@ -58,41 +52,29 @@
make-pbr-properties
pbr-properties?
(float-vec3 base-color-factor pbr-properties-base-color-factor)
- (bool base-color-texture-enabled pbr-properties-base-color-texture-enabled?)
(int base-color-texcoord pbr-properties-base-color-texcoord)
(float metallic-factor pbr-properties-metallic-factor)
(float roughness-factor pbr-properties-roughness-factor)
- (bool metallic-roughness-texture-enabled pbr-properties-metallic-roughness-texture-enabled?)
(int metallic-roughness-texcoord pbr-properties-metallic-roughness-texcoord)
- (float-vec3 normal-factor pbr-properties-normal-factor)
- (bool normal-texture-enabled pbr-properties-normal-texture-enabled)
(int normal-texcoord pbr-properties-normal-texcoord)
- (bool occlusion-texture-enabled pbr-properties-occlusion-texture-enabled)
(int occlusion-texcoord pbr-properties-occlusion-texcoord)
(float-vec3 emissive-factor pbr-properties-emissive-factor)
- (bool emissive-texture-enabled pbr-properties-emissive-texture-enabled)
(int emissive-texcoord pbr-properties-emissive-texcoord)
(int alpha-mode pbr-properties-alpha-mode)
(float alpha-cutoff pbr-properties-alpha-cutoff))
(define default-pbr-properties
(make-pbr-properties #:base-color-factor #v(1.0 1.0 1.0)
- #:base-color-texture-enabled #f
- #:base-color-texcoord 0
- #:metallic-factor 1.0
- #:roughness-factor 1.0
- #:metallic-roughness-texture-enabled #f
- #:metallic-roughness-texcoord 0
- #:normal-factor #v(1.0 1.0 1.0)
- #:normal-texture-enabled #f
- #:normal-texcoord 0
- #:occlusion-texture-enabled #f
- #:occlusion-texcoord 0
- #:emissive-factor #v(1.0 1.0 1.0)
- #:emissive-texture-enabled #f
- #:emissive-texcoord 0
- #:alpha-mode 0
- #:alpha-cutoff 0.5))
+ #:base-color-texcoord 0
+ #:metallic-factor 1.0
+ #:roughness-factor 1.0
+ #:metallic-roughness-texcoord 0
+ #:normal-texcoord 0
+ #:occlusion-texcoord 0
+ #:emissive-factor #v(1.0 1.0 1.0)
+ #:emissive-texcoord 0
+ #:alpha-mode 0
+ #:alpha-cutoff 0.5))
(define %pbr-shader
(delay (load-shader (scope-datadir "shaders/pbr-vert.glsl")
diff --git a/chickadee/graphics/phong.scm b/chickadee/graphics/phong.scm
index edb8686..e3deba2 100644
--- a/chickadee/graphics/phong.scm
+++ b/chickadee/graphics/phong.scm
@@ -34,14 +34,9 @@
phong-properties?
phong-properties-name
phong-properties-ambient
- phong-properties-use-ambient-map?
phong-properties-diffuse
- phong-properties-use-diffuse-map?
phong-properties-specular
- phong-properties-specular-map?
- phong-properties-use-specular-map?
- phong-properties-specular-exponent
- phong-properties-use-normal-map?
+ phong-properties-shininess
default-phong-properties
phong-shader))
@@ -54,23 +49,15 @@
make-phong-properties
phong-properties?
(float-vec3 ambient phong-properties-ambient)
- (bool use-ambient-map phong-properties-use-ambient-map?)
(float-vec3 diffuse phong-properties-diffuse)
- (bool use-diffuse-map phong-properties-use-diffuse-map?)
(float-vec3 specular phong-properties-specular)
- (bool use-specular-map phong-properties-use-specular-map?)
- (float shininess phong-properties-shininess)
- (bool use-normal-map phong-properties-use-normal-map?))
+ (float shininess phong-properties-shininess))
(define default-phong-properties
- (make-phong-properties #:ambient (vec3 0.5 0.5 0.5)
- #:use-ambient-map #f
- #:diffuse (vec3 0.8 0.8 0.8)
- #:use-diffuse-map #f
+ (make-phong-properties #:ambient (vec3 1.0 1.0 1.0)
+ #:diffuse (vec3 1.0 1.0 1.0)
#:specular (vec3 1.0 1.0 1.0)
- #:use-specular-map #f
- #:shininess 32.0
- #:use-normal-map #f))
+ #:shininess 32.0))
;;;
diff --git a/data/shaders/pbr-frag.glsl b/data/shaders/pbr-frag.glsl
index 478c40a..c474981 100644
--- a/data/shaders/pbr-frag.glsl
+++ b/data/shaders/pbr-frag.glsl
@@ -2,19 +2,13 @@
struct Material {
vec3 baseColorFactor;
- bool baseColorTextureEnabled;
int baseColorTexcoord;
float metallicFactor;
float roughnessFactor;
- bool metallicRoughnessTextureEnabled;
int metallicRoughnessTexcoord;
- vec3 normalFactor;
- bool normalTextureEnabled;
int normalTexcoord;
- bool occlusionTextureEnabled;
int occlusionTexcoord;
vec3 emissiveFactor;
- bool emissiveTextureEnabled;
int emissiveTexcoord;
int alphaMode;
float alphaCutoff;
@@ -142,34 +136,25 @@ vec3 toneMap(vec3 color) {
float materialMetallic() {
float m = material.metallicFactor;
-
- if(material.metallicRoughnessTextureEnabled) {
- m *= texture(metallicRoughnessTexture,
- texcoord(material.metallicRoughnessTexcoord)).b;
- }
-
+ m *= texture(metallicRoughnessTexture,
+ texcoord(material.metallicRoughnessTexcoord)).b;
return m;
}
float materialRoughness() {
float r = material.roughnessFactor;
- if(material.metallicRoughnessTextureEnabled) {
- r *= texture(metallicRoughnessTexture,
- texcoord(material.metallicRoughnessTexcoord)).g;
- }
+ r *= texture(metallicRoughnessTexture,
+ texcoord(material.metallicRoughnessTexcoord)).g;
return r;
}
vec4 materialAlbedo() {
- vec4 color = vec4(0.0, 0.0, 1.0, 1.0);
-
- if(material.baseColorTextureEnabled) {
- vec4 texColor = texture(baseColorTexture,
- texcoord(material.baseColorTexcoord));
- color = sRGBtoLinear(texColor);
- }
+ vec4 color = vec4(1.0, 1.0, 1.0, 1.0);
+ vec4 texColor = texture(baseColorTexture,
+ texcoord(material.baseColorTexcoord));
+ color = sRGBtoLinear(texColor);
color *= vec4(material.baseColorFactor, 1.0);
@@ -183,44 +168,33 @@ vec4 materialAlbedo() {
vec3 materialEmissive() {
vec3 color = vec3(0.0);
- if(material.emissiveTextureEnabled) {
- vec4 texColor = texture(emissiveTexture,
- texcoord(material.emissiveTexcoord));
- color = sRGBtoLinear(texColor).rgb;
- }
+ vec4 texColor = texture(emissiveTexture,
+ texcoord(material.emissiveTexcoord));
+ color = sRGBtoLinear(texColor).rgb;
return color * material.emissiveFactor;
}
vec3 materialOcclusion() {
- if(material.occlusionTextureEnabled) {
- return vec3(texture(occlusionTexture,
- texcoord(material.occlusionTexcoord)).r);
- } else {
- return vec3(1.0);
- }
+ return vec3(texture(occlusionTexture,
+ texcoord(material.occlusionTexcoord)).r);
}
vec3 materialNormal() {
- if(material.normalTextureEnabled) {
- // See: http://www.thetenthplanet.de/archives/1180
- vec2 t = texcoord(material.normalTexcoord);
- vec3 tangentNormal = texture(normalTexture, t).xyz * 2.0 - 1.0;
-
- vec3 q1 = dFdx(fragWorldPos);
- vec3 q2 = dFdy(fragWorldPos);
- vec2 st1 = dFdx(fragTexcoord0);
- vec2 st2 = dFdy(fragTexcoord0);
-
- vec3 N = normalize(fragNormal);
- 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);
- } else {
- return normalize(fragNormal);
- }
+ // See: https://github.com/SaschaWillems/Vulkan-glTF-PBR/blob/master/data/shaders/pbr_khr.frag
+ // See: http://www.thetenthplanet.de/archives/1180
+ vec2 uv = texcoord(material.normalTexcoord);
+ vec3 tangentNormal = texture(normalTexture, uv).xyz * 2.0 - 1.0;
+ vec3 q1 = dFdx(fragWorldPos);
+ vec3 q2 = dFdy(fragWorldPos);
+ vec2 st1 = dFdx(uv);
+ vec2 st2 = dFdy(uv);
+ vec3 N = normalize(fragNormal);
+ 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);
}
vec3 lightDirection(Light light) {
diff --git a/data/shaders/phong-frag.glsl b/data/shaders/phong-frag.glsl
index 363c4e7..0beb75b 100644
--- a/data/shaders/phong-frag.glsl
+++ b/data/shaders/phong-frag.glsl
@@ -2,13 +2,9 @@
struct Material {
vec3 ambient;
- bool useAmbientMap;
vec3 diffuse;
- bool useDiffuseMap;
vec3 specular;
- bool useSpecularMap;
float shininess;
- bool useNormalMap;
};
struct Light {
@@ -100,53 +96,37 @@ vec3 lightRadiance(Light light, vec3 direction) {
}
vec3 materialAmbient() {
- if(material.useAmbientMap) {
- return texture(ambientMap, fragTex).rgb;
- } else {
- return material.ambient;
- }
+ return texture(ambientMap, fragTex).rgb * material.ambient;
}
vec3 materialDiffuse() {
- if(material.useDiffuseMap) {
- vec4 color = texture(diffuseMap, fragTex);
- // discard transparent fragments.
- if(color.a == 0.0) {
- discard;
- }
- return color.rgb;
- } else {
- return material.diffuse;
+ vec4 color = texture(diffuseMap, fragTex);
+ // discard transparent fragments.
+ if(color.a == 0.0) {
+ discard;
}
+ return color.rgb * material.diffuse;
}
vec3 materialSpecular() {
- if(material.useSpecularMap) {
- return texture(specularMap, fragTex).rgb;
- } else {
- return material.specular;
- }
+ return texture(specularMap, fragTex).rgb * material.specular;
}
vec3 materialNormal() {
- if(material.useNormalMap) {
- // Compute tangent space using fragment data rather than relying
- // on tangent attributes. See:
- // http://www.thetenthplanet.de/archives/1180
- vec3 tangentNormal = normalize(texture(normalMap, fragTex).xyz * 2.0 - 1.0);
- vec3 q1 = dFdx(fragWorldPos);
- vec3 q2 = dFdy(fragWorldPos);
- vec2 st1 = dFdx(fragTex);
- vec2 st2 = dFdy(fragTex);
- vec3 N = normalize(fragNorm);
- 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);
- } else {
- return normalize(fragNorm);
- }
+ // Compute tangent space using fragment data rather than relying
+ // on tangent attributes. See:
+ // http://www.thetenthplanet.de/archives/1180
+ vec3 tangentNormal = normalize(texture(normalMap, fragTex).xyz * 2.0 - 1.0);
+ vec3 q1 = dFdx(fragWorldPos);
+ vec3 q2 = dFdy(fragWorldPos);
+ vec2 st1 = dFdx(fragTex);
+ vec2 st2 = dFdy(fragTex);
+ vec3 N = normalize(fragNorm);
+ 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() {