summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2009-08-01 14:24:16 -0700
committerEric Anholt <eric@anholt.net>2009-08-01 14:35:15 -0700
commit607b0ae844f42f3fe9387430d8d513ec294682b1 (patch)
tree05bd9ab7a1e50969e711f0095c2aeb3e7ac3e744
parentdbd90f7d607ae99c5eb5427dcf14cd5915952894 (diff)
Add acne-ridden shadowing to rings.
-rw-r--r--glass.c17
-rw-r--r--glass.frag7
-rw-r--r--glass.h2
-rw-r--r--glass.vert4
-rw-r--r--ground.c14
-rw-r--r--shadow_map.c22
6 files changed, 45 insertions, 21 deletions
diff --git a/glass.c b/glass.c
index 4380f31..a0711a7 100644
--- a/glass.c
+++ b/glass.c
@@ -51,9 +51,11 @@ static int win_width, win_height;
enum uniform_list {
UNIFORM_MV,
UNIFORM_MVP,
+ UNIFORM_LIGHT_MVP,
UNIFORM_LIGHT_EYE,
UNIFORM_NORMAL_SAMPLER,
UNIFORM_HEIGHTMAP_SAMPLER,
+ UNIFORM_SHADOW_SAMPLER,
UNIFORM_NI,
UNIFORM_F0,
};
@@ -66,9 +68,11 @@ enum shadowmap_display_uniform_list {
struct uniform_desc uniforms[] = {
[UNIFORM_MV] = { "mv" },
[UNIFORM_MVP] = { "mvp" },
+ [UNIFORM_LIGHT_MVP] = { "light_mvp" },
[UNIFORM_LIGHT_EYE] = { "light_eye" },
[UNIFORM_NORMAL_SAMPLER] = { "normal_sampler" },
[UNIFORM_HEIGHTMAP_SAMPLER] = { "heightmap_sampler" },
+ [UNIFORM_SHADOW_SAMPLER] = { "shadow_sampler" },
[UNIFORM_NI] = { "ni" },
[UNIFORM_F0] = { "F0" },
};
@@ -267,16 +271,19 @@ calc_new_ring_transforms(int instance)
static void
install_transform(int instance)
{
- GLUmat4 mv, mvp;
+ GLUmat4 mv, mvp, light_mvp;
/* Generate the whole mvp */
gluMult4m_4m(&mv, &world_to_eye, &ring_obj_to_world[instance]);
gluMult4m_4m(&mvp, &projection, &mv);
-
+ gluMult4m_4m(&light_mvp, &world_to_shadow_texcoords,
+ &ring_obj_to_world[instance]);
glUniformMatrix4fv(uniforms[UNIFORM_MV].location, 1, 0,
(float *)&mv);
glUniformMatrix4fv(uniforms[UNIFORM_MVP].location, 1, 0,
(float *)&mvp);
+ glUniformMatrix4fv(uniforms[UNIFORM_LIGHT_MVP].location, 1, 0,
+ (float *)&light_mvp);
}
static void
@@ -290,6 +297,9 @@ draw_rings(void)
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, heightmap_tex);
glEnable(GL_TEXTURE_2D);
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, shadow_tex);
+ glEnable(GL_TEXTURE_2D);
if (glass_prog != 0) {
glUseProgram(glass_prog);
@@ -307,6 +317,8 @@ draw_rings(void)
glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE1);
glDisable(GL_TEXTURE_2D);
+ glActiveTexture(GL_TEXTURE2);
+ glDisable(GL_TEXTURE_2D);
}
static void
@@ -800,6 +812,7 @@ load_glass_program(void)
glUniform1i(uniforms[UNIFORM_NORMAL_SAMPLER].location, 0);
glUniform1i(uniforms[UNIFORM_HEIGHTMAP_SAMPLER].location, 1);
+ glUniform1i(uniforms[UNIFORM_SHADOW_SAMPLER].location, 2);
update_brdf_constants();
}
diff --git a/glass.frag b/glass.frag
index 6575a0b..3810c52 100644
--- a/glass.frag
+++ b/glass.frag
@@ -1,9 +1,11 @@
varying vec3 light_surf;
varying vec3 eye_surf;
varying vec3 tangent_surf;
+varying vec4 shadow_coords;
varying vec2 texcoord;
uniform sampler2D normal_sampler;
uniform sampler2D heightmap_sampler;
+uniform sampler2DShadow shadow_sampler;
uniform float F0, ni;
float schlick_fresnel(float n_dot_l)
@@ -27,6 +29,7 @@ float fresnel(float v_dot_h)
void main()
{
+ float shadow = shadow2DProj(shadow_sampler, shadow_coords).x;
const vec4 material_color = vec4(0.7, 0.5, 0.3, 0.0);
vec3 l = normalize(light_surf);
vec3 v = normalize(eye_surf);
@@ -43,7 +46,7 @@ void main()
float v_dot_h = dot(v, h);
float s = .7;
float d = 1 - s;
- float Ii = 0.9; /*intensity of incoming light */
+ float Ii = 0.9 * shadow; /*intensity of incoming light */
float Iia = .1 * Ii; /*intensity of ambient light */
float cos2_alpha = n_dot_h * n_dot_h;
@@ -94,7 +97,7 @@ void main()
gl_FragColor = n_dot_l * step(0, n_dot_l) *
vec4(material_color.xyz *
- (Rd * d + Rs * s),
+ ((Rd * d + Rs * s) * Ii),
material_color.w) +
Iia * Ra * material_color.xyzw;
diff --git a/glass.h b/glass.h
index f3dc795..ac857c2 100644
--- a/glass.h
+++ b/glass.h
@@ -61,7 +61,7 @@ extern struct uniform_desc ground_uniforms[GROUND_UNIFORM_MAX];
extern struct uniform_desc shadow_uniforms[SHADOW_UNIFORM_MAX];
extern GLuint ground_prog, shadow_prog;
extern GLUmat4 projection;
-extern GLUmat4 world_to_eye;
+extern GLUmat4 world_to_eye, world_to_shadow_texcoords;
extern GLUvec4 light_world, light_eye;
extern GLUmat4 ring_obj_to_world[NUM_RINGS];
extern struct revolved_object ring;
diff --git a/glass.vert b/glass.vert
index abb1661..f894214 100644
--- a/glass.vert
+++ b/glass.vert
@@ -3,7 +3,8 @@ varying vec2 texcoord;
varying vec3 light_surf;
varying vec3 eye_surf;
varying vec3 tangent_surf;
-uniform mat4 mvp, mv;
+varying vec4 shadow_coords;
+uniform mat4 mvp, mv, light_mvp;
void main()
{
@@ -18,6 +19,7 @@ void main()
);
vec3 vertex_eye = vec3(mv * gl_Vertex);
+ shadow_coords = light_mvp * gl_Vertex;
texcoord = vec2(gl_MultiTexCoord0.x * 4, gl_MultiTexCoord0.y);
light_surf = normalize((light_eye - vertex_eye) * tbn);
diff --git a/ground.c b/ground.c
index 382d0dd..4979a36 100644
--- a/ground.c
+++ b/ground.c
@@ -53,23 +53,9 @@ static void
install_ground_transform(void)
{
GLUmat4 mvp;
- GLUmat4 world_to_shadow_texcoords;
- GLUmat4 temp;
gluMult4m_4m(&mvp, &projection, &world_to_eye);
- /* Setup the viewport translation to map light NDC to texcoords.
- */
- memcpy(&temp, &gluIdentityMatrix, sizeof(gluIdentityMatrix));
- temp.col[0].values[0] = (1.0 - 0.0) / 2.0;
- temp.col[3].values[0] = temp.col[0].values[0] + 0.0;
- temp.col[1].values[1] = (1.0 - 0.0) / 2.0;
- temp.col[3].values[1] = temp.col[1].values[1] + 0.0;
- temp.col[2].values[2] = (1.0 - 0.0) / 2.0;
- temp.col[3].values[2] = (1.0 - 0.0) / 2.0;
-
- gluMult4m_4m(&world_to_shadow_texcoords, &temp, &world_to_light_ndc);
-
/* Note that ground object coordinates are already in world space. */
glUniformMatrix4fv(ground_uniforms[GROUND_UNIFORM_MV].location, 1, 0,
(float *)&world_to_eye);
diff --git a/shadow_map.c b/shadow_map.c
index 5fc8777..6bef52f 100644
--- a/shadow_map.c
+++ b/shadow_map.c
@@ -41,10 +41,28 @@
extern int no_multi_draw_arrays;
extern GLUvec4 eye_world;
static GLUmat4 world_to_light_eye;
-GLUmat4 world_to_light_ndc;
+GLUmat4 world_to_light_ndc, world_to_shadow_texcoords;
GLuint shadow_tex = 0, shadow_fbo;
static void
+set_world_to_shadow_transform(void)
+{
+ GLUmat4 temp;
+
+ /* Setup the viewport translation to map light NDC to texcoords.
+ */
+ memcpy(&temp, &gluIdentityMatrix, sizeof(gluIdentityMatrix));
+ temp.col[0].values[0] = (1.0 - 0.0) / 2.0;
+ temp.col[3].values[0] = temp.col[0].values[0] + 0.0;
+ temp.col[1].values[1] = (1.0 - 0.0) / 2.0;
+ temp.col[3].values[1] = temp.col[1].values[1] + 0.0;
+ temp.col[2].values[2] = (1.0 - 0.0) / 2.0;
+ temp.col[3].values[2] = (1.0 - 0.0) / 2.0;
+
+ gluMult4m_4m(&world_to_shadow_texcoords, &temp, &world_to_light_ndc);
+}
+
+static void
calculate_light_projection(void)
{
GLUvec4 light_up;
@@ -175,4 +193,6 @@ generate_rings_shadowmap(void)
glDrawBuffer(GL_BACK);
glReadBuffer(GL_BACK);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+
+ set_world_to_shadow_transform();
}