diff --git a/Makefile b/Makefile index 4cb0d8d..6350ea1 100644 --- a/Makefile +++ b/Makefile @@ -46,9 +46,10 @@ IMGUI_SRCS := imgui/imgui.cpp \ imgui/imgui_impl_glfw.cpp \ imgui/imgui_impl_opengl3.cpp -ALL_SRCS := $(IMGUI_SRCS) \ - RT.cpp gl.cpp \ +ALL_SRCS := $(IMGUI_SRCS) gl.cpp \ + RT.cpp RT_utils.cpp \ class/Window.cpp \ + class/ShaderProgram.cpp \ class/Shader.cpp \ class/Camera.cpp \ class/Scene.cpp \ diff --git a/imgui.ini b/imgui.ini index fe07d99..c6c3f9e 100644 --- a/imgui.ini +++ b/imgui.ini @@ -29,6 +29,6 @@ Pos=1556,610 Size=284,382 [Window][Settings] -Pos=1582,12 +Pos=1616,42 Size=340,941 diff --git a/includes/RT.hpp b/includes/RT.hpp index c4d695f..87f7736 100644 --- a/includes/RT.hpp +++ b/includes/RT.hpp @@ -31,6 +31,7 @@ # include "imgui/imgui_impl_glfw.h" # include "imgui/imgui_impl_opengl3.h" +# include # include # include # include @@ -58,10 +59,12 @@ struct Vertex { # include "objects/Portal.hpp" # include "objects/Cylinder.hpp" +# include "Buffer.hpp" # include "Arguments.hpp" # include "Camera.hpp" # include "Renderer.hpp" # include "Window.hpp" +# include "ShaderProgram.hpp" # include "Shader.hpp" # include "Scene.hpp" # include "SceneParser.hpp" diff --git a/includes/RT/Buffer.hpp b/includes/RT/Buffer.hpp new file mode 100644 index 0000000..1cbcadc --- /dev/null +++ b/includes/RT/Buffer.hpp @@ -0,0 +1,54 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* Buffer.hpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: TheRed +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/12 23:45:57 by TheRed #+# #+# */ +/* Updated: 2025/02/12 23:45:57 by TheRed ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef BUFFER_HPP +# define BUFFER_HPP + +# include "RT.hpp" + +class Buffer +{ + public: + enum Type + { + SSBO, + UBO + }; + + Buffer(Type type, GLuint binding_point, GLuint size, const void *data) + : _type(type), _binding_point(binding_point) + { + glGenBuffers(1, &_buffer_id); + glBindBuffer(_type == SSBO ? GL_SHADER_STORAGE_BUFFER : GL_UNIFORM_BUFFER, _buffer_id); + glBufferData(_type == SSBO ? GL_SHADER_STORAGE_BUFFER : GL_UNIFORM_BUFFER, size, data, GL_DYNAMIC_DRAW); + glBindBufferBase(_type == SSBO ? GL_SHADER_STORAGE_BUFFER : GL_UNIFORM_BUFFER, _binding_point, _buffer_id); + glBindBuffer(_type == SSBO ? GL_SHADER_STORAGE_BUFFER : GL_UNIFORM_BUFFER, 0); + } + + ~Buffer() { glDeleteBuffers(1, &_buffer_id); } + + void update(const void *data, GLuint size) + { + glBindBuffer(_type == SSBO ? GL_SHADER_STORAGE_BUFFER : GL_UNIFORM_BUFFER, _buffer_id); + glBufferSubData(_type == SSBO ? GL_SHADER_STORAGE_BUFFER : GL_UNIFORM_BUFFER, 0, size, data); + glBindBuffer(_type == SSBO ? GL_SHADER_STORAGE_BUFFER : GL_UNIFORM_BUFFER, 0); + } + + GLuint getID() const { return _buffer_id; } + + private: + Type _type; + GLuint _buffer_id; + GLuint _binding_point; +}; + +#endif \ No newline at end of file diff --git a/includes/RT/Renderer.hpp b/includes/RT/Renderer.hpp index eb8f5ba..9a6a21f 100644 --- a/includes/RT/Renderer.hpp +++ b/includes/RT/Renderer.hpp @@ -38,7 +38,7 @@ class Renderer public: Renderer(Scene *scene, Window *win, Arguments &args); - void update(Shader &shader); + void update(GLuint &texture); void renderImgui(void); int rendering(void) const; @@ -66,7 +66,7 @@ class Renderer void initRender(); void fillGoodCodecList(std::vector &lst); void updateAvailableCodecs(int mode, AVCodecID id); - void addImageToRender(Shader &shader); + void addImageToRender(GLuint &texture); void endRender(void); diff --git a/includes/RT/Shader.hpp b/includes/RT/Shader.hpp index a76edec..717538e 100644 --- a/includes/RT/Shader.hpp +++ b/includes/RT/Shader.hpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/13 18:10:10 by TheRed #+# #+# */ -/* Updated: 2025/02/02 19:42:13 by ycontre ### ########.fr */ +/* Updated: 2025/02/13 19:10:11 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,56 +18,30 @@ class Shader { public: - Shader(std::string vertexPath, std::string fragmentPath, std::string computePath, std::string denoisingPath); + Shader(GLenum type, const std::string &file_path); ~Shader(void); - void attach(void); - void setupVertexBuffer(); - void drawTriangles(); - - void flipOutputDenoising(bool pass); - - // void setBool(const std::string &name, bool value) const; - void set_int(const std::string &name, int value) const; - void set_float(const std::string &name, float value) const; - void set_vec2(const std::string &name, const glm::vec2 &value) const; - void set_vec3(const std::string &name, const glm::vec3 &value) const; - // void setVec4(const std::string &name, const RT::Vec4f &value) const; - void set_mat4(const std::string &name, const glm::mat4 &value) const; - - void set_textures(std::vector texture_ids, std::vector emissive_texture_ids); - - GLuint getProgram(void) const; - GLuint getProgramCompute(void) const; - GLuint getProgramComputeDenoising(void) const; - - GLuint getNormalTexture(void) const; - GLuint getPositionTexture(void) const; - - std::vector getOutputImage(void); + void compile(void); + void reload(); + + bool hasChanged(); + + void setDefine(const std::string &name, const std::string &value); + + GLuint getShader(void) const; + const std::string &getFilePath(void) const; private: - GLuint _screen_VAO, _screen_VBO; + void checkCompileErrors(); - GLuint _program; - GLuint _program_compute; - GLuint _program_denoising; + std::map _defines; - GLuint _output_texture; - GLuint _accumulation_texture; - GLuint _denoising_texture; - GLuint _normal_texture; - GLuint _position_texture; + GLenum _type; + GLuint _shader_id; + std::string _file_path; - GLuint _vertex; - GLuint _fragment; - GLuint _compute; - GLuint _denoising; - - size_t _size; - - void checkCompileErrors(unsigned int shader); + std::unordered_map _files_timestamps; }; #endif diff --git a/includes/RT/ShaderProgram.hpp b/includes/RT/ShaderProgram.hpp new file mode 100644 index 0000000..9d1314d --- /dev/null +++ b/includes/RT/ShaderProgram.hpp @@ -0,0 +1,52 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ShaderProgram.hpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ycontre +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/12 22:22:17 by TheRed #+# #+# */ +/* Updated: 2025/02/13 19:10:15 by ycontre ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef SHADERPROGRAM_HPP +# define SHADERPROGRAM_HPP + +# include "RT.hpp" + +class ShaderProgram +{ + public: + ShaderProgram(); + ~ShaderProgram(void); + + void attachShader(Shader *shader); + void clearShaders(); + + void link(void); + + void use(void); + void dispathCompute(GLuint x, GLuint y, GLuint z); + + void bindImageTexture(GLuint texture_id, GLuint unit, GLenum access, GLenum format) const; + + void watchForChanges(void); + void reloadShaders(void); + + void set_int(const std::string &name, int value) const; + void set_float(const std::string &name, float value) const; + void set_vec2(const std::string &name, const glm::vec2 &value) const; + + void set_textures(std::map> texture_ids); + + void set_define(const std::string &name, const std::string &value); + + GLuint getProgram(void) const; + + private: + std::vector _shaders; + GLuint _program; +}; + +#endif diff --git a/includes/RT/Window.hpp b/includes/RT/Window.hpp index e139ddf..8bd7088 100644 --- a/includes/RT/Window.hpp +++ b/includes/RT/Window.hpp @@ -16,6 +16,7 @@ # include "RT.hpp" class Scene; +class ShaderProgram; class Window { @@ -35,7 +36,7 @@ class Window static void mouseButtonCallback(GLFWwindow *window, int button, int action, int mods); void imGuiNewFrame(); - void imGuiRender(); + void imGuiRender(ShaderProgram &raytracing_program); GLFWwindow *getWindow(void) const; float getFps(void) const; @@ -47,7 +48,7 @@ class Window void setFrameCount(int nb); - void rendererUpdate(Shader &shader); + void rendererUpdate(GLuint &texture); private: GLFWwindow *_window; Scene *_scene; diff --git a/includes/RT/objects/Portal.hpp b/includes/RT/objects/Portal.hpp index 3d438cc..ebc6464 100644 --- a/includes/RT/objects/Portal.hpp +++ b/includes/RT/objects/Portal.hpp @@ -52,7 +52,6 @@ class Portal : public Object _rotation = glm::mat3(right, up, forward); _normal = forward * (_invert_normal ? -1.0f : 1.0f); - std::cout << glm::to_string(_normal) << std::endl; _linked_portal = -1; _mat_index = mat_index; diff --git a/shaders/compute.glsl b/shaders/compute.glsl index c712094..9bbd2cd 100644 --- a/shaders/compute.glsl +++ b/shaders/compute.glsl @@ -1,278 +1,5 @@ -#version 430 core - -layout(local_size_x = 16, local_size_y = 16) in; -layout(binding = 0, rgba32f) uniform image2D output_image; -layout(binding = 1, rgba32f) uniform image2D accumulation_image; - -layout(binding = 3, rgba32f) uniform image2D normal_texture; -layout(binding = 4, rgba32f) uniform image2D position_texture; - -struct GPUObject { - mat4 rotation; - - vec3 position; // 12 + 4 - - vec3 normal; // 12 + 4 - - vec3 vertex1; // 12 + 4 - vec3 vertex2; // 12 + 4 - - float radius; // 4 - - int mat_index; // 4 - int type; // 4 -}; - -struct GPUTriangle -{ - vec3 position; - vec3 vertex1; - vec3 vertex2; - vec3 normal; - - vec2 texture_vertex1; - vec2 texture_vertex2; - vec2 texture_vertex3; - - int mat_index; -}; - -struct GPUMaterial -{ - vec3 color; // 12 + 4 - float emission; // 4 - float roughness; // 4 - float metallic; // 4 - float refraction; // 4 - int type; // 4 - int texture_index; // 4 - int emission_texture_index; // 4 -}; - -struct GPUCamera -{ - mat4 view_matrix; - vec3 position; - - float aperture_size; - float focus_distance; - float fov; - - int bounce; -}; - -struct GPUVolume -{ - vec3 sigma_a; // absorption coefficient - vec3 sigma_s; // scattering coefficient - vec3 sigma_t; // extinction coefficient - float g; // phase function parameter - int enabled; -}; - -struct GPUBvhData -{ - mat4 transform; - mat4 inv_transform; - vec3 offset; - float scale; - - int bvh_start_index; - int triangle_start_index; -}; - -struct GPUBvh -{ - vec3 min; - vec3 max; - - int index; - int primitive_count; -}; - -layout(std430, binding = 1) buffer ObjectBuffer -{ - GPUObject objects[]; -}; - -layout(std430, binding = 2) buffer TriangleBuffer -{ - GPUTriangle triangles[]; -}; - -layout(std430, binding = 3) buffer BvhDataBuffer -{ - GPUBvhData BvhData[]; -}; - -layout(std430, binding = 4) buffer BvhBuffer -{ - GPUBvh Bvh[]; -}; - -layout(std430, binding = 5) buffer MaterialBuffer -{ - GPUMaterial materials[]; -}; - -layout(std430, binding = 6) buffer LightsBuffer -{ - int lightsIndex[]; -}; - - - -layout(std140, binding = 0) uniform CameraData -{ - GPUCamera camera; -}; - -layout(std140, binding = 1) uniform VolumeData -{ - GPUVolume volume; -}; - - -uniform int u_objectsNum; -uniform int u_bvhNum; -uniform int u_lightsNum; -uniform vec2 u_resolution; -uniform int u_pixelisation; -uniform int u_frameCount; -uniform float u_time; - -struct Ray -{ - vec3 origin; - vec3 direction; - vec3 inv_direction; -}; - -struct hitInfo -{ - float t; - float last_t; - vec3 normal; - vec3 position; - - int obj_index; - int mat_index; - int obj_type; - - float u; - float v; -}; - -#include "shaders/random.glsl" -#include "shaders/intersect.glsl" -#include "shaders/scatter.glsl" -#include "shaders/light.glsl" -#include "shaders/volumetric.glsl" -#include "shaders/trace.glsl" - -vec3 pathtrace(Ray ray, inout uint rng_state) -{ - vec3 color = vec3(1.0); - vec3 light = vec3(0.0); - vec3 transmittance = vec3(1.0); - - for (int i = 0; i < camera.bounce; i++) - { - hitInfo hit = traceRay(ray); - - #if 0 - float t_scatter = 0.0; - bool scatter_valid = bool(volume.enabled != 0 && atmosScatter(hit, t_scatter, rng_state)); - if (scatter_valid) - { - calculateVolumetricLight(t_scatter, ray, color, light, transmittance, rng_state); - continue ; - } - #endif - - if (hit.obj_index == -1) - { - light += transmittance * GetEnvironmentLight(ray); - break; - } - - if (i == 0) - { - imageStore(normal_texture, ivec2(gl_GlobalInvocationID.xy), vec4(normalize(hit.normal), 1.0)); - imageStore(position_texture, ivec2(gl_GlobalInvocationID.xy), vec4(normalize(hit.position), 1.0)); - } - - float p = max(color.r, max(color.g, color.b)); - if (randomValue(rng_state) >= p) break; - color /= max(p, 0.001); - - GPUMaterial mat = materials[hit.mat_index]; - calculateLightColor(mat, hit, color, light, rng_state); - - if (mat.emission > 0.0 && mat.emission_texture_index == -1) - break; - - ray = newRay(hit, ray, rng_state); - ray.inv_direction = 1.0 / ray.direction; - } - - return color * light; -} - -Ray initRay(vec2 uv, inout uint rng_state) -{ - float focal_length = 1.0 / tan(radians(camera.fov) / 2.0); - - vec3 origin = camera.position; - vec3 view_space_ray = normalize(vec3(uv.x, uv.y, -focal_length)); - vec3 ray_direction = normalize((inverse(camera.view_matrix) * vec4(view_space_ray, 0.0)).xyz); - - vec3 right = vec3(camera.view_matrix[0][0], camera.view_matrix[1][0], camera.view_matrix[2][0]); - vec3 up = vec3(camera.view_matrix[0][1], camera.view_matrix[1][1], camera.view_matrix[2][1]); - - vec3 focal_point = origin + ray_direction * camera.focus_distance; - - float r = sqrt(randomValue(rng_state)); - float theta = 2.0 * M_PI * randomValue(rng_state); - vec2 lens_point = camera.aperture_size * r * vec2(cos(theta), sin(theta)); - - origin += right * lens_point.x + up * lens_point.y; - ray_direction = normalize(focal_point - origin); - - return (Ray(origin, ray_direction, 1.0 / ray_direction)); -} - -void main() -{ - ivec2 pixel_coords = ivec2(gl_GlobalInvocationID.xy); - if (pixel_coords.x >= int(u_resolution.x) || pixel_coords.y >= int(u_resolution.y)) - return; - - if (u_pixelisation != 1 && (uint(pixel_coords.x) % u_pixelisation != 0 || uint(pixel_coords.y) % u_pixelisation != 0)) - return; - - uint rng_state = uint(u_resolution.x) * uint(pixel_coords.y) + uint(pixel_coords.x); - rng_state = rng_state + u_frameCount * 719393; - - vec2 jitter = randomPointInCircle(rng_state) * 1; - - vec2 uv = ((vec2(pixel_coords) + jitter) / u_resolution) * 2.0 - 1.0; - uv.x *= u_resolution.x / u_resolution.y; - - Ray ray = initRay(uv, rng_state); - vec3 color = pathtrace(ray, rng_state); - - float blend = 1.0 / float(u_frameCount + 1); - vec4 accum = imageLoad(accumulation_image, pixel_coords); - accum.rgb = mix(accum.rgb, color, blend); - accum.a = 1.0; - - imageStore(accumulation_image, pixel_coords, accum); - - vec4 final_color = vec4(sqrt(accum.r), sqrt(accum.g), sqrt(accum.b), accum.a); - - for (int y = 0; y < u_pixelisation; y++) - for (int x = 0; x < u_pixelisation; x++) - imageStore(output_image, pixel_coords + ivec2(x, y), final_color); -} - +#if SHADER_DEBUG +#include "shaders/debug.glsl" +#else +#include "shaders/raytracing.glsl" +#endif \ No newline at end of file diff --git a/shaders/debug.glsl b/shaders/debug.glsl index 7edbaf4..4003a4e 100644 --- a/shaders/debug.glsl +++ b/shaders/debug.glsl @@ -1,8 +1,5 @@ -#version 430 core - layout(local_size_x = 16, local_size_y = 16) in; layout(binding = 0, rgba32f) uniform image2D output_image; -layout(binding = 1, rgba32f) uniform image2D accumulation_image; struct GPUCamera { @@ -121,6 +118,7 @@ struct hitInfo vec3 position; int obj_index; int mat_index; + int obj_type; float u; float v; @@ -134,21 +132,31 @@ struct Stats #include "shaders/intersect.glsl" -int traceRay(Ray ray) +hitInfo traceScene(Ray ray) { - int num_hit; + hitInfo hit; - num_hit = 0; - for (int i = 0; i < u_objectsNum; i++) - { - GPUObject obj = objects[i]; + hit.t = 1e30; + hit.obj_index = -1; + + for (int i = 0; i < u_objectsNum; i++) + { + GPUObject obj = objects[i]; - hitInfo temp_hit; - if (intersect(ray, obj, temp_hit)) - num_hit++; - } + hitInfo temp_hit; + + if (intersect(ray, obj, temp_hit) && temp_hit.t < hit.t) + { + hit.t = temp_hit.t; + hit.obj_index = i; + hit.obj_type = obj.type; + hit.mat_index = obj.mat_index; + hit.position = temp_hit.position; + hit.normal = temp_hit.normal; + } + } - return (num_hit); + return (hit); } hitInfo traceBVH(Ray ray, GPUBvhData bvh_data, inout Stats stats) @@ -238,16 +246,27 @@ hitInfo traverseBVHs(Ray ray, inout Stats stats) hitInfo temp_hit = traceBVH(transformedRay, BvhData[i], stats); - temp_hit.t = temp_hit.t / bvh_data.scale; - - if (temp_hit.t < hit.t) + float transformed_t = temp_hit.t / bvh_data.scale; + if (transformed_t < hit.t) { - hit.t = temp_hit.t; + GPUTriangle triangle = triangles[temp_hit.obj_index]; + + hit.u = temp_hit.u; + hit.v = temp_hit.v; + hit.t = transformed_t; hit.obj_index = temp_hit.obj_index; - hit.normal = normalize(inverseTransformMatrix * temp_hit.normal); + hit.mat_index = triangle.mat_index; + + vec3 position = transformedRay.origin + transformedRay.direction * temp_hit.t; + hit.position = inverseTransformMatrix * position + bvh_data.offset; + + vec3 based_normal = triangle.normal * sign(-dot(transformedRay.direction, triangle.normal)); + hit.normal = normalize(inverseTransformMatrix * based_normal); } } + hit.obj_type = 3; + return (hit); } @@ -263,13 +282,24 @@ Ray initRay(vec2 uv) return (Ray(origin, ray_direction, (1.0 / ray_direction))); } +hitInfo trace(Ray ray, inout Stats stats) +{ + hitInfo hitBVH; + hitInfo hitScene; + hitInfo hit; + + hitBVH = traverseBVHs(ray, stats); + hitScene = traceScene(ray); + return (hitBVH.t < hitScene.t ? hitBVH : hitScene); +} + vec3 debugColor(vec2 uv) { Ray ray = initRay(uv); Stats stats = Stats(0, 0); - hitInfo hit = traverseBVHs(ray, stats); - + hitInfo hit = trace(ray, stats); + float box_display = float(stats.box_count) / float(debug.box_treshold); float triangle_display = float(stats.triangle_count) / float(debug.triangle_treshold); @@ -294,7 +324,7 @@ void main() vec2 uv = ((vec2(pixel_coords)) / u_resolution) * 2.0 - 1.0;; uv.x *= u_resolution.x / u_resolution.y; - + vec3 color = debugColor(uv); imageStore(output_image, pixel_coords, vec4(color, 1.)); diff --git a/shaders/denoising.glsl b/shaders/denoising.glsl index 1f94f62..0e5525d 100644 --- a/shaders/denoising.glsl +++ b/shaders/denoising.glsl @@ -1,11 +1,9 @@ -#version 430 core - layout(local_size_x = 16, local_size_y = 16) in; layout(binding = 0, rgba32f) uniform image2D read_texture; layout(binding = 2, rgba32f) uniform image2D write_texture; -layout(binding = 3, rgba32f) uniform image2D position_texture; -layout(binding = 4, rgba32f) uniform image2D normal_texture; +layout(binding = 3, rgba32f) uniform image2D normal_texture; +layout(binding = 4, rgba32f) uniform image2D position_texture; uniform vec2 u_resolution; @@ -20,7 +18,7 @@ void main() ivec2 pixel_coords = ivec2(gl_GlobalInvocationID.xy); if (pixel_coords.x >= int(u_resolution.x) || pixel_coords.y >= int(u_resolution.y)) return; - + int holes = int(pow(2, u_pass)); vec4 color_center = imageLoad(read_texture, pixel_coords); @@ -32,6 +30,7 @@ void main() float totalWeight = 0.; vec4 color = vec4(vec3(0.), 1.0); + for (int x = -2; x <= 2; x++) { for (int y = -2; y <= 2; y++) diff --git a/shaders/frag.frag b/shaders/frag.frag index 017073a..fd4524e 100644 --- a/shaders/frag.frag +++ b/shaders/frag.frag @@ -1,9 +1,9 @@ -#version 430 core in vec2 TexCoords; out vec4 FragColor; uniform sampler2D screenTexture; void main() { + // FragColor = imageLoad(screenTexture, ivec2(gl_FragCoord.xy)); FragColor = texture(screenTexture, TexCoords); } \ No newline at end of file diff --git a/shaders/light.glsl b/shaders/light.glsl index 6c0852b..4a3f1b8 100644 --- a/shaders/light.glsl +++ b/shaders/light.glsl @@ -2,7 +2,7 @@ hitInfo traceRay(inout Ray ray); vec3 GetEnvironmentLight(Ray ray) { - return vec3(0.); + // return vec3(0.); vec3 sun_pos = vec3(-0.5, 0.5, 0.5); float SunFocus = 1.5; float SunIntensity = 1.; diff --git a/shaders/raytracing.glsl b/shaders/raytracing.glsl new file mode 100644 index 0000000..a0366bd --- /dev/null +++ b/shaders/raytracing.glsl @@ -0,0 +1,277 @@ + +layout(local_size_x = 16, local_size_y = 16) in; +layout(binding = 0, rgba32f) uniform image2D output_image; +layout(binding = 1, rgba32f) uniform image2D accumulation_image; + +layout(binding = 3, rgba32f) uniform image2D normal_texture; +layout(binding = 4, rgba32f) uniform image2D position_texture; + +struct GPUObject { + mat4 rotation; + + vec3 position; // 12 + 4 + + vec3 normal; // 12 + 4 + + vec3 vertex1; // 12 + 4 + vec3 vertex2; // 12 + 4 + + float radius; // 4 + + int mat_index; // 4 + int type; // 4 +}; + +struct GPUTriangle +{ + vec3 position; + vec3 vertex1; + vec3 vertex2; + vec3 normal; + + vec2 texture_vertex1; + vec2 texture_vertex2; + vec2 texture_vertex3; + + int mat_index; +}; + +struct GPUMaterial +{ + vec3 color; // 12 + 4 + float emission; // 4 + float roughness; // 4 + float metallic; // 4 + float refraction; // 4 + int type; // 4 + int texture_index; // 4 + int emission_texture_index; // 4 +}; + +struct GPUCamera +{ + mat4 view_matrix; + vec3 position; + + float aperture_size; + float focus_distance; + float fov; + + int bounce; +}; + +struct GPUVolume +{ + vec3 sigma_a; // absorption coefficient + vec3 sigma_s; // scattering coefficient + vec3 sigma_t; // extinction coefficient + float g; // phase function parameter + int enabled; +}; + +struct GPUBvhData +{ + mat4 transform; + mat4 inv_transform; + vec3 offset; + float scale; + + int bvh_start_index; + int triangle_start_index; +}; + +struct GPUBvh +{ + vec3 min; + vec3 max; + + int index; + int primitive_count; +}; + +layout(std430, binding = 1) buffer ObjectBuffer +{ + GPUObject objects[]; +}; + +layout(std430, binding = 2) buffer TriangleBuffer +{ + GPUTriangle triangles[]; +}; + +layout(std430, binding = 3) buffer BvhDataBuffer +{ + GPUBvhData BvhData[]; +}; + +layout(std430, binding = 4) buffer BvhBuffer +{ + GPUBvh Bvh[]; +}; + +layout(std430, binding = 5) buffer MaterialBuffer +{ + GPUMaterial materials[]; +}; + +layout(std430, binding = 6) buffer LightsBuffer +{ + int lightsIndex[]; +}; + + + +layout(std140, binding = 0) uniform CameraData +{ + GPUCamera camera; +}; + +layout(std140, binding = 1) uniform VolumeData +{ + GPUVolume volume; +}; + + +uniform int u_objectsNum; +uniform int u_bvhNum; +uniform int u_lightsNum; +uniform vec2 u_resolution; +uniform int u_pixelisation; +uniform int u_frameCount; +uniform float u_time; + +struct Ray +{ + vec3 origin; + vec3 direction; + vec3 inv_direction; +}; + +struct hitInfo +{ + float t; + float last_t; + vec3 normal; + vec3 position; + + int obj_index; + int mat_index; + int obj_type; + + float u; + float v; +}; + +#include "shaders/random.glsl" +#include "shaders/intersect.glsl" +#include "shaders/scatter.glsl" +#include "shaders/light.glsl" +#include "shaders/volumetric.glsl" +#include "shaders/trace.glsl" + +vec3 pathtrace(Ray ray, inout uint rng_state) +{ + vec3 color = vec3(1.0); + vec3 light = vec3(0.0); + vec3 transmittance = vec3(1.0); + + for (int i = 0; i < camera.bounce; i++) + { + hitInfo hit = traceRay(ray); + + #if SHADER_FOG + float t_scatter = 0.0; + bool scatter_valid = bool(volume.enabled != 0 && atmosScatter(hit, t_scatter, rng_state)); + if (scatter_valid) + { + calculateVolumetricLight(t_scatter, ray, color, light, transmittance, rng_state); + continue ; + } + #endif + + if (hit.obj_index == -1) + { + light += transmittance * GetEnvironmentLight(ray); + break; + } + + if (i == 0) + { + imageStore(normal_texture, ivec2(gl_GlobalInvocationID.xy), vec4(normalize(hit.normal), 1.0)); + imageStore(position_texture, ivec2(gl_GlobalInvocationID.xy), vec4(normalize(hit.position), 1.0)); + } + + float p = max(color.r, max(color.g, color.b)); + if (randomValue(rng_state) >= p) break; + color /= max(p, 0.001); + + GPUMaterial mat = materials[hit.mat_index]; + calculateLightColor(mat, hit, color, light, rng_state); + + if (mat.emission > 0.0 && mat.emission_texture_index == -1) + break; + + ray = newRay(hit, ray, rng_state); + ray.inv_direction = 1.0 / ray.direction; + } + + return color * light; +} + +Ray initRay(vec2 uv, inout uint rng_state) +{ + float focal_length = 1.0 / tan(radians(camera.fov) / 2.0); + + vec3 origin = camera.position; + vec3 view_space_ray = normalize(vec3(uv.x, uv.y, -focal_length)); + vec3 ray_direction = normalize((inverse(camera.view_matrix) * vec4(view_space_ray, 0.0)).xyz); + + vec3 right = vec3(camera.view_matrix[0][0], camera.view_matrix[1][0], camera.view_matrix[2][0]); + vec3 up = vec3(camera.view_matrix[0][1], camera.view_matrix[1][1], camera.view_matrix[2][1]); + + vec3 focal_point = origin + ray_direction * camera.focus_distance; + + float r = sqrt(randomValue(rng_state)); + float theta = 2.0 * M_PI * randomValue(rng_state); + vec2 lens_point = camera.aperture_size * r * vec2(cos(theta), sin(theta)); + + origin += right * lens_point.x + up * lens_point.y; + ray_direction = normalize(focal_point - origin); + + return (Ray(origin, ray_direction, 1.0 / ray_direction)); +} + +void main() +{ + ivec2 pixel_coords = ivec2(gl_GlobalInvocationID.xy); + if (pixel_coords.x >= int(u_resolution.x) || pixel_coords.y >= int(u_resolution.y)) + return; + + if (u_pixelisation != 1 && (uint(pixel_coords.x) % u_pixelisation != 0 || uint(pixel_coords.y) % u_pixelisation != 0)) + return; + + uint rng_state = uint(u_resolution.x) * uint(pixel_coords.y) + uint(pixel_coords.x); + rng_state = rng_state + u_frameCount * 719393; + + vec2 jitter = randomPointInCircle(rng_state) * 1; + + vec2 uv = ((vec2(pixel_coords) + jitter) / u_resolution) * 2.0 - 1.0; + uv.x *= u_resolution.x / u_resolution.y; + + Ray ray = initRay(uv, rng_state); + vec3 color = pathtrace(ray, rng_state); + + float blend = 1.0 / float(u_frameCount + 1); + vec4 accum = imageLoad(accumulation_image, pixel_coords); + accum.rgb = mix(accum.rgb, color, blend); + accum.a = 1.0; + + imageStore(accumulation_image, pixel_coords, accum); + + vec4 final_color = vec4(sqrt(accum.r), sqrt(accum.g), sqrt(accum.b), accum.a); + + for (int y = 0; y < u_pixelisation; y++) + for (int x = 0; x < u_pixelisation; x++) + imageStore(output_image, pixel_coords + ivec2(x, y), final_color); +} + diff --git a/shaders/vertex.vert b/shaders/vertex.vert index 4c038e7..078500c 100644 --- a/shaders/vertex.vert +++ b/shaders/vertex.vert @@ -1,4 +1,3 @@ -#version 430 core layout(location = 0) in vec2 aPos; layout(location = 1) in vec2 aTexCoord; diff --git a/srcs/RT.cpp b/srcs/RT.cpp index 6b7e9f8..5475386 100644 --- a/srcs/RT.cpp +++ b/srcs/RT.cpp @@ -6,178 +6,101 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/27 14:51:49 by TheRed #+# #+# */ -/* Updated: 2025/02/13 14:26:18 by tomoron ### ########.fr */ +/* Updated: 2025/02/14 18:26:34 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ #include "RT.hpp" +void setupScreenTriangle(GLuint *VAO); +void drawScreenTriangle(GLuint VAO, GLuint output_texture, GLuint program); + +std::vector generateTextures(unsigned int textures_count); + +std::vector createDataOnGPU(Scene &scene); +void updateDataOnGPU(Scene &scene, std::vector buffers); + +void shaderDenoise(ShaderProgram &denoising_program, GPUDenoise &denoise, std::vector textures); + int main(int argc, char **argv) { Arguments args(argc, argv); if (args.error()) return (1); + Scene scene(args.getSceneName()); if (scene.fail()) return (1); + Window window(&scene, WIDTH, HEIGHT, "RT_GPU", 0, args); - Shader shader("shaders/vertex.vert", "shaders/frag.frag", "shaders/compute.glsl", "shaders/denoising.glsl"); - // Shader shader("shaders/vertex.vert", "shaders/frag.frag", "shaders/debug.glsl"); + GLuint VAO; + setupScreenTriangle(&VAO); - GLint max_gpu_size; - glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_gpu_size); + std::vector textures = generateTextures(5); - const std::vector &object_data = scene.getObjectData(); - const std::vector &triangle_data = scene.getTriangleData(); - const std::vector &bvh_nodes = scene.getBvh(); - const std::vector &bvh_data = scene.getBvhData(); - const std::vector &material_data = scene.getMaterialData(); + ShaderProgram raytracing_program; + Shader compute = Shader(GL_COMPUTE_SHADER, "shaders/compute.glsl"); + raytracing_program.attachShader(&compute); + raytracing_program.link(); - std::cout << "Sending " << object_data.size() << " objects for " << \ - object_data.size() * sizeof(GPUObject) + \ - triangle_data.size() * sizeof(GPUTriangle) + \ - bvh_nodes.size() * sizeof(GPUBvh) + \ - material_data.size() * sizeof(GPUMaterial) \ - << " / " << max_gpu_size << " bytes" << std::endl; + ShaderProgram denoising_program; + Shader denoise = Shader(GL_COMPUTE_SHADER, "shaders/denoising.glsl"); + denoising_program.attachShader(&denoise); + denoising_program.link(); - GLuint objectSSBO; - glGenBuffers(1, &objectSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, objectSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GPUObject) * object_data.size(), object_data.data(), GL_STATIC_DRAW); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, objectSSBO); + ShaderProgram render_program; + Shader vertex = Shader(GL_VERTEX_SHADER, "shaders/vertex.vert"); + Shader frag = Shader(GL_FRAGMENT_SHADER, "shaders/frag.frag"); + render_program.attachShader(&vertex); + render_program.attachShader(&frag); + render_program.link(); - GLuint trianglesSSBO; - glGenBuffers(1, &trianglesSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, trianglesSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GPUTriangle) * triangle_data.size(), triangle_data.data(), GL_STATIC_DRAW); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, trianglesSSBO); + std::vector buffers = createDataOnGPU(scene); - GLuint bvh_nodesSSBO; - glGenBuffers(1, &bvh_nodesSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, bvh_nodesSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GPUBvhData) * bvh_data.size(), bvh_data.data(), GL_STATIC_DRAW); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, bvh_nodesSSBO); - - GLuint bvhSSBO; - glGenBuffers(1, &bvhSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, bvhSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GPUBvh) * bvh_nodes.size(), bvh_nodes.data(), GL_STATIC_DRAW); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, bvhSSBO); - - GLuint materialSSBO; - glGenBuffers(1, &materialSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, materialSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GPUMaterial) * material_data.size(), nullptr, GL_STATIC_DRAW); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, materialSSBO); - - GLuint lightSSBO; - glGenBuffers(1, &lightSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, lightSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, scene.getGPULights().size() * sizeof(int), nullptr, GL_STATIC_DRAW); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, lightSSBO); - - GLuint cameraUBO; - glGenBuffers(1, &cameraUBO); - glBindBuffer(GL_UNIFORM_BUFFER, cameraUBO); - 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); - - GLuint debugUBO; - glGenBuffers(1, &debugUBO); - glBindBuffer(GL_UNIFORM_BUFFER, debugUBO); - glBufferData(GL_UNIFORM_BUFFER, sizeof(GPUDebug), nullptr, GL_STATIC_DRAW); - glBindBufferBase(GL_UNIFORM_BUFFER, 2, debugUBO); - if (!scene.loadTextures()) - return (1); - - shader.attach(); - - shader.setupVertexBuffer(); + return (-1); while (!window.shouldClose()) { window.updateDeltaTime(); - glUseProgram(shader.getProgramCompute()); + updateDataOnGPU(scene, buffers); + window.rendererUpdate(textures[0]); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, materialSSBO); - glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, material_data.size() * sizeof(GPUMaterial), material_data.data()); - - std::set gpu_lights = scene.getGPULights(); - std::vector gpu_lights_array(gpu_lights.begin(), gpu_lights.end()); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, lightSSBO); - glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, gpu_lights_array.size() * sizeof(int), gpu_lights_array.data()); - window.rendererUpdate(shader); - - GPUCamera camera_data = scene.getCamera()->getGPUData(); - - 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()); - - glBindBuffer(GL_UNIFORM_BUFFER, debugUBO); - glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(GPUDebug), &scene.getDebug()); - - shader.set_int("u_frameCount", window.getFrameCount()); - shader.set_int("u_objectsNum", object_data.size()); - shader.set_int("u_bvhNum", bvh_data.size()); - shader.set_int("u_lightsNum", gpu_lights.size()); - shader.set_int("u_pixelisation", window.getPixelisation()); - shader.set_float("u_time", (float)(glfwGetTime())); - shader.set_vec2("u_resolution", glm::vec2(WIDTH, HEIGHT)); - - shader.set_textures(scene.getTextureIDs(), scene.getEmissionTextureIDs()); - - glDispatchCompute((WIDTH + 15) / 16, (HEIGHT + 15) / 16, 1); - glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); - - GPUDenoise denoise = scene.getDenoise(); - if (denoise.enabled) - { - glUseProgram(shader.getProgramComputeDenoising()); - - glUniform2fv(glGetUniformLocation(shader.getProgramComputeDenoising(), "u_resolution"), 1, glm::value_ptr(glm::vec2(WIDTH, HEIGHT))); - glUniform1f(glGetUniformLocation(shader.getProgramComputeDenoising(), "u_c_phi"), denoise.c_phi); - glUniform1f(glGetUniformLocation(shader.getProgramComputeDenoising(), "u_p_phi"), denoise.p_phi); - glUniform1f(glGetUniformLocation(shader.getProgramComputeDenoising(), "u_n_phi"), denoise.n_phi); - - for (int pass = 0; pass < denoise.pass ; ++pass) - { - shader.flipOutputDenoising(pass % 2 == 0); - - glUniform1i(glGetUniformLocation(shader.getProgramComputeDenoising(), "u_pass"), pass); - - glDispatchCompute((WIDTH + 15) / 16, (HEIGHT + 15) / 16, 1); - glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); - } - shader.flipOutputDenoising(true); - } - - glClear(GL_COLOR_BUFFER_BIT); + + raytracing_program.use(); + raytracing_program.set_int("u_frameCount", window.getFrameCount()); + raytracing_program.set_int("u_objectsNum", scene.getObjectData().size()); + raytracing_program.set_int("u_bvhNum", scene.getBvhData().size()); + raytracing_program.set_int("u_lightsNum", scene.getGPULights().size()); + raytracing_program.set_int("u_pixelisation", window.getPixelisation()); + raytracing_program.set_float("u_time", (float)(glfwGetTime())); + raytracing_program.set_vec2("u_resolution", glm::vec2(WIDTH, HEIGHT)); + + std::map> object_textures; + object_textures["textures"] = scene.getTextureIDs(); + object_textures["emissive_textures"] = scene.getEmissionTextureIDs(); + raytracing_program.set_textures(object_textures); + + raytracing_program.dispathCompute((WIDTH + 15) / 16, (HEIGHT + 15) / 16, 1); + + if (scene.getDenoise().enabled) + shaderDenoise(denoising_program, scene.getDenoise(), textures); window.imGuiNewFrame(); - glUseProgram(shader.getProgram()); - shader.drawTriangles(); + render_program.use(); + drawScreenTriangle(VAO, textures[0], render_program.getProgram()); - window.imGuiRender(); + window.imGuiRender(raytracing_program); window.display(); window.pollEvents(); - glClearTexImage(shader.getNormalTexture(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glClearTexImage(shader.getPositionTexture(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glClearTexImage(textures[3], 0, GL_RGBA, GL_FLOAT, nullptr); + glClearTexImage(textures[4], 0, GL_RGBA, GL_FLOAT, nullptr); } ImGui_ImplOpenGL3_Shutdown(); diff --git a/srcs/RT_utils.cpp b/srcs/RT_utils.cpp new file mode 100644 index 0000000..3acd9f6 --- /dev/null +++ b/srcs/RT_utils.cpp @@ -0,0 +1,144 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* RT_utils.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: TheRed +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/12 23:21:09 by TheRed #+# #+# */ +/* Updated: 2025/02/12 23:21:09 by TheRed ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "RT.hpp" + +void setupScreenTriangle(GLuint *VAO) +{ + GLuint VBO; + + 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}}}; + size_t size = sizeof(vertices) / sizeof(Vertex) / 3; // size 1 + + glGenVertexArrays(1, VAO); + glBindVertexArray(*VAO); + + glGenBuffers(1, &VBO); + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, size * 3 * sizeof(Vertex), vertices, GL_STATIC_DRAW); + + // Position attribute + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0); + glEnableVertexAttribArray(0); + + // Texture coordinate attribute + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, texCoord)); + glEnableVertexAttribArray(1); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); +} + +void drawScreenTriangle(GLuint VAO, GLuint output_texture, GLuint program) +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, output_texture); + glUniform1i(glGetUniformLocation(program, "screenTexture"), 0); + + glBindVertexArray(VAO); + glDrawArrays(GL_TRIANGLES, 0, 1 * 3); // size 1 +} + +std::vector generateTextures(unsigned int textures_count) +{ + std::vector textures(textures_count); + + glGenTextures(textures_count, textures.data()); + for (unsigned int i = 0; i < textures_count; ++i) + { + glBindTexture(GL_TEXTURE_2D, textures[i]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, WIDTH, HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL); + glBindImageTexture(i, textures[i], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); + } + return (textures); +} + +std::vector createDataOnGPU(Scene &scene) +{ + GLint max_gpu_size; + glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_gpu_size); + + const std::vector &object_data = scene.getObjectData(); + const std::vector &triangle_data = scene.getTriangleData(); + const std::vector &bvh_nodes = scene.getBvh(); + const std::vector &bvh_data = scene.getBvhData(); + const std::vector &material_data = scene.getMaterialData(); + + std::cout << "Sending " << object_data.size() << " objects for " << \ + object_data.size() * sizeof(GPUObject) + \ + triangle_data.size() * sizeof(GPUTriangle) + \ + bvh_nodes.size() * sizeof(GPUBvh) + \ + material_data.size() * sizeof(GPUMaterial) \ + << " / " << max_gpu_size << " bytes" << std::endl; + + std::vector buffers; + + buffers.push_back(new Buffer(Buffer::Type::SSBO, 1, sizeof(GPUObject) * object_data.size(), object_data.data())); + buffers.push_back(new Buffer(Buffer::Type::SSBO, 2, sizeof(GPUTriangle) * triangle_data.size(), triangle_data.data())); + buffers.push_back(new Buffer(Buffer::Type::SSBO, 3, sizeof(GPUBvhData) * bvh_data.size(), bvh_data.data())); + buffers.push_back(new Buffer(Buffer::Type::SSBO, 4, sizeof(GPUBvh) * bvh_nodes.size(), bvh_nodes.data())); + buffers.push_back(new Buffer(Buffer::Type::SSBO, 5, sizeof(GPUMaterial) * material_data.size(), nullptr)); + buffers.push_back(new Buffer(Buffer::Type::SSBO, 6, scene.getGPULights().size() * sizeof(int), nullptr)); + + buffers.push_back(new Buffer(Buffer::Type::UBO, 0, sizeof(GPUCamera), nullptr)); + buffers.push_back(new Buffer(Buffer::Type::UBO, 1, sizeof(GPUVolume), nullptr)); + buffers.push_back(new Buffer(Buffer::Type::UBO, 2, sizeof(GPUDebug), nullptr)); + + return (buffers); +} + +void updateDataOnGPU(Scene &scene, std::vector buffers) +{ + const std::vector &material_data = scene.getMaterialData(); + const std::set &gpu_lights = scene.getGPULights(); + std::vector gpu_lights_array(gpu_lights.begin(), gpu_lights.end()); + + buffers[4]->update(material_data.data(), sizeof(GPUMaterial) * material_data.size()); + buffers[5]->update(gpu_lights_array.data(), gpu_lights.size() * sizeof(int)); + + GPUCamera camera_data = scene.getCamera()->getGPUData(); + buffers[6]->update(&camera_data, sizeof(GPUCamera)); + + buffers[7]->update(&scene.getVolume(), sizeof(GPUVolume)); + buffers[8]->update(&scene.getDebug(), sizeof(GPUDebug)); +} + + +void shaderDenoise(ShaderProgram &denoising_program, GPUDenoise &denoise, std::vector textures) +{ + denoising_program.use(); + + denoising_program.set_vec2("u_resolution", glm::vec2(WIDTH, HEIGHT)); + denoising_program.set_float("u_c_phi", denoise.c_phi); + denoising_program.set_float("u_p_phi", denoise.p_phi); + denoising_program.set_float("u_n_phi", denoise.n_phi); + + int output_texture = 0; + int denoising_texture = 2; + + for (int pass = 0; pass < denoise.pass ; ++pass) + { + glBindImageTexture(0, textures[output_texture], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); + glBindImageTexture(2, textures[denoising_texture], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); + + denoising_program.set_int("u_pass", pass); + denoising_program.dispathCompute((WIDTH + 15) / 16, (HEIGHT + 15) / 16, 1); + + std::swap(output_texture, denoising_texture); + } + + glBindImageTexture(0, textures[output_texture], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); +} \ No newline at end of file diff --git a/srcs/class/Renderer.cpp b/srcs/class/Renderer.cpp index 2416a4d..4a8d50e 100644 --- a/srcs/class/Renderer.cpp +++ b/srcs/class/Renderer.cpp @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* Renderer.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: tomoron +#+ +:+ +#+ */ +/* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/22 16:34:53 by tomoron #+# #+# */ -/* Updated: 2025/02/07 23:24:53 by tomoron ### ########.fr */ +/* Updated: 2025/02/13 19:03:34 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ @@ -300,14 +300,17 @@ void Renderer::initRender(void) SWS_BILINEAR, nullptr, nullptr, nullptr); } -void Renderer::addImageToRender(Shader &shader) +void Renderer::addImageToRender(GLuint &texture) { - std::vector image; + std::vector image(WIDTH * HEIGHT * 4); + AVPacket *pkt; long int videoFrameOffset; long int outputImageOffset; - - image = shader.getOutputImage(); + + glBindTexture(GL_TEXTURE_2D, texture); + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, image.data()); + glBindTexture(GL_TEXTURE_2D, 0); for (int x = 0; x < WIDTH; x++) { @@ -400,7 +403,7 @@ void Renderer::addPoint(float time) _path.insert(pos, newPoint); } -void Renderer::update(Shader &shader) +void Renderer::update(GLuint &texture) { double curTime; @@ -421,7 +424,7 @@ void Renderer::update(Shader &shader) if(!_testMode) { - addImageToRender(shader); + addImageToRender(texture); _frameCount++; } makeMovement(curTime - _curSplitStart, curTime); diff --git a/srcs/class/Scene.cpp b/srcs/class/Scene.cpp index fbb4a56..c8677fa 100644 --- a/srcs/class/Scene.cpp +++ b/srcs/class/Scene.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/23 18:29:41 by ycontre #+# #+# */ -/* Updated: 2025/02/04 16:43:33 by tomoron ### ########.fr */ +/* Updated: 2025/02/13 18:13:58 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/srcs/class/Shader.cpp b/srcs/class/Shader.cpp index c8ceb8a..365dff4 100644 --- a/srcs/class/Shader.cpp +++ b/srcs/class/Shader.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/13 20:21:13 by ycontre #+# #+# */ -/* Updated: 2025/02/06 19:48:22 by ycontre ### ########.fr */ +/* Updated: 2025/02/13 18:59:18 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,12 +16,12 @@ #include #include -const char *loadFileWithIncludes(const std::string& path) +std::stringstream loadFileWithIncludes(const std::string& path, std::vector &included_files) { std::ifstream file(path); if (!file.is_open()) { std::cerr << "Failed to open file: " << path << std::endl; - return ""; + return std::stringstream(); } std::stringstream fileContent; @@ -36,7 +36,9 @@ const char *loadFileWithIncludes(const std::string& path) if (start != std::string::npos && end != std::string::npos && end > start) { std::string includePath = line.substr(start + 1, end - start - 1); - std::string includedContent = loadFileWithIncludes(includePath); + included_files.push_back(includePath); + + std::string includedContent = loadFileWithIncludes(includePath, included_files).str(); fileContent << includedContent << "\n"; } } @@ -44,7 +46,7 @@ const char *loadFileWithIncludes(const std::string& path) fileContent << line << "\n"; } - return strdup(fileContent.str().c_str()); + return (fileContent); } @@ -61,263 +63,86 @@ void printWithLineNumbers(const char *str) std::cout << lineNumber++ << ": " << line << std::endl; } -Shader::Shader(std::string vertexPath, std::string fragmentPath, std::string computePath, std::string denoisingPath) +Shader::Shader(GLenum type, const std::string &file_path) { - const char *vertexCode = loadFileWithIncludes(vertexPath); - const char *fragmentCode = loadFileWithIncludes(fragmentPath); - const char *computeCode = loadFileWithIncludes(computePath); - const char *denoisingCode = loadFileWithIncludes(denoisingPath); + _type = type; + _file_path = file_path; + _shader_id = 0; - // printWithLineNumbers(computeCode); - - _vertex = glCreateShader(GL_VERTEX_SHADER); - - glShaderSource(_vertex, 1, &vertexCode, NULL); - glCompileShader(_vertex); - - checkCompileErrors(_vertex); - - _fragment = glCreateShader(GL_FRAGMENT_SHADER); - - glShaderSource(_fragment, 1, &fragmentCode, NULL); - glCompileShader(_fragment); - - checkCompileErrors(_fragment); - - _compute = glCreateShader(GL_COMPUTE_SHADER); - - glShaderSource(_compute, 1, &computeCode, NULL); - glCompileShader(_compute); - - checkCompileErrors(_compute); - - _denoising = glCreateShader(GL_COMPUTE_SHADER); - - glShaderSource(_denoising, 1, &denoisingCode, NULL); - glCompileShader(_denoising); - - checkCompileErrors(_denoising); + this->compile(); } Shader::~Shader(void) { - glDeleteShader(_vertex); - glDeleteShader(_fragment); - glDeleteShader(_compute); - glDeleteProgram(_program); - glDeleteProgram(_program_compute); - glDeleteProgram(_denoising); } -void Shader::attach(void) +void Shader::compile() { - _program = glCreateProgram(); - _program_compute = glCreateProgram(); - _program_denoising = glCreateProgram(); + _shader_id = glCreateShader(_type); + + std::vector files; + files.push_back(_file_path); - glEnable(GL_DEBUG_OUTPUT); - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); - glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE); + std::string shader_code = loadFileWithIncludes(_file_path, files).str(); + for (auto &file : files) + _files_timestamps[file] = std::filesystem::last_write_time(file); - glAttachShader(_program, _vertex); - glAttachShader(_program, _fragment); + for (auto &define : _defines) + shader_code = "#define SHADER_" + define.first + " " + define.second + "\n" + shader_code; + shader_code = "#version 430\n" + shader_code; - glAttachShader(_program_compute, _compute); + const char *shader_code_cstr = shader_code.c_str(); + // printWithLineNumbers(shader_code_cstr); + + glShaderSource(_shader_id, 1, &shader_code_cstr, NULL); + glCompileShader(_shader_id); - glAttachShader(_program_denoising, _denoising); - - glLinkProgram(_program); - glLinkProgram(_program_compute); - glLinkProgram(_program_denoising); - - glGenTextures(1, &_output_texture); - glBindTexture(GL_TEXTURE_2D, _output_texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, WIDTH, HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL); - glBindImageTexture(0, _output_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); - - glGenTextures(1, &_accumulation_texture); - glBindTexture(GL_TEXTURE_2D, _accumulation_texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, WIDTH, HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL); - glBindImageTexture(1, _accumulation_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); - - glGenTextures(1, &_denoising_texture); - glBindTexture(GL_TEXTURE_2D, _denoising_texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, WIDTH, HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL); - glBindImageTexture(2, _denoising_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); - - glGenTextures(1, &_normal_texture); - glBindTexture(GL_TEXTURE_2D, _normal_texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, WIDTH, HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL); - glBindImageTexture(3, _normal_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); - - glGenTextures(1, &_position_texture); - glBindTexture(GL_TEXTURE_2D, _position_texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, WIDTH, HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL); - glBindImageTexture(4, _position_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); + this->checkCompileErrors(); } -void Shader::checkCompileErrors(GLuint shader) +bool Shader::hasChanged() +{ + for (auto &file : _files_timestamps) + { + if (std::filesystem::last_write_time(file.first) != file.second) + { + _files_timestamps[file.first] = std::filesystem::last_write_time(file.first); + return (true); + } + } + return (false); +} + +void Shader::reload() +{ + glDeleteShader(_shader_id); + this->compile(); +} + +void Shader::checkCompileErrors() { GLint success; GLchar infoLog[512]; - glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + glGetShaderiv(_shader_id, GL_COMPILE_STATUS, &success); if (!success) { - glGetShaderInfoLog(shader, 512, NULL, infoLog); + glGetShaderInfoLog(_shader_id, 512, NULL, infoLog); std::cout << "ERROR::SHADER::COMPILATION_FAILED\n" << infoLog << std::endl; } } -void Shader::setupVertexBuffer() +void Shader::setDefine(const std::string &name, const std::string &value) { - - 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}}}; - _size = sizeof(vertices) / sizeof(Vertex) / 3; - - glGenVertexArrays(1, &_screen_VAO); - glGenBuffers(1, &_screen_VBO); - - glBindVertexArray(_screen_VAO); - - glBindBuffer(GL_ARRAY_BUFFER, _screen_VBO); - glBufferData(GL_ARRAY_BUFFER, _size * 3 * sizeof(Vertex), vertices, GL_STATIC_DRAW); - - // Position attribute - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0); - glEnableVertexAttribArray(0); - - // Texture coordinate attribute - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, texCoord)); - glEnableVertexAttribArray(1); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); + _defines[name] = value; } -void Shader::drawTriangles() +GLuint Shader::getShader(void) const { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, _output_texture); - glUniform1i(glGetUniformLocation(_program, "screenTexture"), 0); - - glBindVertexArray(_screen_VAO); - glDrawArrays(GL_TRIANGLES, 0, _size * 3); + return (_shader_id); } -void Shader::flipOutputDenoising(bool pass) +const std::string &Shader::getFilePath(void) const { - if (pass) - { - glBindImageTexture(0, _output_texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); - glBindImageTexture(2, _denoising_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); - } - else - { - glBindImageTexture(0, _denoising_texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); - glBindImageTexture(2, _output_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); - } -} - -void Shader::set_int(const std::string &name, int value) const -{ - glUniform1i(glGetUniformLocation(_program_compute, name.c_str()), value); -} -void Shader::set_float(const std::string &name, float value) const -{ - glUniform1f(glGetUniformLocation(_program_compute, name.c_str()), value); -} -void Shader::set_vec2(const std::string &name, const glm::vec2 &value) const -{ - glUniform2fv(glGetUniformLocation(_program_compute, name.c_str()), 1, glm::value_ptr(value)); -} -void Shader::set_vec3(const std::string &name, const glm::vec3 &value) const -{ - glUniform3fv(glGetUniformLocation(_program_compute, name.c_str()), 1, glm::value_ptr(value)); -} -void Shader::set_mat4(const std::string &name, const glm::mat4 &value) const -{ - glUniformMatrix4fv(glGetUniformLocation(_program_compute, name.c_str()), 1, GL_FALSE, glm::value_ptr(value)); -} - -void Shader::set_textures(std::vector texture_ids, std::vector emissive_texture_ids) -{ - for (size_t i = 0; i < texture_ids.size(); i++) - { - glActiveTexture(GL_TEXTURE0 + i); - glBindTexture(GL_TEXTURE_2D, texture_ids[i]); - - std::string uniform_name = "textures[" + std::to_string(i) + "]"; - // std::cout << "Loading texture " << uniform_name << " at unit " << i << std::endl; - glUniform1i(glGetUniformLocation(_program_compute, uniform_name.c_str()), i); - } - - size_t start_texture = texture_ids.size(); - - for (size_t i = 0; i < emissive_texture_ids.size(); i++) - { - GLuint currentUnit = start_texture + i; - - glActiveTexture(GL_TEXTURE0 + currentUnit); - glBindTexture(GL_TEXTURE_2D, emissive_texture_ids[i]); - std::string uniform_name = "emissive_textures[" + std::to_string(i) + "]"; - // std::cout << "Loading emissive texture " << uniform_name << " (" << emissive_texture_ids[i] << ") at unit " << currentUnit << std::endl; - glUniform1i(glGetUniformLocation(_program_compute, uniform_name.c_str()), currentUnit); - } -} - - -GLuint Shader::getProgram(void) const -{ - return (_program); -} - -GLuint Shader::getProgramCompute(void) const -{ - return (_program_compute); -} - -GLuint Shader::getProgramComputeDenoising(void) const -{ - return (_program_denoising); -} - -GLuint Shader::getNormalTexture(void) const -{ - return (_normal_texture); -} - -GLuint Shader::getPositionTexture(void) const -{ - return (_position_texture); -} - -std::vector Shader::getOutputImage(void) -{ - std::vector res(WIDTH * HEIGHT * 4); - - glBindTexture(GL_TEXTURE_2D, _output_texture); - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, res.data()); - glBindTexture(GL_TEXTURE_2D, 0); - return (res); -} + return (_file_path); +} \ No newline at end of file diff --git a/srcs/class/ShaderProgram.cpp b/srcs/class/ShaderProgram.cpp new file mode 100644 index 0000000..91dbca1 --- /dev/null +++ b/srcs/class/ShaderProgram.cpp @@ -0,0 +1,141 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ShaderProgram.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ycontre +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/12 22:21:46 by TheRed #+# #+# */ +/* Updated: 2025/02/13 19:16:44 by ycontre ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ShaderProgram.hpp" + +ShaderProgram::ShaderProgram() +{ + _program = glCreateProgram(); +} + +ShaderProgram::~ShaderProgram(void) +{ + glDeleteProgram(_program); +} + +void ShaderProgram::attachShader(Shader *shader) +{ + _shaders.push_back(shader); + glAttachShader(_program, shader->getShader()); +} + +void ShaderProgram::clearShaders() +{ + for (Shader *shader : _shaders) + glDetachShader(_program, shader->getShader()); + + _shaders.clear(); +} + +void ShaderProgram::link() +{ + glLinkProgram(_program); + + GLint success; + glGetProgramiv(_program, GL_LINK_STATUS, &success); + if (!success) + { + GLchar infoLog[512]; + glGetProgramInfoLog(_program, 512, NULL, infoLog); + std::cerr << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; + } +} + +void ShaderProgram::use() +{ + glUseProgram(_program); + this->watchForChanges(); +} + +void ShaderProgram::dispathCompute(GLuint x, GLuint y, GLuint z) +{ + this->use(); + glDispatchCompute(x, y, z); + glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); +} + +void ShaderProgram::bindImageTexture(GLuint texture_id, GLuint unit, GLenum access, GLenum format) const +{ + glBindImageTexture(unit, texture_id, 0, GL_FALSE, 0, access, format); +} + +void ShaderProgram::watchForChanges(void) +{ + for (Shader *shader : _shaders) + { + if (shader->hasChanged()) + { + std::cout << "Shader " << shader->getFilePath() << " has changed" << std::endl; + this->reloadShaders(); + break; + } + } +} + +void ShaderProgram::reloadShaders(void) +{ + std::cout << "Reloading shaders" << std::endl; + + for (Shader *shader : _shaders) + { + glDetachShader(_program, shader->getShader()); + shader->reload(); + glAttachShader(_program, shader->getShader()); + } + + this->link(); +} + +void ShaderProgram::set_int(const std::string &name, int value) const +{ + glUniform1i(glGetUniformLocation(_program, name.c_str()), value); +} +void ShaderProgram::set_float(const std::string &name, float value) const +{ + glUniform1f(glGetUniformLocation(_program, name.c_str()), value); +} +void ShaderProgram::set_vec2(const std::string &name, const glm::vec2 &value) const +{ + glUniform2fv(glGetUniformLocation(_program, name.c_str()), 1, glm::value_ptr(value)); +} + +void ShaderProgram::set_textures(std::map> texture_ids) +{ + size_t start_texture = 0; + + for (auto it = texture_ids.begin(); it != texture_ids.end(); it++) + { + for (unsigned int i = 0; i < it->second.size(); i++) + { + GLuint current_unit = start_texture + i; + + glActiveTexture(GL_TEXTURE0 + current_unit); + glBindTexture(GL_TEXTURE_2D, it->second[i]); + + std::string uniform_name = it->first + "[" + std::to_string(i) + "]"; + // std::cout << "Loading texture " << uniform_name << " at unit " << i << std::endl; + glUniform1i(glGetUniformLocation(_program, uniform_name.c_str()), current_unit); + } + start_texture = it->second.size(); + } +} + +void ShaderProgram::set_define(const std::string &name, const std::string &value) +{ + for (Shader *shader : _shaders) + shader->setDefine(name, value); +} + +GLuint ShaderProgram::getProgram(void) const +{ + return (_program); +} \ No newline at end of file diff --git a/srcs/class/Window.cpp b/srcs/class/Window.cpp index 11de6d7..f4227b9 100644 --- a/srcs/class/Window.cpp +++ b/srcs/class/Window.cpp @@ -172,9 +172,9 @@ bool Window::shouldClose() return glfwWindowShouldClose(_window) || _renderer->shouldClose(); } -void Window::rendererUpdate(Shader &shader) +void Window::rendererUpdate(GLuint &texture) { - _renderer->update(shader); + _renderer->update(texture); } void Window::imGuiNewFrame() @@ -184,7 +184,7 @@ void Window::imGuiNewFrame() ImGui::NewFrame(); } -void Window::imGuiRender() +void Window::imGuiRender(ShaderProgram &raytracing_program) { bool has_changed = false; @@ -253,7 +253,12 @@ void Window::imGuiRender() if (ImGui::CollapsingHeader("Fog")) { - has_changed |= ImGui::Checkbox("Enable", (bool *)(&_scene->getVolume().enabled)); + if (ImGui::Checkbox("Enable##0", (bool *)(&_scene->getVolume().enabled))) + { + raytracing_program.set_define("FOG", std::to_string(_scene->getVolume().enabled)); + raytracing_program.reloadShaders(); + has_changed = true; + } ImGui::Separator(); if (ImGui::SliderFloat("Absorption", &_scene->getVolume().sigma_a.x, 0., 0.1)) @@ -274,9 +279,7 @@ void Window::imGuiRender() if (ImGui::CollapsingHeader("Denoiser")) { - ImGui::PushID(0); - - ImGui::Checkbox("Enable", (bool *)(&_scene->getDenoise().enabled)); + ImGui::Checkbox("Enable##1", (bool *)(&_scene->getDenoise().enabled)); ImGui::Separator(); if (ImGui::SliderInt("Pass", &_scene->getDenoise().pass, 0, 8)) _scene->getDenoise().pass = (_scene->getDenoise().pass / 2) * 2; // make sure it's even @@ -284,21 +287,20 @@ void Window::imGuiRender() ImGui::SliderFloat("Color diff", &_scene->getDenoise().c_phi, 0.0f, 1.0f); ImGui::SliderFloat("Position diff", &_scene->getDenoise().p_phi, 0.0f, 1.0f); ImGui::SliderFloat("Normal diff", &_scene->getDenoise().n_phi, 0.0f, 1.0f); - - ImGui::PopID(); } if (ImGui::CollapsingHeader("Debug")) { - ImGui::PushID(0); - - has_changed |= ImGui::Checkbox("Enable", (bool *)(&_scene->getDebug().enabled)); + if (ImGui::Checkbox("Enable##2", (bool *)(&_scene->getDebug().enabled))) + { + raytracing_program.set_define("DEBUG", std::to_string(_scene->getDebug().enabled)); + raytracing_program.reloadShaders(); + has_changed = true; + } ImGui::Separator(); has_changed |= ImGui::SliderInt("Debug mode", &_scene->getDebug().mode, 0, 2); has_changed |= ImGui::SliderInt("Box treshold", &_scene->getDebug().box_treshold, 1, 2000); has_changed |= ImGui::SliderInt("Triangle treshold", &_scene->getDebug().triangle_treshold, 1, 2000); - - ImGui::PopID(); } @@ -346,9 +348,9 @@ int Window::getPixelisation(void) if (mouse || movement) { - if(_fps < 60 && _pixelisation < 16) + if(_fps < 30 && _pixelisation < 16) _pixelisation++; - if(_fps > 120 && _pixelisation > 0) + if(_fps > 60 && _pixelisation > 0) _pixelisation--; } else if(_pixelisation)