Skip to content

Commit

Permalink
Add shadow mapping demo.
Browse files Browse the repository at this point in the history
It uses a FBO with a depth-attachment ony.
The fragment shader samples the depth values from a sampler2D and uses
clip-space to NDC-space perspective divide together with a bias matrix
and a small depth offset to combat shadow acne.
  • Loading branch information
kaiburjack committed Apr 29, 2015
1 parent 4630746 commit 22e4221
Show file tree
Hide file tree
Showing 8 changed files with 621 additions and 0 deletions.
9 changes: 9 additions & 0 deletions res/demo/shadowMapping-fs.glsl
@@ -0,0 +1,9 @@
/*
* Copyright LWJGL. All rights reserved.
* License terms: http://lwjgl.org/license.php
*/
#version 130

void main(void) {
/* Nothing to do here... we are only rendering depth */
}
13 changes: 13 additions & 0 deletions res/demo/shadowMapping-vs.glsl
@@ -0,0 +1,13 @@
/*
* Copyright LWJGL. All rights reserved.
* License terms: http://lwjgl.org/license.php
*/
#version 130

uniform mat4 modelViewProjectionMatrix;

in vec3 position;

void main(void) {
gl_Position = modelViewProjectionMatrix * vec4(position, 1.0);
}
38 changes: 38 additions & 0 deletions res/demo/shadowMappingShade-fs.glsl
@@ -0,0 +1,38 @@
/*
* Copyright LWJGL. All rights reserved.
* License terms: http://lwjgl.org/license.php
*/
#version 130

#define DEPTH_OFFSET 0.00005
#define LIGHT_INTENSITY 0.9
#define SHADOW_INTENSITY 0.1

uniform sampler2D depthTexture;
uniform mat4 lightModelViewMatrix;
uniform vec3 lightPosition;
uniform vec3 lightLookAt;

in vec4 lightBiasedClipPosition;
in vec3 worldNormal;
out vec4 color;

void main(void) {
/* Convert the linearly interpolated clip-space position to NDC */
vec4 lightNDCPosition = lightBiasedClipPosition / lightBiasedClipPosition.w;

/* Sample the depth from the depth texture */
vec4 depth = texture2D(depthTexture, lightNDCPosition.xy);

/* Additionally, do standard lambertian/diffuse lighting */
float dot = max(0.0, dot(normalize(lightPosition - lightLookAt), worldNormal));

/* "in shadow" test... */
if (depth.z >= lightNDCPosition.z - DEPTH_OFFSET) {
/* lit */
color = vec4(LIGHT_INTENSITY, LIGHT_INTENSITY, LIGHT_INTENSITY, 1.0) * dot;
} else {
/* in shadow */
color = vec4(SHADOW_INTENSITY, SHADOW_INTENSITY, SHADOW_INTENSITY, 1.0);
}
}
28 changes: 28 additions & 0 deletions res/demo/shadowMappingShade-vs.glsl
@@ -0,0 +1,28 @@
/*
* Copyright LWJGL. All rights reserved.
* License terms: http://lwjgl.org/license.php
*/
#version 130

uniform mat4 modelViewProjectionMatrix;
uniform mat4 lightModelViewProjectionMatrix;
uniform mat4 biasMatrix;

in vec3 position;
in vec3 normal;
out vec4 lightBiasedClipPosition;
out vec3 worldNormal;

void main(void) {
/* Pass the normal to the fragment shader (we do lighting computations in world coordinates) */
worldNormal = normal;

/* Compute vertex position as seen from
the light and use linear interpolation when passing it
to the fragment shader
*/
lightBiasedClipPosition = biasMatrix * lightModelViewProjectionMatrix * vec4(position, 1.0);

/* Normally transform the vertex */
gl_Position = modelViewProjectionMatrix * vec4(position, 1.0);
}
101 changes: 101 additions & 0 deletions src/tests/org/lwjgl/demo/opengl/DemoUtils.java
@@ -0,0 +1,101 @@
/*
* Copyright LWJGL. All rights reserved.
* License terms: http://lwjgl.org/license.php
*/
package org.lwjgl.demo.opengl;

import static org.lwjgl.demo.util.IOUtil.ioResourceToByteBuffer;
import static org.lwjgl.opengl.GL20.GL_COMPILE_STATUS;
import static org.lwjgl.opengl.GL20.glCompileShader;
import static org.lwjgl.opengl.GL20.glCreateShader;
import static org.lwjgl.opengl.GL20.glGetShaderInfoLog;
import static org.lwjgl.opengl.GL20.glGetShaderi;
import static org.lwjgl.opengl.GL20.glShaderSource;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.PointerBuffer;
import org.lwjgl.demo.util.Vector3f;

