Skip to content

Commit

Permalink
update reach fog conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
Pedro413 committed May 15, 2024
1 parent 0cafcaf commit 6a3c8b7
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 29 deletions.
56 changes: 29 additions & 27 deletions TagTool/Commands/Porting/PortTagCommand.Scenario.cs
Original file line number Diff line number Diff line change
Expand Up @@ -708,49 +708,51 @@ public Scenario ConvertScenario(Stream cacheStream, Stream blamCacheStream, Dict
{
atmosphereSettings.Flags |= SkyAtmParameters.AtmosphereProperty.AtmosphereFlags.OverrideRealSunValues;
atmosphereSettings.Color = fogSettings.FogColor;
atmosphereSettings.Intensity = 3.0f; // tweak?
atmosphereSettings.Intensity = 1.0f; // tweak?
atmosphereSettings.SunAnglePitch = 0.0f;
atmosphereSettings.SunAngleYaw = 0.0f;

// Test for direction
//if (scnr.SkyReferences.Count > 0 && scnr.SkyReferences[0].SkyObject != null)
//{
// var skyObje = CacheContext.Deserialize<GameObject>(cacheStream, scnr.SkyReferences[0].SkyObject);
// var hlmt = CacheContext.Deserialize<Model>(cacheStream, skyObje.Model);
// var mode = CacheContext.Deserialize<RenderModel>(cacheStream, hlmt.RenderModel);
//
// if (mode.LightgenLights.Count > 0)
// {
// var direction = mode.LightgenLights.Last().Direction;
//
// atmosphereSettings.SunAnglePitch = (float)(Math.Acos(direction.K) / Math.PI) * 180.0f;
// atmosphereSettings.SunAngleYaw = (float)(Math.Asin(direction.J / Math.Sin(atmosphereSettings.SunAnglePitch)) / Math.PI) * 180.0f;
// }
//}
// reach has a fog light angle but i think this better for now
if (scnr.SkyReferences.Count > 0 && scnr.SkyReferences[0].SkyObject != null)
{
var skyObje = CacheContext.Deserialize<GameObject>(cacheStream, scnr.SkyReferences[0].SkyObject);
var hlmt = CacheContext.Deserialize<Model>(cacheStream, skyObje.Model);
var mode = CacheContext.Deserialize<RenderModel>(cacheStream, hlmt.RenderModel);

if (mode.LightgenLights.Count > 0)
{
var direction = mode.LightgenLights.Last().Direction; // last light is sun

atmosphereSettings.SunAnglePitch = (float)(Math.Asin(direction.K) * (180.0f / Math.PI));
if (atmosphereSettings.SunAnglePitch < 0.0f) // limit to 0-90
atmosphereSettings.SunAnglePitch = -atmosphereSettings.SunAnglePitch;

atmosphereSettings.SunAngleYaw = (float)(Math.Atan2(direction.J, direction.I) * (180.0f / Math.PI));
}
}

atmosphereSettings.SeaLevel = fogSettings.BaseHeight; // WU, lowest height of scenario

// these are definitely wrong
atmosphereSettings.RayleignHeightScale = fogSettings.FogHeight; // WU, height above sea where atmo 30% thick
atmosphereSettings.MieHeightScale = fogSettings.FogHeight; // WU, height above sea where atmo 30% thick

atmosphereSettings.MaxFogThickness = fogSettings.FogThickness * 10000.0f;
atmosphereSettings.MaxFogThickness = fogSettings.FogThickness * 65536.0f;
}

atmosphereSettings.RayleighMultiplier = 0.0f; // scattering amount, small
atmosphereSettings.MieMultiplier = 0.0f; // scattering amount, large
// todo: scale these with fog thickness
atmosphereSettings.RayleighMultiplier = 0.05f; // scattering amount, small
atmosphereSettings.MieMultiplier = 0.025f; // scattering amount, large

atmosphereSettings.SunPhaseFunction = 0.2f;
atmosphereSettings.SunPhaseFunction = 0.2f; //todo
atmosphereSettings.Desaturation = 0.0f;
atmosphereSettings.DistanceBias = fogg.DistanceBias;

// placeholder for now

atmosphereSettings.BetaM = new RealVector3d(0.0002946603f, 0.0005024257f, 0.001058603f);
atmosphereSettings.BetaP = new RealVector3d(0.001434321f, 0.001849472f, 0.002627869f);
atmosphereSettings.BetaMThetaPrefix = new RealVector3d(1.788872E-05f, 3.050209E-05f, 6.426741E-05f);
atmosphereSettings.BetaPThetaPrefix = new RealVector3d(0.0003334733f, 0.0004336488f, 0.0006244543f);
}
}

// validate all values and recalculate atmosphere constants
skya.Postprocess();

CachedTag skyTag = CacheContext.TagCache.AllocateTag<SkyAtmParameters>(tagName);
CacheContext.Serialize(cacheStream, skyTag, skya);

Expand Down
20 changes: 20 additions & 0 deletions TagTool/Common/MathHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,25 @@ public static bool SphereIntersectsRectangle3d(RealPoint3d center, float radius,

return (radius * radius) >= RealVector3d.Magnitude(d);
}

