com.github.asus4.texture-source 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # Texture Source
2
2
 
3
- TextureSource is an utility for using CV in Unity. It enables you to choose multiple input sources in Editor.
3
+ TextureSource is a utility for using CV in Unity. It enables you to choose multiple input sources in Editor.
4
4
 
5
5
  ## Install via UPM
6
6
 
7
- Add following setting to `Packages/manifest.json`
7
+ Add the following setting to `Packages/manifest.json`
8
8
 
9
- ```
9
+ ```json
10
10
  {
11
11
  "scopedRegistries": [
12
12
  {
@@ -18,7 +18,7 @@ Add following setting to `Packages/manifest.json`
18
18
  }
19
19
  ],
20
20
  "dependencies": {
21
- "com.github.asus4.texture-source": "0.1.0",
21
+ "com.github.asus4.texture-source": "0.1.3",
22
22
  ...// other dependencies
23
23
  }
24
24
  }
@@ -0,0 +1,8 @@
1
+ // Ported from RenderPipeLine-Core, to support both URP and Built-in RP in one shader
2
+ // com.unity.render-pipelines.core copyright © 2020 Unity Technologies ApS
3
+ // Licensed under the Unity Companion License for Unity-dependent projects--see [Unity Companion License](http://www.unity3d.com/legal/licenses/Unity_Companion_License).
4
+
5
+ float3 FastSRGBToLinear(float3 c)
6
+ {
7
+ return c * (c * (c * 0.305306011 + 0.682171111) + 0.012522878);
8
+ }
@@ -0,0 +1,7 @@
1
+ fileFormatVersion: 2
2
+ guid: d73b9c13ee77b4bb48a8ff20c23c9709
3
+ ShaderIncludeImporter:
4
+ externalObjects: {}
5
+ userData:
6
+ assetBundleName:
7
+ assetBundleVariant:
@@ -1,5 +1,7 @@
1
1
  #pragma kernel TextureTransform
2
2
 
3
+ #include "Common.hlsl"
4
+
3
5
  Texture2D<float4> _InputTex;
4
6
  RWTexture2D<float4> _OutputTex;
5
7
  uint2 _OutputTexSize;
@@ -18,7 +20,13 @@ void TextureTransform (uint2 id : SV_DispatchThreadID)
18
20
  float2 uv = (float2)id / float2(_OutputTexSize - 1.0);
19
21
  uv = mul(_TransformMatrix, float4(uv, 0, 1)).xy;
20
22
 
23
+ float4 c = _InputTex.SampleLevel(linearClampSampler, uv, 0);
24
+
25
+ #ifndef UNITY_NO_LINEAR_COLORSPACE
26
+ c.rgb = FastSRGBToLinear(c.rgb);
27
+ #endif // !UNITY_COLORSPACE_GAMMA
28
+
21
29
  _OutputTex[id] = any(uv < 0) || any(uv > 1)
22
30
  ? float4(0, 0, 0, 1)
23
- : _InputTex.SampleLevel(linearClampSampler, uv, 0);
31
+ : c;
24
32
  }
