Fix #80529: Smoke dissolve rate affected by time steps

Now results are similar under different time steps. Additionally it is
now working correctly with different time scale, where smoke lifetime
is proportional to time scale.

Pull Request: https://projects.blender.org/blender/blender/pulls/138347
This commit is contained in:
Bartosz Kosiorek 2025-05-06 19:04:10 +02:00 committed by Brecht Van Lommel
parent 899f8e370f
commit 56144ee59d
4 changed files with 49 additions and 6 deletions

View File

@ -9,3 +9,4 @@ Local modifications:
* ./patches/precision-of-4d-vector.patch to increase precision of 4D vector normalization functions.
* ./patches/liquid-mesh-performance.patch improve liquid mesh generation by puting calculation of inverse radius outside for loops.
* ./patches/liquid-performance.patch improve liquid generation (without mesh) by precalculate sum of vectors and put it outside for loop.
* ./patches/smoke-dissolve-rate.patch Dissolve smoke independently from number of timesteps in Frame.

View File

@ -0,0 +1,38 @@
commit 4a2c116053be7d445f061bee074796dc87529b3f
Author: Bartosz Kosiorek <gang65@poczta.onet.pl>
Date: Fri May 2 19:59:49 2025 +0200
Physics: Dissolve smoke independently from number of timesteps in Frame
Fixes: 80529
diff --git a/extern/mantaflow/preprocessed/plugin/extforces.cpp b/extern/mantaflow/preprocessed/plugin/extforces.cpp
index 88935fa7ae9..eaf3e7d39f4 100644
--- a/extern/mantaflow/preprocessed/plugin/extforces.cpp
+++ b/extern/mantaflow/preprocessed/plugin/extforces.cpp
@@ -1652,10 +1652,11 @@ void dissolveSmoke(const FlagGrid &flags,
Grid<Real> *green = nullptr,
Grid<Real> *blue = nullptr,
int speed = 5,
- bool logFalloff = true)
+ bool logFalloff = true,
+ const float dissolveScale = 1.0)
{
- float dydx = 1.0f / (float)speed; // max density/speed = dydx
- float fac = 1.0f - dydx;
+ const float dydx = dissolveScale / (float)speed; // max density (1.0) * scale / speed = dydx
+ const float fac = 1.0f - dydx;
KnDissolveSmoke(flags, density, heat, red, green, blue, speed, logFalloff, dydx, fac);
}
static PyObject *_W_11(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
@@ -1676,8 +1677,9 @@ static PyObject *_W_11(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
Grid<Real> *blue = _args.getPtrOpt<Grid<Real>>("blue", 5, nullptr, &_lock);
int speed = _args.getOpt<int>("speed", 6, 5, &_lock);
bool logFalloff = _args.getOpt<bool>("logFalloff", 7, true, &_lock);
+ const float dissolveScale = _args.getOpt<float>("dissolveScale", 8, 1.0, &_lock);
_retval = getPyNone();
- dissolveSmoke(flags, density, heat, red, green, blue, speed, logFalloff);
+ dissolveSmoke(flags, density, heat, red, green, blue, speed, logFalloff, dissolveScale);
_args.check();
}
pbFinalizePlugin(parent, "dissolveSmoke", !noTiming);

View File

@ -1652,10 +1652,11 @@ void dissolveSmoke(const FlagGrid &flags,
Grid<Real> *green = nullptr,
Grid<Real> *blue = nullptr,
int speed = 5,
bool logFalloff = true)
bool logFalloff = true,
const float dissolveScale = 1.0)
{
float dydx = 1.0f / (float)speed; // max density/speed = dydx
float fac = 1.0f - dydx;
const float dydx = dissolveScale / (float)speed; // max density (1.0) * scale / speed = dydx
const float fac = 1.0f - dydx;
KnDissolveSmoke(flags, density, heat, red, green, blue, speed, logFalloff, dydx, fac);
}
static PyObject *_W_11(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
@ -1676,8 +1677,9 @@ static PyObject *_W_11(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
Grid<Real> *blue = _args.getPtrOpt<Grid<Real>>("blue", 5, nullptr, &_lock);
int speed = _args.getOpt<int>("speed", 6, 5, &_lock);
bool logFalloff = _args.getOpt<bool>("logFalloff", 7, true, &_lock);
const float dissolveScale = _args.getOpt<float>("dissolveScale", 8, 1.0, &_lock);
_retval = getPyNone();
dissolveSmoke(flags, density, heat, red, green, blue, speed, logFalloff);
dissolveSmoke(flags, density, heat, red, green, blue, speed, logFalloff, dissolveScale);
_args.check();
}
pbFinalizePlugin(parent, "dissolveSmoke", !noTiming);

View File

@ -336,7 +336,8 @@ def smoke_step_$ID$():\n\
\n\
if using_dissolve_s$ID$:\n\
mantaMsg('Dissolving smoke')\n\
dissolveSmoke(flags=flags_s$ID$, density=density_s$ID$, heat=heat_s$ID$, red=color_r_s$ID$, green=color_g_s$ID$, blue=color_b_s$ID$, speed=dissolveSpeed_s$ID$, logFalloff=using_logdissolve_s$ID$)\n\
dissolveSmoke(flags=flags_s$ID$, density=density_s$ID$, heat=heat_s$ID$, red=color_r_s$ID$, green=color_g_s$ID$, blue=color_b_s$ID$, \
speed=dissolveSpeed_s$ID$, logFalloff=using_logdissolve_s$ID$, dissolveScale=s$ID$.timestep / frameLengthUnscaled_s$ID$)\n\
\n\
mantaMsg('Advecting density')\n\
advectSemiLagrange(flags=flags_s$ID$, vel=vel_s$ID$, grid=density_s$ID$, order=2)\n\
@ -469,7 +470,8 @@ def step_noise_$ID$():\n\
\n\
if using_dissolve_s$ID$:\n\
mantaMsg('Dissolving noise')\n\
dissolveSmoke(flags=flags_sn$ID$, density=density_sn$ID$, heat=None, red=color_r_sn$ID$, green=color_g_sn$ID$, blue=color_b_sn$ID$, speed=dissolveSpeed_s$ID$, logFalloff=using_logdissolve_s$ID$)\n\
dissolveSmoke(flags=flags_sn$ID$, density=density_sn$ID$, heat=None, red=color_r_sn$ID$, green=color_g_sn$ID$, blue=color_b_sn$ID$, \
speed=dissolveSpeed_s$ID$, logFalloff=using_logdissolve_s$ID$, dissolveScale=s$ID$.timestep / frameLengthUnscaled_s$ID$)\n\
\n\
mantaMsg('Advecting UVs and updating UV weight')\n\
advectSemiLagrange(flags=flags_s$ID$, vel=vel_s$ID$, grid=uvGrid0_s$ID$, order=2)\n\