public static float Clamp(float value, float min, float max)
{
return Math.Min(Math.Max(value, min), max);
}

public static RealRgbColor Clamp(RealRgbColor value, float min, float max)
{
return new RealRgbColor
{
Red = Math.Min(Math.Max(value.Red, min), max),
Green = Math.Min(Math.Max(value.Green, min), max),
Blue = Math.Min(Math.Max(value.Blue, min), max),
};
}

public static float Lerp(float a, float b, float s)
{
return ((1.0f - s) * a) + (s * b);
}
}
}
27 changes: 25 additions & 2 deletions TagTool/Tags/Definitions/Effect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Linq;
using TagTool.Commands.Common;
using static TagTool.Effects.EditableProperty;
using System.IO;

namespace TagTool.Tags.Definitions
{
Expand Down Expand Up @@ -450,8 +451,15 @@ public enum FlagsValue : byte
None,
Postprocessed = 1 << 0,
IsCpu = 1 << 1,
// This flag is enabled (and disables IsCpu) in the following conditions:
// (Postprocessed == true &&
// Emitter.ParticleMovement.Flags.HasFlag(Wind) &&
// ParticleSystem.CanUpdateOnGpu())
IsGpu = 1 << 2,
// This flag is enabled if:
// (Postprocess == true && ParticleSystem.CanUpdateOnGpu())
BecomesGpuWhenAtRest = 1 << 3,
// I'm not sure what this is or why it's set.
AlphaBlackPoint_Bit3 = 1 << 4,
}

Expand Down Expand Up @@ -970,6 +978,21 @@ public void GetConstantStates(out RuntimeMGpuData.ParticleProperties cppStates,
cotStates |= RuntimeMGpuData.ParticleProperties.ParticleAlphaBlackPoint;
}
}

public bool CanUpdateOnGpu(GameCache cache, Stream stream)
{
bool noAttachments = true;

if (this.Particle != null)
{
var prt3 = cache.Deserialize<Particle>(stream, this.Particle);

if (!prt3.Flags.HasFlag(Definitions.Particle.FlagsValue.NoAttachments))
noAttachments = false;
}

return noAttachments && this.Flags.HasFlag(ParticleSystemFlags.TurnOffNearFadeOnEnhancedGraphics);
}
}
}

Expand Down Expand Up @@ -1010,7 +1033,7 @@ public enum EffectFlags : int
TintFromLightmap = 1 << 10,
TintFromDiffuseTexture = 1 << 11, // geometry sampler
HasEnvironmentRestrictedPart = 1 << 12, // parts->create_in_environment != 0 || ( part->type==beam && any(location->name==stringid(child)) )
UnusedBit = 1 << 13, // unused
HasEnvironmentRestrictedAcceleration = 1 << 13, // unused
HasEnvironmentRestrictedParticleSystem = 1 << 14, // system->environment != 0
TrackSubframeMovements = 1 << 15,
UnknownHO = 1 << 16 // HO only. unknown
Expand All @@ -1036,7 +1059,7 @@ public enum EffectFlagsMCC : int
TintFromLightmap = 1 << 12,
TintFromDiffuseTexture = 1 << 13,
HasEnvironmentRestrictedPart = 1 << 14,
UnusedBit = 1 << 15,
HasEnvironmentRestrictedAcceleration = 1 << 15,
HasEnvironmentRestrictedParticleSystem = 1 << 16,
TrackSubframeMovements = 1 << 17
}
Expand Down
98 changes: 98 additions & 0 deletions TagTool/Tags/Definitions/SkyAtmParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,81 @@ public enum AtmosphereFlags : short
PatchyFog = 1 << 2,
Bit3 = 1 << 3,
}

