FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

fix: half float delta position dither by NoelStephensUnity · Pull Request #4128 · Unity-Technologies/com.unity.netcode.gameobjects · GitHub

4 changes: 4 additions & 0 deletions com.unity.netcode.gameobjects/CHANGELOG.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ Additional documentation and release notes are available at [Multiplayer Documen

### Changed

- Changed `NetworkTransform.UseHalfFloatPrecision` to synchronize position with a resolution of approximately 1mm regardless of how far an object has travelled. Previously the resolution could degrade to approximately 3cm. This does not increase bandwidth, but projects using `NetworkTransform.UseUnreliableDeltas` will send full precision position updates more often. (#4128)


### Deprecated

Expand All @@ -22,6 +24,8 @@ Additional documentation and release notes are available at [Multiplayer Documen

### Fixed

- Issue where objects using `NetworkTransform.UseHalfFloatPrecision` appeared to jitter on non-authority instances while they were stationary or coming to rest, even though the authority was not moving them. (#4128)


### Security

Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@ namespace Unity.Netcode.Components
[Serializable]
public struct NetworkDeltaPosition : INetworkSerializable
{
internal const float MaxDeltaBeforeAdjustment = 64f;
/// <summary>
/// How far the delta may grow before it is folded into the base position.
/// </summary>
/// <remarks>
/// This determines the transmitted position resolution, since a half float's step size grows with its
/// magnitude. Keeping the delta small keeps that step small: at 2 the coarsest step is roughly 1mm.
/// </remarks>
internal const float MaxDeltaBeforeAdjustment = 2f;
Comment thread
NoelStephensUnity marked this conversation as resolved.

/// <summary>
/// The HalfVector3 used to synchronize the delta in position
Expand Down Expand Up @@ -138,14 +145,29 @@ public void UpdateFrom(ref Vector3 vector3, int networkTick)
{
CollapsedDeltaIntoBase = false;
NetworkTick = networkTick;
DeltaPosition = (vector3 + PrecisionLossDelta) - CurrentBasePosition;
for (int i = 0; i < HalfVector3.Length; i++)
{
if (HalfVector3.AxisToSynchronize[i])
{
var rawDelta = vector3[i] - CurrentBasePosition[i];

// Adding the previous rounding loss back in keeps the average position accurate while the
// value is moving, but it also changes the value being sent. Once the value stops moving
// that is all it does, which makes a stationary object appear to oscillate.
var movedSinceLastSend = Mathf.Abs(vector3[i] - PreviousPosition[i]);
var applyPrecisionLoss = movedSinceLastSend >= HalfPrecisionQuantum(rawDelta);

DeltaPosition[i] = applyPrecisionLoss ? rawDelta + PrecisionLossDelta[i] : rawDelta;

HalfVector3.Axis[i] = math.half(DeltaPosition[i]);
HalfDeltaConvertedBack[i] = Mathf.HalfToFloat(HalfVector3.Axis[i].value);
PrecisionLossDelta[i] = DeltaPosition[i] - HalfDeltaConvertedBack[i];

// Left unchanged when skipped so it is still applied once movement resumes.
if (applyPrecisionLoss)
{
PrecisionLossDelta[i] = DeltaPosition[i] - HalfDeltaConvertedBack[i];
}

if (Mathf.Abs(HalfDeltaConvertedBack[i]) >= MaxDeltaBeforeAdjustment)
{
CurrentBasePosition[i] += HalfDeltaConvertedBack[i];
Expand All @@ -165,6 +187,26 @@ public void UpdateFrom(ref Vector3 vector3, int networkTick)
}
}

/// <summary>
/// The smallest change a half float can represent at the magnitude of the value passed in.
/// </summary>
/// <param name="value">The value to get the step size for.</param>
/// <returns>The distance to the next representable half float value.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static float HalfPrecisionQuantum(float value)
{
// The step size is symmetric about zero, so the sign is dropped.
var magnitude = (ushort)(math.half(value).value & 0x7FFF);

// Guard only: stepping past the largest finite half float would give infinity.
if (magnitude >= 0x7BFF)
{
return MaxDeltaBeforeAdjustment;
}

return Mathf.HalfToFloat((ushort)(magnitude + 1)) - Mathf.HalfToFloat(magnitude);
}

/// <summary>
/// Constructor
/// </summary>
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ namespace Unity.Netcode
/// </summary>
internal static class NetworkConstants
{
internal const string PROTOCOL_VERSION = "15.0.0";
internal const string PROTOCOL_VERSION = "15.1.0";
}
}
Loading

Back | FazBrowse Home | New Git URL