diff --git a/imgui.ini b/imgui.ini index 9f12d97..a46996e 100644 --- a/imgui.ini +++ b/imgui.ini @@ -11,6 +11,14 @@ Pos=1620,226 Size=290,238 [Window][Camera] -Pos=1624,25 +Pos=1579,33 Size=279,183 +[Window][Fog] +Pos=1621,467 +Size=51,48 + +[Window][Fog settings] +Pos=1607,480 +Size=284,137 + diff --git a/includes/RT/Scene.hpp b/includes/RT/Scene.hpp index c12d9e8..825fa11 100644 --- a/includes/RT/Scene.hpp +++ b/includes/RT/Scene.hpp @@ -23,8 +23,8 @@ struct GPUObject alignas(16) glm::vec3 normal; // plane triangle - alignas(16) glm::vec3 vertex1; //quad triangle - alignas(16) glm::vec3 vertex2; //quad triangle + alignas(16) glm::vec3 vertex1;//quad triangle + alignas(16) glm::vec3 vertex2;//quad triangle float radius; // sphere @@ -43,6 +43,17 @@ struct GPUMaterial int type; }; +struct GPUVolume +{ + alignas(16) glm::vec3 sigma_a; + alignas(16) glm::vec3 sigma_s; + alignas(16) glm::vec3 sigma_t; + + float g; + + bool enabled; +}; + class Sphere; class Camera; @@ -59,6 +70,7 @@ class Scene const std::vector &getObjectData() const; std::vector &getMaterialData(); + GPUVolume &getVolume(); Camera *getCamera(void) const; GPUMaterial getMaterial(int material_index); @@ -67,6 +79,8 @@ class Scene std::vector _gpu_objects; std::vector _gpu_materials; + GPUVolume _gpu_volume; + Camera *_camera; }; diff --git a/scenes/window.rt b/scenes/window.rt index 69f78da..4b6f998 100644 --- a/scenes/window.rt +++ b/scenes/window.rt @@ -7,7 +7,7 @@ MAT 255 255 255 10.0 0.0 0.0 //light pl 0 0 0 0 1 0 1 -sp -100 50 0 50 2 +sp -10 10 -9 0.01 2 qu 0 0 0 0 6 0 18 0 0 0 qu 0 0 -18 0 6 0 18 0 0 0 diff --git a/shaders/compute.glsl b/shaders/compute.glsl index 8430e8b..6d9ef86 100644 --- a/shaders/compute.glsl +++ b/shaders/compute.glsl @@ -32,14 +32,23 @@ struct GPUMaterial struct GPUCamera { - mat4 view_matrix; - vec3 position; + mat4 view_matrix; + vec3 position; + + float aperture_size; + float focus_distance; + float fov; - float aperture_size; - float focus_distance; - float fov; + int bounce; +}; - int bounce; +struct GPUVolume +{ + vec3 sigma_a; // absorption coefficient + vec3 sigma_s; // scattering coefficient + vec3 sigma_t; // extinction coefficient + float g; // phase function parameter + bool enabled; }; layout(std430, binding = 1) buffer ObjectBuffer @@ -52,11 +61,16 @@ layout(std430, binding = 2) buffer MaterialBuffer GPUMaterial materials[]; }; -layout(std140) uniform CameraData +layout(std140, binding = 0) uniform CameraData { GPUCamera camera; }; +layout(std140, binding = 1) uniform VolumeData +{ + GPUVolume volume; +}; + uniform int u_objectsNum; uniform vec2 u_resolution; uniform int u_pixelisation; @@ -148,31 +162,25 @@ vec3 pathtrace(Ray ray, inout uint rng_state) vec3 transmittance = vec3(1.0); - VolumeProperties volume; - volume.sigma_a = vec3(0.0001); - volume.sigma_s = vec3(0.0800); - volume.sigma_t = volume.sigma_a + volume.sigma_s; - volume.g = 1.; - for (int i = 0; i < camera.bounce; i++) { hitInfo hit = traceRay(ray); float t_scatter = 0.0; - if (atmosScatter(volume, hit, t_scatter, rng_state)) + if (volume.enabled && atmosScatter(hit, t_scatter, rng_state)) { - calculateVolumetricLight(t_scatter, volume, ray, color, light, transmittance, rng_state); + calculateVolumetricLight(t_scatter, ray, color, light, transmittance, rng_state); continue; } if (hit.obj_index == -1) { light += transmittance * GetEnvironmentLight(ray); - // light += vec3(135 / 255.0f, 206 / 255.0f, 235 / 255.0f); //ambient color break; } - transmittance *= exp(-volume.sigma_t * hit.t); + if (volume.enabled) + transmittance *= exp(-volume.sigma_t * hit.t); GPUObject obj = objects[hit.obj_index]; GPUMaterial mat = materials[obj.mat_index]; diff --git a/shaders/light.glsl b/shaders/light.glsl index 49e5bc8..41f886f 100644 --- a/shaders/light.glsl +++ b/shaders/light.glsl @@ -1,9 +1,9 @@ vec3 GetEnvironmentLight(Ray ray) { - vec3 sun_pos = vec3(-1., 1.0, 0.); + vec3 sun_pos = vec3(-0.5, 0.5, 0.5); float SunFocus = 1.5; - float SunIntensity = 0.5; + float SunIntensity = 1.; vec3 GroundColour = vec3(0.5, 0.5, 0.5); vec3 SkyColourHorizon = vec3(135 / 255.0f, 206 / 255.0f, 235 / 255.0f); @@ -29,7 +29,7 @@ vec3 sampleLights(vec3 position) GPUObject obj = objects[i]; GPUMaterial mat = materials[obj.mat_index]; - if (obj.type == 0 && mat.emission > 0.0) + if (mat.emission > 0.0) { vec3 light_dir = normalize(obj.position - position); float light_dist = length(obj.position - position); diff --git a/shaders/volumetric.glsl b/shaders/volumetric.glsl index 239517d..ad8c814 100644 --- a/shaders/volumetric.glsl +++ b/shaders/volumetric.glsl @@ -1,11 +1,4 @@ -struct VolumeProperties { - vec3 sigma_a; // absorption coefficient - vec3 sigma_s; // scattering coefficient - vec3 sigma_t; // extinction coefficient - float g; // phase function parameter -}; - float sampleHG(float g, inout uint rng_state) { if (abs(g) < 0.001) @@ -36,17 +29,18 @@ vec3 sampleDirection(vec3 forward, float cos_theta, inout uint rng_state) ); } -bool atmosScatter(VolumeProperties volume, hitInfo hit, inout float t_scatter, inout uint rng_state) +bool atmosScatter(hitInfo hit, inout float t_scatter, inout uint rng_state) { - t_scatter = -log(randomValue(rng_state)) / volume.sigma_t.x; + float density = volume.sigma_t.x; + t_scatter = -log(randomValue(rng_state)) / density; - return (t_scatter < hit.t && volume.sigma_t.x > 0.0); + return (t_scatter < hit.t && density > 0.0); } -void calculateVolumetricLight(float t_scatter, VolumeProperties volume, inout Ray ray, inout vec3 color, inout vec3 light, inout vec3 transmittance, inout uint rng_state) +void calculateVolumetricLight(float t_scatter, inout Ray ray, inout vec3 color, inout vec3 light, inout vec3 transmittance, inout uint rng_state) { vec3 scatter_pos = ray.origin + ray.direction * t_scatter; - + transmittance *= exp(-volume.sigma_t * t_scatter); color *= volume.sigma_s / volume.sigma_t; diff --git a/srcs/RT.cpp b/srcs/RT.cpp index 2b5ac52..bcb0b45 100644 --- a/srcs/RT.cpp +++ b/srcs/RT.cpp @@ -50,6 +50,12 @@ int main(int argc, char **argv) glBufferData(GL_UNIFORM_BUFFER, sizeof(GPUCamera), nullptr, GL_DYNAMIC_DRAW); glBindBufferBase(GL_UNIFORM_BUFFER, 0, cameraUBO); + GLuint volumeUBO; + glGenBuffers(1, &volumeUBO); + glBindBuffer(GL_UNIFORM_BUFFER, volumeUBO); + glBufferData(GL_UNIFORM_BUFFER, sizeof(GPUVolume), nullptr, GL_STATIC_DRAW); + glBindBufferBase(GL_UNIFORM_BUFFER, 1, volumeUBO); + shader.attach(); Vertex vertices[3] = {{{-1.0f, -1.0f}, {0.0f, 0.0f}},{{3.0f, -1.0f}, {2.0f, 0.0f}},{{-1.0f, 3.0f}, {0.0f, 2.0f}}}; @@ -70,6 +76,9 @@ int main(int argc, char **argv) glBindBuffer(GL_UNIFORM_BUFFER, cameraUBO); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(GPUCamera), &camera_data); + glBindBuffer(GL_UNIFORM_BUFFER, volumeUBO); + glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(GPUVolume), &scene.getVolume()); + shader.set_int("u_frameCount", window.getFrameCount()); shader.set_int("u_objectsNum", object_data.size()); shader.set_int("u_pixelisation", window.getPixelisation()); diff --git a/srcs/class/Scene.cpp b/srcs/class/Scene.cpp index 9710ebb..d4a24e1 100644 --- a/srcs/class/Scene.cpp +++ b/srcs/class/Scene.cpp @@ -15,6 +15,12 @@ Scene::Scene() { _camera = new Camera(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), -90.0f, 0.0f); + + _gpu_volume.enabled = false; + _gpu_volume.sigma_a = glm::vec3(0.0001f); + _gpu_volume.sigma_s = glm::vec3(0.0800f); + _gpu_volume.sigma_t = _gpu_volume.sigma_a + _gpu_volume.sigma_s; + _gpu_volume.g = 0.9f; } Scene::~Scene() @@ -143,6 +149,11 @@ std::vector& Scene::getMaterialData() return (_gpu_materials); } +GPUVolume &Scene::getVolume() +{ + return (_gpu_volume); +} + Camera *Scene::getCamera(void) const { return (_camera); diff --git a/srcs/class/Window.cpp b/srcs/class/Window.cpp index 297ca34..73d274b 100644 --- a/srcs/class/Window.cpp +++ b/srcs/class/Window.cpp @@ -215,6 +215,29 @@ void Window::imGuiRender() ImGui::End(); + ImGui::Begin("Fog settings"); + + has_changed |= ImGui::Checkbox("Enable", &_scene->getVolume().enabled); + ImGui::Separator(); + + if (ImGui::SliderFloat("Absorption", &_scene->getVolume().sigma_a.x, 0., 0.1)) + { + _scene->getVolume().sigma_a = glm::vec3(_scene->getVolume().sigma_a.x); + _scene->getVolume().sigma_t = _scene->getVolume().sigma_a + _scene->getVolume().sigma_s; + has_changed = true; + } + if (ImGui::SliderFloat("Scattering", &_scene->getVolume().sigma_s.x, 0., 0.5)) + { + _scene->getVolume().sigma_s = glm::vec3(_scene->getVolume().sigma_s.x); + _scene->getVolume().sigma_t = _scene->getVolume().sigma_a + _scene->getVolume().sigma_s; + has_changed = true; + } + if (ImGui::SliderFloat("G", &_scene->getVolume().g, 0., 1.)) + has_changed = true; + + ImGui::End(); + + ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());