private void PostprocessFogConstants()
{
// todo: B particle and molecular calculation according to tool.
// these are still accurate, as the only thing that changes these constants are:
// mie_multiplier, rayleigh_multiplier, desaturation
BetaM = new RealVector3d(0.000005893206f, 0.000010048514f, 0.00002117206f);
BetaP = new RealVector3d(0.00005737284f, 0.00007397888f, 0.00010511476f);
BetaMThetaPrefix = new RealVector3d(0.0000003577744f, 0.0000006100418f, 0.0000012853482f);
BetaPThetaPrefix = new RealVector3d(0.000013338932f, 0.000017345952f, 0.000024978172f);

// apply multipliers
BetaM *= RayleighMultiplier;
BetaMThetaPrefix *= RayleighMultiplier;
BetaP *= MieMultiplier;
BetaPThetaPrefix *= MieMultiplier;

// rescale
BetaM *= 1000.0f;
BetaMThetaPrefix *= 1000.0f;
BetaP *= 1000.0f;
BetaPThetaPrefix *= 1000.0f;

// apply desaturation
if (Desaturation > 0.0f)
{
float pLum = (BetaP.I + BetaP.J + BetaP.K) / 3.0f;
BetaP.I = MathHelper.Lerp(BetaP.I, pLum, Desaturation);
BetaP.J = MathHelper.Lerp(BetaP.J, pLum, Desaturation);
BetaP.K = MathHelper.Lerp(BetaP.K, pLum, Desaturation);

float mLum = (BetaM.I + BetaM.J + BetaM.K) / 3.0f;
BetaM.I = MathHelper.Lerp(BetaM.I, mLum, Desaturation);
BetaM.J = MathHelper.Lerp(BetaM.J, mLum, Desaturation);
BetaM.K = MathHelper.Lerp(BetaM.K, mLum, Desaturation);

float pThetaLum = (BetaPThetaPrefix.I + BetaPThetaPrefix.J + BetaPThetaPrefix.K) / 3.0f;
BetaPThetaPrefix.I = MathHelper.Lerp(BetaPThetaPrefix.I, pThetaLum, Desaturation);
BetaPThetaPrefix.J = MathHelper.Lerp(BetaPThetaPrefix.J, pThetaLum, Desaturation);
BetaPThetaPrefix.K = MathHelper.Lerp(BetaPThetaPrefix.K, pThetaLum, Desaturation);

float mThetaLum = (BetaMThetaPrefix.I + BetaMThetaPrefix.J + BetaMThetaPrefix.K) / 3.0f;
BetaMThetaPrefix.I = MathHelper.Lerp(BetaMThetaPrefix.I, mThetaLum, Desaturation);
BetaMThetaPrefix.J = MathHelper.Lerp(BetaMThetaPrefix.J, mThetaLum, Desaturation);
BetaMThetaPrefix.K = MathHelper.Lerp(BetaMThetaPrefix.K, mThetaLum, Desaturation);
}
}

private void ClampValues()
{
SunAnglePitch = MathHelper.Clamp(SunAnglePitch, 0.0f, 90.0f);
SunAngleYaw = MathHelper.Clamp(SunAngleYaw, 0.0f, 360.0f);
Color = MathHelper.Clamp(Color, 0.0f, 1.0f);
Intensity = MathHelper.Clamp(Intensity, 0.0f, 65536.0f);
SeaLevel = MathHelper.Clamp(SeaLevel, -65536.0f, 65536.0f);
RayleignHeightScale = MathHelper.Clamp(RayleignHeightScale, 0.01f, 65536.0f);
MieHeightScale = MathHelper.Clamp(MieHeightScale, 0.01f, 65536.0f);
RayleighMultiplier = MathHelper.Clamp(RayleighMultiplier, 0.0f, 1000.0f);
MieMultiplier = MathHelper.Clamp(MieMultiplier, 0.0f, 1000.0f);
SunPhaseFunction = MathHelper.Clamp(SunPhaseFunction, 0.0f, 0.95f);
DistanceBias = MathHelper.Clamp(DistanceBias, -65536.0f, 65536.0f);
MaxFogThickness = MathHelper.Clamp(MaxFogThickness, 0.01f, 65536.0f);
Desaturation = MathHelper.Clamp(Desaturation, 0.0f, 1.0f);
SheetDensity = MathHelper.Clamp(SheetDensity, 0.0f, 10000.0f);
}

public void Postprocess()
{
if (Math.Abs(MaxFogThickness) < 0.001f)
MaxFogThickness = 65535.0f;
RuntimeWeight = 0.0f;

ClampValues();
PostprocessFogConstants();
}
}

// probably lots of wrong fields, unused anyway
Expand Down Expand Up @@ -146,5 +221,28 @@ public class UnderwaterBlock : TagStructure
public float Murkiness;
public RealRgbColor FogColor;
}

public void Postprocess()
{
if (Math.Abs(DistanceFalloffPower) < 0.001f)
DistanceFalloffPower = 2.0f;
if (Math.Abs(FalloffStartDistance) < 0.001f)
FalloffStartDistance = 5.0f;
if (Math.Abs(ClusterSearchRadius) < 0.001f)
ClusterSearchRadius = 25.0f;
if (Math.Abs(TransparentSortDistance) < 0.001f)
TransparentSortDistance = 100.0f;

foreach (var atmosphere in AtmosphereSettings)
atmosphere.Postprocess();

TextureRepeatRate = MathHelper.Clamp(TextureRepeatRate, 0.1f, 100.0f);
DistanceBetweenSheets = MathHelper.Clamp(DistanceBetweenSheets, 0.1f, 10000.0f);
DepthFadeFactor = MathHelper.Clamp(DepthFadeFactor, 0.00001f, 10.0f);
ClusterSearchRadius = MathHelper.Clamp(ClusterSearchRadius, 1.0f, 50.0f);
FalloffStartDistance = MathHelper.Clamp(FalloffStartDistance, 0.1f, 10.0f);
DistanceFalloffPower = MathHelper.Clamp(DistanceFalloffPower, 0.1f, 10.0f);
TransparentSortDistance = MathHelper.Clamp(TransparentSortDistance, 0.1f, 65535.0f);
}
}
}

0 comments on commit 6a3c8b7

Please sign in to comment.