Skip to content

Commit 755c4c4

Browse files
authored
Fix Volumetric Nebula Bugs and Add Smoothing (#6854)
* Fix 3d tex generation * Fix blending and emissive * Add Smoothing * Add smoothing parameter * Correctly calculate fractional smoothing
1 parent 168b331 commit 755c4c4

5 files changed

Lines changed: 33 additions & 13 deletions

File tree

code/def_files/data/effects/volumetric-f.sdr

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,6 @@ void main()
100100
vec3 sampleposition = position / nebSize + 0.5;
101101
vec4 volume_sample = textureGrad(volume_tex, sampleposition, gradX, gradY);
102102

103-
float stepsize_current = min(max(stepsize, volume_sample.x * udfScale), mintMax - stept);
104-
105103
#ifdef DO_EDGE_SMOOTHING
106104
//Average 3D texel with texels on corner, in an attempt to reduce jagged edges.
107105
float stepcolor_alpha = volume_sample.a;
@@ -121,6 +119,8 @@ void main()
121119
float stepcolor_alpha = volume_sample.a;
122120
#endif
123121

122+
float stepsize_current = min(max(stepsize, step(stepcolor_alpha, 0.01) * volume_sample.x * udfScale), mintMax - stept);
123+
124124
float stepalpha = -(pow(alphalim, 1.0 / (opacitydistance / stepsize_current)) - 1.0f) * stepcolor_alpha;
125125
//All the following computations are just required if we have a stepcoloralpha that is non-zero.
126126
if(stepcolor_alpha > 0.01)
@@ -151,7 +151,7 @@ void main()
151151
//Emissive
152152
cumnebdist += stepcolor_alpha * stepsize_current;
153153
vec3 emissive_lod = textureLod(emissive, fragTexCoord.xy, clamp(cumnebdist * emissiveSpreadFactor, 0, float(textureQueryLevels(emissive) - 1))).rgb;
154-
vec3 stepcolor_emissive = emissive_lod.rgb * pow(alphalim, 1.0 / (opacitydistance / ((depth - stept) * emissiveFalloff + 0.01))) * emissiveIntensity;
154+
vec3 stepcolor_emissive = clamp(emissive_lod.rgb * pow(alphalim, 1.0 / (opacitydistance / ((depth - stept) * emissiveFalloff + 0.01))) * emissiveIntensity, 0, 1);
155155

156156
//Step finish
157157
vec3 stepcolor = clamp(stepcolor_diffuse + stepcolor_emissive, 0, 1);
@@ -165,7 +165,5 @@ void main()
165165
break;
166166
}
167167

168-
cumcolor += cumOMAlpha * color_in.rgb;
169-
170-
fragOut0 = vec4(cumcolor, 1);
168+
fragOut0 = vec4(cumOMAlpha * color_in.rgb + ((1.0 - cumOMAlpha) * cumcolor), 1);
171169
}

code/nebula/volumetrics.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ volumetric_nebula& volumetric_nebula::parse_volumetric_nebula() {
5555
stuff_int(&oversampling);
5656
}
5757

58+
if (optional_string("+Smoothing:")) {
59+
stuff_float(&smoothing);
60+
}
61+
5862
//Lighting settings
5963
if (optional_string("+Heyney Greenstein Coefficient:")) {
6064
stuff_float(&henyeyGreensteinCoeff);
@@ -155,6 +159,10 @@ const std::tuple<float, float, float>& volumetric_nebula::getNebulaColor() const
155159
return nebulaColor;
156160
}
157161

162+
int volumetric_nebula::getVolumeBitmapSmoothingSteps() const {
163+
return std::max(1, static_cast<int>(static_cast<float>(1 << (resolution + oversampling - 1)) * std::min(smoothing, 0.5f)));
164+
}
165+
158166
bool volumetric_nebula::getEdgeSmoothing() const {
159167
return Detail.nebula_detail == MAX_DETAIL_VALUE || doEdgeSmoothing; //Only for highest setting, or when the lab has an override.
160168
}
@@ -208,7 +216,7 @@ float volumetric_nebula::getGlobalLightDistanceFactor() const {
208216
}
209217

