diff --git a/src/FluidRenderer.cpp b/src/FluidRenderer.cpp index 9ffaedae277485d6647733bd68dfe7180a1363f7..7f0764433b953827e5bf76791b6a4ea18b8a7b39 100644 --- a/src/FluidRenderer.cpp +++ b/src/FluidRenderer.cpp @@ -637,7 +637,7 @@ void FluidRenderer::renderDepthFrame(size_t particleCount, size_t boundaryCount) glUniformMatrix4fv(m_depthRenderProgram.viewMatrixLoc, 1, GL_TRUE, viewMatrix.m); if (m_depthRenderProgram.sphereRadiusLoc != -1) { - glUniform1f(m_depthRenderProgram.sphereRadiusLoc, 0.05f); + glUniform1f(m_depthRenderProgram.sphereRadiusLoc, m_sphereRadius); } if (m_depthRenderProgram.pointRadiusLoc != -1) { glUniform1f(m_depthRenderProgram.pointRadiusLoc, m_pointRadius); @@ -729,16 +729,16 @@ void FluidRenderer::renderDepthFilterFrame() m_fbHeight); glUniform1f(glGetUniformLocation(m_depthFilterProgram.programID, "worldRadiusMeters"), - worldRadiusMeters); + m_worldSmoothingRadius); glUniform1f(glGetUniformLocation(m_depthFilterProgram.programID, "maxPixelRadius"), - maxPixelRadius); + m_maxPixelRadius); glUniform1f(glGetUniformLocation(m_depthFilterProgram.programID, "sigmaSpatialFactor"), - sigmaSpatialFactor); + m_spatialFactor); glUniform1f(glGetUniformLocation(m_depthFilterProgram.programID, "sigma_r"), - sigmaR); + m_blurrStrength); glUniform1f(glGetUniformLocation(m_depthFilterProgram.programID, "depthThreshold"), - depthThresh); + m_deptThreshold); // Render the fullscreen quad glBindVertexArray(quadVAO); @@ -991,7 +991,7 @@ void FluidRenderer::renderThicknessAttenFrame() // 3) Set uniform: absorption, fluidColor, etc. float absorption = 0.2f; // tweak to taste GLuint absorpLoc = glGetUniformLocation(m_thicknessAttenProgram.programID, "absorption"); - glUniform1f(absorpLoc, absorption); + glUniform1f(absorpLoc, m_absorbtion); // color float fluidR = 0.2f, fluidG = 0.7f, fluidB = 1.0f; @@ -1069,18 +1069,18 @@ void FluidRenderer::renderFinalCombineFrame() // Set fluid color and shininess vec3 fluidColor = vec3(0.05f, 0.5f, 0.9f); // Example color glUniform3f(glGetUniformLocation(m_finalCombineProgram.programID, "fluidColor"), - fluidColor.x, fluidColor.y, fluidColor.z); + m_fluidColor.x, m_fluidColor.y, m_fluidColor.z); float shininess = 82.0f; // Example shininess - glUniform1f(glGetUniformLocation(m_finalCombineProgram.programID, "shininess"), shininess); + glUniform1f(glGetUniformLocation(m_finalCombineProgram.programID, "shininess"), m_shininess); // Set Fresnel parameters float fresnelPower = 2.0f; float fresnelScale = 0.5f; float fresnelBias = 0.1f; - glUniform1f(glGetUniformLocation(m_finalCombineProgram.programID, "fresnelPower"), fresnelPower); - glUniform1f(glGetUniformLocation(m_finalCombineProgram.programID, "fresnelScale"), fresnelScale); - glUniform1f(glGetUniformLocation(m_finalCombineProgram.programID, "fresnelBias"), fresnelBias); + glUniform1f(glGetUniformLocation(m_finalCombineProgram.programID, "fresnelPower"), m_fresnelPower); + glUniform1f(glGetUniformLocation(m_finalCombineProgram.programID, "fresnelScale"), m_fresnelScale); + glUniform1f(glGetUniformLocation(m_finalCombineProgram.programID, "fresnelBias"), m_fresnelBias); // Render the fullscreen quad glBindVertexArray(quadVAO); diff --git a/src/FluidSimulationApp.cpp b/src/FluidSimulationApp.cpp index 79ee9c9fafe4172831e82d3c8ba77b1deb375aa1..afcfe12b792f3ab1eb2cc1d16017100e068e5612 100644 --- a/src/FluidSimulationApp.cpp +++ b/src/FluidSimulationApp.cpp @@ -55,8 +55,6 @@ 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 @@ -80,11 +78,6 @@ 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 @@ -104,9 +97,6 @@ namespace FluidSimulation { // Update constants on the CUDA device m_fluidSimulation->updateConstants(); - - m_fluidRenderer->setPointRadius(pointRadius); - m_fluidRenderer->setPointScale(pointScale); } } else @@ -119,9 +109,6 @@ 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))) @@ -133,17 +120,216 @@ namespace FluidSimulation { viscosity = m_fluidSimulation->getViscosity(); smoothingRadius = m_fluidSimulation->getSmoothingRadius(); static int restDensityInt = static_cast<int>(restDensity); + } + + } + + } + + void FluidSimulatorApp::RenderParameterControl() + { + float buttonWidth = ImGui::GetContentRegionAvail().x; + ImGui::Spacing(); + + if (ImGui::CollapsingHeader("Screen Space Parameters", ImGuiTreeNodeFlags_DefaultOpen)) + { + // Sliders for each parameter, storing locally + static float pointScale = m_fluidRenderer->getPointScale(); + static float pointRadius = m_fluidRenderer->getPointRadius(); + static float sphereRadius = m_fluidRenderer->getSphereRadius(); + + static float worldSmoothingRadius = m_fluidRenderer->getWorldSmoothingRadius(); + static float maxPixelRadius = m_fluidRenderer->getMaxPixelRadius(); + static float spatialFactor = m_fluidRenderer->getSpatialFactor(); + static float blurStrength = m_fluidRenderer->getBlurStrength(); + static float depthThreshold = m_fluidRenderer->getDepthThreshold(); + + static int thicknessBlurRadius = m_fluidRenderer->getThicknessBlurRadius(); + static float absorption = m_fluidRenderer->getAbsorption(); + + static float shininess = m_fluidRenderer->getShininess(); + static float fresnelPower = m_fluidRenderer->getFresnelPower(); + static float fresnelScale = m_fluidRenderer->getFresnelScale(); + static float fresnelBias = m_fluidRenderer->getFresnelBias(); + + static float fluidColorArray[3] = {1.0f, 1.0f, 1.0f}; + static bool once = false; + if (!once) + { + float3 initialColor = m_fluidRenderer->getFluidColor(); + fluidColorArray[0] = initialColor.x; + fluidColorArray[1] = initialColor.y; + fluidColorArray[2] = initialColor.z; + once = true; + } + + ImGui::Text("Fluid Color"); ImGui::SameLine(); + ImGuiColorEditFlags colorFlags = ImGuiColorEditFlags_NoInputs + | ImGuiColorEditFlags_NoLabel + | ImGuiColorEditFlags_PickerHueWheel; + if (ImGui::ColorEdit3("##FluidColor", fluidColorArray, colorFlags)) + { + m_fluidRenderer->setFluidColor( + make_float3(fluidColorArray[0], fluidColorArray[1], fluidColorArray[2]) + ); + } + // Begin Sliders + ImGui::PushItemWidth(-1); // let sliders use full width + + ImGui::Text("Point Radius"); + if (ImGui::SliderFloat("##PointRadius", &pointRadius, 1.0f, 50.0f, "%.1f")) + { + m_fluidRenderer->setPointRadius(pointRadius); + } + + ImGui::Text("Point Scale"); + if (ImGui::SliderFloat("##PointScale", &pointScale, 1.0f, 30.0f, "%.1f")) + { + m_fluidRenderer->setPointScale(pointScale); + } + + ImGui::Text("Sphere Radius"); + if (ImGui::SliderFloat("##SphereRadius", &sphereRadius, 0.0f, 1.0f, "%.3f")) + { + m_fluidRenderer->setSphereRadius(sphereRadius); + } + + // -- World Smoothing Radius + ImGui::Text("World Smoothing Radius"); + if (ImGui::SliderFloat("##WorldSmoothRadius", &worldSmoothingRadius, 0.0f, 1.0f, "%.3f")) + { + m_fluidRenderer->setWorldSmoothingRadius(worldSmoothingRadius); + } + + // -- Max Pixel Radius + ImGui::Text("Max Pixel Radius"); + if (ImGui::SliderFloat("##MaxPixelRadius", &maxPixelRadius, 1.0f, 200.0f, "%.1f")) + { + m_fluidRenderer->setMaxPixelRadius(maxPixelRadius); + } + + // -- Spatial Factor + ImGui::Text("Spatial Factor"); + if (ImGui::SliderFloat("##SpatialFactor", &spatialFactor, 1.0f, 30.0f, "%.1f")) + { + m_fluidRenderer->setSpatialFactor(spatialFactor); + } + + // -- Blur Strength + ImGui::Text("Blur Strength"); + if (ImGui::SliderFloat("##BlurStrength", &blurStrength, 0.0f, 10.0f, "%.1f")) + { + m_fluidRenderer->setBlurStrength(blurStrength); + } + + // -- Depth Threshold + ImGui::Text("Depth Threshold"); + if (ImGui::SliderFloat("##DepthThreshold", &depthThreshold, 0.0f, 1.0f, "%.3f")) + { + m_fluidRenderer->setDepthThreshold(depthThreshold); + } + + // -- Thickness Blur Radius (int) + ImGui::Text("Thickness Blur Radius"); + if (ImGui::SliderInt("##ThickBlurRadius", &thicknessBlurRadius, 0, 100)) + { + m_fluidRenderer->setThicknessBlurRadius(thicknessBlurRadius); + } + + // -- Absorption + ImGui::Text("Absorption"); + if (ImGui::SliderFloat("##Absorption", &absorption, 0.0f, 2.0f, "%.2f")) + { + m_fluidRenderer->setAbsorption(absorption); + } + + // -- Shininess + ImGui::Text("Shininess"); + if (ImGui::SliderFloat("##Shininess", &shininess, 0.0f, 200.0f, "%.1f")) + { + m_fluidRenderer->setShininess(shininess); + } + + // -- Fresnel Power + ImGui::Text("Fresnel Power"); + if (ImGui::SliderFloat("##FresnelPower", &fresnelPower, 0.0f, 10.0f, "%.2f")) + { + m_fluidRenderer->setFresnelPower(fresnelPower); + } + + // -- Fresnel Scale + ImGui::Text("Fresnel Scale"); + if (ImGui::SliderFloat("##FresnelScale", &fresnelScale, 0.0f, 1.0f, "%.2f")) + { + m_fluidRenderer->setFresnelScale(fresnelScale); + } + + // -- Fresnel Bias + ImGui::Text("Fresnel Bias"); + if (ImGui::SliderFloat("##FresnelBias", &fresnelBias, 0.0f, 1.0f, "%.2f")) + { + m_fluidRenderer->setFresnelBias(fresnelBias); + } + + ImGui::PopItemWidth(); + + // Reset + if (ImGui::Button("Reset Parameters", ImVec2(buttonWidth, 0))) + { + // Revert to your constant defaults m_fluidRenderer->setPointScale(h_POINT_SCALE); m_fluidRenderer->setPointRadius(h_POINT_RADIUS); - pointScale = m_fluidRenderer->getPointScale(); - pointRadius = m_fluidRenderer->getPointRadius(); - } + pointScale = m_fluidRenderer->getPointScale(); + pointRadius = m_fluidRenderer->getPointRadius(); - } + m_fluidRenderer->setSphereRadius(h_SPHERE_RADIUS); + sphereRadius = m_fluidRenderer->getSphereRadius(); + + m_fluidRenderer->setWorldSmoothingRadius(h_worldRadiusMeters); + worldSmoothingRadius = m_fluidRenderer->getWorldSmoothingRadius(); + + m_fluidRenderer->setMaxPixelRadius(h_maxPixelRadius); + maxPixelRadius = m_fluidRenderer->getMaxPixelRadius(); + + m_fluidRenderer->setSpatialFactor(h_sigmaSpatialFactor); + spatialFactor = m_fluidRenderer->getSpatialFactor(); + + m_fluidRenderer->setBlurStrength(h_sigmaR); + blurStrength = m_fluidRenderer->getBlurStrength(); + m_fluidRenderer->setDepthThreshold(h_depthThresh); + depthThreshold = m_fluidRenderer->getDepthThreshold(); + + m_fluidRenderer->setThicknessBlurRadius(h_thickBlurrRadius); + thicknessBlurRadius = m_fluidRenderer->getThicknessBlurRadius(); + + m_fluidRenderer->setAbsorption(h_absorbtion); + absorption = m_fluidRenderer->getAbsorption(); + + m_fluidRenderer->setShininess(h_shininess); + shininess = m_fluidRenderer->getShininess(); + + m_fluidRenderer->setFresnelPower(h_fresnelPower); + fresnelPower = m_fluidRenderer->getFresnelPower(); + + m_fluidRenderer->setFresnelScale(h_fresnelScale); + fresnelScale = m_fluidRenderer->getFresnelScale(); + + m_fluidRenderer->setFresnelBias(h_fresnelBias); + fresnelBias = m_fluidRenderer->getFresnelBias(); + + // Reset fluid color + float3 defaultColor = h_fluidColor; + m_fluidRenderer->setFluidColor(defaultColor); + fluidColorArray[0] = defaultColor.x; + fluidColorArray[1] = defaultColor.y; + fluidColorArray[2] = defaultColor.z; + } + } } + void FluidSimulatorApp::RenderControlPannel() { @@ -207,6 +393,8 @@ namespace FluidSimulation { FluidParameterControl(); + RenderParameterControl(); + ImGui::End(); } diff --git a/src/cuda/init_cuda.cu b/src/cuda/init_cuda.cu index 54234d582eb551b011bc93e4aac9d2d06ab16cbc..779ea6277c67b757e0f97d2e09cefab2ddb4316a 100644 --- a/src/cuda/init_cuda.cu +++ b/src/cuda/init_cuda.cu @@ -382,10 +382,14 @@ void resetSimulation( void updateConstantsOnDevice(float particleMass, float restDensity, float viscosity, float smoothingRadius) { // Recalculate derived constants float h_H2 = smoothingRadius * smoothingRadius; - float h_POLY6_CONST = 315.0f / (64.0f * h_PI * powf(smoothingRadius, 9)); - float h_SPIKY_GRAD_CONST = -45.0f / (h_PI * powf(smoothingRadius, 6)); - float h_VISC_LAP_CONST = 45.0f / (h_PI * powf(smoothingRadius, 6)); + float h_POLY6_CONST = 315.0f / (64.0f * M_PI * powf(smoothingRadius, 9)); + float h_SPIKY_GRAD_CONST = -45.0f / (M_PI * powf(smoothingRadius, 6)); + float h_VISC_LAP_CONST = 45.0f / (M_PI * powf(smoothingRadius, 6)); + const float poly6_d1 = -945.f / (32.f * M_PI * powf(smoothingRadius, 9.f)); + const float surface_tens_normalization = 32.f / (M_PI * powf(smoothingRadius, 9.f)); + const float surface_tens_term = powf(smoothingRadius, 6.f) / 64.f; + // Send constants to CUDA device cudaMemcpyToSymbol(PARTICLE_MASS, &particleMass, sizeof(float)); cudaMemcpyToSymbol(REST_DENSITY, &restDensity, sizeof(float)); @@ -395,6 +399,22 @@ void updateConstantsOnDevice(float particleMass, float restDensity, float viscos cudaMemcpyToSymbol(POLY6_CONST, &h_POLY6_CONST, sizeof(float)); cudaMemcpyToSymbol(SPIKY_GRAD_CONST, &h_SPIKY_GRAD_CONST, sizeof(float)); cudaMemcpyToSymbol(VISC_LAP_CONST, &h_VISC_LAP_CONST, sizeof(float)); + + cudaMemcpyToSymbol(POLY6_D1_CONST, &poly6_d1, sizeof(float)); + cudaMemcpyToSymbol(SURFACE_TENS_CONST, &surface_tens_normalization, sizeof(float)); + cudaMemcpyToSymbol(SURFACE_TENS_TERM, &surface_tens_term, sizeof(float)); + + // Add surfacetension coefficiant when implmented + //cudaMemcpyToSymbol(SURFACE_TENS_COEFFICIENT, &h_surface_tenns_coef, sizeof(float)); + + ComputePCISPHStiffness( + 0.006, + particleMass, + restDensity, + smoothingRadius, + smoothingRadius/2.0f, + h_SPIKY_GRAD_CONST + ); } // Cleanup device arrays diff --git a/src/include/FluidRenderer.h b/src/include/FluidRenderer.h index efbd63af5e2a7e2f94e82da0cf6b623d50e7bc82..eb1bed756c941bcfa74de06fa31f29456ce7de2f 100644 --- a/src/include/FluidRenderer.h +++ b/src/include/FluidRenderer.h @@ -104,6 +104,24 @@ private: float m_pointScale = h_POINT_SCALE; float m_pointRadius = h_POINT_RADIUS; + + float m_sphereRadius = h_SPHERE_RADIUS; + + float m_worldSmoothingRadius = h_worldRadiusMeters; + float m_maxPixelRadius = h_maxPixelRadius; + float m_spatialFactor = h_sigmaSpatialFactor; + float m_blurrStrength = h_sigmaR; + float m_deptThreshold = h_depthThresh; + + int thicknesBlurrRadius = h_thickBlurrRadius; + float m_absorbtion = h_absorbtion; + + float3 m_fluidColor = h_fluidColor; + float m_shininess = h_shininess; + + float m_fresnelPower = h_fresnelPower; + float m_fresnelScale = h_fresnelScale; + float m_fresnelBias = h_fresnelBias; // Initialization helper methods void initGLEW(); // Initialize GLEW @@ -167,6 +185,45 @@ public: float getPointRadius() { return m_pointRadius; }; void setPointScale(float pScale) { m_pointScale = pScale; }; void setPointRadius(float pRadius) { m_pointRadius = pRadius; }; + + float getSphereRadius() const { return m_sphereRadius; } + void setSphereRadius(float radius) { m_sphereRadius = radius; } + + float getWorldSmoothingRadius() const { return m_worldSmoothingRadius; } + void setWorldSmoothingRadius(float worldRadius) { m_worldSmoothingRadius = worldRadius; } + + float getMaxPixelRadius() const { return m_maxPixelRadius; } + void setMaxPixelRadius(float maxPixRad) { m_maxPixelRadius = maxPixRad; } + + float getSpatialFactor() const { return m_spatialFactor; } + void setSpatialFactor(float spatialFactor) { m_spatialFactor = spatialFactor; } + + float getBlurStrength() const { return m_blurrStrength; } + void setBlurStrength(float blurStrength) { m_blurrStrength = blurStrength; } + + float getDepthThreshold() const { return m_deptThreshold; } + void setDepthThreshold(float depthThresh) { m_deptThreshold = depthThresh; } + + int getThicknessBlurRadius() const { return thicknesBlurrRadius; } + void setThicknessBlurRadius(int blurRadius) { thicknesBlurrRadius = blurRadius; } + + float getAbsorption() const { return m_absorbtion; } + void setAbsorption(float absorption) { m_absorbtion = absorption; } + + float getShininess() const { return m_shininess; } + void setShininess(float shininess) { m_shininess = shininess; } + + float getFresnelPower() const { return m_fresnelPower; } + void setFresnelPower(float power) { m_fresnelPower = power; } + + float getFresnelScale() const { return m_fresnelScale; } + void setFresnelScale(float scale) { m_fresnelScale = scale; } + + float getFresnelBias() const { return m_fresnelBias; } + void setFresnelBias(float bias) { m_fresnelBias = bias; } + + float3 getFluidColor() const { return m_fluidColor; }; + void setFluidColor(float3 newColor) { m_fluidColor = newColor; }; }; } // namespace FluidSimulation diff --git a/src/include/FluidSimulationApp.h b/src/include/FluidSimulationApp.h index 0211cbf52d1ab6a9ac385e83103359a4679bc041..d5dc8ae98847a11b7a2275f6b4eaa65ddf805cee 100644 --- a/src/include/FluidSimulationApp.h +++ b/src/include/FluidSimulationApp.h @@ -28,6 +28,7 @@ namespace FluidSimulation void RenderControlPannel(); void RenderFluidView(); void FluidParameterControl(); + void RenderParameterControl(); public: FluidSimulatorApp(appSettings* appSettings); diff --git a/src/settings/constants.h b/src/settings/constants.h index 29d7adc9eb88d74f2d08e2fcb30a053ff38fb456..b8ad4fb20a07aee9f10c60b52f6cb411623fba25 100644 --- a/src/settings/constants.h +++ b/src/settings/constants.h @@ -21,7 +21,29 @@ const float h_H = 0.20f; // Smoothing radius const int NUM_PARTICLES = 200000; +// Rendner parameters + const float h_POINT_SCALE = 14.0f; const float h_POINT_RADIUS = 25.0f; +const float h_SPHERE_RADIUS = 0.05f; + +const float h_worldRadiusMeters = 0.2f; // e.g. 2 cm smoothing in real space +const float h_maxPixelRadius = 60.0f; // clamp for performance +const float h_sigmaSpatialFactor = 10.0f; // controls the spatial falloff in the blur loop +const float h_sigmaR = 4.0f; // range weight exponent +const float h_depthThresh = 0.2f; // bilateral threshold for ignoring big depth jumps + +const int h_thickBlurrRadius = 24; +const float h_absorbtion = 0.2f; + +const float h_shininess = 82.0f; + +// fresnel parameters +const float h_fresnelPower = 2.0f; +const float h_fresnelScale = 0.5f; +const float h_fresnelBias = 0.1f; + +const float3 h_fluidColor = {0.2f, 0.7f, 1.0f}; + #endif // CONSTANTS_H