From 7e727abda10ec78f2d2eede585cb2ddcfedaccce Mon Sep 17 00:00:00 2001
From: Axel Matstoms <axema990@student.liu.se>
Date: Mon, 11 Nov 2024 13:41:52 +0100
Subject: [PATCH] Add skybox reflection to surface

---
 shaders/surface.frag | 33 +++++++++++++++++++++++++++++++--
 shaders/surface.vert |  8 +++++---
 src/main.cpp         |  5 +++--
 3 files changed, 39 insertions(+), 7 deletions(-)

diff --git a/shaders/surface.frag b/shaders/surface.frag
index 7d92382..dfb45f6 100644
--- a/shaders/surface.frag
+++ b/shaders/surface.frag
@@ -1,11 +1,40 @@
 #version 150
 
-in float shade;
+in vec3 world_pos;
+in vec3 normal;
 
 out vec4 out_Color;
 
+uniform sampler2D sky;
+uniform vec3 camera_pos;
+
+const float PI = 3.1415926535897f;
+const float R0 = 0.04;
+
+vec2 sphere_uv(vec3 direction)
+{
+    float u = 0.5 + atan(direction.z, direction.x) / (2 * PI);
+    float v = 0.5 + asin(direction.y) / PI;
+
+    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);
+}
+
 void main(void)
 {
-	out_Color=vec4(shade,shade,shade,1.0);
+    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.3, 0.5);
+
+    vec3 sky_color = texture(sky, sphere_uv(reflected)).rgb;
+
+    out_Color = vec4(mix(water_color, sky_color, R), 1.0);
 }
 
diff --git a/shaders/surface.vert b/shaders/surface.vert
index a3adbe9..571f4bd 100644
--- a/shaders/surface.vert
+++ b/shaders/surface.vert
@@ -7,11 +7,13 @@ in  vec2  in_TexCoord;
 uniform mat4 projectionMatrix;
 uniform mat4 modelToWorldToView;
 
-out float shade;
+out vec3 world_pos;
+out vec3 normal;
 
 void main(void)
 {
-	shade = (mat3(modelToWorldToView)*in_Normal).z; // Fake shading
-	gl_Position=projectionMatrix*modelToWorldToView*vec4(in_Position, 1.0);
+    world_pos = in_Position;
+    normal = in_Normal;
+	gl_Position = projectionMatrix * modelToWorldToView * vec4(in_Position, 1.0);
 }
 
diff --git a/src/main.cpp b/src/main.cpp
index 51b4f34..38eb461 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -65,8 +65,6 @@ struct Scene {
         LoadTGATextureSimple("textures/sky4k.tga", &skybox_tex);
         glBindTexture(GL_TEXTURE_2D, skybox_tex);
         printError("bind texture");
-        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
-        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
         printError("tex parameteri");
     }
@@ -131,10 +129,13 @@ struct Scene {
         GLuint program = surface.program;
         glUniformMatrix4fv(glGetUniformLocation(program, "projectionMatrix"), 1, GL_TRUE, proj_matrix.m);
         glUniformMatrix4fv(glGetUniformLocation(program, "modelToWorldToView"), 1, GL_TRUE, view_matrix.m);
+        glUniform1i(glGetUniformLocation(program, "sky"), 0);
+        glUniform3f(glGetUniformLocation(program, "camera_pos"), pos.x, pos.y, pos.z);
 
         surface.draw();
     }
 
+
     void draw_ground()
     {
         ground.use();
-- 
GitLab