@@ -0,0 +1,144 @@
1
+ // Only available with AR Foundation
2
+ #if MODULE_ARFOUNDATION_ENABLED
3
+ namespace TextureSource
4
+ {
5
+ using System;
6
+ using UnityEngine;
7
+ using UnityEngine.XR.ARFoundation;
8
+
9
+ [CreateAssetMenu(menuName = "ScriptableObject/Texture Source/ARFoundation", fileName = "ARFoundationTextureSource")]
10
+ public sealed class ARFoundationTextureSource : BaseTextureSource
11
+ {
12
+ private static readonly int _DisplayTransformID = Shader.PropertyToID("_UnityDisplayTransform");
13
+
14
+ private ARCameraManager cameraManager;
15
+ private RenderTexture texture;
16
+ private Material material;
17
+ private int lastUpdatedFrame = -1;
18
+
19
+ private static readonly Lazy<Shader> ARCameraBackgroundShader = new(() =>
20
+ {
21
+ string shaderName = Application.platform switch
22
+ {
23
+ RuntimePlatform.Android => "Unlit/ARCoreBackground",
24
+ RuntimePlatform.IPhonePlayer => "Unlit/ARKitBackground",
25
+ #if UNITY_ANDROID
26
+ _ => "Unlit/ARCoreBackground",
27
+ #elif UNITY_IOS
28
+ _ => "Unlit/ARKitBackground",
29
+ #else
30
+ _ => throw new NotSupportedException($"ARFoundationTextureSource is not supported on {Application.platform}"),
31
+ #endif
32
+ };
33
+ return Shader.Find(shaderName);
34
+ });
35
+
36
+ public override bool DidUpdateThisFrame => lastUpdatedFrame == Time.frameCount;
37
+ public override Texture Texture => texture;
38
+
39
+ public override void Start()
40
+ {
41
+ cameraManager = FindAnyObjectByType<ARCameraManager>();
42
+ if (cameraManager == null)
43
+ {
44
+ throw new InvalidOperationException("ARCameraManager is not found");
45
+ }
46
+
47
+ var shader = ARCameraBackgroundShader.Value;
48
+ material = new Material(shader);
49
+
50
+ cameraManager.frameReceived += OnFrameReceived;
51
+ }
52
+
53
+ public override void Stop()
54
+ {
55
+ if (cameraManager != null)
56
+ {
57
+ cameraManager.frameReceived -= OnFrameReceived;
58
+ }
59
+
60
+ if (texture != null)
61
+ {
62
+ texture.Release();
63
+ Destroy(texture);
64
+ texture = null;
65
+ }
66
+
67
+ if (material != null)
68
+ {
69
+ Destroy(material);
70
+ material = null;
71
+ }
72
+ }
73
+
74
+ public override void Next()
75
+ {
76
+ if (cameraManager == null)
77
+ {
78
+ return;
79
+ }
80
+ // Switch the camera facing direction.
81
+ cameraManager.requestedFacingDirection = cameraManager.currentFacingDirection switch
82
+ {
83
+ CameraFacingDirection.World => CameraFacingDirection.User,
84
+ CameraFacingDirection.User => CameraFacingDirection.World,
85
+ _ => CameraFacingDirection.World,
86
+ };
87
+ }
88
+
89
+ private void OnFrameReceived(ARCameraFrameEventArgs args)
90
+ {
91
+ // Find best texture size
92
+ int bestWidth = 0;
93
+ int bestHeight = 0;
94
+ int count = args.textures.Count;
95
+ for (int i = 0; i < count; i++)
96
+ {
97
+ var tex = args.textures[i];
98
+ bestWidth = Math.Max(bestWidth, tex.width);
99
+ bestHeight = Math.Max(bestHeight, tex.height);
100
+ material.SetTexture(args.propertyNameIds[i], tex);
101
+ }
102
+
103
+ // Swap if screen is portrait
104
+ float screenAspect = (float)Screen.width / Screen.height;
105
+ if (bestWidth > bestHeight && screenAspect < 1f)
106
+ {
107
+ (bestWidth, bestHeight) = (bestHeight, bestWidth);
108
+ }
109
+
110
+ // Create render texture
111
+ Utils.GetTargetSizeScale(
112
+ new Vector2Int(bestWidth, bestHeight), screenAspect,
113
+ out Vector2Int dstSize, out Vector2 scale);
114
+ EnsureRenderTexture(dstSize.x, dstSize.y);
115
+
116
+ // SetMaterialKeywords(material, args.enabledMaterialKeywords, args.disabledMaterialKeywords);
117
+
118
+ if (args.displayMatrix.HasValue)
119
+ {
120
+ material.SetMatrix(_DisplayTransformID, args.displayMatrix.Value);
121
+ }
122
+
123
+ Graphics.Blit(null, texture, material);
124
+
125
+ lastUpdatedFrame = Time.frameCount;
126
+ }
127
+
128
+ private void EnsureRenderTexture(int width, int height)
129
+ {
130
+ if (texture == null || texture.width != width || texture.height != height)
131
+ {
132
+ if (texture != null)
133
+ {
134
+ texture.Release();
135
+ texture = null;
136
+ }
137
+ int depth = 32;
138
+ texture = new RenderTexture(width, height, depth, RenderTextureFormat.ARGB32);
139
+ texture.Create();
140
+ }
141
+ }
142
+ }
143
+ }
144
+ #endif // MODULE_ARFOUNDATION_ENABLED
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 107561cd512c541429a04e0ab1d41f54
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -1,7 +1,9 @@
1
1
  {
2
2
  "name": "TextureSource",
3
3
  "rootNamespace": "",
4
- "references": [],
4
+ "references": [
5
+ "GUID:a9420e37d7990b54abdef6688edbe313"
6
+ ],
5
7
  "includePlatforms": [],
6
8
  "excludePlatforms": [],
7
9
  "allowUnsafeCode": false,
@@ -9,6 +11,12 @@
9
11
  "precompiledReferences": [],
10
12
  "autoReferenced": true,
11
13
  "defineConstraints": [],
12
- "versionDefines": [],
14
+ "versionDefines": [
15
+ {
16
+ "name": "com.unity.xr.arfoundation",
17
+ "expression": "4.0.0",
18
+ "define": "MODULE_ARFOUNDATION_ENABLED"
19
+ }
20
+ ],
13
21
  "noEngineReferences": false
14
22
  }
