Preserve provider temporal projection convention
This commit is contained in:
parent
3763383854
commit
3135d24bb8
4 changed files with 44 additions and 7 deletions
|
|
@ -82,6 +82,12 @@ the field textures it samples. A `world.scene3d` may also request
|
|||
quality, and sharpening values to URP TAA and restores the previous camera
|
||||
state when the world releases the camera.
|
||||
|
||||
Native volume programs also advertise the projection convention consumed by
|
||||
their history matrix. `non-render-target-projection.previous-view.v1` preserves
|
||||
the projection convention used by legacy `Graphics.Blit` temporal shaders even
|
||||
when EveUnity executes the program through a render-target-backed URP pass;
|
||||
providers must not rely on a runtime guessing that Y-axis convention.
|
||||
|
||||
`field.particles3d` may advertise provider material textures, viewport-relative
|
||||
texture scales, and a logical render-frame index port. These are presentation
|
||||
inputs: EveUnity binds the selected provider assets and current display frame
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ namespace GameCult.Eve.UnityScene.Fields
|
|||
ApplyQuality(field, _historyTextureIndex < 0);
|
||||
|
||||
var gpuProjection = GL.GetGPUProjectionMatrix(camera.projectionMatrix, true);
|
||||
var nonRenderTargetProjection = GL.GetGPUProjectionMatrix(camera.projectionMatrix, false);
|
||||
var viewProjection = gpuProjection * camera.worldToCameraMatrix;
|
||||
SetMatrixPort("cameraInverseViewProjection", viewProjection.inverse);
|
||||
SetMatrixPort("cameraToWorld", CameraTransformToWorld(camera));
|
||||
|
|
@ -170,6 +171,7 @@ namespace GameCult.Eve.UnityScene.Fields
|
|||
_programMetadata,
|
||||
_previousViewProjection,
|
||||
gpuProjection,
|
||||
nonRenderTargetProjection,
|
||||
_previousView));
|
||||
SetFloatPort("resetHistory", _historyTextureIndex < 0 ? 1f : 0f);
|
||||
}
|
||||
|
|
@ -496,13 +498,17 @@ namespace GameCult.Eve.UnityScene.Fields
|
|||
IReadOnlyDictionary<string, string>? metadata,
|
||||
Matrix4x4 previousViewProjection,
|
||||
Matrix4x4 currentGpuProjection,
|
||||
Matrix4x4 currentNonRenderTargetProjection,
|
||||
Matrix4x4 previousView)
|
||||
{
|
||||
return metadata != null &&
|
||||
metadata.TryGetValue("unity.volume.matrixSemantic.previousViewProjection", out var semantic) &&
|
||||
string.Equals(semantic, "current-projection.previous-view.v1", StringComparison.Ordinal)
|
||||
? currentGpuProjection * previousView
|
||||
: previousViewProjection;
|
||||
if (metadata == null ||
|
||||
!metadata.TryGetValue("unity.volume.matrixSemantic.previousViewProjection", out var semantic))
|
||||
return previousViewProjection;
|
||||
if (string.Equals(semantic, "current-projection.previous-view.v1", StringComparison.Ordinal))
|
||||
return currentGpuProjection * previousView;
|
||||
if (string.Equals(semantic, "non-render-target-projection.previous-view.v1", StringComparison.Ordinal))
|
||||
return currentNonRenderTargetProjection * previousView;
|
||||
return previousViewProjection;
|
||||
}
|
||||
|
||||
private bool HasTemporalProgram() => ProgramPass("temporal") >= 0;
|
||||
|
|
@ -583,7 +589,8 @@ namespace GameCult.Eve.UnityScene.Fields
|
|||
return Fail("Native volume temporal pass is missing a required history port.", out error);
|
||||
if (metadata.TryGetValue("unity.volume.matrixSemantic.previousViewProjection", out var semantic) &&
|
||||
!string.Equals(semantic, "previous-view-projection.v1", StringComparison.Ordinal) &&
|
||||
!string.Equals(semantic, "current-projection.previous-view.v1", StringComparison.Ordinal))
|
||||
!string.Equals(semantic, "current-projection.previous-view.v1", StringComparison.Ordinal) &&
|
||||
!string.Equals(semantic, "non-render-target-projection.previous-view.v1", StringComparison.Ordinal))
|
||||
return Fail("Native volume temporal pass has an unsupported previous-view-projection semantic.", out error);
|
||||
if (metadata.TryGetValue("unity.volume.quality.bootstrap", out var bootstrapQuality) &&
|
||||
(!metadata.TryGetValue(
|
||||
|
|
|
|||
|
|
@ -341,6 +341,7 @@ namespace GameCult.Eve.UnityScene.Tests
|
|||
metadata,
|
||||
previousViewProjection,
|
||||
currentProjection,
|
||||
Matrix4x4.identity,
|
||||
previousView);
|
||||
|
||||
Assert.That(resolved, Is.EqualTo(currentProjection * previousView));
|
||||
|
|
@ -356,11 +357,34 @@ namespace GameCult.Eve.UnityScene.Tests
|
|||
RequiredVolumeProgramMetadata(),
|
||||
previousViewProjection,
|
||||
Matrix4x4.Scale(Vector3.one * 2f),
|
||||
Matrix4x4.identity,
|
||||
Matrix4x4.Rotate(Quaternion.Euler(10f, 20f, 30f)));
|
||||
|
||||
Assert.That(resolved, Is.EqualTo(previousViewProjection));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void VolumeRendererUsesNonRenderTargetProjectionWhenAdvertised()
|
||||
{
|
||||
var metadata = RequiredVolumeProgramMetadata();
|
||||
metadata["unity.volume.matrixSemantic.previousViewProjection"] =
|
||||
"non-render-target-projection.previous-view.v1";
|
||||
var previousViewProjection = Matrix4x4.Translate(new Vector3(1f, 2f, 3f));
|
||||
var renderTargetProjection = Matrix4x4.Scale(new Vector3(2f, -3f, 4f));
|
||||
var nonRenderTargetProjection = Matrix4x4.Scale(new Vector3(2f, 3f, 4f));
|
||||
var previousView = Matrix4x4.Rotate(Quaternion.Euler(10f, 20f, 30f));
|
||||
|
||||
var resolved = EveUnityFieldsVolumeRenderer.ResolvePreviousViewProjection(
|
||||
metadata,
|
||||
previousViewProjection,
|
||||
renderTargetProjection,
|
||||
nonRenderTargetProjection,
|
||||
previousView);
|
||||
|
||||
Assert.That(resolved, Is.EqualTo(nonRenderTargetProjection * previousView));
|
||||
Assert.That(resolved, Is.Not.EqualTo(renderTargetProjection * previousView));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void VolumeProgramRejectsUnknownPreviousViewProjectionSemantic()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "org.gamecult.eve.unity-scene",
|
||||
"displayName": "Eve Unity Scene Lowering",
|
||||
"version": "0.3.62",
|
||||
"version": "0.3.63",
|
||||
"unity": "6000.0",
|
||||
"description": "Provider-agnostic Unity scene shell for gamecult.eve.surface.v1 interactive world surfaces.",
|
||||
"dependencies": {
|
||||
|
|
|
|||
Reference in a new issue