/**
* Utility methods for most of the ray tracing demos.
*
* @author Kai Burjack
*
*/
public class DemoUtils {

/**
* Write the vertices (position and normal) of an axis-aligned unit box into
* the provided {@link FloatBuffer}.
*
* @param fv
* the {@link FloatBuffer} receiving the vertex position and
* normal
*/
public static void triangulateUnitBox(FloatBuffer fv) {
triangulateBox(new Vector3f(-1.0f, -1.0f, -1.0f), new Vector3f(1.0f, 1.0f, 1.0f), fv);
}

/**
* Write the vertices (position and normal) of an axis-aligned box with the
* given corner coordinates into the provided {@link FloatBuffer}.
*
* @param min
* the min corner
* @param max
* the max corner
* @param fv
* the {@link FloatBuffer} receiving the vertex position and
* normal
*/
public static void triangulateBox(Vector3f min, Vector3f max, FloatBuffer fv) {
/* Front face */
fv.put(min.x).put(min.y).put(max.z).put(0.0f).put(0.0f).put(1.0f);
fv.put(max.x).put(min.y).put(max.z).put(0.0f).put(0.0f).put(1.0f);
fv.put(max.x).put(max.y).put(max.z).put(0.0f).put(0.0f).put(1.0f);
fv.put(max.x).put(max.y).put(max.z).put(0.0f).put(0.0f).put(1.0f);
fv.put(min.x).put(max.y).put(max.z).put(0.0f).put(0.0f).put(1.0f);
fv.put(min.x).put(min.y).put(max.z).put(0.0f).put(0.0f).put(1.0f);
/* Back face */
fv.put(max.x).put(min.y).put(min.z).put(0.0f).put(0.0f).put(-1.0f);
fv.put(min.x).put(min.y).put(min.z).put(0.0f).put(0.0f).put(-1.0f);
fv.put(min.x).put(max.y).put(min.z).put(0.0f).put(0.0f).put(-1.0f);
fv.put(min.x).put(max.y).put(min.z).put(0.0f).put(0.0f).put(-1.0f);
fv.put(max.x).put(max.y).put(min.z).put(0.0f).put(0.0f).put(-1.0f);
fv.put(max.x).put(min.y).put(min.z).put(0.0f).put(0.0f).put(-1.0f);
/* Left face */
fv.put(min.x).put(min.y).put(min.z).put(-1.0f).put(0.0f).put(0.0f);
fv.put(min.x).put(min.y).put(max.z).put(-1.0f).put(0.0f).put(0.0f);
fv.put(min.x).put(max.y).put(max.z).put(-1.0f).put(0.0f).put(0.0f);
fv.put(min.x).put(max.y).put(max.z).put(-1.0f).put(0.0f).put(0.0f);
fv.put(min.x).put(max.y).put(min.z).put(-1.0f).put(0.0f).put(0.0f);
fv.put(min.x).put(min.y).put(min.z).put(-1.0f).put(0.0f).put(0.0f);
/* Right face */
fv.put(max.x).put(min.y).put(max.z).put(1.0f).put(0.0f).put(0.0f);
fv.put(max.x).put(min.y).put(min.z).put(1.0f).put(0.0f).put(0.0f);
fv.put(max.x).put(max.y).put(min.z).put(1.0f).put(0.0f).put(0.0f);
fv.put(max.x).put(max.y).put(min.z).put(1.0f).put(0.0f).put(0.0f);
fv.put(max.x).put(max.y).put(max.z).put(1.0f).put(0.0f).put(0.0f);
fv.put(max.x).put(min.y).put(max.z).put(1.0f).put(0.0f).put(0.0f);
/* Top face */
fv.put(min.x).put(max.y).put(max.z).put(0.0f).put(1.0f).put(0.0f);
fv.put(max.x).put(max.y).put(max.z).put(0.0f).put(1.0f).put(0.0f);
fv.put(max.x).put(max.y).put(min.z).put(0.0f).put(1.0f).put(0.0f);
fv.put(max.x).put(max.y).put(min.z).put(0.0f).put(1.0f).put(0.0f);
fv.put(min.x).put(max.y).put(min.z).put(0.0f).put(1.0f).put(0.0f);
fv.put(min.x).put(max.y).put(max.z).put(0.0f).put(1.0f).put(0.0f);
/* Bottom face */
fv.put(min.x).put(min.y).put(min.z).put(0.0f).put(-1.0f).put(0.0f);
fv.put(max.x).put(min.y).put(min.z).put(0.0f).put(-1.0f).put(0.0f);
fv.put(max.x).put(min.y).put(max.z).put(0.0f).put(-1.0f).put(0.0f);
fv.put(max.x).put(min.y).put(max.z).put(0.0f).put(-1.0f).put(0.0f);
fv.put(min.x).put(min.y).put(max.z).put(0.0f).put(-1.0f).put(0.0f);
fv.put(min.x).put(min.y).put(min.z).put(0.0f).put(-1.0f).put(0.0f);
}

}

0 comments on commit 22e4221

Please sign in to comment.