Search Unity

Applying Material to UI.Image Causes Drawing Outside Viewport

Discussion in 'Shaders' started by Corpse0327, Sep 8, 2017.

  1. Corpse0327

    Corpse0327

    Joined:
    Oct 4, 2014
    Posts:
    26
    Hello everyone

    I would like to start by saying i am new to shaders. Anyways, i have written some simple outline shader for UI.Image component to use. It simply makes the original image disappear and draws an outline around it.

    However, when i apply it to an image, it gets drawn even outside of its viewport parent, which is a big issue. I tried standard unity shaders and same thing happens. I guess it is an issue with shaders? How can i make it so that it doesnt get drawn outside of its viewport.

    a.jpg


    Here is the code for shader:

    Code (CSharp):
    1. Shader "Unlit/Outline"
    2. {
    3.     Properties
    4.     {
    5.         [PerRendererData] _MainTex ("Texture", 2D) = "white" {}
    6.         _Thickness ("Thickness", Range(0.0, 0.15)) = 0.05
    7.         _Color ("Color", Color) = (1, 1, 1, 1)
    8.     }
    9.     SubShader
    10.     {
    11.         Tags
    12.         {
    13.             "Queue"="Transparent"
    14.             "IgnoreProjector"="True"
    15.             "RenderType"="Transparent"
    16.             "PreviewType"="Plane"
    17.             "CanUseSpriteAtlas"="True"
    18.         }
    19.  
    20.         Cull Off
    21.         Lighting Off
    22.         ZWrite Off
    23.         ZTest [unity_GUIZTestMode]
    24.         Blend SrcAlpha OneMinusSrcAlpha
    25.  
    26.         Pass
    27.         {
    28.             CGPROGRAM
    29.             #pragma vertex vert
    30.             #pragma fragment frag
    31.          
    32.             #include "UnityCG.cginc"
    33.  
    34.             struct appdata
    35.             {
    36.                 float4 vertex : POSITION;
    37.                 float2 uv : TEXCOORD0;
    38.             };
    39.  
    40.             struct v2f
    41.             {
    42.                 float2 uv : TEXCOORD0;
    43.                 float4 vertex : SV_POSITION;
    44.             };
    45.  
    46.             sampler2D _MainTex;
    47.             float4 _MainTex_ST;
    48.             float _Thickness;
    49.             float4 _Color;
    50.  
    51.             v2f vert (appdata v)
    52.             {
    53.                 v2f o;
    54.                 o.vertex = UnityObjectToClipPos(v.vertex);
    55.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    56.                 return o;
    57.             }
    58.          
    59.             fixed4 frag (v2f i) : SV_Target
    60.             {
    61.                 float minAlpha = 0.85;
    62.                 // sample the texture
    63.                 if (tex2D(_MainTex, i.uv).a > minAlpha)
    64.                     return fixed4(0, 0, 0, 0);
    65.  
    66.                 float2 myOffSet = float2(_Thickness * 0.7071, _Thickness * 0.7071);
    67.                 float2 myOffSetV = float2(0, _Thickness);
    68.                 float2 myOffSetH = float2(_Thickness, 0);
    69.  
    70.                 float alphaStrength = 0;
    71.  
    72.                 alphaStrength = tex2D(_MainTex, i.uv + (myOffSetV * 1)).a
    73.                 + tex2D(_MainTex, i.uv + (myOffSetV * -1)).a
    74.                 + tex2D(_MainTex, i.uv + (myOffSetH * 1)).a
    75.                 + tex2D(_MainTex, i.uv + (myOffSetH * -1)).a
    76.                 + tex2D(_MainTex, i.uv + (myOffSet * (1, 1))).a
    77.                 + tex2D(_MainTex, i.uv + (myOffSet * (-1, 1))).a
    78.                 + tex2D(_MainTex, i.uv + (myOffSet * (1, -1))).a
    79.                 + tex2D(_MainTex, i.uv + (myOffSet * (-1, -1))).a;
    80.  
    81.                 if (alphaStrength > 1.0)
    82.                     alphaStrength = 1.0;
    83.  
    84.                 return fixed4(_Color.r, _Color.g, _Color.b, _Color.a * alphaStrength - tex2D(_MainTex, i.uv).a);
    85.             }
    86.             ENDCG
    87.         }
    88.     }
    89. }
    90.  
     
  2. Corpse0327

    Corpse0327

    Joined:
    Oct 4, 2014
    Posts:
    26
    Alright

    I made some development.

    I used this code. Now, it creates a sprite and changes image.sprite to it. Here is the code:

    Code (CSharp):
    1.                         renderTexture = new RenderTexture (image.sprite.texture.width, image.sprite.texture.height, 24);
    2.             Graphics.Blit (image.sprite.texture, renderTexture, material);
    3.  
    4.             RenderTexture.active = renderTexture;
    5.             texture = new Texture2D (renderTexture.width, renderTexture.height);
    6.             texture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
    7.             texture.Apply();
    8.  
    9.             image.sprite = Sprite.Create(texture, new Rect(0.0f, 0.0f, texture.width, texture.height), new Vector2(0.5f, 0.5f), 100.0f);
    Which is quite cool and solves my problem with viewport. However, now another problem happens! The color is somehow blackened or how do i say it, it is a bit darker than what value i give? Why is this happening and how can i solve it? Here is a pic

    Left: material applied to image, middle and right: material used with Graphics.Blit and RenderTexture
    s.png
     
  3. Corpse0327

    Corpse0327

    Joined:
    Oct 4, 2014
    Posts:
    26
    Alright

    Solution is... not found one. However i kinda found the problem. I guess blit isn't too good with transparent pixels? Anyways, i solved it by changing the colors alpha to 255 from 196 and... thats it. It is way more visible now.

    I guess it will do for now.