diff --git a/shaders/surface.frag b/shaders/surface.frag index 451c16c9484f96c43522b4a1ee1c956de528dc87..cd97f4c09f277f7297e852a194f575c0a64c35e9 100644 --- a/shaders/surface.frag +++ b/shaders/surface.frag @@ -18,7 +18,7 @@ const float R0 = 0.0204; const float ATTENUATION = 0.145f; //const float ATTENUATION = 0.5f; -const float MIN_T = 0; +const float MIN_T = 0.05; const float MAX_T = 10.0; const float DT = 0.1; @@ -77,7 +77,7 @@ vec3 refraction_ray(vec3 pos, vec3 dir) { ly = cur_pos.y; } - return vec3(1, 0, 1); + return vec3(0, 0, 0); } vec3 reflection_ray_second_bounce(vec3 pos, vec3 dir) { @@ -147,10 +147,10 @@ vec3 reflection_ray_first_bounce(vec3 pos, vec3 dir) { float R = fresnel(nnormal, dir); // vec3 water_color = vec3(0, 0.05, 0.1); - vec3 sky_color = reflection_ray_second_bounce(world_pos, reflected); + vec3 sky_color = reflection_ray_second_bounce(cur_pos, reflected); //vec3 sky_color = texture(sky, sphere_uv(reflected)).rgb; vec3 refracted = refract(dir, nnormal, 0.75); - vec3 water_color = refraction_ray(world_pos, refracted); + vec3 water_color = refraction_ray(cur_pos, refracted); return mix(water_color, sky_color, R); } } @@ -163,6 +163,104 @@ vec3 reflection_ray_first_bounce(vec3 pos, vec3 dir) { return texture(sky, sphere_uv(dir)).rgb; } +vec3 inside_reflection_ray_second_bounce(vec3 pos, vec3 dir) { + float lh = 0.0f; + float lh2 = 0.0f; + float ly = 0.0f; + + for (float t = MIN_T; t < MAX_T; t += DT) { + vec3 cur_pos = pos + t * dir; + + if (abs(cur_pos.x) > 5.0 || abs(cur_pos.z) > 5.0) { + break; + } + + float ground_y_at = depth_at(cur_pos); + float wave_y_at = wave_depth_at(cur_pos); + float y_at = max(ground_y_at, wave_y_at); + + if (cur_pos.y < ground_y_at) { + float res_t = t - DT + DT * (lh - ly) / (cur_pos.y - ly - y_at + lh); + vec3 hit_pos = pos + res_t * dir; + + return texture(ground, tex_at(hit_pos)).rgb; + } else if (cur_pos.y > wave_y_at) { + float res_t = t - DT + DT * (lh2 - ly) / (cur_pos.y - ly - y_at + lh2); + vec3 hit_pos = pos + res_t * dir; + + vec3 nnormal = normalize(wave_normal_at(hit_pos)); + vec3 reflected = reflect(dir, nnormal); + vec3 refracted = refract(dir, -nnormal, 1.333); + float R = fresnel(nnormal, -refracted); + if (dot(refracted, refracted) < 0.1) { + R = 1.0; + } + // vec3 water_color = vec3(0, 0.05, 0.1); + + //vec3 sky_color = reflection_ray_second_bounce(cur_pos, refracted); + vec3 sky_color = texture(sky, sphere_uv(reflected)).rgb; + vec3 water_color = refraction_ray(cur_pos, reflected); + return mix(sky_color, water_color, R); + } + + + lh = ground_y_at; + lh2 = wave_y_at; + ly = cur_pos.y; + } + + return texture(sky, sphere_uv(dir)).rgb; +} + +vec3 inside_reflection_ray_first_bounce(vec3 pos, vec3 dir) { + float lh = 0.0f; + float lh2 = 0.0f; + float ly = 0.0f; + + for (float t = MIN_T; t < MAX_T; t += DT) { + vec3 cur_pos = pos + t * dir; + + if (abs(cur_pos.x) > 5.0 || abs(cur_pos.z) > 5.0) { + break; + } + + float ground_y_at = depth_at(cur_pos); + float wave_y_at = wave_depth_at(cur_pos); + float y_at = max(ground_y_at, wave_y_at); + + if (cur_pos.y < ground_y_at) { + float res_t = t - DT + DT * (lh - ly) / (cur_pos.y - ly - y_at + lh); + vec3 hit_pos = pos + res_t * dir; + + return texture(ground, tex_at(hit_pos)).rgb; + } else if (cur_pos.y > wave_y_at) { + float res_t = t - DT + DT * (lh2 - ly) / (cur_pos.y - ly - y_at + lh2); + vec3 hit_pos = pos + res_t * dir; + + vec3 nnormal = normalize(wave_normal_at(hit_pos)); + vec3 reflected = reflect(dir, nnormal); + vec3 refracted = refract(dir, -nnormal, 1.333); + float R = fresnel(nnormal, -refracted); + if (dot(refracted, refracted) < 0.1) { + R = 1.0; + } + // vec3 water_color = vec3(0, 0.05, 0.1); + + vec3 sky_color = reflection_ray_second_bounce(cur_pos, refracted); + //vec3 sky_color = texture(sky, sphere_uv(reflected)).rgb; + vec3 water_color = inside_reflection_ray_second_bounce(cur_pos, reflected); + return mix(sky_color, water_color, R); + } + + + lh = ground_y_at; + lh2 = wave_y_at; + ly = cur_pos.y; + } + + return texture(sky, sphere_uv(dir)).rgb; +} + vec3 map(float v) { if (v > 1.0 || v < 0.0) { @@ -176,15 +274,29 @@ void main(void) { vec3 view = normalize(world_pos - camera_pos); vec3 nnormal = normalize(normal); - vec3 reflected = reflect(view, nnormal); - float R = fresnel(nnormal, view); - // vec3 water_color = vec3(0, 0.05, 0.1); + vec3 color; + if (gl_FrontFacing) { + vec3 reflected = reflect(view, nnormal); + vec3 refracted = refract(view, nnormal, 0.75); + float R = fresnel(nnormal, view); + + vec3 sky_color = reflection_ray_first_bounce(world_pos + vec3(0, 0.001, 0), reflected); + vec3 water_color = refraction_ray(world_pos, refracted); - vec3 sky_color = reflection_ray_first_bounce(world_pos + vec3(0, 0.001, 0), reflected); - vec3 refracted = refract(view, nnormal, 0.75); - vec3 water_color = refraction_ray(world_pos, refracted); + color = mix(water_color, sky_color, R); + } else { + vec3 reflected = reflect(view, nnormal); + vec3 refracted = refract(view, -nnormal, 1.333); + float R = fresnel(nnormal, -refracted); + if (dot(refracted, refracted) < 0.1) { + R = 1.0; + } - vec3 hdr = mix(water_color, sky_color, R); - out_Color = vec4(hdr, 1.0); + vec3 sky_color = reflection_ray_second_bounce(world_pos + vec3(0, 0.001, 0), refracted); + vec3 water_color = inside_reflection_ray_first_bounce(world_pos - vec3(0, 0.001, 0), reflected); + + color = mix(sky_color, water_color, R); + } + out_Color = vec4(color, 1.0); } diff --git a/src/main.cpp b/src/main.cpp index 2b8ee8f6512cdca07ef5f34e32e0c55b6f019350..e3487458e52c0d5310ef73962f9c12dc82198e31 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -372,7 +372,9 @@ struct Scene { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); draw_skybox(); + glDisable(GL_CULL_FACE); draw_surface(); + glEnable(GL_CULL_FACE); draw_ground(); draw_waterfall(); draw_bubble();