@@ -1,11 +1,10 @@
1
1
  namespace TextureSource
2
2
  {
3
+ using System;
3
4
  using UnityEngine;
4
5
 
5
- public class TextureTransformer : System.IDisposable
6
+ public class TextureTransformer : IDisposable
6
7
  {
7
- private static ComputeShader compute;
8
- private static int kernel;
9
8
  private static readonly int _InputTex = Shader.PropertyToID("_InputTex");
10
9
  private static readonly int _OutputTex = Shader.PropertyToID("_OutputTex");
11
10
  private static readonly int _OutputTexSize = Shader.PropertyToID("_OutputTexSize");
@@ -14,14 +13,24 @@ namespace TextureSource
14
13
  private static readonly Matrix4x4 PopMatrix = Matrix4x4.Translate(new Vector3(0.5f, 0.5f, 0));
15
14
  private static readonly Matrix4x4 PushMatrix = Matrix4x4.Translate(new Vector3(-0.5f, -0.5f, 0));
16
15
 
16
+ public static readonly Lazy<ComputeShader> DefaultComputeShader = new(()
17
+ => Resources.Load<ComputeShader>("com.github.asus4.texture-source/TextureTransform"));
18
+
19
+ private readonly ComputeShader compute;
20
+ private readonly int kernel;
17
21
  private RenderTexture texture;
18
22
  public readonly int width;
19
23
  public readonly int height;
20
24
 
21
25
  public RenderTexture Texture => texture;
22
26
 
23
- public TextureTransformer(int width, int height)
27
+ public TextureTransformer(int width, int height, ComputeShader shader = null)
24
28
  {
29
+ compute = shader != null
30
+ ? shader
31
+ : DefaultComputeShader.Value;
32
+ kernel = compute.FindKernel("TextureTransform");
33
+
25
34
  this.width = width;
26
35
  this.height = height;
27
36
 
@@ -30,16 +39,10 @@ namespace TextureSource
30
39
  enableRandomWrite = true,
31
40
  useMipMap = false,
32
41
  depthBufferBits = 0,
42
+ // sRGB = QualitySettings.activeColorSpace == ColorSpace.Linear,
33
43
  };
34
44
  texture = new RenderTexture(desc);
35
45
  texture.Create();
36
-
37
- if (compute == null)
38
- {
39
- const string SHADER_PATH = "com.github.asus4.texture-source/TextureTransform";
40
- compute = Resources.Load<ComputeShader>(SHADER_PATH);
41
- kernel = compute.FindKernel("TextureTransform");
42
- }
43
46
  }
44
47
 
45
48
  public void Dispose()
@@ -47,11 +50,17 @@ namespace TextureSource
47
50
  if (texture != null)
48
51
  {
49
52
  texture.Release();
50
- Object.Destroy(texture);
53
+ UnityEngine.Object.Destroy(texture);
51
54
  }
52
55
  texture = null;
53
56
  }
