Derive native volume texture scale from viewport
This commit is contained in:
parent
9799dbe9fe
commit
3c8d127ef8
4 changed files with 68 additions and 3 deletions
|
|
@ -19,6 +19,7 @@ drivers, asset-provider hooks, package release, runtime tests, and captures.
|
|||
- provider asset-manifest documents
|
||||
- runtime-selected asset-variant metadata, including native rendering-program bindings
|
||||
- generic field-volume lifecycle declarations and logical texture/scalar/matrix ports
|
||||
- generic viewport-to-texture scale bindings between logical vector and texture ports
|
||||
- provider command receipts
|
||||
- semantic render-channel inclusion and exclusion policy
|
||||
- Unity input and local presentation assets
|
||||
|
|
@ -51,6 +52,13 @@ temporal pass must also advertise its current-sample, history,
|
|||
previous-view-projection, and reset-history ports; partial temporal programs fail
|
||||
closed.
|
||||
|
||||
Viewport-sized shader inputs are likewise presentation state. A provider may
|
||||
relate a logical vector port to a logical native texture port through
|
||||
`viewportTextureScaleBindings`; EveUnity derives the vector from the active
|
||||
camera viewport and resolved texture dimensions on every render. A provider
|
||||
literal is not allowed to impersonate those runtime dimensions, and an
|
||||
unresolvable relation fails closed.
|
||||
|
||||
The provider selects camera semantics and framing from its authoritative mode.
|
||||
`planar.top-down-follow.v1` derives a downward presentation from the advertised
|
||||
target and framing values. `perspective.entity-forward-follow.v1` derives its
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ namespace GameCult.Eve.UnityScene.Fields
|
|||
private Material? _material;
|
||||
private Shader? _sourceShader;
|
||||
private IReadOnlyDictionary<string, string>? _programMetadata;
|
||||
private readonly Dictionary<string, Texture> _assetTexturesByPort =
|
||||
new Dictionary<string, Texture>(StringComparer.Ordinal);
|
||||
private RenderTexture? _raymarchTexture;
|
||||
private readonly RenderTexture?[] _historyTextures = new RenderTexture?[2];
|
||||
private int _historyTextureIndex = -1;
|
||||
|
|
@ -89,7 +91,7 @@ namespace GameCult.Eve.UnityScene.Fields
|
|||
ApplyFieldBindings(field, _document);
|
||||
camera.depthTextureMode |= DepthTextureMode.Depth;
|
||||
EnsureVolumeTextures(camera, field);
|
||||
if (_raymarchTexture == null) return;
|
||||
if (_raymarchTexture == null || !ApplyViewportTextureScaleBindings(field, camera)) return;
|
||||
|
||||
var gpuProjection = GL.GetGPUProjectionMatrix(camera.projectionMatrix, true);
|
||||
var viewProjection = gpuProjection * camera.worldToCameraMatrix;
|
||||
|
|
@ -168,6 +170,7 @@ namespace GameCult.Eve.UnityScene.Fields
|
|||
_sourceShader = shader;
|
||||
_activeNodeId = field.NodeId;
|
||||
_material = new Material(shader) { hideFlags = HideFlags.DontSave };
|
||||
_assetTexturesByPort.Clear();
|
||||
ResetTemporalHistory();
|
||||
foreach (var parameter in ParseBindings(Prop(field, "floatParameters")))
|
||||
{
|
||||
|
|
@ -180,7 +183,11 @@ namespace GameCult.Eve.UnityScene.Fields
|
|||
var texture = provider.ResolveAsset(
|
||||
new EveUnityPlayableWorldAssetBinding(binding.Key, "", "provider-asset-ref"),
|
||||
typeof(Texture)) as Texture;
|
||||
if (texture != null) SetTexturePort(binding.Value, texture);
|
||||
if (texture != null)
|
||||
{
|
||||
_assetTexturesByPort[binding.Value] = texture;
|
||||
SetTexturePort(binding.Value, texture);
|
||||
}
|
||||
}
|
||||
var quality = Prop(field, "quality").Trim().ToLowerInvariant();
|
||||
if (TryProgramValue($"unity.volume.quality.{quality}.keyword", out var keyword) &&
|
||||
|
|
@ -262,6 +269,7 @@ namespace GameCult.Eve.UnityScene.Fields
|
|||
if (_material != null) { Destroy(_material); _material = null; }
|
||||
_sourceShader = null;
|
||||
_programMetadata = null;
|
||||
_assetTexturesByPort.Clear();
|
||||
_activeNodeId = "";
|
||||
PresentedFrameId = -1;
|
||||
CompositeCount = 0;
|
||||
|
|
@ -276,6 +284,36 @@ namespace GameCult.Eve.UnityScene.Fields
|
|||
|
||||
private bool HasTemporalProgram() => ProgramPass("temporal") >= 0;
|
||||
|
||||
private bool ApplyViewportTextureScaleBindings(EveUnityFieldVolumeProjection field, Camera camera)
|
||||
{
|
||||
foreach (var binding in ParseBindings(Prop(field, "viewportTextureScaleBindings")))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(ProgramPort("vector", binding.Key)) ||
|
||||
string.IsNullOrWhiteSpace(ProgramPort("texture", binding.Value)) ||
|
||||
!_assetTexturesByPort.TryGetValue(binding.Value, out var texture) ||
|
||||
!TryComputeViewportTextureScale(camera.pixelWidth, camera.pixelHeight, texture, out var scale))
|
||||
return false;
|
||||
SetVectorPort(binding.Key, scale);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool TryComputeViewportTextureScale(
|
||||
int viewportWidth,
|
||||
int viewportHeight,
|
||||
Texture? texture,
|
||||
out Vector4 scale)
|
||||
{
|
||||
scale = default;
|
||||
if (texture == null || texture.width <= 0 || texture.height <= 0) return false;
|
||||
scale = new Vector4(
|
||||
(float)Math.Max(1, viewportWidth) / texture.width,
|
||||
(float)Math.Max(1, viewportHeight) / texture.height,
|
||||
0f,
|
||||
0f);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool EnsureRenderTexture(ref RenderTexture? texture, int width, int height, string name)
|
||||
{
|
||||
if (texture != null && texture.width == width && texture.height == height) return false;
|
||||
|
|
|
|||
|
|
@ -73,6 +73,25 @@ namespace GameCult.Eve.UnityScene.Tests
|
|||
Assert.That(error, Does.Contain("history port"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void VolumeRendererDerivesViewportTextureScaleFromNativeDimensions()
|
||||
{
|
||||
var texture = new Texture2D(128, 64, TextureFormat.RGBA32, false);
|
||||
try
|
||||
{
|
||||
Assert.That(EveUnityFieldsVolumeRenderer.TryComputeViewportTextureScale(
|
||||
640,
|
||||
360,
|
||||
texture,
|
||||
out var scale), Is.True);
|
||||
Assert.That(scale, Is.EqualTo(new Vector4(5f, 5.625f, 0f, 0f)));
|
||||
}
|
||||
finally
|
||||
{
|
||||
UnityEngine.Object.DestroyImmediate(texture);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PackageContainsGenericFieldsShader()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "org.gamecult.eve.unity-scene",
|
||||
"displayName": "Eve Unity Scene Lowering",
|
||||
"version": "0.3.39",
|
||||
"version": "0.3.40",
|
||||
"unity": "2021.3",
|
||||
"description": "Provider-agnostic Unity scene shell for gamecult.eve.surface.v1 interactive world surfaces.",
|
||||
"dependencies": {
|
||||
|
|
|
|||
Reference in a new issue