]> git.tdb.fi Git - libs/gl.git/commitdiff
Add reflection and refaction to the water in forest pond
authorMikko Rasa <tdb@tdb.fi>
Sun, 9 Oct 2022 13:22:18 +0000 (16:22 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 9 Oct 2022 13:22:18 +0000 (16:22 +0300)
demos/forestpond/data/water.glsl
demos/forestpond/source/forestpond.cpp
demos/forestpond/source/forestpond.h

index d200b6d76987112507a3a65b0683d606720fb985..4e680f68479c15faf22ffe73cd5364d1ac12f366 100644 (file)
@@ -1,5 +1,6 @@
 import msp_interface;
 import lighting;
+import environment;
 
 uniform Tessellation
 {
@@ -46,11 +47,11 @@ void main()
        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)
@@ -91,9 +92,15 @@ void main()
        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);
 }
index b327489d56430baae63e0e22cbad304033331f13..d1a0d03215f21d7f1c87bf4b8a016a0376dc761e 100644 (file)
@@ -23,8 +23,17 @@ ForestPond::ForestPond(int, char **):
        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());
index c035dcd8eccd52bc19c9c28d09bd091cd1dda54a..b22db689eda89586ce3ab3e5c49f50691217392e 100644 (file)
@@ -5,6 +5,7 @@
 #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>
@@ -38,6 +39,8 @@ private:
 
        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 **);