aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/shaders/light-refract.frag32
-rw-r--r--src/scene-refract.cpp7
2 files changed, 21 insertions, 18 deletions
diff --git a/data/shaders/light-refract.frag b/data/shaders/light-refract.frag
index f71a283..bcc5096 100644
--- a/data/shaders/light-refract.frag
+++ b/data/shaders/light-refract.frag
@@ -13,23 +13,29 @@ void main()
const float matShininess = 100.0;
const vec2 point_five = vec2(0.5);
// Need the normalized eye direction and surface normal vectors to
- // compute the refraction vector through the "front" surface of the object.
+ // compute the transmitted vector through the "front" surface of the object.
vec3 eye_direction = normalize(-vertex_position.xyz);
vec3 normalized_normal = normalize(vertex_normal);
- vec3 front_refraction = refract(eye_direction, normalized_normal, 1.5);
- // Offset the base map coordinate by the refaction vector, and re-normalize
- // to texture coordinate space [0, 1].
- vec4 mc_perspective = MapCoord / MapCoord.w;
- vec4 distance_value = texture2D(DistanceMap, mc_perspective.st);
- float frontToBack = distance_value.z - mc_perspective.z;
- vec3 back_position = (front_refraction - vertex_position) + frontToBack;
- vec2 normcoord = (mc_perspective.st + front_refraction.st + point_five) * point_five;
+ vec3 front_refraction = refract(eye_direction, normalized_normal, 1.45);
+ // Find our best distance approximation through the object so we can
+ // project the transmitted vector to the back of the object to find
+ // the exit point.
+ vec3 mc_perspective = (MapCoord.xyz / MapCoord.w) + front_refraction;
+ vec2 dcoord = mc_perspective.st * point_five + point_five;
+ vec4 distance_value = texture2D(DistanceMap, dcoord);
+ vec3 back_position = vertex_position.xyz + front_refraction * distance_value.z;
+ // Use the exit point to index the map of back-side normals, and use the
+ // back-side position and normal to find the transmitted vector out of the
+ // object.
+ vec2 normcoord = back_position.st * point_five + point_five;
vec3 back_normal = texture2D(NormalMap, normcoord).xyz;
- // Now refract again, using the normal from the lookup.
- vec3 back_refraction = refract(back_position, back_normal.xyz, 1.0);
- vec2 imagecoord = (normcoord + back_refraction.st + point_five) * point_five;
+ vec3 back_refraction = refract(back_position, back_normal, 1.0);
+ // Use the transmitted vector from the exit point to determine where
+ // the vector would intersect the environment (in this case a background
+ // image.
+ vec2 imagecoord = back_refraction.st * point_five + point_five;
vec4 texel = texture2D(ImageMap, imagecoord);
- // Add in a specular component
+ // Add in specular reflection, and we have our fragment value.
vec3 light_direction = normalize(vertex_position.xyz/vertex_position.w -
LightSourcePosition.xyz/LightSourcePosition.w);
vec3 reflection = reflect(light_direction, normalized_normal);
diff --git a/src/scene-refract.cpp b/src/scene-refract.cpp
index e7fa659..f4188e0 100644
--- a/src/scene-refract.cpp
+++ b/src/scene-refract.cpp
@@ -203,11 +203,12 @@ DistanceRenderTarget::setup(unsigned int width, unsigned int height)
GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
glBindTexture(GL_TEXTURE_2D, tex_[COLOR]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
glGenFramebuffers(1, &fbo_);
@@ -254,7 +255,6 @@ DistanceRenderTarget::enable(const mat4& mvp)
glViewport(0, 0, width_, height_);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glCullFace(GL_FRONT);
- glDepthFunc(GL_GREATER);
}
void DistanceRenderTarget::disable()
@@ -262,7 +262,6 @@ void DistanceRenderTarget::disable()
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, canvas_width_, canvas_height_);
glCullFace(GL_BACK);
- glDepthFunc(GL_LEQUAL);
}
bool
@@ -271,7 +270,6 @@ RefractPrivate::setup(map<string, Scene::Option>& options)
// Program object setup
static const string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/light-refract.vert");
static const string frg_shader_filename(GLMARK_DATA_PATH"/shaders/light-refract.frag");
- static const vec4 materialDiffuse(1.0f, 1.0f, 1.0f, 0.0f);
static const vec4 lightColor(0.4, 0.4, 0.4, 1.0);
ShaderSource vtx_source(vtx_shader_filename);
@@ -279,7 +277,6 @@ RefractPrivate::setup(map<string, Scene::Option>& options)
frg_source.add_const("LightColor", lightColor);
frg_source.add_const("LightSourcePosition", lightPosition);
- frg_source.add_const("MaterialDiffuse", materialDiffuse);
if (!Scene::load_shaders_from_strings(program_, vtx_source.str(), frg_source.str())) {
return false;