The mirror test compared a normalised reading of two spellings and was beaten twice (a statement before the return, gravityHeight's sum). GravityShader writes the whole file (potential, zero-strength guard, reference term, height sum) from GravityField's constant (TailOffset); GravityShaderTests fails on any difference. GravityShaderMirrorTests deleted. GravityFieldParityVerify opens Main Menu.unity: no ZoneRenderer there, its Fog Surface Displacement camera is the menu's own brush presentation (layers 9 and 10) by spec. Builds not yet verified on this commit; verified at the final merge. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
65 lines
2.5 KiB
C#
65 lines
2.5 KiB
C#
using System.Globalization;
|
|
|
|
/// <summary>
|
|
/// The single author of Assets/Shaders/Gravity.cginc, the GPU lowering of the zone's potential. The law is
|
|
/// GravityField's (its constants are read here, not respelled) and the height is Zone.GetHeight: each well's
|
|
/// potential minus its reference, summed, divided by the exaggeration. Unity does not run C# when it imports a
|
|
/// shader, so the committed cginc is this output; GravityShaderTests fails unless it equals Source() exactly.
|
|
/// To change the shader, change this file and regenerate: AETHERIA_REGENERATE_GRAVITY_CGINC=1 dotnet test --filter GravityShaderTests.
|
|
/// </summary>
|
|
public static class GravityShader
|
|
{
|
|
public const string Path = "Assets/Shaders/Gravity.cginc";
|
|
|
|
/// <summary>The whole file, with LF line ends.</summary>
|
|
public static string Source() => (Template
|
|
.Replace("@TAIL@", GravityField.TailOffset.ToString("R", CultureInfo.InvariantCulture)))
|
|
.Replace("\r\n", "\n");
|
|
|
|
private const string Template = """
|
|
#ifndef AETHERIA_GRAVITY_INCLUDED
|
|
#define AETHERIA_GRAVITY_INCLUDED
|
|
|
|
// GENERATED by ServerShared/GravityShader.cs from GravityField; do not edit (GravityShaderTests fails on any difference).
|
|
// The lowering of the zone's potential (aetheria-gravity, cut grid-lowering). The law is ServerShared's GravityField
|
|
// and the height is Zone.GetHeight; this file decides nothing. GravityLowering.Lower fills the buffer and the globals
|
|
// from the zone (positions from Orbit.Position, reference from Zone.WellReference) each frame.
|
|
// GravityFieldParityVerify renders it and compares every texel with -Zone.GetHeight.
|
|
|
|
struct GravityWell
|
|
{
|
|
float2 position;
|
|
float strength;
|
|
float coreRadius;
|
|
float reference;
|
|
};
|
|
|
|
StructuredBuffer<GravityWell> _GravityWells;
|
|
int _GravityWellCount;
|
|
float _HeightExaggeration;
|
|
|
|
// GravityField.Potential: c is the well's strength, R its core radius, r the distance.
|
|
float gravityPotential(float c, float R, float r)
|
|
{
|
|
return c == 0 ? 0 :
|
|
r < R
|
|
? c * r * r / (2 * R * R)
|
|
: c * (log(r / R) + @TAIL@);
|
|
}
|
|
|
|
// Zone.GetHeight at world xz: each well's potential minus its own reference, summed, divided by the exaggeration.
|
|
float gravityHeight(float2 p)
|
|
{
|
|
float result = 0;
|
|
for (int i = 0; i < _GravityWellCount; i++)
|
|
{
|
|
GravityWell well = _GravityWells[i];
|
|
result += gravityPotential(well.strength, well.coreRadius, length(p - well.position)) - well.reference;
|
|
}
|
|
return result / _HeightExaggeration;
|
|
}
|
|
|
|
#endif
|
|
|
|
""";
|
|
}
|