54
57
 
58
+ /// <summary>
59
+ /// Transform with a matrix
60
+ /// </summary>
61
+ /// <param name="input">A input texture</param>
62
+ /// <param name="t">A matrix</param>
63
+ /// <returns>The transformed texture</returns>
55
64
  public RenderTexture Transform(Texture input, Matrix4x4 t)
56
65
  {
57
66
  compute.SetTexture(kernel, _InputTex, input, 0);
@@ -62,6 +71,14 @@ namespace TextureSource
62
71
  return texture;
63
72
  }
64
73
 
74
+ /// <summary>
75
+ /// Transform with offset, rotation, and scale
76
+ /// </summary>
77
+ /// <param name="input">A input texture</param>
78
+ /// <param name="offset">A 2D offset</param>
79
+ /// <param name="eulerRotation">A rotation in euler angles</param>
80
+ /// <param name="scale">A scale</param>
81
+ /// <returns>The transformed texture</returns>
65
82
  public RenderTexture Transform(Texture input, Vector2 offset, float eulerRotation, Vector2 scale)
66
83
  {
67
84
  Matrix4x4 trs = Matrix4x4.TRS(
@@ -70,5 +87,25 @@ namespace TextureSource
70
87
  new Vector3(1f / scale.x, 1f / scale.y, 1));
71
88
  return Transform(input, PopMatrix * trs * PushMatrix);
72
89
  }
90
+
91
+ /// <summary>
92
+ /// Transform with multiple textures
93
+ /// </summary>
94
+ /// <param name="propertyIds">An array of property name IDs associated with each texture</param>
95
+ /// <param name="textures">An array of textures</param>
96
+ /// <param name="t">A matrix</param>
97
+ /// <returns>The transformed texture</returns>
98
+ public RenderTexture Transform(ReadOnlySpan<int> propertyIds, ReadOnlySpan<Texture> textures, Matrix4x4 t)
99
+ {
100
+ for (int i = 0; i < propertyIds.Length; i++)
101
+ {
102
+ compute.SetTexture(kernel, propertyIds[i], textures[i], 0);
103
+ }
104
+ compute.SetTexture(kernel, _OutputTex, texture, 0);
105
+ compute.SetInts(_OutputTexSize, texture.width, texture.height);
106
+ compute.SetMatrix(_TransformMatrix, t);
107
+ compute.Dispatch(kernel, Mathf.CeilToInt(texture.width / 8f), Mathf.CeilToInt(texture.height / 8f), 1);
108
+ return texture;
109
+ }
73
110
  }
74
111
  }
@@ -0,0 +1,33 @@
1
+ namespace TextureSource
2
+ {
3
+ using UnityEngine;
4
+
5
+ internal static class Utils
6
+ {
7
+ public static void GetTargetSizeScale(
8
+ Vector2Int srcSize, float dstAspect,
9
+ out Vector2Int dstSize, out Vector2 scale)
10
+ {
11
+ float srcAspect = (float)srcSize.x / srcSize.y;
12
+ int width, height;
13
+ if (srcAspect > dstAspect)
14
+ {
15
+ width = RoundToEven(srcSize.y * dstAspect);
16
+ height = srcSize.y;
17
+ scale = new Vector2((float)srcSize.x / width, 1);
18
+ }
19
+ else
20
+ {
21
+ width = srcSize.x;
22
+ height = RoundToEven(srcSize.x / dstAspect);
23
+ scale = new Vector2(1, (float)srcSize.y / height);
24
+ }
25
+ dstSize = new Vector2Int(width, height);
26
+ }
27
+
28
+ private static int RoundToEven(float n)
29
+ {
30
+ return Mathf.RoundToInt(n / 2) * 2;
31
+ }
32
+ }
33
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 994d1f7299166498fb0798e74fd2cbf0
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -101,42 +101,27 @@ namespace TextureSource
101
101
 
102
102
  private Texture TrimToScreen(Texture texture)
103
103
  {
104
- float cameraAspect = (float)texture.width / texture.height;
105
- float targetAspect = (float)Screen.width / Screen.height;
104
+ float srcAspect = (float)texture.width / texture.height;
105
+ float dstAspect = (float)Screen.width / Screen.height;
106
106
 
107
- if (Mathf.Abs(cameraAspect - targetAspect) < 0.01f)
107
+ // Allow 1% mismatch
108
+ if (Mathf.Abs(srcAspect - dstAspect) < 0.01f)
108
109
  {
109
110
  return texture;
110
111
  }
111
112
 
112
- int width, height;
113
- Vector2 scale;
114
- if (cameraAspect > targetAspect)
115
- {
116
- width = RoundToEven(texture.height * targetAspect);
117
- height = texture.height;
118
- scale = new Vector2((float)texture.width / width, 1);
119
- }
120
- else
121
- {
122
- width = texture.width;
123
- height = RoundToEven(texture.width / targetAspect);
124
- scale = new Vector2(1, (float)texture.height / height);
125
- }
113
+ Utils.GetTargetSizeScale(
114
+ new Vector2Int(texture.width, texture.height), dstAspect,
115
+ out Vector2Int dstSize, out Vector2 scale);
126
116
 
127
- bool needInitialize = transformer == null || width != transformer.width || height != transformer.height;
117
+ bool needInitialize = transformer == null || dstSize.x != transformer.width || dstSize.y != transformer.height;
128
118
  if (needInitialize)
129
119
  {
130
120
  transformer?.Dispose();
131
- transformer = new TextureTransformer(width, height);
121
+ transformer = new TextureTransformer(dstSize.x, dstSize.y);
132
122
  }
133
123
 
134
124
  return transformer.Transform(texture, Vector2.zero, 0, scale);
135
125
  }
136
-
137
- private static int RoundToEven(float n)
138
- {
139
- return Mathf.RoundToInt(n / 2) * 2;
140
- }
141
126
  }
142
127
  }
package/package.json CHANGED
@@ -1,14 +1,22 @@
1
1
  {
2
2
  "name": "com.github.asus4.texture-source",
3
+ "version": "0.2.0",
3
4
  "displayName": "TextureSource",
4
- "author": "Koki Ibukuro",
5
- "description": "Virtual Texture Source",
6
- "keywords": [
7
- "unity"
8
- ],
9
- "license": "SEE LICENSE IN LICENSE",
5
+ "description": "Simplify WebCamera and test video handling for using Computer Vision in Unity",
10
6
  "unity": "2020.3",
11
7
  "unityRelease": "0f1",
12
- "version": "0.1.3",
13
- "type": "tool"
8
+ "keywords": [
9
+ "unity",
10
+ "cv"
11
+ ],
12
+ "documentationUrl": "https://github.com/asus4/TextureSource/tree/main",
13
+ "changelogUrl": "https://github.com/asus4/TextureSource/releases",
14
+ "licensesUrl": "https://github.com/asus4/TextureSource/blob/main/Packages/com.github.asus4.texture-source/LICENSE",
15
+ "author": {
16
+ "name": "Koki Ibukuro",
17
+ "url": "https://github.com/asus4"
18
+ },
19
+ "dependencies": {
20
+ "com.unity.modules.video": "1.0.0"
21
+ }
14
22
  }