From: Mikko Rasa Date: Sun, 9 Oct 2022 13:22:18 +0000 (+0300) Subject: Add reflection and refaction to the water in forest pond X-Git-Url: https://git.tdb.fi/?a=commitdiff_plain;h=4068ffedbd32bd9f1de211a88d00d71547bbcf27;p=libs%2Fgl.git Add reflection and refaction to the water in forest pond --- diff --git a/demos/forestpond/data/water.glsl b/demos/forestpond/data/water.glsl index d200b6d7..4e680f68 100644 --- a/demos/forestpond/data/water.glsl +++ b/demos/forestpond/data/water.glsl @@ -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); } diff --git a/demos/forestpond/source/forestpond.cpp b/demos/forestpond/source/forestpond.cpp index b327489d..d1a0d032 100644 --- a/demos/forestpond/source/forestpond.cpp +++ b/demos/forestpond/source/forestpond.cpp @@ -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("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(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("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()); diff --git a/demos/forestpond/source/forestpond.h b/demos/forestpond/source/forestpond.h index c035dcd8..b22db689 100644 --- a/demos/forestpond/source/forestpond.h +++ b/demos/forestpond/source/forestpond.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,8 @@ private: Msp::GL::OrderedScene content; Water water; + std::unique_ptr env_seq; + std::unique_ptr env_map; public: ForestPond(int, char **);