From 0925559c181ffd31ebee4b3329c84e1e6440f517 Mon Sep 17 00:00:00 2001 From: adany292 <adany292@student.liu.se> Date: Mon, 23 Dec 2024 01:23:39 +0100 Subject: [PATCH] Depth aware world radius adpative billateral gausiann deepth buffer smoothing WIP --- shaders/depth_filter.frag | 84 ++++++++++++++ shaders/depth_filter.vert | 12 ++ src/Camera.cpp | 4 + src/FluidRenderer.cpp | 225 ++++++++++++++++++++++++++++++++++-- src/FluidSimulationApp.cpp | 36 +++++- src/include/Camera.h | 1 + src/include/FluidRenderer.h | 16 +++ src/settings/constants.h | 3 + 8 files changed, 369 insertions(+), 12 deletions(-) create mode 100644 shaders/depth_filter.frag create mode 100644 shaders/depth_filter.vert diff --git a/shaders/depth_filter.frag b/shaders/depth_filter.frag new file mode 100644 index 0000000..d148a34 --- /dev/null +++ b/shaders/depth_filter.frag @@ -0,0 +1,84 @@ +#version 330 core + +in vec2 TexCoords; +out vec4 FragColor; + +uniform sampler2D uDepthTex; +uniform float sigma_r; +uniform float depthThreshold; +uniform vec2 passDirection; // (1.0/width, 0) or (0, 1.0/height) + +// Bilateral parameters +uniform float zNear; +uniform float zFar; +uniform float cameraFovY; +uniform int screenHeight; + +// World-space smoothing +uniform float worldRadiusMeters; +uniform float maxPixelRadius; // clamp so we don't do huge loops + +uniform float sigmaSpatialFactor; // if we still want a gaussWeights fallback + +void main() +{ + // 1) Read the center depth [0..1], convert to eye-dist + float centerDepthN = texture(uDepthTex, TexCoords).r; + if (centerDepthN <= 0.0 || centerDepthN >= 1.0) { + // out of range, maybe skip + discard; + } + float eyeDist = mix(zNear, zFar, centerDepthN); + + // 2) Convert to screen-space pixel radius + float planeHeight = 2.0 * eyeDist * tan(cameraFovY * 0.5); + float pxPerMeter = float(screenHeight) / planeHeight; + float pixelRadius = worldRadiusMeters * pxPerMeter; + pixelRadius = min(pixelRadius, maxPixelRadius); + + int iRadius = int(ceil(pixelRadius)); + + float centerDepth = centerDepthN; // if our depth is actually linear, that's fine + float sum = 0.0; + float wSum = 0.0; + + // Loop from -maxPixelKernel..+maxPixelKernel + int maxPixelKernel = 64; // or something bigger, but 64 seems good enough + for (int i = -maxPixelKernel; i <= maxPixelKernel; i++) + { + if (abs(i) > iRadius) { + continue; + } + + // offset + vec2 offset = passDirection * float(i); + vec2 sampleUV = TexCoords + offset; + + float neighborDepthN = texture(uDepthTex, sampleUV).r; + if (neighborDepthN <= 0.0 || neighborDepthN >= 1.0) { + continue; + } + float d = abs(neighborDepthN - centerDepth); + + // range check + if (d > depthThreshold) { + continue; + } + + // Spatial weight (some 1D Gaussian). + // Compute on-the-fly: + // e.g. float spatial = exp(-(i*i)/(2.0*sigmaSpatialFactor*sigmaSpatialFactor)); + // could be replaced by passinng in a small look-up array + float wSpatial = exp(- (float(i)*float(i)) / (2.0 * sigmaSpatialFactor * sigmaSpatialFactor)); + + // Range weight + float wRange = exp(- (d*d) / (2.0 * sigma_r * sigma_r)); + + float w = wSpatial * wRange; + sum += neighborDepthN * w; + wSum += w; + } + + float blurredDepth = sum / max(wSum, 1e-5); + FragColor = vec4(blurredDepth, 0, 0, 1); +} diff --git a/shaders/depth_filter.vert b/shaders/depth_filter.vert new file mode 100644 index 0000000..2b8c1a0 --- /dev/null +++ b/shaders/depth_filter.vert @@ -0,0 +1,12 @@ +#version 330 core + +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec2 aTexCoord; + +out vec2 TexCoords; + +void main() +{ + TexCoords = aTexCoord; + gl_Position = vec4(aPos, 1.0); +} diff --git a/src/Camera.cpp b/src/Camera.cpp index f44b438..b65a1b3 100644 --- a/src/Camera.cpp +++ b/src/Camera.cpp @@ -82,4 +82,8 @@ namespace FluidSimulation { g_camera = &camera; } + float Camera::getFovyRadians() const { + return fov * static_cast<float>(M_PI) / 180.0f; + } + } // namespace FluidSimulation \ No newline at end of file diff --git a/src/FluidRenderer.cpp b/src/FluidRenderer.cpp index d167360..825623f 100644 --- a/src/FluidRenderer.cpp +++ b/src/FluidRenderer.cpp @@ -38,7 +38,7 @@ FluidRenderer::~FluidRenderer() { // Cleanup Depth Render Program deleteFramebufferResources(m_depthRenderProgram); - + deleteFramebufferResources(m_depthFilterProgram); // Cleanup Visualization Render Program deleteFramebufferResources(m_visualizationProgram); @@ -123,6 +123,7 @@ void FluidRenderer::initShaders() { glUseProgram(m_normalRenderProgram.programID); std::cout << "Normal Render Shaders initialized successfully." << std::endl; + // =================== Depth shader stages ========================= // Depth Render Shader m_depthRenderProgram.programID = loadShaders("../shaders/depth.vert", "../shaders/depth.frag"); if (m_depthRenderProgram.programID == 0) { @@ -132,7 +133,19 @@ void FluidRenderer::initShaders() { glUseProgram(m_depthRenderProgram.programID); std::cout << "Depth Render Shaders initialized successfully." << std::endl; - // Thickness Render Shader + m_depthFilterProgram.programID = loadShaders( + "../shaders/depth_filter.vert", + "../shaders/depth_filter.frag" + ); + if (m_depthFilterProgram.programID == 0) { + std::cerr << "Failed to load Depth Filter Shaders." << std::endl; + exit(1); + } + glUseProgram(m_depthFilterProgram.programID); + std::cout << "Depth Filter Shaders initialized successfully." << std::endl; + + // =================== Thickness shader stages ========================= + // Thickness Render Shader m_thicknessRenderProgram.programID = loadShaders( "../shaders/thickness.vert", "../shaders/thickness.frag" @@ -145,6 +158,7 @@ void FluidRenderer::initShaders() { std::cout << "Thickness Render Shaders initialized successfully." << std::endl; + // =================== Visulisation shader ========================= // Visualization Shader m_visualizationProgram.programID = loadShaders("../shaders/visualize_grayscale.vert", "../shaders/visualize_grayscale.frag"); if (m_visualizationProgram.programID == 0) { @@ -194,10 +208,10 @@ void FluidRenderer::setupShaderProgram(ShaderProgram& shaderProgram) // For point rendering (as in particle shaders): if (shaderProgram.pointRadiusLoc != -1) { - glUniform1f(shaderProgram.pointRadiusLoc, 20.0f); + glUniform1f(shaderProgram.pointRadiusLoc, m_pointRadius); } if (shaderProgram.pointScaleLoc != -1) { - glUniform1f(shaderProgram.pointScaleLoc, 10.0f); + glUniform1f(shaderProgram.pointScaleLoc, m_pointScale); } // For model matrix, set to Identity by default if (shaderProgram.modelMatrixLoc != -1) { @@ -227,9 +241,13 @@ void FluidRenderer::initShaderUniforms() // Normal render program: setupShaderProgram(m_normalRenderProgram); + // =================== Depth shader stages ========================= // Depth render program: setupShaderProgram(m_depthRenderProgram); - + // Depth Filter program: + setupShaderProgram(m_depthFilterProgram); + + // =================== Thickness shader stages ========================= // Thickness buffer program: setupShaderProgram(m_thicknessRenderProgram); @@ -278,9 +296,33 @@ void FluidRenderer::initFBOs() { // Initialize Normal Render Shader FBO with GL_RGBA8 initializeFramebuffer(m_normalRenderProgram, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE); + // =================== Depth shader stages ========================= // Initialize Depth Render Shader FBO with GL_R32F initializeFramebuffer(m_depthRenderProgram, GL_R32F, GL_RED, GL_FLOAT); + initializeFramebuffer(m_depthFilterProgram, + GL_R32F, GL_RED, GL_FLOAT); + + glGenTextures(1, &m_depthFilterTempTex); + glBindTexture(GL_TEXTURE_2D, m_depthFilterTempTex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, m_fbWidth, m_fbHeight, 0, GL_RED, GL_FLOAT, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glBindTexture(GL_TEXTURE_2D, 0); + + // Also create an FBO for it: + glGenFramebuffers(1, &m_depthFilterTempFBO); + glBindFramebuffer(GL_FRAMEBUFFER, m_depthFilterTempFBO); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_depthFilterTempTex, 0); + GLenum drawBufs[1] = {GL_COLOR_ATTACHMENT0}; + glDrawBuffers(1, drawBufs); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + std::cerr << "Temp FBO not complete!\n"; + } + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + // =================== Thickness shader stages ========================= // Initialize Thickness Render Shader FBO with GL_R32F initializeFramebuffer(m_thicknessRenderProgram, GL_R32F, // internal format @@ -367,15 +409,21 @@ void FluidRenderer::resizeFBO(int newWidth, int newHeight) { GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, newWidth, newHeight); + // =================== Depth shader stages ========================= // Resize Depth Render Shader FBO resizeFramebuffer(m_depthRenderProgram, GL_R32F, GL_RED, GL_FLOAT, newWidth, newHeight); - resizeFramebuffer(m_thicknessRenderProgram, + resizeFramebuffer(m_depthFilterProgram, GL_R32F, GL_RED, GL_FLOAT, newWidth, newHeight); + // =================== Thickness shader stages ========================= + resizeFramebuffer(m_thicknessRenderProgram, + GL_R32F, GL_RED, GL_FLOAT, + newWidth, newHeight); + // Resize Visualization Render Shader FBO resizeFramebuffer(m_visualizationProgram, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, @@ -459,6 +507,13 @@ void FluidRenderer::renderNormalFrame(size_t particleCount, size_t boundaryCount mat4 viewMatrix = m_camera->getViewMatrix(); glUniformMatrix4fv(m_normalRenderProgram.viewMatrixLoc, 1, GL_TRUE, viewMatrix.m); + + if (m_normalRenderProgram.pointRadiusLoc != -1) { + glUniform1f(m_normalRenderProgram.pointRadiusLoc, m_pointRadius); + } + if (m_normalRenderProgram.pointScaleLoc != -1) { + glUniform1f(m_normalRenderProgram.pointScaleLoc, m_pointScale); + } renderParticles(particleCount, m_normalRenderProgram); @@ -480,7 +535,7 @@ void FluidRenderer::renderDepthFrame(size_t particleCount, size_t boundaryCount) // Set the viewport to match the framebuffer size glViewport(0, 0, m_fbWidth, m_fbHeight); - glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Clear color and depth buffers glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); @@ -499,6 +554,12 @@ void FluidRenderer::renderDepthFrame(size_t particleCount, size_t boundaryCount) if (m_depthRenderProgram.sphereRadiusLoc != -1) { glUniform1f(m_depthRenderProgram.sphereRadiusLoc, 1.0f); } + if (m_depthRenderProgram.pointRadiusLoc != -1) { + glUniform1f(m_depthRenderProgram.pointRadiusLoc, m_pointRadius); + } + if (m_depthRenderProgram.pointScaleLoc != -1) { + glUniform1f(m_depthRenderProgram.pointScaleLoc, m_pointScale); + } float cameraNearPlane = m_camera->getNearPlane(); float cameraFarPlane = m_camera->getFarPlane(); @@ -516,6 +577,146 @@ void FluidRenderer::renderDepthFrame(size_t particleCount, size_t boundaryCount) glBindFramebuffer(GL_FRAMEBUFFER, 0); } +// Currenntly onuseed - probably remove later, since we do adptive in shader +void FluidRenderer::computeGaussianWeights(int radius, std::vector<float>& outWeights) +{ + outWeights.resize(radius+1); // we store only half + center + float sigma = float(radius) / 3.0f; // or pick your approach + float sum = 0.0f; + + // Compute weights + for (int i = 0; i <= radius; i++) { + float w = exp(-(i*i) / (2.0f * sigma * sigma)); + outWeights[i] = w; + // we only store half, so account for symmetry in sum + sum += (i == 0) ? w : 2.0f * w; + } + + // Normalize + for (int i = 0; i <= radius; i++) { + outWeights[i] /= sum; + } +} + +void FluidRenderer::renderDepthFilterFrame() +{ + // Defining the parameters for a world-space radius blur + // (and other relevant uniforms). + float worldRadiusMeters = 0.2f; // e.g. 2 cm smoothing in real space + float maxPixelRadius = 60.0f; // clamp for performance + float sigmaSpatialFactor = 10.0f; // controls the spatial falloff in the blur loop + float sigmaR = 6.0f; // range weight exponent + float depthThresh = 0.5f; // bilateral threshold for ignoring big depth jumps + + // Retrieve camera values for FOV, near/far from your Camera object + float cameraFovY = m_camera->getFovyRadians(); + float zNear = m_camera->getNearPlane(); + float zFar = m_camera->getFarPlane(); + + // =============== PASS 1: HORIZONTAL =============== + { + // Bind the temp FBO (for horizontal pass) + glBindFramebuffer(GL_FRAMEBUFFER, m_depthFilterTempFBO); + glViewport(0, 0, m_fbWidth, m_fbHeight); + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_DEPTH_TEST); + + // Use the depthFilterProgram + glUseProgram(m_depthFilterProgram.programID); + + // Input texture = the original depth buffer + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_depthRenderProgram.fboTexture); + glUniform1i(glGetUniformLocation(m_depthFilterProgram.programID, "uDepthTex"), 0); + + // passDirection = horizontal + float passDirX = 1.0f / m_fbWidth; + float passDirY = 0.0f; + glUniform2f(glGetUniformLocation(m_depthFilterProgram.programID, "passDirection"), + passDirX, passDirY); + + // Set "per-pixel" uniforms: + glUniform1f(glGetUniformLocation(m_depthFilterProgram.programID, "cameraFovY"), cameraFovY); + glUniform1f(glGetUniformLocation(m_depthFilterProgram.programID, "zNear"), zNear); + glUniform1f(glGetUniformLocation(m_depthFilterProgram.programID, "zFar"), zFar); + glUniform1i(glGetUniformLocation(m_depthFilterProgram.programID, "screenHeight"), + m_fbHeight); + + glUniform1f(glGetUniformLocation(m_depthFilterProgram.programID, "worldRadiusMeters"), + worldRadiusMeters); + glUniform1f(glGetUniformLocation(m_depthFilterProgram.programID, "maxPixelRadius"), + maxPixelRadius); + + glUniform1f(glGetUniformLocation(m_depthFilterProgram.programID, "sigmaSpatialFactor"), + sigmaSpatialFactor); + glUniform1f(glGetUniformLocation(m_depthFilterProgram.programID, "sigma_r"), + sigmaR); + glUniform1f(glGetUniformLocation(m_depthFilterProgram.programID, "depthThreshold"), + depthThresh); + + // Render the fullscreen quad + glBindVertexArray(quadVAO); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); + + // Restore states + glEnable(GL_DEPTH_TEST); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } + + // =============== PASS 2: VERTICAL =============== + { + // Bind final FBO (the main depthFilterProgram's FBO) + glBindFramebuffer(GL_FRAMEBUFFER, m_depthFilterProgram.fbo); + glViewport(0, 0, m_fbWidth, m_fbHeight); + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_DEPTH_TEST); + + // Same program + glUseProgram(m_depthFilterProgram.programID); + + // Input = pass 1's texture + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_depthFilterTempTex); + glUniform1i(glGetUniformLocation(m_depthFilterProgram.programID, "uDepthTex"), 0); + + // passDirection = vertical + float passDirX2 = 0.0f; + float passDirY2 = 1.0f / m_fbHeight; + glUniform2f(glGetUniformLocation(m_depthFilterProgram.programID, "passDirection"), + passDirX2, passDirY2); + + // Set the same per-pixel uniforms again + glUniform1f(glGetUniformLocation(m_depthFilterProgram.programID, "cameraFovY"), cameraFovY); + glUniform1f(glGetUniformLocation(m_depthFilterProgram.programID, "zNear"), zNear); + glUniform1f(glGetUniformLocation(m_depthFilterProgram.programID, "zFar"), zFar); + glUniform1i(glGetUniformLocation(m_depthFilterProgram.programID, "screenHeight"), + m_fbHeight); + + glUniform1f(glGetUniformLocation(m_depthFilterProgram.programID, "worldRadiusMeters"), + worldRadiusMeters); + glUniform1f(glGetUniformLocation(m_depthFilterProgram.programID, "maxPixelRadius"), + maxPixelRadius); + + glUniform1f(glGetUniformLocation(m_depthFilterProgram.programID, "sigmaSpatialFactor"), + sigmaSpatialFactor); + glUniform1f(glGetUniformLocation(m_depthFilterProgram.programID, "sigma_r"), sigmaR); + glUniform1f(glGetUniformLocation(m_depthFilterProgram.programID, "depthThreshold"), + depthThresh); + + // Draw the fullscreen quad + glBindVertexArray(quadVAO); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); + + // Restore states + glEnable(GL_DEPTH_TEST); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } +} + void FluidRenderer::renderThicknessFrame(size_t particleCount, size_t boundaryCount) { glBindFramebuffer(GL_FRAMEBUFFER, m_thicknessRenderProgram.fbo); @@ -544,7 +745,13 @@ void FluidRenderer::renderThicknessFrame(size_t particleCount, size_t boundaryCo glUniformMatrix4fv(m_thicknessRenderProgram.viewMatrixLoc, 1, GL_TRUE, viewMatrix.m); } if (m_thicknessRenderProgram.pointRadiusLoc != -1) { - glUniform1f(m_thicknessRenderProgram.pointRadiusLoc, 20.0f); + glUniform1f(m_thicknessRenderProgram.pointRadiusLoc, m_pointRadius); + } + if (m_thicknessRenderProgram.pointRadiusLoc != -1) { + glUniform1f(m_thicknessRenderProgram.pointRadiusLoc, m_pointRadius); + } + if (m_thicknessRenderProgram.pointScaleLoc != -1) { + glUniform1f(m_thicknessRenderProgram.pointScaleLoc, m_pointScale); } renderParticles(particleCount, m_thicknessRenderProgram); @@ -604,6 +811,8 @@ GLuint FluidRenderer::getTexture(RenderStage stage) const { return m_depthRenderProgram.fboTexture; case RenderStage::ThicknessBuffer: return m_thicknessRenderProgram.fboTexture; + case RenderStage::FilteredDepth: + return m_depthFilterProgram.fboTexture; default: return 0; // Return 0 if no valid stage was selected } diff --git a/src/FluidSimulationApp.cpp b/src/FluidSimulationApp.cpp index d4b564e..477d985 100644 --- a/src/FluidSimulationApp.cpp +++ b/src/FluidSimulationApp.cpp @@ -18,7 +18,7 @@ namespace FluidSimulation { 45.0f, appSettings->width / (float)appSettings->height, 0.1f, - 25.0f + 30.0f ); m_fluidRenderer = new FluidRenderer(appSettings->width, appSettings->height, m_camera); @@ -55,6 +55,8 @@ namespace FluidSimulation { static float restDensity = m_fluidSimulation->getRestDensity(); static float viscosity = m_fluidSimulation->getViscosity(); static float smoothingRadius = m_fluidSimulation->getSmoothingRadius(); + static float pointScale = m_fluidRenderer->getPointScale(); + static float pointRadius = m_fluidRenderer->getPointRadius(); // Full-width sliders ImGui::PushItemWidth(-1); // Make sliders take up the full available width @@ -78,6 +80,12 @@ namespace FluidSimulation { ImGui::Text("Smoothing Radius"); ImGui::SliderFloat("##SmoothingRadius", &smoothingRadius, 0.1f, 1.0f, "%.2f"); + ImGui::Text("Point Radius"); + ImGui::SliderFloat("##PointRadius", &pointRadius, 10.0f, 30.0f, "%.1f"); + + ImGui::Text("Point Scale"); + ImGui::SliderFloat("##PointScale", &pointScale, 4.0f, 16.0f, "%.1f"); + ImGui::PopItemWidth(); // Restore default width ImGui::Spacing(); @@ -93,9 +101,12 @@ namespace FluidSimulation { m_fluidSimulation->setRestDensity(restDensity); m_fluidSimulation->setViscosity(viscosity); m_fluidSimulation->setSmoothingRadius(smoothingRadius); - + // Update constants on the CUDA device m_fluidSimulation->updateConstants(); + + m_fluidRenderer->setPointRadius(pointRadius); + m_fluidRenderer->setPointScale(pointScale); } } else @@ -108,6 +119,9 @@ namespace FluidSimulation { // Update constants on the CUDA device m_fluidSimulation->updateConstants(); + + m_fluidRenderer->setPointRadius(pointRadius); + m_fluidRenderer->setPointScale(pointScale); } if (ImGui::Button("Reset Parmeters", ImVec2(buttonWidth, 0))) @@ -119,6 +133,11 @@ namespace FluidSimulation { viscosity = m_fluidSimulation->getViscosity(); smoothingRadius = m_fluidSimulation->getSmoothingRadius(); static int restDensityInt = static_cast<int>(restDensity); + + m_fluidRenderer->setPointScale(h_POINT_SCALE); + m_fluidRenderer->setPointRadius(h_POINT_RADIUS); + pointScale = m_fluidRenderer->getPointScale(); + pointRadius = m_fluidRenderer->getPointRadius(); } } @@ -202,13 +221,20 @@ namespace FluidSimulation { m_fluidSimulation->getBoundaryParticleCount() ); } - else if (selectedStage == RenderStage::DepthBuffer) + else if (selectedStage == RenderStage::DepthBuffer + || selectedStage == RenderStage::FilteredDepth) { m_fluidRenderer->renderDepthFrame( m_fluidSimulation->getParticleCount(), m_fluidSimulation->getBoundaryParticleCount() ); + if (selectedStage == RenderStage::FilteredDepth) + { + printf("Thicnes stage active \n"); + m_fluidRenderer->renderDepthFilterFrame(); + } + // After rendering the depth frame, perform visualization m_fluidRenderer->visualizeBuffer(selectedStage); } @@ -239,7 +265,9 @@ namespace FluidSimulation { { textureID = m_fluidRenderer->getTexture(selectedStage); // RGBA8 } - else if (selectedStage == RenderStage::DepthBuffer || selectedStage == RenderStage::ThicknessBuffer) + else if (selectedStage == RenderStage::DepthBuffer + || selectedStage == RenderStage::ThicknessBuffer + || selectedStage == RenderStage::FilteredDepth) { // Use the visualization texture textureID = m_fluidRenderer->getVisualizationTexture(); diff --git a/src/include/Camera.h b/src/include/Camera.h index 1d331b9..bebde71 100644 --- a/src/include/Camera.h +++ b/src/include/Camera.h @@ -30,6 +30,7 @@ namespace FluidSimulation { void setAspectRatio(float aspect) { aspectRatio = aspect; } float getNearPlane() { return zNear; }; float getFarPlane() { return zFar; }; + float getFovyRadians() const; }; void initCamera(Camera& camera); diff --git a/src/include/FluidRenderer.h b/src/include/FluidRenderer.h index 0f20fac..4fab8e7 100644 --- a/src/include/FluidRenderer.h +++ b/src/include/FluidRenderer.h @@ -5,6 +5,7 @@ #include <vector> #include <cuda_runtime.h> #include "include/Camera.h" +#include "settings/constants.h" namespace FluidSimulation { @@ -66,9 +67,13 @@ private: // Shader programs ShaderProgram m_normalRenderProgram; // For particle shaders ShaderProgram m_depthRenderProgram; // For depth shaders + ShaderProgram m_depthFilterProgram; ShaderProgram m_thicknessRenderProgram; // For thickness shaders ShaderProgram m_visualizationProgram; // For visualization shaders + GLuint m_depthFilterTempTex; + GLuint m_depthFilterTempFBO; // temporary fbo forfilter passes + // VBOs for particles and boundaries GLuint m_particleVBO; GLuint m_boundaryVBO; @@ -85,6 +90,9 @@ private: // Fullscreen quad VAO GLuint quadVAO; + float m_pointScale = h_POINT_SCALE; + float m_pointRadius = h_POINT_RADIUS; + // Initialization helper methods void initGLEW(); // Initialize GLEW void initOpenGLSettings(); // Set up OpenGL state @@ -95,6 +103,8 @@ private: void initFullscreenQuad(); // Set up fullscreen quad for visualization void setupShaderProgram(ShaderProgram& shaderProgram); + void computeGaussianWeights(int radius, std::vector<float>& outWeights); + void deleteFramebufferResources(ShaderProgram& shaderProgram); void resizeFramebuffer( ShaderProgram& shaderProgram, @@ -126,12 +136,18 @@ public: // Separate rendering functions void renderNormalFrame(size_t particleCount, size_t boundaryCount); // Render using Normal Shaders void renderDepthFrame(size_t particleCount, size_t boundaryCount); // Render using Depth Shaders + void renderDepthFilterFrame(); void renderThicknessFrame(size_t particleCount, size_t boundaryCount); void visualizeBuffer(RenderStage stage); // Visualize selected render stage // Methods to retrieve textures based on RenderStage GLuint getTexture(RenderStage stage) const; // Get original FBO texture GLuint getVisualizationTexture() const; // Get visualization FBO texture + + float getPointScale() { return m_pointScale; }; + float getPointRadius() { return m_pointRadius; }; + void setPointScale(float pScale) { m_pointScale = pScale; }; + void setPointRadius(float pRadius) { m_pointRadius = pRadius; }; }; } // namespace FluidSimulation diff --git a/src/settings/constants.h b/src/settings/constants.h index 5ea4afd..ba5edf1 100644 --- a/src/settings/constants.h +++ b/src/settings/constants.h @@ -20,4 +20,7 @@ const float h_H = 0.25f; // Smoothing radius const int NUM_PARTICLES = 50000; +const float h_POINT_SCALE = 14.0f; +const float h_POINT_RADIUS = 25.0f; + #endif // CONSTANTS_H -- GitLab