Skip to content
Snippets Groups Projects
Commit 2a275c12 authored by Axel Matstoms's avatar Axel Matstoms
Browse files

Final tweaks :)

parent 255059ef
No related branches found
No related tags found
No related merge requests found
...@@ -17,6 +17,7 @@ const float tex_scale = 4.0; ...@@ -17,6 +17,7 @@ const float tex_scale = 4.0;
const float PI = 3.1415926535897f; const float PI = 3.1415926535897f;
const float ETA = 1.333; const float ETA = 1.333;
const float R0 = 0.0204;
const float ATTENUATION = 0.145f; const float ATTENUATION = 0.145f;
const vec2 CAUSTICS_OFFSETS[] = vec2[]( const vec2 CAUSTICS_OFFSETS[] = vec2[](
...@@ -95,6 +96,12 @@ vec2 sphere_uv(vec3 direction) ...@@ -95,6 +96,12 @@ vec2 sphere_uv(vec3 direction)
return vec2(u, v); return vec2(u, v);
} }
float fresnel(vec3 normal, vec3 view) {
float cos_theta = dot(normal, -view);
float x = 1.0 - cos_theta;
return mix(R0, 1.0, x * x * x * x * x);
}
float unlerp(float lo, float hi, float t) float unlerp(float lo, float hi, float t)
{ {
return clamp((t - lo) / (hi - lo), 0.0, 1.0); return clamp((t - lo) / (hi - lo), 0.0, 1.0);
...@@ -115,37 +122,35 @@ vec3 wave_normal_at(vec3 pos) { ...@@ -115,37 +122,35 @@ vec3 wave_normal_at(vec3 pos) {
vec3 caustics(vec3 nnormal) vec3 caustics(vec3 nnormal)
{ {
vec3 light = vec3(0); vec3 light = vec3(0);
int count = 1; //int count = 1;
for (int i = 0; i < CAUSTICS_OFFSETS.length(); ++i) { for (int i = 0; i < CAUSTICS_OFFSETS.length(); ++i) {
vec2 cur_offset = CAUSTICS_OFFSETS[i]; vec2 cur_offset = CAUSTICS_OFFSETS[i];
vec3 offset_pos = position + vec3(cur_offset.x, 0, cur_offset.y); vec3 offset_pos = position + vec3(cur_offset.x, 0, cur_offset.y);
vec3 wave_pos = vec3(offset_pos.x, depth_at(offset_pos), offset_pos.z); vec3 wave_pos = vec3(offset_pos.x, depth_at(offset_pos), offset_pos.z);
vec3 wave_normal = wave_normal_at(offset_pos); vec3 wave_normal = normalize(wave_normal_at(offset_pos));
vec3 ray = wave_pos - position; vec3 ray = wave_pos - position;
float ray_length = length(ray); float ray_length = length(ray);
vec3 incident = ray / ray_length; vec3 incident = ray / ray_length;
vec3 refracted = refract(incident, wave_normal, ETA); vec3 refracted = refract(incident, -wave_normal, ETA);
float shade = exp(-ray_length * ATTENUATION); float shade = exp(-ray_length * ATTENUATION);
float F = 1.0 - fresnel(wave_normal, -refracted); // Fraction of refracted light
if (incident.y > 0 && refracted != vec3(0)) { if (incident.y > 0 && refracted != vec3(0)) {
light += dot(nnormal, incident) * texture(skybox, sphere_uv(refracted)).rgb * shade; light += dot(nnormal, incident) * texture(skybox, sphere_uv(refracted)).rgb * shade * F;
//light += refracted;
count += 1;
} }
} }
// ambient light // ambient light
return 0.05 + 2.0 * light / float(CAUSTICS_OFFSETS.length()); return vec3(0.05) + light / float(CAUSTICS_OFFSETS.length());
} }
void main(void) void main(void)
{ {
vec3 nnormal = normalize(normal); vec3 nnormal = normalize(normal);
//float light = max(0.0, dot(nnormal, sun));
vec3 albedo = mix(texture(dirt, tex_coord * tex_scale).rgb, texture(grass, tex_coord * tex_scale).rgb, unlerp(-0.2, 0.2, position.y)); vec3 albedo = mix(texture(dirt, tex_coord * tex_scale).rgb, texture(grass, tex_coord * tex_scale).rgb, unlerp(-0.2, 0.2, position.y));
...@@ -158,6 +163,5 @@ void main(void) ...@@ -158,6 +163,5 @@ void main(void)
} }
out_Color = vec4(albedo * light, 1.0); out_Color = vec4(albedo * light, 1.0);
//out_Color = texture(surf_normal, tex_coord);
} }
...@@ -18,9 +18,12 @@ const float R0 = 0.0204; ...@@ -18,9 +18,12 @@ const float R0 = 0.0204;
const float ATTENUATION = 0.145f; const float ATTENUATION = 0.145f;
//const float ATTENUATION = 0.5f; //const float ATTENUATION = 0.5f;
const float MIN_T = 0.05; const float IOR = 0.75;
const float MAX_T = 10.0; const float INV_IOR = 1.333;
const float DT = 0.1;
const float MIN_T = 0.02;
const float MAX_T = 7.5;
const float DT = 0.05;
out vec4 out_Color; out vec4 out_Color;
...@@ -35,7 +38,7 @@ vec2 sphere_uv(vec3 direction) ...@@ -35,7 +38,7 @@ vec2 sphere_uv(vec3 direction)
float fresnel(vec3 normal, vec3 view) { float fresnel(vec3 normal, vec3 view) {
float cos_theta = dot(normal, -view); float cos_theta = dot(normal, -view);
float x = 1.0 - cos_theta; float x = clamp(1.0 - cos_theta, 0, 1);
return mix(R0, 1.0, x * x * x * x * x); return mix(R0, 1.0, x * x * x * x * x);
} }
...@@ -109,6 +112,9 @@ vec3 reflection_ray_second_bounce(vec3 pos, vec3 dir) { ...@@ -109,6 +112,9 @@ vec3 reflection_ray_second_bounce(vec3 pos, vec3 dir) {
vec3 sky_color = texture(sky, sphere_uv(reflected)).rgb; vec3 sky_color = texture(sky, sphere_uv(reflected)).rgb;
vec3 refracted = refract(dir, nnormal, 0.75); vec3 refracted = refract(dir, nnormal, 0.75);
vec3 water_color = refraction_ray(world_pos, refracted); vec3 water_color = refraction_ray(world_pos, refracted);
return mix(water_color, sky_color, R);
//return map(dot(dir, nnormal));
} }
} }
...@@ -120,8 +126,9 @@ vec3 reflection_ray_second_bounce(vec3 pos, vec3 dir) { ...@@ -120,8 +126,9 @@ vec3 reflection_ray_second_bounce(vec3 pos, vec3 dir) {
return texture(sky, sphere_uv(dir)).rgb; return texture(sky, sphere_uv(dir)).rgb;
} }
vec3 reflection_ray_first_bounce(vec3 pos, vec3 dir) { vec3 inside_reflection_ray_second_bounce(vec3 pos, vec3 dir) {
float lh = 0.0f; float lh = 0.0f;
float lh2 = 0.0f;
float ly = 0.0f; float ly = 0.0f;
for (float t = MIN_T; t < MAX_T; t += DT) { for (float t = MIN_T; t < MAX_T; t += DT) {
...@@ -135,37 +142,44 @@ vec3 reflection_ray_first_bounce(vec3 pos, vec3 dir) { ...@@ -135,37 +142,44 @@ vec3 reflection_ray_first_bounce(vec3 pos, vec3 dir) {
float wave_y_at = wave_depth_at(cur_pos); float wave_y_at = wave_depth_at(cur_pos);
float y_at = max(ground_y_at, wave_y_at); float y_at = max(ground_y_at, wave_y_at);
if (cur_pos.y < y_at) { if (cur_pos.y < ground_y_at) {
float res_t = t - DT + DT * (lh - ly) / (cur_pos.y - ly - y_at + lh); float res_t = t - DT + DT * (lh - ly) / (cur_pos.y - ly - y_at + lh);
vec3 hit_pos = pos + res_t * dir; vec3 hit_pos = pos + res_t * dir;
float shade = exp(-res_t * ATTENUATION);
if (ground_y_at > wave_y_at) { return shade * texture(ground, tex_at(hit_pos)).rgb;
return texture(ground, tex_at(hit_pos)).rgb; } else if (cur_pos.y > wave_y_at) {
} else { float res_t = t - DT + DT * (lh2 - ly) / (cur_pos.y - ly - y_at + lh2);
vec3 nnormal = normalize(wave_normal_at(hit_pos)); vec3 hit_pos = pos + res_t * dir;
vec3 reflected = reflect(dir, nnormal);
float R = fresnel(nnormal, dir);
// vec3 water_color = vec3(0, 0.05, 0.1);
vec3 sky_color = reflection_ray_second_bounce(cur_pos, reflected); vec3 nnormal = normalize(wave_normal_at(hit_pos));
//vec3 sky_color = texture(sky, sphere_uv(reflected)).rgb; vec3 reflected = reflect(dir, nnormal);
vec3 refracted = refract(dir, nnormal, 0.75); vec3 refracted = refract(dir, -nnormal, 1.333);
vec3 water_color = refraction_ray(cur_pos, refracted); float R = fresnel(nnormal, -refracted);
return mix(water_color, sky_color, R); 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);
float shade = exp(-res_t * ATTENUATION);
return shade * mix(sky_color, water_color, R);
} }
lh = y_at; lh = ground_y_at;
lh2 = wave_y_at;
ly = cur_pos.y; ly = cur_pos.y;
} }
return texture(sky, sphere_uv(dir)).rgb; return vec3(0);
} }
vec3 inside_reflection_ray_second_bounce(vec3 pos, vec3 dir) { vec3 reflection_ray_first_bounce(vec3 pos, vec3 dir) {
float lh = 0.0f; float lh = 0.0f;
float lh2 = 0.0f;
float ly = 0.0f; float ly = 0.0f;
for (float t = MIN_T; t < MAX_T; t += DT) { for (float t = MIN_T; t < MAX_T; t += DT) {
...@@ -179,39 +193,35 @@ vec3 inside_reflection_ray_second_bounce(vec3 pos, vec3 dir) { ...@@ -179,39 +193,35 @@ vec3 inside_reflection_ray_second_bounce(vec3 pos, vec3 dir) {
float wave_y_at = wave_depth_at(cur_pos); float wave_y_at = wave_depth_at(cur_pos);
float y_at = max(ground_y_at, wave_y_at); float y_at = max(ground_y_at, wave_y_at);
if (cur_pos.y < ground_y_at) { if (cur_pos.y < y_at) {
float res_t = t - DT + DT * (lh - ly) / (cur_pos.y - ly - y_at + lh); float res_t = t - DT + DT * (lh - ly) / (cur_pos.y - ly - y_at + lh);
vec3 hit_pos = pos + res_t * dir; vec3 hit_pos = pos + res_t * dir;
return texture(ground, tex_at(hit_pos)).rgb; if (ground_y_at > wave_y_at) {
} else if (cur_pos.y > wave_y_at) { return texture(ground, tex_at(hit_pos)).rgb;
float res_t = t - DT + DT * (lh2 - ly) / (cur_pos.y - ly - y_at + lh2); } else {
vec3 hit_pos = pos + res_t * dir; vec3 nnormal = normalize(wave_normal_at(hit_pos));
vec3 reflected = reflect(dir, nnormal);
float R = fresnel(nnormal, dir);
// vec3 water_color = vec3(0, 0.05, 0.1);
vec3 nnormal = normalize(wave_normal_at(hit_pos)); vec3 sky_color = reflection_ray_second_bounce(cur_pos, reflected);
vec3 reflected = reflect(dir, nnormal); //vec3 sky_color = texture(sky, sphere_uv(reflected)).rgb;
vec3 refracted = refract(dir, -nnormal, 1.333); vec3 refracted = refract(dir, nnormal, 0.75);
float R = fresnel(nnormal, -refracted); vec3 water_color = inside_reflection_ray_second_bounce(cur_pos, refracted);
if (dot(refracted, refracted) < 0.1) { return mix(water_color, sky_color, R);
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; lh = y_at;
lh2 = wave_y_at;
ly = cur_pos.y; ly = cur_pos.y;
} }
return texture(sky, sphere_uv(dir)).rgb; return texture(sky, sphere_uv(dir)).rgb;
} }
vec3 inside_reflection_ray_first_bounce(vec3 pos, vec3 dir) { vec3 inside_reflection_ray_first_bounce(vec3 pos, vec3 dir) {
float lh = 0.0f; float lh = 0.0f;
float lh2 = 0.0f; float lh2 = 0.0f;
...@@ -231,8 +241,9 @@ vec3 inside_reflection_ray_first_bounce(vec3 pos, vec3 dir) { ...@@ -231,8 +241,9 @@ vec3 inside_reflection_ray_first_bounce(vec3 pos, vec3 dir) {
if (cur_pos.y < ground_y_at) { if (cur_pos.y < ground_y_at) {
float res_t = t - DT + DT * (lh - ly) / (cur_pos.y - ly - y_at + lh); float res_t = t - DT + DT * (lh - ly) / (cur_pos.y - ly - y_at + lh);
vec3 hit_pos = pos + res_t * dir; vec3 hit_pos = pos + res_t * dir;
float shade = exp(-res_t * ATTENUATION);
return texture(ground, tex_at(hit_pos)).rgb; return shade * texture(ground, tex_at(hit_pos)).rgb;
} else if (cur_pos.y > wave_y_at) { } else if (cur_pos.y > wave_y_at) {
float res_t = t - DT + DT * (lh2 - ly) / (cur_pos.y - ly - y_at + lh2); float res_t = t - DT + DT * (lh2 - ly) / (cur_pos.y - ly - y_at + lh2);
vec3 hit_pos = pos + res_t * dir; vec3 hit_pos = pos + res_t * dir;
...@@ -249,7 +260,9 @@ vec3 inside_reflection_ray_first_bounce(vec3 pos, vec3 dir) { ...@@ -249,7 +260,9 @@ vec3 inside_reflection_ray_first_bounce(vec3 pos, vec3 dir) {
vec3 sky_color = reflection_ray_second_bounce(cur_pos, refracted); vec3 sky_color = reflection_ray_second_bounce(cur_pos, refracted);
//vec3 sky_color = texture(sky, sphere_uv(reflected)).rgb; //vec3 sky_color = texture(sky, sphere_uv(reflected)).rgb;
vec3 water_color = inside_reflection_ray_second_bounce(cur_pos, reflected); vec3 water_color = inside_reflection_ray_second_bounce(cur_pos, reflected);
return mix(sky_color, water_color, R);
float shade = exp(-res_t * ATTENUATION);
return shade * mix(sky_color, water_color, R);
} }
...@@ -258,17 +271,9 @@ vec3 inside_reflection_ray_first_bounce(vec3 pos, vec3 dir) { ...@@ -258,17 +271,9 @@ vec3 inside_reflection_ray_first_bounce(vec3 pos, vec3 dir) {
ly = cur_pos.y; ly = cur_pos.y;
} }
return texture(sky, sphere_uv(dir)).rgb; return vec3(0);
} }
vec3 map(float v)
{
if (v > 1.0 || v < 0.0) {
return vec3(1, 0, 1);
} else {
return vec3(v);
}
}
void main(void) void main(void)
{ {
...@@ -281,7 +286,7 @@ void main(void) ...@@ -281,7 +286,7 @@ void main(void)
float R = fresnel(nnormal, view); float R = fresnel(nnormal, view);
vec3 sky_color = reflection_ray_first_bounce(world_pos + vec3(0, 0.001, 0), reflected); vec3 sky_color = reflection_ray_first_bounce(world_pos + vec3(0, 0.001, 0), reflected);
vec3 water_color = refraction_ray(world_pos, refracted); vec3 water_color = inside_reflection_ray_first_bounce(world_pos, refracted);
color = mix(water_color, sky_color, R); color = mix(water_color, sky_color, R);
} else { } else {
...@@ -292,10 +297,11 @@ void main(void) ...@@ -292,10 +297,11 @@ void main(void)
R = 1.0; R = 1.0;
} }
vec3 sky_color = reflection_ray_second_bounce(world_pos + vec3(0, 0.001, 0), refracted); float shade = exp(-length(world_pos - camera_pos) * ATTENUATION);
vec3 sky_color = reflection_ray_first_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); vec3 water_color = inside_reflection_ray_first_bounce(world_pos - vec3(0, 0.001, 0), reflected);
color = mix(sky_color, water_color, R); color = shade * mix(sky_color, water_color, R);
} }
out_Color = vec4(color, 1.0); out_Color = vec4(color, 1.0);
} }
......
...@@ -139,8 +139,8 @@ struct Scene { ...@@ -139,8 +139,8 @@ struct Scene {
} }
void draw_surface_fbo() { void draw_surface_fbo() {
glUseProgram(env_map_program);
useFBO(surf_fbo, nullptr, nullptr); useFBO(surf_fbo, nullptr, nullptr);
glUseProgram(env_map_program);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
...@@ -159,10 +159,11 @@ struct Scene { ...@@ -159,10 +159,11 @@ struct Scene {
} }
void draw_ground_fbo() { void draw_ground_fbo() {
useFBO(ground_fbo, nullptr, nullptr);
ground.use(); ground.use();
GLuint program = ground.program; GLuint program = ground.program;
useFBO(ground_fbo, nullptr, nullptr);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUniformMatrix4fv(glGetUniformLocation(program, "projectionMatrix"), 1, glUniformMatrix4fv(glGetUniformLocation(program, "projectionMatrix"), 1,
...@@ -311,6 +312,7 @@ struct Scene { ...@@ -311,6 +312,7 @@ struct Scene {
waterfall.draw(); waterfall.draw();
waterfall.move_waterfall_balls(); waterfall.move_waterfall_balls();
} }
void draw_ground() { void draw_ground() {
ground.use(); ground.use();
GLuint program = ground.program; GLuint program = ground.program;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment