Lower portable power pulse field splats
This commit is contained in:
parent
6ff45d0bbf
commit
441471949a
4 changed files with 62 additions and 5 deletions
|
|
@ -12,7 +12,7 @@ namespace GameCult.Eve.UnityScene.Fields
|
|||
public const string ViewportToClipPropertyName = "_EveFieldsViewportToClip";
|
||||
public const string ChannelFilterPropertyName = "_EveFieldsChannelFilter";
|
||||
|
||||
private const int SplatStrideBytes = 80;
|
||||
private const int SplatStrideBytes = 96;
|
||||
private EveFieldsGpuSplat[] splats = Array.Empty<EveFieldsGpuSplat>();
|
||||
private GraphicsBuffer buffer;
|
||||
private int capacity;
|
||||
|
|
@ -54,6 +54,7 @@ namespace GameCult.Eve.UnityScene.Fields
|
|||
RotationChannelFalloff = new Vector4((float)Read(source.RotationCos, index, 1), (float)Read(source.RotationSin, index, 0), channel, Read(source.Falloff, index, EveFieldsSplatFalloffs.Smooth)),
|
||||
LayerSource = new Vector4(layer, Read(source.SourceKind, index, EveFieldsSplatSourceKinds.Constant), (float)Read(source.AnimationSpeed, index, 0), (float)Read(source.SourceFlags, index, 0)),
|
||||
SourceFrequencyPhase = new Vector4((float)Read(source.FrequencyX, index, 1), (float)Read(source.FrequencyY, index, 1), (float)Read(source.PhaseX, index, 0), (float)Read(source.PhaseY, index, 0)),
|
||||
FalloffParameters = new Vector4((float)Read(source.FalloffScale, index, 1), (float)Read(source.FalloffExponent, index, 1), 0, 0),
|
||||
Value = new Vector4((float)Read(source.ValueR, index, 0), (float)Read(source.ValueG, index, 0), (float)Read(source.ValueB, index, 0), (float)Read(source.ValueA, index, 1))
|
||||
};
|
||||
}
|
||||
|
|
@ -99,6 +100,7 @@ namespace GameCult.Eve.UnityScene.Fields
|
|||
public Vector4 RotationChannelFalloff;
|
||||
public Vector4 LayerSource;
|
||||
public Vector4 SourceFrequencyPhase;
|
||||
public Vector4 FalloffParameters;
|
||||
public Vector4 Value;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ struct EveFieldsSplat
|
|||
float4 rotationChannelFalloff;
|
||||
float4 layerSource;
|
||||
float4 sourceFrequencyPhase;
|
||||
float4 falloffParameters;
|
||||
float4 value;
|
||||
};
|
||||
|
||||
|
|
@ -58,12 +59,17 @@ Varyings Vert(uint vertexId : SV_VertexID, uint instanceId : SV_InstanceID)
|
|||
return output;
|
||||
}
|
||||
|
||||
float ResolveFalloff(float2 localUv, int falloff)
|
||||
float ResolveFalloff(float2 localUv, int falloff, float scale, float exponent)
|
||||
{
|
||||
float distance01 = saturate(length(localUv));
|
||||
if (falloff == 0) return 1;
|
||||
if (falloff == 1) return saturate(1 - distance01);
|
||||
if (falloff == 3) return smoothstep(0, 1, distance01);
|
||||
if (falloff == 4)
|
||||
{
|
||||
float pulseDistance = distance01 * max(0, scale);
|
||||
return pow(saturate(1 - pulseDistance * pulseDistance), max(0.0001, exponent));
|
||||
}
|
||||
return 1 - smoothstep(0, 1, distance01);
|
||||
}
|
||||
|
||||
|
|
@ -72,7 +78,11 @@ float4 Frag(Varyings input) : SV_Target
|
|||
EveFieldsSplat splat = _EveFieldsSplats[input.instanceId];
|
||||
int channel = (int)round(splat.rotationChannelFalloff.z);
|
||||
if (_EveFieldsChannelFilter >= 0 && channel != _EveFieldsChannelFilter) discard;
|
||||
float alpha = ResolveFalloff(input.localUv, (int)round(splat.rotationChannelFalloff.w));
|
||||
float alpha = ResolveFalloff(
|
||||
input.localUv,
|
||||
(int)round(splat.rotationChannelFalloff.w),
|
||||
splat.falloffParameters.x,
|
||||
splat.falloffParameters.y);
|
||||
clip(alpha - 0.0001);
|
||||
int sourceKind = (int)round(splat.layerSource.y);
|
||||
float source = 1;
|
||||
|
|
|
|||
|
|
@ -131,6 +131,49 @@ namespace GameCult.Eve.UnityScene.Tests
|
|||
UnityEngine.Object.DestroyImmediate(host);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RasterizerLowersPortablePowerPulseParameters()
|
||||
{
|
||||
var document = new EveFieldsSplatsDocument
|
||||
{
|
||||
Viewport = new EveFieldsViewport { MinX = -1, MinY = -1, MaxX = 1, MaxY = 1 },
|
||||
Splats = new EveFieldsSplatSoa
|
||||
{
|
||||
Count = 1,
|
||||
CenterX = new[] { 0d },
|
||||
CenterY = new[] { 0d },
|
||||
HalfExtentX = new[] { 1d },
|
||||
HalfExtentY = new[] { 1d },
|
||||
RotationCos = new[] { 1d },
|
||||
RotationSin = new[] { 0d },
|
||||
Channel = new[] { 0 },
|
||||
Falloff = new[] { EveFieldsSplatFalloffs.PowerPulse },
|
||||
FalloffScale = new[] { 2d },
|
||||
FalloffExponent = new[] { 1d },
|
||||
ValueR = new[] { 1d },
|
||||
ValueA = new[] { 1d },
|
||||
LayerIndex = new[] { 0 },
|
||||
SourceKind = new[] { EveFieldsSplatSourceKinds.Constant }
|
||||
}
|
||||
};
|
||||
var host = new GameObject("eve-fields-power-pulse");
|
||||
var rasterizer = host.AddComponent<EveFieldsSplatRasterizer>();
|
||||
var output = rasterizer.Render(document, 128, 128);
|
||||
var previous = RenderTexture.active;
|
||||
RenderTexture.active = output;
|
||||
var readback = new Texture2D(128, 128, TextureFormat.RGBAFloat, false, true);
|
||||
readback.ReadPixels(new Rect(0, 0, 128, 128), 0, 0);
|
||||
readback.Apply();
|
||||
RenderTexture.active = previous;
|
||||
|
||||
Assert.That(readback.GetPixel(64, 64).r, Is.GreaterThan(0.95f));
|
||||
Assert.That(readback.GetPixel(80, 64).r, Is.InRange(0.65f, 0.85f));
|
||||
Assert.That(readback.GetPixel(96, 64).r, Is.LessThan(0.02f));
|
||||
|
||||
UnityEngine.Object.DestroyImmediate(readback);
|
||||
UnityEngine.Object.DestroyImmediate(host);
|
||||
}
|
||||
|
||||
private sealed class CaptureDocument : IEveFieldsSplatsDocument
|
||||
{
|
||||
public string Schema => EveFieldsSchemas.Splats;
|
||||
|
|
@ -188,6 +231,8 @@ namespace GameCult.Eve.UnityScene.Tests
|
|||
public IReadOnlyList<double> PhaseY => Zero;
|
||||
public IReadOnlyList<double> AnimationSpeed => Zero;
|
||||
public IReadOnlyList<double> SourceFlags => Zero;
|
||||
public IReadOnlyList<double> FalloffScale => One;
|
||||
public IReadOnlyList<double> FalloffExponent => One;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "org.gamecult.eve.unity-scene",
|
||||
"displayName": "Eve Unity Scene Lowering",
|
||||
"version": "0.3.41",
|
||||
"version": "0.3.42",
|
||||
"unity": "2021.3",
|
||||
"description": "Provider-agnostic Unity scene shell for gamecult.eve.surface.v1 interactive world surfaces.",
|
||||
"dependencies": {
|
||||
"org.gamecult.cultlib": "1.0.13",
|
||||
"org.gamecult.eve.plugin-fields": "0.2.0",
|
||||
"org.gamecult.eve.plugin-fields": "0.2.1",
|
||||
"org.gamecult.eve.surface": "0.2.2",
|
||||
"com.unity.mathematics": "1.3.2",
|
||||
"com.unity.modules.particlesystem": "1.0.0"
|
||||
|
|
|
|||
Reference in a new issue