diff --git a/includes/RT/Object.hpp b/includes/RT/Object.hpp index 3530f1f..7a2061b 100644 --- a/includes/RT/Object.hpp +++ b/includes/RT/Object.hpp @@ -21,6 +21,7 @@ typedef struct s_Material float emission; float roughness; float metallic; + int type; } Material; class Object diff --git a/includes/RT/Scene.hpp b/includes/RT/Scene.hpp index 98b4900..9b7be5e 100644 --- a/includes/RT/Scene.hpp +++ b/includes/RT/Scene.hpp @@ -37,6 +37,7 @@ struct GPUMaterial float emission; float roughness; float metallic; + int type; }; class Sphere; diff --git a/scenes/colored_light.rt b/scenes/colored_light.rt index a8d53c4..3d4e45b 100644 --- a/scenes/colored_light.rt +++ b/scenes/colored_light.rt @@ -1,9 +1,10 @@ +CAM 0 -0.5 4 MAT 255 010 010 5 0.0 1.0 MAT 010 255 010 5 0.0 1.0 MAT 010 010 255 5 0.0 1.0 -MAT 255 255 255 0 1.0 1.0 +MAT 255 255 255 0 1.7 1.0 1 MAT 255 255 255 0 0.0 1.0 diff --git a/shaders/compute.glsl b/shaders/compute.glsl index cb1b0d5..6ad09bc 100644 --- a/shaders/compute.glsl +++ b/shaders/compute.glsl @@ -24,6 +24,7 @@ struct GPUMaterial float emission; // 4 float roughness; // 4 float metallic; // 4 + int type; // 4 }; layout(std430, binding = 1) buffer ObjectBuffer diff --git a/shaders/scatter.glsl b/shaders/scatter.glsl index 3eda948..75f23d6 100644 --- a/shaders/scatter.glsl +++ b/shaders/scatter.glsl @@ -1,20 +1,68 @@ -Ray newRay(hitInfo hit, Ray ray, inout uint rng_state) +Ray lambertRay(hitInfo hit, Ray ray, GPUMaterial mat, uint rng_state) { - GPUObject obj; - GPUMaterial mat; - Ray new_ray; - - obj = objects[hit.obj_index]; - mat = materials[obj.mat_index]; - vec3 diffuse_dir = normalize(hit.normal + randomDirection(rng_state)); vec3 specular_dir = reflect(ray.direction, hit.normal); bool is_specular = (mat.metallic >= randomValue(rng_state)); - new_ray.origin = hit.position + hit.normal * 0.001; - new_ray.direction = mix(diffuse_dir, specular_dir, mat.roughness * float(is_specular)); + ray.origin = hit.position + hit.normal * 0.001; + ray.direction = mix(diffuse_dir, specular_dir, mat.roughness * float(is_specular)); - return (new_ray); + return (ray); +} + +// Ray dieletricRay(hitInfo hit, Ray ray, GPUMaterial mat) +// { +// float refraction_ratio; +// vec3 unit_direction; + +// refraction_ratio = 1.0f / mat.roughness; //mat.roughness = refraction (saving memory) + +// if (dot(ray.direction, hit.normal) > 0.0f) +// { +// hit.normal = -hit.normal; +// refraction_ratio = mat.roughness; +// } + +// unit_direction = normalize(ray.direction); +// ray.origin = hit.position + hit.normal * -0.0001f; +// ray.direction = refract(unit_direction, hit.normal, refraction_ratio); + +// return (ray); +// } + +Ray dieletricRay(hitInfo hit, Ray ray, GPUMaterial mat) +{ + float refraction_ratio; + vec3 unit_direction; + + refraction_ratio = 1.0f / mat.roughness; //mat.roughness = refraction (saving memory) + + float d = dot(ray.direction, hit.normal); + hit.normal *= sign(d); + + if (d > 0.0f) + refraction_ratio = mat.roughness; + + unit_direction = normalize(ray.direction); + ray.origin = hit.position + hit.normal * 0.0001f; + ray.direction = refract(unit_direction, -hit.normal, refraction_ratio); + + return (ray); +} + +Ray newRay(hitInfo hit, Ray ray, uint rng_state) +{ + GPUObject obj; + GPUMaterial mat; + + obj = objects[hit.obj_index]; + mat = materials[obj.mat_index]; + + if (mat.type == 0) + return (lambertRay(hit, ray, mat, rng_state)); + else if (mat.type == 1) + return (dieletricRay(hit, ray, mat)); + return (ray); } \ No newline at end of file diff --git a/srcs/class/Scene.cpp b/srcs/class/Scene.cpp index cfe5488..3005871 100644 --- a/srcs/class/Scene.cpp +++ b/srcs/class/Scene.cpp @@ -108,6 +108,7 @@ void Scene::updateGPUData() gpu_mat.emission = material->emission; gpu_mat.roughness = material->roughness; gpu_mat.metallic = material->metallic; + gpu_mat.type = material->type; _gpu_materials.push_back(gpu_mat); } diff --git a/srcs/class/SceneParser.cpp b/srcs/class/SceneParser.cpp index 886bca5..c28c11f 100644 --- a/srcs/class/SceneParser.cpp +++ b/srcs/class/SceneParser.cpp @@ -45,17 +45,23 @@ void SceneParser::parseMaterial(std::stringstream &line) float emission; float roughness; float metallic; + int type; + Material *mat; if (!(line >> r >> g >> b >> emission >> roughness >> metallic)) throw std::runtime_error("Material: Missing material properties"); + if (!(line >> type)) + type = 0; + mat = new Material; mat->color = glm::vec3(r / 255.0f, g / 255.0f, b / 255.0f); mat->emission = emission; mat->roughness = roughness; mat->metallic = metallic; + mat->type = type; _scene->addMaterial(mat); } diff --git a/srcs/class/Shader.cpp b/srcs/class/Shader.cpp index 262905b..d93c2ee 100644 --- a/srcs/class/Shader.cpp +++ b/srcs/class/Shader.cpp @@ -48,13 +48,26 @@ const char *loadFileWithIncludes(const std::string& path) } +void printWithLineNumbers(const char *str) +{ + if (!str) + return; + + std::istringstream stream(str); + std::string line; + int lineNumber = 1; + + while (std::getline(stream, line)) + std::cout << lineNumber++ << ": " << line << std::endl; +} + Shader::Shader(std::string vertexPath, std::string fragmentPath, std::string computePath) { const char *vertexCode = loadFileWithIncludes(vertexPath); const char *fragmentCode = loadFileWithIncludes(fragmentPath); const char *computeCode = loadFileWithIncludes(computePath); - std::cout << computeCode << std::endl; + printWithLineNumbers(computeCode); _vertex = glCreateShader(GL_VERTEX_SHADER);