summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Thompson <dthompson2@worcester.edu>2021-08-16 17:12:23 -0400
committerDavid Thompson <dthompson2@worcester.edu>2021-08-16 17:12:23 -0400
commit7a4f04f1df6896a4978ba302ea3fc79b6e7dd1f7 (patch)
tree6b9de3a151435c3e125bcbe3068fe5b8967f10f2
parent8c6326a46f82ae46cc63bd431b0678d4f6b10d00 (diff)
graphics: Add basic image based ambient lighting.
-rw-r--r--chickadee/graphics/mesh.scm25
-rw-r--r--chickadee/graphics/model.scm11
-rw-r--r--data/shaders/pbr-frag.glsl14
-rw-r--r--data/shaders/phong-frag.glsl11
4 files changed, 36 insertions, 25 deletions
diff --git a/chickadee/graphics/mesh.scm b/chickadee/graphics/mesh.scm
index ab7ad45..44c670e 100644
--- a/chickadee/graphics/mesh.scm
+++ b/chickadee/graphics/mesh.scm
@@ -33,6 +33,7 @@
#:use-module (chickadee graphics light)
#:use-module (chickadee graphics polygon)
#:use-module (chickadee graphics shader)
+ #:use-module (chickadee graphics skybox)
#:use-module (chickadee graphics stencil)
#:use-module (chickadee graphics texture)
#:use-module (chickadee utils)
@@ -123,24 +124,26 @@
(define %camera-position (vec3 0.0 0.0 0.0))
(define (material-apply material vertex-array model-matrix view-matrix
- camera-position ambient-light light-vector)
+ camera-position skybox light-vector)
(with-graphics-state ((g:blend-mode (material-blend-mode material))
(g:cull-face-mode (material-cull-face-mode material))
(g:depth-test (material-depth-test material))
(g:multisample? (material-multisample? material))
(g:polygon-mode (material-polygon-mode material))
(g:stencil-test (material-stencil-test material))
- (g:texture-0 (material-texture-0 material))
- (g:texture-1 (material-texture-1 material))
- (g:texture-2 (material-texture-2 material))
- (g:texture-3 (material-texture-3 material))
- (g:texture-4 (material-texture-4 material)))
+ (g:texture-0 (if skybox
+ (skybox-cube-map skybox)
+ null-texture))
+ (g:texture-1 (material-texture-0 material))
+ (g:texture-2 (material-texture-1 material))
+ (g:texture-3 (material-texture-2 material))
+ (g:texture-4 (material-texture-3 material))
+ (g:texture-5 (material-texture-4 material)))
(shader-apply (material-shader material) vertex-array
#:model model-matrix
#:view view-matrix
#:projection (current-projection)
#:camera-position camera-position
- #:ambient-light ambient-light
#:lights light-vector
#:material (material-properties material))))
@@ -159,13 +162,13 @@
(material primitive-material))
(define (draw-primitive primitive model-matrix view-matrix camera-position
- ambient-light light-vector)
+ skybox light-vector)
(material-apply (primitive-material primitive)
(primitive-vertex-array primitive)
model-matrix
view-matrix
camera-position
- ambient-light
+ skybox
light-vector))
@@ -190,7 +193,7 @@
(define* (draw-mesh mesh #:key (model-matrix %identity-matrix)
(view-matrix %identity-matrix)
(camera-position %origin)
- (ambient-light black)
+ skybox
(lights '()))
;; Populate light vector to pass on to shader.
(let ((light-vector (mesh-light-vector mesh)))
@@ -206,7 +209,7 @@
(loop (+ i 1) rest)))))
(for-each (lambda (primitive)
(draw-primitive primitive model-matrix view-matrix camera-position
- ambient-light light-vector))
+ skybox light-vector))
(mesh-primitives mesh))))
diff --git a/chickadee/graphics/model.scm b/chickadee/graphics/model.scm
index 8b7cbda..839ddd1 100644
--- a/chickadee/graphics/model.scm
+++ b/chickadee/graphics/model.scm
@@ -114,11 +114,10 @@
(children '()))
(%make-model-node name mesh matrix world-matrix children))
-(define (draw-model-node node state view-matrix camera-position ambient-light
- lights)
+(define (draw-model-node node state view-matrix camera-position skybox lights)
(for-each (lambda (child)
(draw-model-node child state view-matrix camera-position
- ambient-light lights))
+ skybox lights))
(model-node-children node))
(let ((mesh (model-node-mesh node)))
(when mesh
@@ -128,7 +127,7 @@
#:model-matrix (render-state-world-model-matrix state)
#:view-matrix view-matrix
#:camera-position camera-position
- #:ambient-light ambient-light
+ #:skybox skybox
#:lights lights))))
@@ -152,7 +151,7 @@
(define %depth-test (make-depth-test))
(define* (draw-model model model-matrix view-matrix camera-position #:key
- (ambient-light black)
+ skybox
(lights '()))
(with-graphics-state ((g:depth-test %depth-test)
(g:multisample? #t))
@@ -161,7 +160,7 @@
(render-state-model-matrix-mult! state model-matrix)
;; TODO: Support drawing non-default scenes.
(draw-model-node (model-default-scene model) state view-matrix
- camera-position ambient-light lights))))
+ camera-position skybox lights))))
;;;
diff --git a/data/shaders/pbr-frag.glsl b/data/shaders/pbr-frag.glsl
index c474981..fff725a 100644
--- a/data/shaders/pbr-frag.glsl
+++ b/data/shaders/pbr-frag.glsl
@@ -47,9 +47,9 @@ out vec4 fragColor;
uniform Material material;
uniform Light lights[MAX_LIGHTS];
-uniform vec4 ambientLight;
uniform bool vertexColored;
uniform vec3 cameraPosition;
+uniform samplerCube skybox;
uniform sampler2D baseColorTexture;
uniform sampler2D metallicRoughnessTexture;
uniform sampler2D normalTexture;
@@ -244,6 +244,7 @@ void main(void) {
float metallic = materialMetallic();
float roughness = materialRoughness();
vec3 normal = materialNormal();
+ vec3 reflection = reflect(-viewDirection, normal);
// The "raw" albedo has an alpha channel which we need to preserve
// so that we can apply the desired alpha blending method at the
// end, but it is completely ignored for lighting calculations.
@@ -356,11 +357,14 @@ void main(void) {
// The emissive texture says which fragments emit light. We simply
// add this light value to the color accumulator.
color += materialEmissive();
- // Apply simple ambient lighting. The affect of the ambient light
- // is dampened by the ambient occlusion factor.
+ // Apply image based ambient lighting. The affect of the ambient
+ // light is dampened by the ambient occlusion factor.
//
- // TODO: Use image based lighting.
- color += ambientLight.rgb * albedo * ambientOcclusion;
+ // TODO: Use fancy PBR equations instead of these basic ones.
+ float fresnel = pow(1.0 - clamp(dot(viewDirection, normal), 0.0, 1.0), 5);
+ vec3 ambientDiffuse = textureCube(skybox, normal).rgb;
+ vec3 ambientSpecular = textureLod(skybox, reflection, roughness * 7.0).rgb;
+ color += (ambientDiffuse * albedo + ambientSpecular * fresnel) * ambientOcclusion;
// Apply Reinhard tone mapping to convert our high dynamic range
// color value to low dynamic range. All of the lighting
// calculations stacked on top of each other is likely to create
diff --git a/data/shaders/phong-frag.glsl b/data/shaders/phong-frag.glsl
index 0beb75b..9c86c83 100644
--- a/data/shaders/phong-frag.glsl
+++ b/data/shaders/phong-frag.glsl
@@ -32,6 +32,7 @@ in vec2 fragTex;
out vec4 fragColor;
#endif
+uniform samplerCube skybox;
uniform sampler2D ambientMap;
uniform sampler2D diffuseMap;
uniform sampler2D specularMap;
@@ -39,7 +40,6 @@ uniform sampler2D normalMap;
uniform Material material;
uniform Light lights[MAX_LIGHTS];
uniform vec3 cameraPosition;
-uniform vec4 ambientLight;
const float GAMMA = 2.2;
@@ -135,6 +135,7 @@ void main() {
vec3 diffuseColor = materialDiffuse();
vec3 specularColor = materialSpecular();
vec3 normal = materialNormal();
+ vec3 reflection = reflect(-viewDir, normal);
vec3 color = vec3(0.0);
// Apply direct lighting.
@@ -155,8 +156,12 @@ void main() {
color += diffuseLight * diffuseColor + specularLight * specularColor;
}
- // Apply ambient lighting.
- vec3 ambientColor = diffuseColor * ambientLight.rgb * ambientOcclusion;
+ // Apply image based ambient lighting.
+ float fresnel = pow(1.0 - clamp(dot(viewDir, normal), 0.0, 1.0), 5);
+ float roughness = 1.0 - (material.shininess / 1000.0);
+ vec3 ambientDiffuse = textureCube(skybox, normal).rgb * diffuseColor;
+ vec3 ambientSpecular = textureLod(skybox, reflection, roughness * 7.0).rgb * fresnel;
+ vec3 ambientColor = (ambientDiffuse + ambientSpecular) * ambientOcclusion;
color += ambientColor;
// Apply gamma correction and HDR tone mapping to get the final