diff --git a/projects/saf_r/shaders/raytracing.comp b/projects/saf_r/shaders/raytracing.comp index d8ff6e684025420581ada2ce8db78fbdceb11e53..056382246dcc589abd2c9d088997f30115b0df8e 100644 --- a/projects/saf_r/shaders/raytracing.comp +++ b/projects/saf_r/shaders/raytracing.comp @@ -1,42 +1,49 @@ #version 450 core #extension GL_ARB_separate_shader_objects : enable +layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; + struct Material { vec3 albedo; vec3 diffuse_color; float specular_exponent; }; -layout(std430, binding = 0) coherent buffer Lights{ +struct Light{ vec3 position; float intensity; }; -layout(std430, binding = 1) coherent buffer Materials{ - vec3 albedo; - vec3 diffuse_color; - float specular_exponent; -}; - -layout(std430, binding = 2) coherent buffer Spheres{ +struct Sphere{ vec3 center; float radius; Material material; }; -layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; +layout(std430, binding = 0) coherent buffer lights{ + Light inLights[]; +}; + +layout(std430, binding = 1) coherent buffer materials{ + Material inMaterials[]; +}; + +layout(std430, binding = 2) coherent buffer spheres{ + 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)); } -bool ray_intersect(const vec3 origin, const vec3 dir, float t0){ - vec3 L = center - origin; +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 > radius * radius) return false; - float thc = float(sqrt(radius * radius - d2)); + 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; @@ -44,56 +51,60 @@ bool ray_intersect(const vec3 origin, const vec3 dir, float t0){ return true; } -bool sceneIntersect(const vec3 orig, const vec3 dir, const Spheres spheres[], vec3 hit, vec3 hit_center, Material material) { - float spheres_dist = std::numeric_limits<float>::max(); - for (int i = 0; i < spheres.size(); i++) { +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 (spheres[i].ray_intersect(orig, dir, dist_i) && dist_i < spheres_dist) { + 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 - spheres[i].center); - material = spheres[i].material; + hit_center = normalize(hit - inSpheres[id].center); + material = inSpheres[id].material; } - } return spheres_dist < 1000; } -vec3 castRay(const vec orig, const vec3 dir, const Spheres spheres[4], const Lights lights[3], int depth) { +/* +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, spheres, point, hit_center, 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 + //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, spheres, lights, depth + 1); + 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 + //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 < lights.size(); i++) { - vec3 light_dir = normalize(lights[i].position - point); - float light_distance = distance(lights[i].position, point); + // 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] + 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, spheres, shadow_pt, shadow_hit_center, tmpmaterial) - && distance(shadow_pt, shadow_orig) < light_distance) + if (sceneIntersect(shadow_orig, light_dir, shadow_pt, shadow_hit_center, tmpmaterial, id) + && distance(shadow_pt, shadow_orig) < light_distance){ continue; - diffuse_light_intensity += lights[i].intensity * max(0.f, dot(light_dir, hit_center)); - specular_light_intensity += powf(max(0.f, dot(safr_reflect(light_dir, hit_center), dir)), material.specular_exponent) * lights[i].intensity; + } + 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]; -} */ +} +*/ void main(){ int i = 42; + uint id = gl_GlobalInvocationID.x; } \ No newline at end of file