From e509d231597c9e8257d5fe9482ed23bf6dc90af5 Mon Sep 17 00:00:00 2001
From: Alexander Gauggel <agauggel@uni-koblenz.de>
Date: Wed, 8 Sep 2021 14:59:27 +0200
Subject: [PATCH] [#94] Corrected ray direction computation

---
 projects/saf_r/shaders/raytracing.comp | 26 +++++++++++++++++++++-----
 projects/saf_r/src/main.cpp            |  6 +++---
 2 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/projects/saf_r/shaders/raytracing.comp b/projects/saf_r/shaders/raytracing.comp
index 59a10c2a..db7a1852 100644
--- a/projects/saf_r/shaders/raytracing.comp
+++ b/projects/saf_r/shaders/raytracing.comp
@@ -160,11 +160,27 @@ vec3 castRay(const vec3 initialOrigin, const vec3 initialDirection, int max_dept
 
 vec3 computeDirection(ivec2 coord){
 
-    ivec2 outImageRes           = imageSize(outImage);
-    float fov                   = pi / 2.f;
-    float x                     =  (2 * (float(coord.x) + 0.5f) / float(outImageRes.x) - 1) * tan(fov / 2.f) * outImageRes.x / float(outImageRes.y);
-    float y                     = -(2 * (float(coord.y) + 0.5f) / float(outImageRes.y) - 1) * tan(fov / 2.f);
-    vec3 directionViewSpace     = normalize(vec3(x, y, 1));
+    ivec2 outImageRes   = imageSize(outImage);
+    float fovDegree     = 45;
+    float fov           = fovDegree * pi / 180;
+    
+    vec2 uv     = coord / vec2(outImageRes);
+    vec2 ndc    = 2 * uv - 1;
+    
+    float tanFovHalf    = tan(fov / 2.f);
+    float aspectRatio   = outImageRes.x / float(outImageRes.y);
+    float x             =  ndc.x * tanFovHalf * aspectRatio;
+    float y             = -ndc.y * tanFovHalf;
+    
+    // z component must be chosen so vector length equals 1
+    // setting z=1 and normalizing shortens x and y, changing the fov
+    // the final length must satisfy:
+    //                    1 = |v|                   <=> 
+    //                    1 = sqrt(x^2 + y^2 + z^2) <=>
+    //                    1 = x^2 + y^2 + z^2       <=>
+    //        1 - x^2 - y^2 = z^2                   <=>
+    //  sqrt(1 - x^2 - y^2) = z
+    vec3 directionViewSpace     = vec3(x, y, sqrt(1 - x*x - y*y));
     vec3 directionWorldSpace    = mat3(viewToWorld) * directionViewSpace;
     return directionWorldSpace;
 }
diff --git a/projects/saf_r/src/main.cpp b/projects/saf_r/src/main.cpp
index a6319ce3..6078bf5c 100644
--- a/projects/saf_r/src/main.cpp
+++ b/projects/saf_r/src/main.cpp
@@ -99,9 +99,9 @@ int main(int argc, const char** argv) {
 
 	//lights for the scene
 	std::vector<safrScene::Light> lights;
-	lights.push_back(safrScene::Light(glm::vec3(-20, 20, 20), 1.5));
-	lights.push_back(safrScene::Light(glm::vec3(30, 50, -25), 1.8));
-	lights.push_back(safrScene::Light(glm::vec3(30, 20, 30), 1.7));
+	lights.push_back(safrScene::Light(glm::vec3(-20, 20,  20), 1.5));
+	lights.push_back(safrScene::Light(glm::vec3(30,  50, -25), 1.8));
+	lights.push_back(safrScene::Light(glm::vec3(30,  20,  30), 1.7));
 	//create the raytracer image for rendering
 	safrScene scene;
 	vkcv::asset::Texture texData = scene.render(spheres, lights);
-- 
GitLab