import msp_interface;
import lighting;
+import environment;
uniform Tessellation
{
float w1 = gl_TessCoord.x*(1.0-gl_TessCoord.y);
float w2 = gl_TessCoord.x*gl_TessCoord.y;
float w3 = (1.0-gl_TessCoord.x)*gl_TessCoord.y;
- vec4 pos = w0*gl_in[0].gl_Position+w1*gl_in[1].gl_Position+w2*gl_in[2].gl_Position+w3*gl_in[3].gl_Position;
- out vec2 texcoord = pos.xy*region.scale+region.offset;
- pos.z = textureLod(surface, texcoord, 0).x*region.amplitude-0.01;
- out vec3 world_look = pos.xyz-world_eye_matrix[3].xyz;
- gl_Position = clip_eye_matrix*eye_world_matrix*pos;
+ out vec4 world_pos = w0*gl_in[0].gl_Position+w1*gl_in[1].gl_Position+w2*gl_in[2].gl_Position+w3*gl_in[3].gl_Position;
+ out vec2 texcoord = world_pos.xy*region.scale+region.offset;
+ world_pos.z = textureLod(surface, texcoord, 0).x*region.amplitude-0.01;
+ out vec3 world_look = world_pos.xyz-world_eye_matrix[3].xyz;
+ gl_Position = clip_eye_matrix*eye_world_matrix*world_pos;
}
#pragma MSP stage(fragment)
float std_dev = sqrt(slope_var);
float fresnel_e = 0.02+0.98*pow(1.0+dot(look, normal), 5.0*exp(-2.69*std_dev))/(1+22.7*pow(std_dev, 1.5));
vec3 reflect_dir = reflect(look, normal);
- vec3 env_color = (reflect_dir.z>0 ? vec3(0.34, 0.54, 0.9) : vec3(0.0));
-
- color += env_color*fresnel_e;
+ vec3 refract_dir = refract(look, normal, 0.75);
+ float roughness = 1.0-pow(2.0, -slope_var);
+ vec3 reflect_color = get_environment_sample(world_pos.xyz, reflect_dir, roughness);
+ vec3 refract_color = get_environment_sample(world_pos.xyz, refract_dir, roughness);
+ /* It would be more correct to use the distance along the refracted ray, but
+ there's no easy way to get it. Water depth is a good enough approximation. */
+ float transmittance = pow(0.1, depth/100.0);
+
+ color += reflect_color*fresnel_e + refract_color*(1-fresnel_e)*transmittance;
frag_color = vec4(color, 1.0);
}
seq_bld.set_renderable("content", content);
sequence.reset(seq_bld.build(view));
+ GL::SequenceBuilder env_bld(resources.get<GL::SequenceTemplate>("Forest_environment.seq"));
+ env_bld.set_debug_name("Environment sequence");
+ env_bld.set_renderable("content", *sequence->get_steps().front().get_renderable());
+ env_seq.reset(env_bld.build());
+
+ env_map = std::make_unique<GL::EnvironmentMap>(512, GL::RGBA16F, 5, water, *env_seq);
+ env_map->set_debug_name("Water environment");
+ env_map->set_fixed_position(GL::Vector3(-3, 2, 1));
+
content.add(resources.get<GL::Scene>("Forest.scene"));
- content.add(water);
+ content.add(*env_map);
water.set_matrix(GL::Matrix::translation(GL::Vector3(-3, 2, 0)));
view.set_content(sequence.get());
#include <msp/core/application.h>
#include <msp/datafile/directorysource.h>
#include <msp/gl/device.h>
+#include <msp/gl/environmentmap.h>
#include <msp/gl/orderedscene.h>
#include <msp/gl/resourcemanager.h>
#include <msp/gl/resources.h>
Msp::GL::OrderedScene content;
Water water;
+ std::unique_ptr<Msp::GL::Sequence> env_seq;
+ std::unique_ptr<Msp::GL::EnvironmentMap> env_map;
public:
ForestPond(int, char **);