Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Image Effects

Discussion in 'Project Tiny' started by wxxhrt, Apr 11, 2020.

  1. wxxhrt

    wxxhrt

    Joined:
    Mar 18, 2014
    Posts:
    163
    Hi,

    Totally new to Project Tiny and DOTS but seems to be perfect for my current project. Just wanted to know if it's possible to apply Image Effect Shaders to everything on the screen- I'm wanting to use an Edge Detection Normals shader but have seen that PostProcessing isn't currently implemented in Project Tiny, I have a Legacy Image Effect that does Edge Detection, would this work if I converted it to DOTS?

    Thanks-

    Oh, here's the shader and script

    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3.  
    4. namespace UnityStandardAssets.ImageEffects
    5. {
    6.     [ExecuteInEditMode]
    7.     [RequireComponent (typeof (Camera))]
    8.     [AddComponentMenu ("Image Effects/Edge Detection/Edge Detection Color")]
    9.     public class EdgeDetectionColor : PostEffectsBase
    10.     {
    11.         public enum EdgeDetectMode
    12.         {
    13.             TriangleDepthNormals = 0,
    14.             RobertsCrossDepthNormals = 1,
    15. //            SobelDepth = 2,
    16. //            SobelDepthThin = 3,
    17. //            TriangleLuminance = 4,
    18.         }
    19.        
    20.        
    21.         public EdgeDetectMode mode = EdgeDetectMode.RobertsCrossDepthNormals;
    22.         public float sensitivityDepth = 1.0f;
    23.         public float sensitivityNormals = 1.0f;
    24.         public float lumThreshold = 0.2f;
    25.         public float edgeExp = 1.0f;
    26.         public float sampleDist = 1.0f;
    27.         public float edgesOnly = 0.0f;
    28.         public Color edgesOnlyBgColor = Color.black;
    29.         public Color edgesColor = Color.red;
    30.        
    31.         public Shader edgeDetectShader;
    32.         public Material edgeDetectMaterial = null;
    33.         private EdgeDetectMode oldMode = EdgeDetectMode.RobertsCrossDepthNormals;
    34.        
    35.         // Wills bit
    36.         public Color gradientTop = Color.white;
    37.         public Color gradientBot = Color.blue;
    38.         public float gradientHorizon = 1.0f;
    39.         public float screenHeight = 1920.0f;
    40.        
    41.         public override bool CheckResources ()
    42.         {
    43.             CheckSupport (true);
    44.            
    45.             edgeDetectMaterial = CheckShaderAndCreateMaterial (edgeDetectShader,edgeDetectMaterial);
    46.             if (mode != oldMode)
    47.                 SetCameraFlag ();
    48.            
    49.             oldMode = mode;
    50.            
    51.             if (!isSupported)
    52.                 ReportAutoDisable ();
    53.             return isSupported;
    54.         }
    55.        
    56.        
    57.         new void Start ()
    58.         {
    59.             oldMode    = mode;
    60.         }
    61.        
    62.         void SetCameraFlag ()
    63.         {
    64. //            if (mode == EdgeDetectMode.SobelDepth || mode == EdgeDetectMode.SobelDepthThin)
    65. //                GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth;
    66.             //else
    67.                 if (mode == EdgeDetectMode.TriangleDepthNormals || mode == EdgeDetectMode.RobertsCrossDepthNormals)
    68.                 GetComponent<Camera>().depthTextureMode |= DepthTextureMode.DepthNormals;
    69.         }
    70.        
    71.         void OnEnable ()
    72.         {
    73.             SetCameraFlag();
    74.         }
    75.        
    76.         [ImageEffectOpaque]
    77.         void OnRenderImage (RenderTexture source, RenderTexture destination)
    78.         {
    79.             if (CheckResources () == false)
    80.             {
    81.                 Graphics.Blit (source, destination);
    82.                 return;
    83.             }
    84.             if (edgeDetectMaterial == null)
    85.             {
    86.                 edgeDetectShader = Shader.Find("Hidden/EdgeDetectColors");
    87.                 edgeDetectMaterial = CheckShaderAndCreateMaterial(edgeDetectShader, edgeDetectMaterial);
    88.             }
    89.             Vector2 sensitivity = new Vector2 (sensitivityDepth, sensitivityNormals);
    90.             edgeDetectMaterial.SetVector ("_Sensitivity", new Vector4 (sensitivity.x, sensitivity.y, 1.0f, sensitivity.y));
    91.             edgeDetectMaterial.SetFloat ("_BgFade", edgesOnly);
    92.             edgeDetectMaterial.SetFloat ("_SampleDistance", sampleDist);
    93.             edgeDetectMaterial.SetVector ("_BgColor", edgesOnlyBgColor);
    94.             edgeDetectMaterial.SetFloat ("_Exponent", edgeExp);
    95.             edgeDetectMaterial.SetFloat ("_Threshold", lumThreshold);
    96.             edgeDetectMaterial.SetVector("_Color", edgesColor);
    97.  
    98.             edgeDetectMaterial.SetVector("_GradientTop", gradientTop);
    99.             edgeDetectMaterial.SetVector("_GradientBot", gradientBot);
    100.             edgeDetectMaterial.SetFloat ("_GradientHorizon", gradientHorizon);
    101.             edgeDetectMaterial.SetFloat ("_ScreenHeight", screenHeight);
    102.            
    103.             Graphics.Blit (source, destination, edgeDetectMaterial, (int) mode);
    104.         }
    105.     }
    106. }
    107.  
    Code (CSharp):
    1. // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
    2.  
    3.  
    4. Shader "Hidden/EdgeDetectColors" {
    5.     Properties {
    6.         _MainTex ("Base (RGB)", 2D) = "" {}
    7.         //_Color ("Color", color) = (1,1,1,1)
    8.     }
    9.  
    10.     CGINCLUDE
    11.    
    12.     #include "UnityCG.cginc"
    13.    
    14.     struct v2f {
    15.         //float4 pos : SV_POSITION;
    16.         float2 uv[5] : TEXCOORD0;
    17.         //float2 screenPos2 : TEXCOORD1;
    18.     };
    19.    
    20.     struct v2fd {
    21.         float4 pos : SV_POSITION;
    22.         float2 uv[2] : TEXCOORD0;
    23.     };
    24.  
    25.     sampler2D _MainTex;
    26.     uniform half4 _Color;
    27.     uniform float4 _MainTex_TexelSize;
    28.  
    29.     sampler2D _CameraDepthNormalsTexture;
    30.     sampler2D_float _CameraDepthTexture;
    31.  
    32.     uniform half4 _Sensitivity;
    33.     uniform half4 _BgColor;
    34.     uniform half _BgFade;
    35.     uniform half _SampleDistance;
    36.     uniform float _Exponent;
    37.  
    38.     uniform float _Threshold;
    39.  
    40.     uniform half4 _GradientTop;
    41.     uniform half4 _GradientBot;
    42.     uniform float _GradientHorizon;
    43.     uniform float _ScreenHeight;
    44.  
    45.     struct v2flum {
    46.         float4 pos : SV_POSITION;
    47.         float2 uv[3] : TEXCOORD0;
    48.     };
    49.  
    50.     v2flum vertLum (appdata_img v)
    51.     {
    52.         v2flum o;
    53.         o.pos = UnityObjectToClipPos (v.vertex);
    54.         float2 uv = MultiplyUV( UNITY_MATRIX_TEXTURE0, v.texcoord );
    55.         o.uv[0] = uv;
    56.         o.uv[1] = uv + float2(-_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance;
    57.         o.uv[2] = uv + float2(+_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance;
    58.         return o;
    59.     }
    60.  
    61.  
    62.     fixed4 fragLum (v2flum i) : SV_Target
    63.     {
    64.         fixed4 original = tex2D(_MainTex, i.uv[0]);
    65.  
    66.         // a very simple cross gradient filter
    67.  
    68.         half3 p1 = original.rgb;
    69.         half3 p2 = tex2D(_MainTex, i.uv[1]).rgb;
    70.         half3 p3 = tex2D(_MainTex, i.uv[2]).rgb;
    71.        
    72.         half3 diff = p1 * 2 - p2 - p3;
    73.         half len = dot(diff, diff);
    74.         len = step(len, _Threshold);
    75.         //if(len >= _Threshold)
    76.         //    original.rgb = 0;
    77.  
    78.         return len * lerp(original*2, _BgColor, _BgFade);          
    79.     }  
    80.    
    81.     inline half CheckSame (half2 centerNormal, float centerDepth, half4 theSample)
    82.     {
    83.         // difference in normals
    84.         // do not bother decoding normals - there's no need here
    85.         half2 diff = abs(centerNormal - theSample.xy) * _Sensitivity.y;
    86.         half isSameNormal = (diff.x + diff.y) * _Sensitivity.y < 0.1;
    87.         // difference in depth
    88.         float sampleDepth = DecodeFloatRG (theSample.zw);
    89.         float zdiff = abs(centerDepth-sampleDepth);
    90.         // scale the required threshold by the distance
    91.         half isSameDepth = zdiff * _Sensitivity.x < 0.09 * centerDepth;
    92.    
    93.         // return:
    94.         // 1 - if normals and depth are similar enough
    95.         // 0 - otherwise
    96.        
    97.         return isSameNormal * isSameDepth;
    98.     }  
    99.     /////// HEREHERE
    100.     v2f vertRobert( appdata_img v, out float4 outpos : SV_POSITION )
    101.     {
    102.         v2f o;
    103.         outpos = UnityObjectToClipPos(v.vertex);
    104.  
    105.         //o.vertex = mult(UNITY_MATRIX_MVP, v.vertex);
    106.         //o.screenPos2 = ComputeScreenPos(o.vertex);
    107.        
    108.        
    109.         float2 uv = v.texcoord.xy;
    110.         o.uv[0] = uv;
    111.         #if UNITY_UV_STARTS_AT_TOP
    112.         if (_MainTex_TexelSize.y < 0)
    113.             uv.y = 1-uv.y; //colour not here.. but this S***s things kind of..
    114.         #endif
    115.                
    116.         // calc coord for the X pattern
    117.         // maybe nicer TODO for the future: 'rotated triangles'
    118.        
    119.         //colours not in here?
    120.         o.uv[1] = uv + _MainTex_TexelSize.xy * half2(1,1) * _SampleDistance;
    121.         o.uv[2] = uv + _MainTex_TexelSize.xy * half2(-1,-1) * _SampleDistance;
    122.         o.uv[3] = uv + _MainTex_TexelSize.xy * half2(-1,1) * _SampleDistance;
    123.         o.uv[4] = uv + _MainTex_TexelSize.xy * half2(1,-1) * _SampleDistance;
    124.         return o;
    125.     }
    126.    
    127.     v2f vertThin( appdata_img v, out float4 outpos : SV_POSITION )
    128.     {
    129.         v2f o;
    130.         outpos = UnityObjectToClipPos (v.vertex);
    131.        
    132.         float2 uv = v.texcoord.xy;
    133.         o.uv[0] = uv;
    134.        
    135.         #if UNITY_UV_STARTS_AT_TOP
    136.         if (_MainTex_TexelSize.y < 0)
    137.             uv.y = 1-uv.y;
    138.         #endif
    139.        
    140.         o.uv[1] = uv;
    141.         o.uv[4] = uv;
    142.                
    143.         // offsets for two additional samples
    144.         o.uv[2] = uv + float2(-_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance;
    145.         o.uv[3] = uv + float2(+_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance;
    146.        
    147.         return o;
    148.     }    
    149.    
    150.     v2fd vertD( appdata_img v )
    151.     {
    152.         v2fd o;
    153.         o.pos = UnityObjectToClipPos (v.vertex);
    154.        
    155.         float2 uv = v.texcoord.xy;
    156.         o.uv[0] = uv;
    157.        
    158.         #if UNITY_UV_STARTS_AT_TOP
    159.         if (_MainTex_TexelSize.y < 0)
    160.             uv.y = 1-uv.y;
    161.         #endif
    162.        
    163.         o.uv[1] = uv;
    164.        
    165.         return o;
    166.     }
    167.  
    168.     float4 fragDCheap(v2fd i) : SV_Target
    169.     {  
    170.         // inspired by borderlands implementation of popular "sobel filter"
    171.  
    172.         float centerDepth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv[1]));
    173.         float4 depthsDiag;
    174.         float4 depthsAxis;
    175.  
    176.         float2 uvDist = _SampleDistance * _MainTex_TexelSize.xy;
    177.  
    178.         depthsDiag.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist)); // TR
    179.         depthsDiag.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(-1,1))); // TL
    180.         depthsDiag.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(-1,1))); // BR
    181.         depthsDiag.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist)); // BL
    182.  
    183.         depthsAxis.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(0,1))); // T
    184.         depthsAxis.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(1,0))); // L
    185.         depthsAxis.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(1,0))); // R
    186.         depthsAxis.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(0,1))); // B
    187.  
    188.         depthsDiag -= centerDepth;
    189.         depthsAxis /= centerDepth;
    190.  
    191.         const float4 HorizDiagCoeff = float4(1,1,-1,-1);
    192.         const float4 VertDiagCoeff = float4(-1,1,-1,1);
    193.         const float4 HorizAxisCoeff = float4(1,0,0,-1);
    194.         const float4 VertAxisCoeff = float4(0,1,-1,0);
    195.  
    196.         float4 SobelH = depthsDiag * HorizDiagCoeff + depthsAxis * HorizAxisCoeff;
    197.         float4 SobelV = depthsDiag * VertDiagCoeff + depthsAxis * VertAxisCoeff;
    198.  
    199.         float SobelX = dot(SobelH, float4(1,1,1,1));
    200.         float SobelY = dot(SobelV, float4(1,1,1,1));
    201.         float Sobel = sqrt(SobelX * SobelX + SobelY * SobelY);
    202.  
    203.         Sobel = 1.0-pow(saturate(Sobel), _Exponent);
    204.         return Sobel * lerp(tex2D(_MainTex, i.uv[0].xy), _BgColor, _BgFade);
    205.     }
    206.  
    207.     // pretty much also just a sobel filter, except for that edges "outside" the silhouette get discarded
    208.     //  which makes it compatible with other depth based post fx
    209.  
    210.     float4 fragD(v2fd i) : SV_Target
    211.     {  
    212.         // inspired by borderlands implementation of popular "sobel filter"
    213.  
    214.         float centerDepth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv[1]));
    215.         float4 depthsDiag;
    216.         float4 depthsAxis;
    217.  
    218.         float2 uvDist = _SampleDistance * _MainTex_TexelSize.xy;
    219.  
    220.         depthsDiag.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist)); // TR
    221.         depthsDiag.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(-1,1))); // TL
    222.         depthsDiag.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(-1,1))); // BR
    223.         depthsDiag.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist)); // BL
    224.  
    225.         depthsAxis.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(0,1))); // T
    226.         depthsAxis.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(1,0))); // L
    227.         depthsAxis.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(1,0))); // R
    228.         depthsAxis.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(0,1))); // B
    229.  
    230.         // make it work nicely with depth based image effects such as depth of field:
    231.         depthsDiag = (depthsDiag > centerDepth.xxxx) ? depthsDiag : centerDepth.xxxx;
    232.         depthsAxis = (depthsAxis > centerDepth.xxxx) ? depthsAxis : centerDepth.xxxx;
    233.  
    234.         depthsDiag -= centerDepth;
    235.         depthsAxis /= centerDepth;
    236.  
    237.         const float4 HorizDiagCoeff = float4(1,1,-1,-1);
    238.         const float4 VertDiagCoeff = float4(-1,1,-1,1);
    239.         const float4 HorizAxisCoeff = float4(1,0,0,-1);
    240.         const float4 VertAxisCoeff = float4(0,1,-1,0);
    241.  
    242.         float4 SobelH = depthsDiag * HorizDiagCoeff + depthsAxis * HorizAxisCoeff;
    243.         float4 SobelV = depthsDiag * VertDiagCoeff + depthsAxis * VertAxisCoeff;
    244.  
    245.         float SobelX = dot(SobelH, float4(1,1,1,1));
    246.         float SobelY = dot(SobelV, float4(1,1,1,1));
    247.         float Sobel = sqrt(SobelX * SobelX + SobelY * SobelY);
    248.  
    249.         Sobel = 1.0-pow(saturate(Sobel), _Exponent);
    250.         return Sobel * lerp(tex2D(_MainTex, i.uv[0].xy), _BgColor, _BgFade);
    251.     }
    252.  
    253.     half4 fragRobert(v2f i, UNITY_VPOS_TYPE screenPos : VPOS) : SV_Target {              
    254.         half4 sample1 = tex2D(_CameraDepthNormalsTexture, i.uv[1].xy);
    255.         half4 sample2 = tex2D(_CameraDepthNormalsTexture, i.uv[2].xy);
    256.         half4 sample3 = tex2D(_CameraDepthNormalsTexture, i.uv[3].xy);
    257.         half4 sample4 = tex2D(_CameraDepthNormalsTexture, i.uv[4].xy);
    258.  
    259.         half edge = 1.0;
    260.        
    261.         edge *= CheckSame(sample1.xy, DecodeFloatRG(sample1.zw), sample2);
    262.         edge *= CheckSame(sample3.xy, DecodeFloatRG(sample3.zw), sample4);
    263.        
    264.         //return edge * lerp(tex2D(_MainTex, i.uv[0]), _BgColor, _BgFade);
    265.        
    266.         //half d = dot (normalize (i.texcoord), float4(0, 1, 0, 0)) * 0.5f + 0.5f;
    267.         half4 finalColor = lerp(_GradientBot, _GradientTop,  screenPos.x / _GradientHorizon );
    268.         //+ _ScreenHeight / _GradientHorizon
    269.         //half4 finalColor = lerp(_GradientTop, _GradientBot, i.screenPos2.y);
    270.  
    271.          if(edge > 0)
    272.              return lerp(tex2D(_MainTex, i.uv[0].xy), _BgColor, _BgFade);
    273.              //return finalColor;
    274.          else
    275.              //return _BgColor;
    276.              return finalColor;
    277.     }
    278.    
    279.     half4 fragThin (v2f i) : SV_Target
    280.     {
    281.         half4 original = tex2D(_MainTex, i.uv[0]);
    282.        
    283.         half4 center = tex2D (_CameraDepthNormalsTexture, i.uv[1]);
    284.         half4 sample1 = tex2D (_CameraDepthNormalsTexture, i.uv[2]);
    285.         half4 sample2 = tex2D (_CameraDepthNormalsTexture, i.uv[3]);
    286.        
    287.         // encoded normal
    288.         half2 centerNormal = center.xy;
    289.         // decoded depth
    290.         float centerDepth = DecodeFloatRG (center.zw);
    291.        
    292.         half edge = 1.0;
    293.        
    294.         edge *= CheckSame(centerNormal, centerDepth, sample1);
    295.         edge *= CheckSame(centerNormal, centerDepth, sample2);
    296.            
    297.  
    298.          //return edge * lerp(original, _BgColor, _BgFade);
    299.          if(edge > 0)
    300.              return lerp(original, _BgColor, _BgFade);
    301.          else
    302.              return _Color;
    303.     }
    304.    
    305.     ENDCG
    306.    
    307. Subshader {
    308. Pass {
    309.       ZTest Always Cull Off ZWrite Off
    310.  
    311.       CGPROGRAM
    312.       #pragma vertex vertThin
    313.       #pragma fragment fragThin
    314.       ENDCG
    315.   }
    316. Pass {
    317.       ZTest Always Cull Off ZWrite Off
    318.  
    319.       CGPROGRAM
    320.       #pragma target 3.0
    321.       #pragma vertex vertRobert
    322.       #pragma fragment fragRobert
    323.       ENDCG
    324.   }
    325. Pass {
    326.       ZTest Always Cull Off ZWrite Off
    327.  
    328.       CGPROGRAM
    329.       #pragma target 3.0  
    330.       #pragma vertex vertD
    331.       #pragma fragment fragDCheap
    332.       ENDCG
    333.   }
    334. Pass {
    335.       ZTest Always Cull Off ZWrite Off
    336.  
    337.       CGPROGRAM
    338.       #pragma target 3.0  
    339.       #pragma vertex vertD
    340.       #pragma fragment fragD
    341.       ENDCG
    342.   }
    343. Pass {
    344.       ZTest Always Cull Off ZWrite Off
    345.  
    346.       CGPROGRAM
    347.       #pragma target 3.0  
    348.       #pragma vertex vertLum
    349.       #pragma fragment fragLum
    350.       ENDCG
    351.   }
    352. }
    353.  
    354. Fallback off
    355.    
    356. } // shader
     
  2. AbdulAlgharbi

    AbdulAlgharbi

    Unity Technologies

    Joined:
    Jul 27, 2018
    Posts:
    319
    Hi,
    No, unfortunately, you can't do custom shaders or post-processing with the current version of Tiny
    We only support URP Lit and Unlit shaders
    post-processing and custom shader support are on our roadmap so stay tuned for future releases.
     
    wxxhrt likes this.
  3. charlescex

    charlescex

    Joined:
    Feb 24, 2020
    Posts:
    6
    • Will Tiny support custom shader or custom urp shader.
     
  4. JoNax97

    JoNax97

    Joined:
    Feb 4, 2016
    Posts:
    611
    Read the message above.
     
    MelvMay likes this.
  5. charlescex

    charlescex

    Joined:
    Feb 24, 2020
    Posts:
    6
    Thank you, I ignored the reply content