diff --git a/Runtime/MaskRenderer.cs b/Runtime/MaskRenderer.cs new file mode 100644 index 0000000..fc5947e --- /dev/null +++ b/Runtime/MaskRenderer.cs @@ -0,0 +1,193 @@ +using UnityEngine; + +namespace TAO.InteractiveMask +{ + public class MaskRenderer : MonoBehaviour + { + public Mode mode = Mode.EachFrame; + + public Shader clearBlit = null; + private Material clearBlitMaterial; + // Camera source. + public RenderTexture source = null; + // Output target. + public RenderTexture target = null; + + public Layer[] layers; + + public bool debugGui = false; + + public void Awake() + { + clearBlitMaterial = new Material(clearBlit); + + foreach (Layer layer in layers) + { + layer.Init(source, target); + } + } + + private void Update() + { + if (mode == Mode.EachFrame) + { + Render(); + } + } + + public void Render() + { + Graphics.Blit(target, target, clearBlitMaterial); + + foreach (Layer layer in layers) + { + layer.Blit(source, target); + } + } + + private void OnValidate() + { + if (clearBlit == null) + { + clearBlit = Shader.Find("TAO/InteractiveMask/Clear"); + } + + if (layers != null) + { + for (int i = 0; i < layers.Length; i++) + { + if (layers[i].blit == null) + { + layers[i].blit = Shader.Find("TAO/InteractiveMask/Add"); + } + + if (layers[i].persistentBlit == null) + { + layers[i].persistentBlit = Shader.Find("TAO/InteractiveMask/AddPersistent"); + } + } + } + } + + private void OnGUI() + { + if (debugGui) + { + using (new GUILayout.HorizontalScope()) + { + GUITexture(source); + GUITexture(target); + + foreach (var l in layers) + { + switch (l.type) + { + case Layer.Type.Clear: + break; + case Layer.Type.Persistent: + { + GUITexture(l.PersistentTarget); + } + break; + default: + break; + } + } + } + } + } + + private void GUITexture(Texture texture) + { + using (new GUILayout.VerticalScope()) + { + GUILayout.Label(texture, GUILayout.Width(256), GUILayout.Height(256)); + GUILayout.Label(string.Format("{0}\n{1}x{2}\n{3}", texture.name, texture.width, texture.height, texture.graphicsFormat)); + } + } + + public enum Mode + { + EachFrame, + Manual + } + } + + [System.Serializable] + public class Layer + { + public static int LayerCount = 0; + + public Type type; + public Shader blit; + private Material blitMaterial; + public Vector4 channels; + + // Only when mode is persistent. + public Shader persistentBlit; + public RenderTexture PersistentTarget + { + get; private set; + } + private Material persistentBlitMaterial; + + public void Init(RenderTexture source, RenderTexture target) + { + blitMaterial = new Material(blit); + + switch (type) + { + case Type.Clear: + break; + case Type.Persistent: + { + persistentBlitMaterial = new Material(persistentBlit); + + if (PersistentTarget == null) + { + PersistentTarget = new RenderTexture(target) + { + name = LayerCount.ToString() + }; + LayerCount++; + } + + persistentBlitMaterial.SetTexture("_Source", source); + persistentBlitMaterial.SetTexture("_Persistent", PersistentTarget); + } + break; + default: + break; + } + + blitMaterial.SetTexture("_Source", source); + blitMaterial.SetVector("_Channels", channels); + } + + public void Blit(RenderTexture source, RenderTexture target) + { + switch (type) + { + case Type.Clear: + { + Graphics.Blit(source, target, blitMaterial); + } + break; + case Type.Persistent: + { + Graphics.Blit(source, PersistentTarget, persistentBlitMaterial); + Graphics.Blit(PersistentTarget, target, blitMaterial); + } + break; + default: + break; + } + } + + public enum Type + { + Clear, + Persistent + } + } +} \ No newline at end of file diff --git a/Runtime/MaskRenderer.cs.meta b/Runtime/MaskRenderer.cs.meta new file mode 100644 index 0000000..b6acab6 --- /dev/null +++ b/Runtime/MaskRenderer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c7ace5587b33c154490f78c11ec9a297 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Shaders.meta b/Runtime/Shaders.meta new file mode 100644 index 0000000..8c221cf --- /dev/null +++ b/Runtime/Shaders.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ad86bba476a81e942aef62ebcad19e59 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Shaders/Add.shader b/Runtime/Shaders/Add.shader new file mode 100644 index 0000000..44369a5 --- /dev/null +++ b/Runtime/Shaders/Add.shader @@ -0,0 +1,62 @@ +Shader "TAO/InteractiveMask/Add" +{ + Properties + { + [HideInInspector] [NoScaleOffset] _MainTex("main", 2D) = "white" {} + _Channels("Channels", Vector) = (1, 1, 1, 1) + } + + SubShader + { + Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" } + Blend One One + + Pass + { + HLSLPROGRAM + #pragma vertex vert + #pragma fragment frag + + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + + struct Attributes + { + float4 positionOS : POSITION; + float2 uv : TEXCOORD0; + }; + + struct Varyings + { + float4 positionHCS : SV_POSITION; + float2 uv : TEXCOORD0; + }; + + TEXTURE2D(_MainTex); + SAMPLER(sampler_MainTex); + float4 _Channels; + + CBUFFER_START(UnityPerMaterial) + float4 _MainTex_ST; + CBUFFER_END + + Varyings vert(Attributes IN) + { + Varyings OUT; + + OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz); + + OUT.uv = TRANSFORM_TEX(IN.uv, _MainTex); + + return OUT; + } + + half4 frag(Varyings IN) : SV_Target + { + half4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uv) * _Channels; + return color; + } + + ENDHLSL + } + } +} \ No newline at end of file diff --git a/Runtime/Shaders/Add.shader.meta b/Runtime/Shaders/Add.shader.meta new file mode 100644 index 0000000..28bb68b --- /dev/null +++ b/Runtime/Shaders/Add.shader.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b56b79d9c9a85fb45bf1a263d73bd938 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + preprocessorOverride: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Shaders/AddPersistent.shader b/Runtime/Shaders/AddPersistent.shader new file mode 100644 index 0000000..123f62b --- /dev/null +++ b/Runtime/Shaders/AddPersistent.shader @@ -0,0 +1,63 @@ +Shader "TAO/InteractiveMask/AddPersistent" +{ + Properties + { + [HideInInspector] [NoScaleOffset] _MainTex("main", 2D) = "white" {} + [NoScaleOffset] _Persistent("persistent", 2D) = "white" {} + } + + SubShader + { + Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" } + Blend One One + + Pass + { + HLSLPROGRAM + #pragma vertex vert + #pragma fragment frag + + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + + struct Attributes + { + float4 positionOS : POSITION; + float2 uv : TEXCOORD0; + }; + + struct Varyings + { + float4 positionHCS : SV_POSITION; + float2 uv : TEXCOORD0; + }; + + TEXTURE2D(_MainTex); + SAMPLER(sampler_MainTex); + TEXTURE2D(_Persistent); + SAMPLER(sampler_Persistent); + + CBUFFER_START(UnityPerMaterial) + float4 _MainTex_ST; + CBUFFER_END + + Varyings vert(Attributes IN) + { + Varyings OUT; + + OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz); + + OUT.uv = TRANSFORM_TEX(IN.uv, _MainTex); + + return OUT; + } + + half4 frag(Varyings IN) : SV_Target + { + half4 color = SAMPLE_TEXTURE2D(_Persistent, sampler_Persistent, IN.uv) + SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uv); + return color; + } + + ENDHLSL + } + } +} \ No newline at end of file diff --git a/Runtime/Shaders/AddPersistent.shader.meta b/Runtime/Shaders/AddPersistent.shader.meta new file mode 100644 index 0000000..bc7a928 --- /dev/null +++ b/Runtime/Shaders/AddPersistent.shader.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 794c349d1ba10d34c86b6dd5c2b8bb7e +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + preprocessorOverride: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Shaders/Clear.shader b/Runtime/Shaders/Clear.shader new file mode 100644 index 0000000..bb06750 --- /dev/null +++ b/Runtime/Shaders/Clear.shader @@ -0,0 +1,58 @@ +Shader "TAO/InteractiveMask/Clear" +{ + Properties + { + [HideInInspector] [NoScaleOffset] _MainTex("main", 2D) = "white" {} + } + + SubShader + { + Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" } + + Pass + { + HLSLPROGRAM + #pragma vertex vert + #pragma fragment frag + + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + + struct Attributes + { + float4 positionOS : POSITION; + float2 uv : TEXCOORD0; + }; + + struct Varyings + { + float4 positionHCS : SV_POSITION; + float2 uv : TEXCOORD0; + }; + + TEXTURE2D(_MainTex); + SAMPLER(sampler_MainTex); + + CBUFFER_START(UnityPerMaterial) + float4 _MainTex_ST; + CBUFFER_END + + Varyings vert(Attributes IN) + { + Varyings OUT; + + OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz); + + OUT.uv = TRANSFORM_TEX(IN.uv, _MainTex); + + return OUT; + } + + half4 frag(Varyings IN) : SV_Target + { + return half4(0, 0, 0, 0); + } + + ENDHLSL + } + } +} \ No newline at end of file diff --git a/Runtime/Shaders/Clear.shader.meta b/Runtime/Shaders/Clear.shader.meta new file mode 100644 index 0000000..cd030f8 --- /dev/null +++ b/Runtime/Shaders/Clear.shader.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 612652bd41e196b408fe733989b1d223 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + preprocessorOverride: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Textures.meta b/Runtime/Textures.meta new file mode 100644 index 0000000..b571231 --- /dev/null +++ b/Runtime/Textures.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 09c1b73271dc0944dad462995cae5ca7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Textures/Source.renderTexture b/Runtime/Textures/Source.renderTexture new file mode 100644 index 0000000..4bf585c --- /dev/null +++ b/Runtime/Textures/Source.renderTexture @@ -0,0 +1,38 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!84 &8400000 +RenderTexture: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Source + m_ImageContentsHash: + serializedVersion: 2 + Hash: 00000000000000000000000000000000 + m_ForcedFallbackFormat: 4 + m_DownscaleFallback: 0 + m_IsAlphaChannelOptional: 0 + serializedVersion: 3 + m_Width: 256 + m_Height: 256 + m_AntiAliasing: 1 + m_MipCount: -1 + m_DepthFormat: 0 + m_ColorFormat: 8 + m_MipMap: 0 + m_GenerateMips: 1 + m_SRGB: 0 + m_UseDynamicScale: 0 + m_BindMS: 0 + m_EnableCompatibleFormat: 1 + m_TextureSettings: + serializedVersion: 2 + m_FilterMode: 1 + m_Aniso: 0 + m_MipBias: 0 + m_WrapU: 1 + m_WrapV: 1 + m_WrapW: 1 + m_Dimension: 2 + m_VolumeDepth: 1 diff --git a/Runtime/Textures/Source.renderTexture.meta b/Runtime/Textures/Source.renderTexture.meta new file mode 100644 index 0000000..9a2c779 --- /dev/null +++ b/Runtime/Textures/Source.renderTexture.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1100058e32530e546a7ae167f97c11c5 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 8400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Textures/Target.renderTexture b/Runtime/Textures/Target.renderTexture new file mode 100644 index 0000000..ed4fb07 --- /dev/null +++ b/Runtime/Textures/Target.renderTexture @@ -0,0 +1,38 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!84 &8400000 +RenderTexture: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Target + m_ImageContentsHash: + serializedVersion: 2 + Hash: 00000000000000000000000000000000 + m_ForcedFallbackFormat: 4 + m_DownscaleFallback: 0 + m_IsAlphaChannelOptional: 0 + serializedVersion: 3 + m_Width: 256 + m_Height: 256 + m_AntiAliasing: 1 + m_MipCount: -1 + m_DepthFormat: 0 + m_ColorFormat: 8 + m_MipMap: 0 + m_GenerateMips: 1 + m_SRGB: 0 + m_UseDynamicScale: 0 + m_BindMS: 0 + m_EnableCompatibleFormat: 1 + m_TextureSettings: + serializedVersion: 2 + m_FilterMode: 1 + m_Aniso: 0 + m_MipBias: 0 + m_WrapU: 1 + m_WrapV: 1 + m_WrapW: 1 + m_Dimension: 2 + m_VolumeDepth: 1 diff --git a/Runtime/Textures/Target.renderTexture.meta b/Runtime/Textures/Target.renderTexture.meta new file mode 100644 index 0000000..bbd5ad2 --- /dev/null +++ b/Runtime/Textures/Target.renderTexture.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6dbf8770b857bc143a3ebf8ac17ff43a +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 8400000 + userData: + assetBundleName: + assetBundleVariant: