exponential height fog (#275)
This commit is contained in:
+40
-12
@@ -11,7 +11,7 @@ using namespace wiGraphics;
|
||||
void WeatherWindow::Create(EditorComponent* editor)
|
||||
{
|
||||
wiWindow::Create("Weather Window");
|
||||
SetSize(XMFLOAT2(660, 560));
|
||||
SetSize(XMFLOAT2(660, 610));
|
||||
|
||||
float x = 180;
|
||||
float y = 20;
|
||||
@@ -19,6 +19,15 @@ void WeatherWindow::Create(EditorComponent* editor)
|
||||
float step = hei + 2;
|
||||
|
||||
|
||||
heightFogCheckBox.Create("Height fog: ");
|
||||
heightFogCheckBox.SetSize(XMFLOAT2(hei, hei));
|
||||
heightFogCheckBox.SetPos(XMFLOAT2(x + 100, y += step));
|
||||
heightFogCheckBox.OnClick([&](wiEventArgs args) {
|
||||
auto& weather = GetWeather();
|
||||
weather.SetHeightFog(args.bValue);
|
||||
});
|
||||
AddWidget(&heightFogCheckBox);
|
||||
|
||||
fogStartSlider.Create(0, 5000, 0, 100000, "Fog Start: ");
|
||||
fogStartSlider.SetSize(XMFLOAT2(100, hei));
|
||||
fogStartSlider.SetPos(XMFLOAT2(x, y += step));
|
||||
@@ -35,13 +44,29 @@ void WeatherWindow::Create(EditorComponent* editor)
|
||||
});
|
||||
AddWidget(&fogEndSlider);
|
||||
|
||||
fogHeightSlider.Create(0, 1, 0, 10000, "Fog Height: ");
|
||||
fogHeightSlider.SetSize(XMFLOAT2(100, hei));
|
||||
fogHeightSlider.SetPos(XMFLOAT2(x, y += step));
|
||||
fogHeightSlider.OnSlide([&](wiEventArgs args) {
|
||||
GetWeather().fogHeight = args.fValue;
|
||||
fogHeightStartSlider.Create(-100, 100, 1, 10000, "Fog Height Start: ");
|
||||
fogHeightStartSlider.SetSize(XMFLOAT2(100, hei));
|
||||
fogHeightStartSlider.SetPos(XMFLOAT2(x, y += step));
|
||||
fogHeightStartSlider.OnSlide([&](wiEventArgs args) {
|
||||
GetWeather().fogHeightStart = args.fValue;
|
||||
});
|
||||
AddWidget(&fogHeightStartSlider);
|
||||
|
||||
fogHeightEndSlider.Create(-100, 100, 3, 10000, "Fog Height End: ");
|
||||
fogHeightEndSlider.SetSize(XMFLOAT2(100, hei));
|
||||
fogHeightEndSlider.SetPos(XMFLOAT2(x, y += step));
|
||||
fogHeightEndSlider.OnSlide([&](wiEventArgs args) {
|
||||
GetWeather().fogHeightEnd = args.fValue;
|
||||
});
|
||||
AddWidget(&fogHeightEndSlider);
|
||||
|
||||
fogHeightSkySlider.Create(0, 1, 0, 10000, "Fog Height Sky: ");
|
||||
fogHeightSkySlider.SetSize(XMFLOAT2(100, hei));
|
||||
fogHeightSkySlider.SetPos(XMFLOAT2(x, y += step));
|
||||
fogHeightSkySlider.OnSlide([&](wiEventArgs args) {
|
||||
GetWeather().fogHeightSky = args.fValue;
|
||||
});
|
||||
AddWidget(&fogHeightSlider);
|
||||
AddWidget(&fogHeightSkySlider);
|
||||
|
||||
cloudinessSlider.Create(0, 1, 0.0f, 10000, "Cloudiness: ");
|
||||
cloudinessSlider.SetSize(XMFLOAT2(100, hei));
|
||||
@@ -445,7 +470,7 @@ void WeatherWindow::Create(EditorComponent* editor)
|
||||
weather.cloudiness = 0.4f;
|
||||
weather.fogStart = 100;
|
||||
weather.fogEnd = 1000;
|
||||
weather.fogHeight = 0;
|
||||
weather.fogHeightSky = 0;
|
||||
|
||||
InvalidateProbes();
|
||||
|
||||
@@ -465,7 +490,7 @@ void WeatherWindow::Create(EditorComponent* editor)
|
||||
weather.cloudiness = 0.36f;
|
||||
weather.fogStart = 50;
|
||||
weather.fogEnd = 600;
|
||||
weather.fogHeight = 0;
|
||||
weather.fogHeightSky = 0;
|
||||
|
||||
InvalidateProbes();
|
||||
|
||||
@@ -485,7 +510,7 @@ void WeatherWindow::Create(EditorComponent* editor)
|
||||
weather.cloudiness = 0.75f;
|
||||
weather.fogStart = 0;
|
||||
weather.fogEnd = 500;
|
||||
weather.fogHeight = 0;
|
||||
weather.fogHeightSky = 0;
|
||||
|
||||
InvalidateProbes();
|
||||
|
||||
@@ -505,7 +530,7 @@ void WeatherWindow::Create(EditorComponent* editor)
|
||||
weather.cloudiness = 0.28f;
|
||||
weather.fogStart = 10;
|
||||
weather.fogEnd = 400;
|
||||
weather.fogHeight = 0;
|
||||
weather.fogHeightSky = 0;
|
||||
|
||||
InvalidateProbes();
|
||||
|
||||
@@ -552,9 +577,12 @@ void WeatherWindow::Update()
|
||||
colorgradingButton.SetText(wiHelper::GetFileNameFromPath(weather.colorGradingMapName));
|
||||
}
|
||||
|
||||
heightFogCheckBox.SetCheck(weather.IsHeightFog());
|
||||
fogStartSlider.SetValue(weather.fogStart);
|
||||
fogEndSlider.SetValue(weather.fogEnd);
|
||||
fogHeightSlider.SetValue(weather.fogHeight);
|
||||
fogHeightStartSlider.SetValue(weather.fogHeightStart);
|
||||
fogHeightEndSlider.SetValue(weather.fogHeightEnd);
|
||||
fogHeightSkySlider.SetValue(weather.fogHeightSky);
|
||||
cloudinessSlider.SetValue(weather.cloudiness);
|
||||
cloudScaleSlider.SetValue(weather.cloudScale);
|
||||
cloudSpeedSlider.SetValue(weather.cloudSpeed);
|
||||
|
||||
@@ -14,9 +14,12 @@ public:
|
||||
wiScene::WeatherComponent& GetWeather() const;
|
||||
void InvalidateProbes() const;
|
||||
|
||||
wiCheckBox heightFogCheckBox;
|
||||
wiSlider fogStartSlider;
|
||||
wiSlider fogEndSlider;
|
||||
wiSlider fogHeightSlider;
|
||||
wiSlider fogHeightStartSlider;
|
||||
wiSlider fogHeightEndSlider;
|
||||
wiSlider fogHeightSkySlider;
|
||||
wiSlider cloudinessSlider;
|
||||
wiSlider cloudScaleSlider;
|
||||
wiSlider cloudSpeedSlider;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
This file contains changelog of wiArchive versions
|
||||
|
||||
71: serialized WeatherComponent::fogHeightStart and fogHeightEnd
|
||||
70: serialized VolumetricCloudParameters
|
||||
69: serialized AABB:: layerMask and userdata parameters
|
||||
68: serialized MaterialComponent SPECULARMAP (for KHR_materials_specular)
|
||||
|
||||
@@ -533,9 +533,10 @@ static const uint OPTION_BIT_VOXELGI_REFLECTIONS_ENABLED = 1 << 3;
|
||||
static const uint OPTION_BIT_VOXELGI_RETARGETTED = 1 << 4;
|
||||
static const uint OPTION_BIT_SIMPLE_SKY = 1 << 5;
|
||||
static const uint OPTION_BIT_REALISTIC_SKY = 1 << 6;
|
||||
static const uint OPTION_BIT_RAYTRACED_SHADOWS = 1 << 7;
|
||||
static const uint OPTION_BIT_DISABLE_ALBEDO_MAPS = 1 << 8;
|
||||
static const uint OPTION_BIT_SHADOW_MASK = 1 << 9;
|
||||
static const uint OPTION_BIT_HEIGHT_FOG = 1 << 7;
|
||||
static const uint OPTION_BIT_RAYTRACED_SHADOWS = 1 << 8;
|
||||
static const uint OPTION_BIT_DISABLE_ALBEDO_MAPS = 1 << 9;
|
||||
static const uint OPTION_BIT_SHADOW_MASK = 1 << 10;
|
||||
|
||||
// ---------- Common Constant buffers: -----------------
|
||||
|
||||
@@ -562,10 +563,11 @@ CBUFFER(FrameCB, CBSLOT_RENDERER_FRAME)
|
||||
float3 g_xFrame_Ambient;
|
||||
float g_xFrame_Cloudiness;
|
||||
|
||||
float3 g_xFrame_padding0;
|
||||
float g_xFrame_SkyExposure;
|
||||
float4 g_xFrame_Fog; // Fog Start,End,Height Start,Height End
|
||||
|
||||
float3 g_xFrame_Fog; // Fog Start,End,Height
|
||||
float g_xFrame_padding0;
|
||||
float g_xFrame_FogHeightSky;
|
||||
float g_xFrame_SkyExposure;
|
||||
float g_xFrame_VoxelRadianceMaxDistance; // maximum raymarch distance for voxel GI in world-space
|
||||
|
||||
float g_xFrame_VoxelRadianceDataSize; // voxel half-extent in world space units
|
||||
|
||||
@@ -67,9 +67,47 @@ inline float GetTime() { return g_xFrame_Time; }
|
||||
inline uint2 GetTemporalAASampleRotation() { return uint2((g_xFrame_TemporalAASampleRotation >> 0u) & 0x000000FF, (g_xFrame_TemporalAASampleRotation >> 8) & 0x000000FF); }
|
||||
inline bool IsStaticSky() { return g_xFrame_StaticSkyGamma > 0.0; }
|
||||
|
||||
inline float GetFogAmount(float dist)
|
||||
// Exponential height fog based on: https://www.iquilezles.org/www/articles/fog/fog.htm
|
||||
// Non constant density function
|
||||
// distance : sample to point distance
|
||||
// O : sample position
|
||||
// V : sample to point vector
|
||||
inline float GetFogAmount(float distance, float3 O, float3 V)
|
||||
{
|
||||
return saturate((dist - g_xFrame_Fog.x) / (g_xFrame_Fog.y - g_xFrame_Fog.x));
|
||||
float fogDensity = saturate((distance - g_xFrame_Fog.x) / (g_xFrame_Fog.y - g_xFrame_Fog.x));
|
||||
|
||||
if (g_xFrame_Options & OPTION_BIT_HEIGHT_FOG)
|
||||
{
|
||||
float fogHeightStart = g_xFrame_Fog.z;
|
||||
float fogHeightEnd = g_xFrame_Fog.w;
|
||||
float fogFalloffScale = 1.0 / max(0.01, fogHeightEnd - fogHeightStart);
|
||||
|
||||
// solve for x, e^(-h * x) = 0.001
|
||||
// x = 6.907755 * h^-1
|
||||
float fogFalloff = 6.907755 * fogFalloffScale;
|
||||
|
||||
float originHeight = O.y;
|
||||
float Z = -V.y;
|
||||
float effectiveZ = max(abs(Z), 0.001);
|
||||
|
||||
float endLineHeight = originHeight + distance * Z; // Isolated vector equation for y
|
||||
float minLineHeight = min(originHeight, endLineHeight);
|
||||
float heightLineFalloff = max(minLineHeight - fogHeightStart, 0);
|
||||
|
||||
float baseHeightFogDistance = clamp((fogHeightStart - minLineHeight) / effectiveZ, 0, distance);
|
||||
float exponentialFogDistance = distance - baseHeightFogDistance; // Exclude distance below base height
|
||||
float exponentialHeightLineIntegral = exp(-heightLineFalloff * fogFalloff) * (1.0 - exp(-exponentialFogDistance * effectiveZ * fogFalloff)) / (effectiveZ * fogFalloff);
|
||||
|
||||
float opticalDepthHeightFog = fogDensity * (baseHeightFogDistance + exponentialHeightLineIntegral);
|
||||
float transmittanceHeightFog = exp(-opticalDepthHeightFog);
|
||||
|
||||
float fogAmount = transmittanceHeightFog;
|
||||
return 1.0 - fogAmount;
|
||||
}
|
||||
else
|
||||
{
|
||||
return fogDensity;
|
||||
}
|
||||
}
|
||||
|
||||
float3 tonemap(float3 x)
|
||||
|
||||
@@ -49,7 +49,7 @@ GBuffer main(VertexToPixel input)
|
||||
|
||||
ApplyLighting(surface, lighting, color);
|
||||
|
||||
ApplyFog(dist, color);
|
||||
ApplyFog(dist, g_xCamera_CamPos, V, color);
|
||||
|
||||
return CreateGBuffer(color, surface);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ GBuffer main(VSOut input)
|
||||
|
||||
ApplyLighting(surface, lighting, color);
|
||||
|
||||
ApplyFog(dist, color);
|
||||
ApplyFog(dist, g_xCamera_CamPos, V, color);
|
||||
|
||||
return CreateGBuffer(color, surface);
|
||||
}
|
||||
|
||||
@@ -1166,17 +1166,19 @@ inline void ApplyLighting(in Surface surface, in Lighting lighting, inout float4
|
||||
color.rgb = lerp(surface.albedo * combined_lighting.diffuse, surface.refraction.rgb, surface.refraction.a) + combined_lighting.specular;
|
||||
}
|
||||
|
||||
inline void ApplyFog(in float dist, inout float4 color)
|
||||
inline void ApplyFog(in float distance, float3 P, float3 V, inout float4 color)
|
||||
{
|
||||
const float fogAmount = GetFogAmount(distance, P, V);
|
||||
|
||||
if (g_xFrame_Options & OPTION_BIT_REALISTIC_SKY)
|
||||
{
|
||||
const float3 skyLuminance = texture_skyluminancelut.SampleLevel(sampler_point_clamp, float2(0.5, 0.5), 0).rgb;
|
||||
color.rgb = lerp(color.rgb, skyLuminance, GetFogAmount(dist));
|
||||
color.rgb = lerp(color.rgb, skyLuminance, fogAmount);
|
||||
}
|
||||
else
|
||||
{
|
||||
const float3 V = float3(0.0, -1.0, 0.0);
|
||||
color.rgb = lerp(color.rgb, GetDynamicSkyColor(V, false, false, false, true), GetFogAmount(dist));
|
||||
color.rgb = lerp(color.rgb, GetDynamicSkyColor(V, false, false, false, true), fogAmount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1927,7 +1929,7 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_TARGET
|
||||
|
||||
|
||||
#ifdef OBJECTSHADER_USE_POSITION3D
|
||||
ApplyFog(dist, color);
|
||||
ApplyFog(dist, g_xCamera_CamPos, surface.V, color);
|
||||
#endif // OBJECTSHADER_USE_POSITION3D
|
||||
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ float4 main(PSIn input) : SV_TARGET
|
||||
|
||||
ApplyLighting(surface, lighting, color);
|
||||
|
||||
ApplyFog(dist, color);
|
||||
ApplyFog(dist, g_xCamera_CamPos, V, color);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ float3 CustomAtmosphericScattering(float3 V, float3 sunDirection, float3 sunColo
|
||||
const float zenith = V.y; // how much is above (0: horizon, 1: directly above)
|
||||
const float sunScatter = saturate(sunDirection.y + 0.1f); // how much the sun is directly above. Even if sunis at horizon, we add a constant scattering amount so that light still scatters at horizon
|
||||
|
||||
const float atmosphereDensity = 0.5 + g_xFrame_Fog.z; // constant of air density, or "fog height" as interpreted here (bigger is more obstruction of sun)
|
||||
const float atmosphereDensity = 0.5 + g_xFrame_FogHeightSky; // constant of air density, or "fog height" as interpreted here (bigger is more obstruction of sun)
|
||||
const float zenithDensity = atmosphereDensity / pow(max(0.000001f, zenith), 0.75f);
|
||||
const float sunScatterDensity = atmosphereDensity / pow(max(0.000001f, sunScatter), 0.75f);
|
||||
|
||||
|
||||
@@ -48,8 +48,9 @@ float4 main(VertexToPixel input) : SV_TARGET
|
||||
{
|
||||
float3 attenuation = shadowCascade(light, ShPos, ShTex.xy, cascade);
|
||||
|
||||
attenuation *= GetFogAmount(cameraDistance - marchedDistance) * scattering;
|
||||
|
||||
// Evaluate sample height for height fog calculation, given 0 for V:
|
||||
attenuation *= GetFogAmount(cameraDistance - marchedDistance, P, float3(0.0, 0.0, 0.0)) * scattering;
|
||||
|
||||
accumulation += attenuation;
|
||||
|
||||
marchedDistance += stepSize;
|
||||
|
||||
@@ -49,8 +49,9 @@ float4 main(VertexToPixel input) : SV_TARGET
|
||||
attenuation *= shadowCube(light, L, Lunnormalized);
|
||||
}
|
||||
|
||||
attenuation *= GetFogAmount(cameraDistance - marchedDistance);
|
||||
|
||||
// Evaluate sample height for height fog calculation, given 0 for V:
|
||||
attenuation *= GetFogAmount(cameraDistance - marchedDistance, P, float3(0.0, 0.0, 0.0));
|
||||
|
||||
accumulation += attenuation;
|
||||
|
||||
marchedDistance += stepSize;
|
||||
|
||||
@@ -58,7 +58,8 @@ float4 main(VertexToPixel input) : SV_TARGET
|
||||
}
|
||||
}
|
||||
|
||||
attenuation *= GetFogAmount(cameraDistance - marchedDistance);
|
||||
// Evaluate sample height for exponential fog calculation, given 0 for V:
|
||||
attenuation *= GetFogAmount(cameraDistance - marchedDistance, P, float3(0.0, 0.0, 0.0));
|
||||
|
||||
accumulation += attenuation;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <fstream>
|
||||
|
||||
// this should always be only INCREMENTED and only if a new serialization is implemeted somewhere!
|
||||
uint64_t __archiveVersion = 70;
|
||||
uint64_t __archiveVersion = 71;
|
||||
// this is the version number of which below the archive is not compatible with the current version
|
||||
uint64_t __archiveVersionBarrier = 22;
|
||||
|
||||
|
||||
@@ -3552,7 +3552,8 @@ void UpdatePerFrameData(
|
||||
frameCB.g_xFrame_Cloudiness = vis.scene->weather.cloudiness;
|
||||
frameCB.g_xFrame_CloudScale = vis.scene->weather.cloudScale;
|
||||
frameCB.g_xFrame_CloudSpeed = vis.scene->weather.cloudSpeed;
|
||||
frameCB.g_xFrame_Fog = float3(vis.scene->weather.fogStart, vis.scene->weather.fogEnd, vis.scene->weather.fogHeight);
|
||||
frameCB.g_xFrame_Fog = float4(vis.scene->weather.fogStart, vis.scene->weather.fogEnd, vis.scene->weather.fogHeightStart, vis.scene->weather.fogHeightEnd);
|
||||
frameCB.g_xFrame_FogHeightSky = vis.scene->weather.fogHeightSky;
|
||||
frameCB.g_xFrame_Horizon = vis.scene->weather.horizon;
|
||||
frameCB.g_xFrame_Zenith = vis.scene->weather.zenith;
|
||||
frameCB.g_xFrame_SkyExposure = vis.scene->weather.skyExposure;
|
||||
@@ -3668,6 +3669,10 @@ void UpdatePerFrameData(
|
||||
{
|
||||
frameCB.g_xFrame_Options |= OPTION_BIT_REALISTIC_SKY;
|
||||
}
|
||||
if (vis.scene->weather.IsHeightFog())
|
||||
{
|
||||
frameCB.g_xFrame_Options |= OPTION_BIT_HEIGHT_FOG;
|
||||
}
|
||||
if (device->CheckCapability(GRAPHICSDEVICE_CAPABILITY_RAYTRACING_INLINE) && GetRaytracedShadowsEnabled())
|
||||
{
|
||||
frameCB.g_xFrame_Options |= OPTION_BIT_RAYTRACED_SHADOWS;
|
||||
|
||||
@@ -1112,6 +1112,7 @@ namespace wiScene
|
||||
SIMPLE_SKY = 1 << 1,
|
||||
REALISTIC_SKY = 1 << 2,
|
||||
VOLUMETRIC_CLOUDS = 1 << 3,
|
||||
HEIGHT_FOG = 1 << 4,
|
||||
};
|
||||
uint32_t _flags = EMPTY;
|
||||
|
||||
@@ -1119,11 +1120,13 @@ namespace wiScene
|
||||
inline bool IsSimpleSky() const { return _flags & SIMPLE_SKY; }
|
||||
inline bool IsRealisticSky() const { return _flags & REALISTIC_SKY; }
|
||||
inline bool IsVolumetricClouds() const { return _flags & VOLUMETRIC_CLOUDS; }
|
||||
inline bool IsHeightFog() const { return _flags & HEIGHT_FOG; }
|
||||
|
||||
inline void SetOceanEnabled(bool value = true) { if (value) { _flags |= OCEAN_ENABLED; } else { _flags &= ~OCEAN_ENABLED; } }
|
||||
inline void SetSimpleSky(bool value = true) { if (value) { _flags |= SIMPLE_SKY; } else { _flags &= ~SIMPLE_SKY; } }
|
||||
inline void SetRealisticSky(bool value = true) { if (value) { _flags |= REALISTIC_SKY; } else { _flags &= ~REALISTIC_SKY; } }
|
||||
inline void SetVolumetricClouds(bool value = true) { if (value) { _flags |= VOLUMETRIC_CLOUDS; } else { _flags &= ~VOLUMETRIC_CLOUDS; } }
|
||||
inline void SetHeightFog(bool value = true) { if (value) { _flags |= HEIGHT_FOG; } else { _flags &= ~HEIGHT_FOG; } }
|
||||
|
||||
XMFLOAT3 sunColor = XMFLOAT3(0, 0, 0);
|
||||
XMFLOAT3 sunDirection = XMFLOAT3(0, 1, 0);
|
||||
@@ -1134,7 +1137,9 @@ namespace wiScene
|
||||
XMFLOAT3 ambient = XMFLOAT3(0.2f, 0.2f, 0.2f);
|
||||
float fogStart = 100;
|
||||
float fogEnd = 1000;
|
||||
float fogHeight = 0;
|
||||
float fogHeightStart = 1;
|
||||
float fogHeightEnd = 3;
|
||||
float fogHeightSky = 0;
|
||||
float cloudiness = 0.0f;
|
||||
float cloudScale = 0.0003f;
|
||||
float cloudSpeed = 0.1f;
|
||||
|
||||
@@ -939,7 +939,7 @@ namespace wiScene
|
||||
archive >> ambient;
|
||||
archive >> fogStart;
|
||||
archive >> fogEnd;
|
||||
archive >> fogHeight;
|
||||
archive >> fogHeightSky;
|
||||
archive >> cloudiness;
|
||||
archive >> cloudScale;
|
||||
archive >> cloudSpeed;
|
||||
@@ -1074,6 +1074,11 @@ namespace wiScene
|
||||
archive >> volumetricCloudParameters.GroundContributionSampleCount;
|
||||
}
|
||||
|
||||
if (archive.GetVersion() >= 71)
|
||||
{
|
||||
archive >> fogHeightStart;
|
||||
archive >> fogHeightEnd;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1085,7 +1090,7 @@ namespace wiScene
|
||||
archive << ambient;
|
||||
archive << fogStart;
|
||||
archive << fogEnd;
|
||||
archive << fogHeight;
|
||||
archive << fogHeightSky;
|
||||
archive << cloudiness;
|
||||
archive << cloudScale;
|
||||
archive << cloudSpeed;
|
||||
@@ -1202,6 +1207,11 @@ namespace wiScene
|
||||
archive << volumetricCloudParameters.GroundContributionSampleCount;
|
||||
}
|
||||
|
||||
if (archive.GetVersion() >= 71)
|
||||
{
|
||||
archive << fogHeightStart;
|
||||
archive << fogHeightEnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
void SoundComponent::Serialize(wiArchive& archive, EntitySerializer& seri)
|
||||
|
||||
Reference in New Issue
Block a user