210218
float volumetric_nebula::getGlobalLightStepsize() const {
211-
return getOpacityDistance() / static_cast<float>(getGlobalLightSteps()) * getGlobalLightDistanceFactor();
219+
return getOpacityDistance() * static_cast<float>(getVolumeBitmapSmoothingSteps()) / static_cast<float>(getGlobalLightSteps()) * getGlobalLightDistanceFactor();
212220
}
213221

214222
bool volumetric_nebula::getNoiseActive() const {
@@ -354,16 +362,22 @@ void volumetric_nebula::renderVolumeBitmap() {
354362

355363
//Sample the nebula values from the binary cubegrid.
356364
volumeBitmapData = make_unique<ubyte[]>(n * n * n * 4);
357-
int oversamplingCount = (1 << (oversampling - 1)) + 1;
358-
float oversamplingDivisor = 255.1f / static_cast<float>(oversamplingCount);
365+
int oversamplingCount = (1 << (oversampling - 1));
366+
367+
int smoothing_steps = getVolumeBitmapSmoothingSteps();
368+
float oversamplingDivisor = 255.1f / (static_cast<float>(oversamplingCount + smoothing_steps) * static_cast<float>(oversamplingCount + smoothing_steps) * static_cast<float>(oversamplingCount + smoothing_steps));
369+
int smoothStart = smoothing_steps / 2;
370+
int smoothStop = (smoothing_steps / 2 + (1 & smoothing_steps));
371+
359372
for (int x = 0; x < n; x++) {
360373
for (int y = 0; y < n; y++) {
361374
for (int z = 0; z < n; z++) {
362375
int sum = 0;
363-
for (int sx = x * oversampling; sx <= (x + 1) * oversampling; sx++) {
364-
for (int sy = y * oversampling; sy <= (y + 1) * oversampling; sy++) {
365-
for (int sz = z * oversampling; sz <= (z + 1) * oversampling; sz++) {
366-
if (volumeSampleCache[sx * nSample * nSample + sy * nSample + sz])
376+
for (int sx = x * oversamplingCount - smoothStart; sx < (x + 1) * oversamplingCount + smoothStop; sx++) {
377+
for (int sy = y * oversamplingCount - smoothStart; sy < (y + 1) * oversamplingCount + smoothStop; sy++) {
378+
for (int sz = z * oversamplingCount - smoothStart; sz < (z + 1) * oversamplingCount + smoothStop; sz++) {
379+
if (sx >= 0 && sx < nSample && sy >= 0 && sy < nSample && sz >= 0 && sz < nSample &&
380+
volumeSampleCache[sx * nSample * nSample + sy * nSample + sz])
367381
sum++;
368382
}
369383
}

code/nebula/volumetrics.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ class volumetric_nebula {
3434
int resolution = 6;
3535
//Oversampling of 3D-Texture. Will quadruple loading computation time for each increment, but improves banding especially at lower resolutions. 1 - 3. Mostly Loading time cost.
3636
int oversampling = 2;
37+
//How much the edge of the POF should be smoothed to be less hard
38+
float smoothing = 0.f;
3739
//Resolution of Noise 3D-Texture as 2^n. 5 - 8 recommended. Mostly VRAM cost
3840
int noiseResolution = 5;
3941

@@ -95,6 +97,8 @@ class volumetric_nebula {
9597
const vec3d& getSize() const;
9698
const std::tuple<float, float, float>& getNebulaColor() const;
9799

100+
int getVolumeBitmapSmoothingSteps() const;
101+
98102
bool getEdgeSmoothing() const;
99103
int getSteps() const;
100104
int getGlobalLightSteps() const;

fred2/missionsave.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2794,6 +2794,7 @@ int CFred_mission_save::save_mission_info()
27942794
FRED_ENSURE_PROPERTY_VERSION_WITH_DEFAULT("+Steps:", 1, ";;FSO 23.1.0;;", 15, " %d", The_mission.volumetrics->steps);
27952795
FRED_ENSURE_PROPERTY_VERSION_WITH_DEFAULT("+Resolution:", 1, ";;FSO 23.1.0;;", 6, " %d", The_mission.volumetrics->resolution);
27962796
FRED_ENSURE_PROPERTY_VERSION_WITH_DEFAULT("+Oversampling:", 1, ";;FSO 23.1.0;;", 2, " %d", The_mission.volumetrics->oversampling);
2797+
FRED_ENSURE_PROPERTY_VERSION_WITH_DEFAULT("+Smoothing:", 1, ";;FSO 25.0.0;;", 0.f, " %f", The_mission.volumetrics->smoothing);
27972798
FRED_ENSURE_PROPERTY_VERSION_WITH_DEFAULT_F("+Heyney Greenstein Coefficient:", 1, ";;FSO 23.1.0;;", 0.2f, " %f", The_mission.volumetrics->henyeyGreensteinCoeff);
27982799
FRED_ENSURE_PROPERTY_VERSION_WITH_DEFAULT_F("+Sun Falloff Factor:", 1, ";;FSO 23.1.0;;", 1.0f, " %f", The_mission.volumetrics->globalLightDistanceFactor);
27992800
FRED_ENSURE_PROPERTY_VERSION_WITH_DEFAULT("+Sun Steps:", 1, ";;FSO 23.1.0;;", 6, " %d", The_mission.volumetrics->globalLightSteps);
@@ -2831,6 +2832,7 @@ int CFred_mission_save::save_mission_info()
28312832
bypass_comment(";;FSO 23.1.0;; +Steps:");
28322833
bypass_comment(";;FSO 23.1.0;; +Resolution:");
28332834
bypass_comment(";;FSO 23.1.0;; +Oversampling:");
2835+
bypass_comment(";;FSO 25.0.0;; +Smoothing:");
28342836
bypass_comment(";;FSO 23.1.0;; +Heyney Greenstein Coefficient:");
28352837
bypass_comment(";;FSO 23.1.0;; +Sun Falloff Factor:");
28362838
bypass_comment(";;FSO 23.1.0;; +Sun Steps:");

qtfred/src/mission/missionsave.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2684,6 +2684,7 @@ int CFred_mission_save::save_mission_info()
26842684
FRED_ENSURE_PROPERTY_VERSION_WITH_DEFAULT("+Steps:", 1, ";;FSO 23.1.0;;", 15, " %d", The_mission.volumetrics->steps);
26852685
FRED_ENSURE_PROPERTY_VERSION_WITH_DEFAULT("+Resolution:", 1, ";;FSO 23.1.0;;", 6, " %d", The_mission.volumetrics->resolution);
26862686
FRED_ENSURE_PROPERTY_VERSION_WITH_DEFAULT("+Oversampling:", 1, ";;FSO 23.1.0;;", 2, " %d", The_mission.volumetrics->oversampling);
2687+
FRED_ENSURE_PROPERTY_VERSION_WITH_DEFAULT("+Smoothing:", 1, ";;FSO 25.0.0;;", 0.f, " %f", The_mission.volumetrics->smoothing);
26872688
FRED_ENSURE_PROPERTY_VERSION_WITH_DEFAULT_F("+Heyney Greenstein Coefficient:", 1, ";;FSO 23.1.0;;", 0.2f, " %f", The_mission.volumetrics->henyeyGreensteinCoeff);
26882689
FRED_ENSURE_PROPERTY_VERSION_WITH_DEFAULT_F("+Sun Falloff Factor:", 1, ";;FSO 23.1.0;;", 1.0f, " %f", The_mission.volumetrics->globalLightDistanceFactor);
26892690
FRED_ENSURE_PROPERTY_VERSION_WITH_DEFAULT("+Sun Steps:", 1, ";;FSO 23.1.0;;", 6, " %d", The_mission.volumetrics->globalLightSteps);
@@ -2721,6 +2722,7 @@ int CFred_mission_save::save_mission_info()
27212722
bypass_comment(";;FSO 23.1.0;; +Steps:");
27222723
bypass_comment(";;FSO 23.1.0;; +Resolution:");
27232724
bypass_comment(";;FSO 23.1.0;; +Oversampling:");
2725+
bypass_comment(";;FSO 25.0.0;; +Smoothing:");
27242726
bypass_comment(";;FSO 23.1.0;; +Heyney Greenstein Coefficient:");
27252727
bypass_comment(";;FSO 23.1.0;; +Sun Falloff Factor:");
27262728
bypass_comment(";;FSO 23.1.0;; +Sun Steps:");

0 commit comments

Comments
 (0)