From 7699573c138efd9cc285061fd07931d79e93415e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Katharina=20Kr=C3=A4mer?= <kkraemer4@uni-koblenz.de>
Date: Fri, 3 Sep 2021 17:36:37 +0200
Subject: [PATCH] [#94] worked on integrating functions in raytracing compute
 shader

---
 projects/saf_r/shaders/raytracing.comp | 178 ++++++++++++++-----------
 1 file changed, 102 insertions(+), 76 deletions(-)

diff --git a/projects/saf_r/shaders/raytracing.comp b/projects/saf_r/shaders/raytracing.comp
index 05638224..e4ab9582 100644
--- a/projects/saf_r/shaders/raytracing.comp
+++ b/projects/saf_r/shaders/raytracing.comp
@@ -4,107 +4,133 @@
 layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
 
 struct Material {
-	vec3 albedo;
-	vec3 diffuse_color;
-	float specular_exponent;
+    vec3 albedo;
+    vec3 diffuse_color;
+    float specular_exponent;
 };
 
 struct Light{
-	vec3 position;
-	float intensity;
+    vec3 position;
+    float intensity;
 };
 
 struct Sphere{
-	vec3 center;
-	float radius;
-	Material material;
+    vec3 center;
+    float radius;
+    Material material;
 };
 
 layout(std430, binding = 0) coherent buffer lights{
-	Light inLights[];
+    Light inLights[];
 };
 
 layout(std430, binding = 1) coherent buffer materials{
-	Material inMaterials[];
+    Material inMaterials[];
 };
 
 layout(std430, binding = 2) coherent buffer spheres{
-	Sphere inSpheres[];
+    Sphere inSpheres[];
 };
 
-//TODO: replace [id] with for loop over all spheres
-
 vec3 safr_reflect(const vec3 dir, const vec3 hit_center) {
-	return dir - hit_center * 2.f * (dot(dir, hit_center));
+    return dir - hit_center * 2.f * (dot(dir, hit_center));
 }
 
-bool ray_intersect(const vec3 origin, const vec3 dir, float t0, uint id){
-	vec3 L = inSpheres[id].center - origin;
-	float tca = dot(L, dir);
-	float d2 = dot(L, L) - tca * tca;
-	if (d2 > inSpheres[id].radius * inSpheres[id].radius) return false;
-	float thc = float(sqrt(inSpheres[id].radius * inSpheres[id].radius - d2));
-	t0 = tca - thc;
-	float t1 = tca + thc;
-	if (t0 < 0) t0 = t1;
-	if (t0 < 0) return false;
-	return true;
+bool ray_intersect(const vec3 origin, const vec3 dir, float t0, int id){
+        vec3 L = inSpheres[id].center - origin;
+        float tca = dot(L, dir);
+        float d2 = dot(L, L) - tca * tca;
+        if (d2 > inSpheres[id].radius * inSpheres[id].radius){
+            return false;
+        }
+        float thc = float(sqrt(inSpheres[id].radius * inSpheres[id].radius - d2));
+        t0 = tca - thc;
+        float t1 = tca + thc;
+        if (t0 < 0) {
+            t0 = t1;
+        }
+        if (t0 < 0){
+            return false;
+        }
+        return true;
 }
 
-bool sceneIntersect(const vec3 orig, const vec3 dir, vec3 hit, vec3 hit_center, Material material, uint id) {
-	float spheres_dist = 1.0 / 0.0;
-		float dist_i;
-		if (ray_intersect(orig, dir, dist_i, id) && dist_i < spheres_dist) {
-			spheres_dist = dist_i;
-			hit = orig + dir * dist_i;
-			hit_center = normalize(hit - inSpheres[id].center);
-			material = inSpheres[id].material;
-		}
-	return spheres_dist < 1000;
+int sceneIntersect(const vec3 orig, const vec3 dir, vec3 hit, vec3 hit_center, Material material) {
+    float spheres_dist = 1.0 / 0.0;
+    int index = -1;
+    for (int i = 0; i < inSpheres.length(); i++) {
+        float dist_i;
+        if (ray_intersect(orig, dir, dist_i, i) && dist_i < spheres_dist) {
+            spheres_dist = dist_i;
+            hit = orig + dir * dist_i;
+            hit_center = normalize(hit - inSpheres[i].center);
+            material = inSpheres[i].material;
+            index = i;
+            break;
+        }
+    }
+    if(spheres_dist < 1000){
+        return index;
+    }
+    return -1;
 }
 
-/*
-vec3 castRay(const vec3 orig, const vec3 dir, int depth, uint id) {
-	depth = 0;
-	vec3 point, hit_center;
-	Material material;
-
-	//return background color if a max recursive depth is reached
-	if (depth > 4 || !sceneIntersect(orig, dir, point, hit_center, material, id)) {
-		return vec3(0.2, 0.7, 0.8);
-	}
-
-	//compute recursive directions and origins of rays and then call the function
-	vec3 reflect_dir = normalize(safr_reflect(dir, hit_center));
-	vec3 reflect_orig = (dot(reflect_dir, hit_center) < 0) ? point - hit_center * float(1e-3) :
-		point + hit_center * float(1e-3); // offset the original point to avoid occlusion by the object itself
-	vec3 reflect_color = castRay(reflect_orig, reflect_dir, depth + 1, id);
-
-	//compute shadows and other light properties for the returned ray color
-	float diffuse_light_intensity = 0, specular_light_intensity = 0;
-	// TODO: https://stackoverflow.com/questions/4108313/how-do-i-find-the-length-of-an-array/4108340#4108340
-	// instead of length
-	for (int i = 0; i < inLights.length(); i++) {
-		vec3 light_dir = normalize(inLights[i].position - point);
-		float light_distance = distance(inLights[i].position, point);
-
-		vec3 shadow_orig = (dot(light_dir, hit_center) < 0) ? point - hit_center * float(1e-3) :
-			point + hit_center * float(1e-3); // checking if the point lies in the shadow of the lights[i]
-		vec3 shadow_pt, shadow_hit_center;
-		Material tmpmaterial;
-		if (sceneIntersect(shadow_orig, light_dir, shadow_pt, shadow_hit_center, tmpmaterial, id)
-			&& distance(shadow_pt, shadow_orig) < light_distance){
-			continue;
-		}
-		diffuse_light_intensity += inLights[i].intensity * max(0.f, dot(light_dir, hit_center));
-		specular_light_intensity += pow(max(0.f, dot(safr_reflect(light_dir, hit_center), dir)), material.specular_exponent) * inLights[i].intensity;
-	}
-	return material.diffuse_color * diffuse_light_intensity * material.albedo[0] +
-			vec3(1., 1., 1.) * specular_light_intensity * material.albedo[1] + reflect_color * material.albedo[2];
+
+vec3 castRay(const vec3 orig, const vec3 dir, int max_depth) {
+
+    // max depth is 5
+    int depth = 0;
+    vec3 point, hit_center;
+    Material material;
+    vec3 result = vec3(0.2, 0.7, 0.8);
+    int intersect;
+    vec3 direction = dir;
+    vec3 reflect_dir = direction;
+    vec3 reflect_orig = orig;
+
+    for(int i = 0; i < depth;i++){
+        depth++;
+        intersect = sceneIntersect(reflect_orig, reflect_dir, point, hit_center, material);
+        if(intersect != -1){
+            break;
+        }
+        //compute recursive directions and origins of rays and then call the function
+        reflect_dir = normalize(safr_reflect(direction, hit_center));
+        reflect_orig = (dot(reflect_dir, hit_center) < 0) ? point - hit_center * float(1e-3) : point + hit_center * float(1e-3);// offset the original point to avoid occlusion by the object itself
+        direction = reflect_dir;
+    }
+
+    //TODO: Warum wollten wir nochmal einene Sphere Index haben?
+    if(intersect != -1){
+        vec3 reflect_color = result;
+        for(int i = 0; i < depth; i++){
+
+            //compute shadows and other light properties for the returned ray color
+            float diffuse_light_intensity = 0, specular_light_intensity = 0;
+
+            for (int i = 0; i < inLights.length(); i++) {
+                vec3 light_dir = normalize(inLights[i].position - point);
+                float light_distance = distance(inLights[i].position, point);
+
+                vec3 shadow_orig = (dot(light_dir, hit_center) < 0) ? point - hit_center * float(1e-3) :
+                point + hit_center * float(1e-3);// checking if the point lies in the shadow of the lights[i]
+                vec3 shadow_pt, shadow_hit_center;
+                Material tmpmaterial;
+                if ((sceneIntersect(shadow_orig, light_dir, shadow_pt, shadow_hit_center, tmpmaterial) != -1)
+                && distance(shadow_pt, shadow_orig) < light_distance){
+                    continue;
+                }
+                diffuse_light_intensity += inLights[i].intensity * max(0.f, dot(light_dir, hit_center));
+                specular_light_intensity += pow(max(0.f, dot(safr_reflect(light_dir, hit_center), dir)), material.specular_exponent) * inLights[i].intensity;
+            }
+            result = material.diffuse_color * diffuse_light_intensity * material.albedo[0] +
+            vec3(1., 1., 1.) * specular_light_intensity * material.albedo[1] + reflect_color * material.albedo[2];
+        }
+    }
+    return result;
 }
-*/
+
 
 void main(){
-	int i = 42;
-	uint id = gl_GlobalInvocationID.x;
+    int i = 42;
 }
\ No newline at end of file
-- 
GitLab