diff --git a/examples/cornell_box b/examples/cornell_box index 96dd06d..c498fdb 100644 Binary files a/examples/cornell_box and b/examples/cornell_box differ diff --git a/examples/cornell_box.cpp b/examples/cornell_box.cpp index 23ad966..fec2dda 100644 --- a/examples/cornell_box.cpp +++ b/examples/cornell_box.cpp @@ -442,10 +442,10 @@ int main() { RendererConfig config; config.width_ = WINDOW_WIDTH; config.height_ = WINDOW_HEIGHT; - config.samples_per_pixel_ = 10; + config.samples_per_pixel_ = 4; config.max_ray_depth_ = 4; - config.enable_accumulation_ = true; - config.enable_denoising_ = true; + config.enable_accumulation_ = false; + config.enable_denoising_ = false; g_renderer = std::make_unique(config); if (!g_renderer->initialize()) { diff --git a/include/core/denoiser.h b/include/core/denoiser.h deleted file mode 100644 index 50ad16b..0000000 --- a/include/core/denoiser.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef ARE_INCLUDE_CORE_DENOISER_H -#define ARE_INCLUDE_CORE_DENOISER_H - -#include "basic/types.h" -#include "resource/shader.h" -#include - -namespace are { - -/** - * @brief Mean filter denoiser using compute shader - */ -class Denoiser { -public: - /** - * @brief Construct denoiser - * @param width Output width - * @param height Output height - */ - Denoiser(uint width, uint height); - - /** - * @brief Destroy denoiser - */ - ~Denoiser(); - - /** - * @brief Initialize GPU resources - * @param shader Denoise compute shader (managed by ShaderManager) - * @return True on success - */ - bool initialize(const std::shared_ptr& shader); - - /** - * @brief Release GPU resources - */ - void release(); - - /** - * @brief Resize internal targets - * @param width New width - * @param height New height - */ - void resize(uint width, uint height); - - /** - * @brief Apply mean filter - * @param input_texture RGBA32F input texture - * @param radius Filter radius (1 => 3x3) - * @return Output texture handle (internal) - */ - TextureHandle denoise(TextureHandle input_texture, int radius); - -private: - uint width_; - uint height_; - std::shared_ptr shader_; - TextureHandle output_texture_; - bool initialized_; - - /** - * @brief Create output texture - */ - void create_output_texture_(); -}; - -} // namespace are - -#endif // ARE_INCLUDE_CORE_DENOISER_H diff --git a/include/core/renderer.h b/include/core/renderer.h index a9be406..b0b29b6 100644 --- a/include/core/renderer.h +++ b/include/core/renderer.h @@ -7,7 +7,6 @@ #include "core/raytracer.h" #include "core/screen_blit.h" #include "core/shader_manager.h" -#include "core/denoiser.h" #include namespace are { @@ -67,7 +66,6 @@ private: std::unique_ptr raytracer_; std::unique_ptr shader_manager_; std::unique_ptr screen_blit_; - std::unique_ptr denoiser_; bool initialized_; uint frame_count_; diff --git a/include/core/shader_manager.h b/include/core/shader_manager.h index 2d8a19c..c48665a 100644 --- a/include/core/shader_manager.h +++ b/include/core/shader_manager.h @@ -54,15 +54,10 @@ public: /// @return Ray tracing shader const std::shared_ptr& get_raytracing_shader() const { return raytracing_shader_; } - /// @brief Get mean denoise compute shader - /// @return Denoise shader (nullptr if not loaded) - const std::shared_ptr& get_denoise_shader() const { return denoise_shader_; } - private: std::unordered_map> shader_cache_; std::shared_ptr gbuffer_shader_; std::shared_ptr raytracing_shader_; - std::shared_ptr denoise_shader_; bool initialized_; diff --git a/shaders/denoiser.comp b/shaders/denoiser.comp deleted file mode 100644 index adb3a9a..0000000 --- a/shaders/denoiser.comp +++ /dev/null @@ -1,24 +0,0 @@ -#version 430 core - -layout(local_size_x = 16, local_size_y = 16) in; - -layout(binding = 0, rgba32f) uniform readonly image2D u_input; -layout(binding = 1, rgba32f) uniform writeonly image2D u_output; - -// uniform int u_radius; // 已经不需要了,但保留定义以防外部报错 - -void main() { - ivec2 p = ivec2(gl_GlobalInvocationID.xy); - ivec2 size = imageSize(u_output); - - // 边界检查:如果像素超出范围,直接返回 - if (p.x >= size.x || p.y >= size.y) return; - - // 【修改点】: - // 1. 不再使用循环去遍历周围的像素 (dy, dx)。 - // 2. 直接读取当前位置 (p) 的颜色。 - vec3 original_color = imageLoad(u_input, p).rgb; - - // 直接写入输出图像,不做任何平均计算 - imageStore(u_output, p, vec4(original_color, 1.0)); -} diff --git a/shaders/raytracing.comp b/shaders/raytracing.comp index 3f094fd..a34c5eb 100644 --- a/shaders/raytracing.comp +++ b/shaders/raytracing.comp @@ -603,18 +603,22 @@ void main() { uint base_seed = uint(pixel_coords.x) + uint(pixel_coords.y) * uint(image_size.x); uint seed = base_seed + u_frame_count * 719393u; - vec3 sample_color = trace_path_primary_gbuffer(pixel_coords, image_size, seed); - sample_color = clamp(sample_color, vec3(0.0), vec3(10.0)); + vec3 color = vec3(0.0); + uint spp = max(u_samples_per_pixel, 1u); - if (u_enable_accumulation) { - vec3 sum = imageLoad(accumulation_image, pixel_coords).rgb; - sum += sample_color; - imageStore(accumulation_image, pixel_coords, vec4(sum, 1.0)); + for (uint s = 0u; s < spp; ++s) { + color += trace_path_primary_gbuffer(pixel_coords, image_size, seed); + } + color /= float(spp); - float inv_n = 1.0 / float(u_frame_count + 1u); // u_frame_count is "sample index" - vec3 avg = sum * inv_n; - imageStore(output_image, pixel_coords, vec4(avg, 1.0)); - } else { - imageStore(output_image, pixel_coords, vec4(sample_color, 1.0)); - } + color = clamp(color, vec3(0.0), vec3(10.0)); + + if (u_enable_accumulation && u_frame_count > 0u) { + vec3 accumulated = imageLoad(accumulation_image, pixel_coords).rgb; + float w = 1.0 / float(u_frame_count + 1u); + color = mix(accumulated, color, w); + } + + imageStore(accumulation_image, pixel_coords, vec4(color, 1.0)); + imageStore(output_image, pixel_coords, vec4(color, 1.0)); } diff --git a/src/core/denoiser.cpp b/src/core/denoiser.cpp deleted file mode 100644 index d96326d..0000000 --- a/src/core/denoiser.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "core/denoiser.h" -#include "basic/constants.h" -#include "utils/logger.h" -#include - -namespace are { - -Denoiser::Denoiser(uint width, uint height) - : width_(width) - , height_(height) - , output_texture_(INVALID_HANDLE) - , initialized_(false) { -} - -Denoiser::~Denoiser() { - release(); -} - -bool Denoiser::initialize(const std::shared_ptr& shader) { - if (initialized_) return true; - - if (!shader || !shader->is_valid()) { - Logger::error("Invalid denoise shader"); - return false; - } - - shader_ = shader; - create_output_texture_(); - - initialized_ = true; - Logger::info("Denoiser initialized"); - return true; -} - -void Denoiser::release() { - if (!initialized_) return; - - shader_.reset(); - - if (output_texture_ != INVALID_HANDLE) { - glDeleteTextures(1, &output_texture_); - output_texture_ = INVALID_HANDLE; - } - - initialized_ = false; -} - -void Denoiser::resize(uint width, uint height) { - if (width == width_ && height == height_) return; - width_ = width; - height_ = height; - - if (!initialized_) return; - - if (output_texture_ != INVALID_HANDLE) { - glDeleteTextures(1, &output_texture_); - output_texture_ = INVALID_HANDLE; - } - create_output_texture_(); -} - -TextureHandle Denoiser::denoise(TextureHandle input_texture, int radius) { - if (!initialized_) return input_texture; - - radius = (radius < 0) ? 0 : radius; - - shader_->use(); - - glBindImageTexture(0, input_texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); - glBindImageTexture(1, output_texture_, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); - - shader_->set_int("u_radius", radius); - - uint groups_x = (width_ + COMPUTE_GROUP_SIZE_X - 1) / COMPUTE_GROUP_SIZE_X; - uint groups_y = (height_ + COMPUTE_GROUP_SIZE_Y - 1) / COMPUTE_GROUP_SIZE_Y; - glDispatchCompute(groups_x, groups_y, 1); - - glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); - - return output_texture_; -} - -void Denoiser::create_output_texture_() { - glGenTextures(1, &output_texture_); - glBindTexture(GL_TEXTURE_2D, output_texture_); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width_, height_, 0, GL_RGBA, GL_FLOAT, nullptr); - 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); -} - -} // namespace are diff --git a/src/core/raytracer.cpp b/src/core/raytracer.cpp index 92c08bf..8568a99 100644 --- a/src/core/raytracer.cpp +++ b/src/core/raytracer.cpp @@ -184,48 +184,14 @@ void RayTracer::trace(const Scene &scene, const GBuffer &gbuffer, TextureHandle uint num_groups_x = (width_ + COMPUTE_GROUP_SIZE_X - 1) / COMPUTE_GROUP_SIZE_X; uint num_groups_y = (height_ + COMPUTE_GROUP_SIZE_Y - 1) / COMPUTE_GROUP_SIZE_Y; - const uint spp = std::max(config_.samples_per_pixel_, 1u); + glDispatchCompute(num_groups_x, num_groups_y, 1); - // We interpret frame_count_ as "accumulated sample count" - for (uint i = 0; i < spp; ++i) { - compute_shader_->use(); + // Memory barrier + glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); - // Bind G-Buffer textures - bind_gbuffer_(gbuffer); - - // Bind output and accumulation textures - glBindImageTexture(3, output_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); - glBindImageTexture(4, accumulation_texture_, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); - - // Bind BVH buffers if enabled - if (config_.use_bvh_ && bvh_built_) { - bvh_node_buffer_.bind_base(2); - bvh_triangle_buffer_.bind_base(3); - compute_shader_->set_bool("u_use_bvh", true); - compute_shader_->set_uint("u_bvh_node_count", bvh_->get_node_count()); - } else { - compute_shader_->set_bool("u_use_bvh", false); - compute_shader_->set_uint("u_bvh_node_count", 0u); - } - - // Set uniforms (u_frame_count is sample index) - compute_shader_->set_uint("u_frame_count", frame_count_); - compute_shader_->set_uint("u_samples_per_pixel", 1u); // shader does 1 sample per dispatch now - compute_shader_->set_uint("u_max_depth", config_.max_depth_); - compute_shader_->set_uint("u_light_count", static_cast(scene.get_lights().size())); - compute_shader_->set_bool("u_enable_accumulation", config_.enable_accumulation_); - - // Camera - const Camera& camera = scene.get_camera(); - Mat4 inv_vp = glm::inverse(camera.get_view_projection_matrix()); - compute_shader_->set_mat4("u_inv_view_projection", inv_vp); - - glDispatchCompute(num_groups_x, num_groups_y, 1); - glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); - - if (config_.enable_accumulation_) { - frame_count_++; - } + // Increment frame count for accumulation + if (config_.enable_accumulation_) { + frame_count_++; } } diff --git a/src/core/renderer.cpp b/src/core/renderer.cpp index 021024c..bb1d2ec 100644 --- a/src/core/renderer.cpp +++ b/src/core/renderer.cpp @@ -66,15 +66,7 @@ bool Renderer::initialize() { Logger::error("Failed to initialize screen blit"); return false; } - - // Initialize denoiser - denoiser_ = std::make_unique(config_.width_, config_.height_); - const auto& denoise_shader = shader_manager_->get_denoise_shader(); - if (!denoiser_->initialize(denoise_shader)) { - Logger::error("Failed to initialize denoiser"); - return false; - } - + initialized_ = true; Logger::info("Aurora Rendering Engine initialized successfully"); return true; @@ -106,11 +98,6 @@ void Renderer::shutdown() { shader_manager_.reset(); } - if(denoiser_) { - denoiser_->release(); - denoiser_.reset(); - } - initialized_ = false; Logger::info("Aurora Rendering Engine shut down"); } @@ -161,18 +148,11 @@ RenderStats Renderer::render(const Scene& scene, TextureHandle output_texture) { auto raytrace_end = std::chrono::high_resolution_clock::now(); stats.raytrace_time_ms_ = std::chrono::duration(raytrace_end - raytrace_start).count(); - // Phase 3: Denoise texture - TextureHandle final_output = rt_output; - - if (denoiser_) { - final_output = denoiser_->denoise(rt_output, 1); // radius=1 => 3x3 - } - - // Phase 4: Blit to screen if output is default framebuffer - if (created_temp_texture && output_texture == 0) { - screen_blit_->blit_fullscreen(final_output); - glDeleteTextures(1, &rt_output); - } + // Phase 3: Blit to screen if output is default framebuffer + if (created_temp_texture && output_texture == 0) { + screen_blit_->blit_fullscreen(rt_output); + glDeleteTextures(1, &rt_output); + } // Calculate total frame time auto end_time = std::chrono::high_resolution_clock::now(); @@ -202,7 +182,6 @@ void Renderer::resize(uint width, uint height) { if (initialized_) { gbuffer_->resize(width, height); raytracer_->resize(width, height); - denoiser_->resize(width, height); Logger::info("Renderer resized to " + std::to_string(width) + "x" + std::to_string(height)); } diff --git a/src/core/shader_manager.cpp b/src/core/shader_manager.cpp index f18c0d9..6c9c48f 100644 --- a/src/core/shader_manager.cpp +++ b/src/core/shader_manager.cpp @@ -39,7 +39,6 @@ void ShaderManager::release() { gbuffer_shader_.reset(); raytracing_shader_.reset(); - denoise_shader_.reset(); initialized_ = false; Logger::info("ShaderManager released"); @@ -109,15 +108,6 @@ bool ShaderManager::load_builtin_shaders_() { shader_cache_["raytracing"] = raytracing_shader_; Logger::info("Ray tracing shader loaded successfully"); - Logger::info("Loading denoise compute shader..."); - denoise_shader_ = std::make_shared(); - if (!denoise_shader_->load_compute("shaders/denoiser.comp")) { - Logger::error("Failed to load denoise shader"); - return false; - } - shader_cache_["denoise"] = denoise_shader_; - Logger::info("Denoise shader loaded successfully"); - return true; }