Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Shader job quality on Mobile (2D effects)

Discussion in 'Shaders' started by Glukozavr, Oct 24, 2017.

  1. Glukozavr

    Glukozavr

    Joined:
    Jan 3, 2016
    Posts:
    1
    Hello everyone. I can't get it right and need your help.

    So, the input data.
    I have a drawing\coloring application, so I use Canvas and Raw Textures to display images to color.
    To improve coloring speed I decided to try shaders and it did helped, though it`s great on PC it's horrible on mobile.

    This is on the PC
    Screenshot_PC.png
    And this is on Mobile (Android 6.0.1 Samsung Note 4)
    Screenshot_MOBILE.png

    This is the code, where texture is main image Texture and mapTexture is Texture of the same size that maps image zones.

    Code (csharp):
    1.  
    2. rt = new RenderTexture(mapBuilder.map.width, mapBuilder.map.height, 16);
    3. rt.Create();
    4.  
    5. colMat = new Material(Shader.Find("Coloring/ColorReplace"));
    6. colMat.SetTexture("_Ref", mapTexture);
    7.  
    8. colMat.SetTexture("_MainTex", texture);
    9. colMat.SetColor("_Color", fillType.Evaluate());
    10.  
    11. colMat.SetFloat("_ZoneX", hit.x / (float)texture.width);
    12. colMat.SetFloat("_ZoneY", hit.y / (float)texture.height);
    13.  
    14. RenderTexture.active = rt;
    15.  
    16. Graphics.Blit(texture, rt, colMat);
    17.  
    18. texture.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
    19.  
    20.  
    It seems like aproximation used where I don't want it, and I am sure I can fix this but I just can't get it how.

    Shader
    Code (csharp):
    1.  
    2. Shader "Coloring/ColorReplace"
    3. {
    4.     Properties
    5.     {
    6.         _MainTex("Texture", 2D) = "white" {}
    7.     _Ref("Referece Texture", 2d) = "white" {}
    8.     _Color("Replace Color", Color) = (1,1,1,1)
    9.         _ZoneX("ZoneX", Float) = 0
    10.         _ZoneY("ZoneY", Float) = 0
    11.     }
    12.         SubShader
    13.     {
    14.         // No culling or depth
    15.         Cull Off ZWrite Off ZTest Always
    16.  
    17.         Pass
    18.     {
    19.         CGPROGRAM
    20. #pragma vertex vert
    21. #pragma fragment frag
    22.  
    23. #include "UnityCG.cginc"
    24.  
    25.         struct appdata
    26.     {
    27.         float4 vertex : POSITION;
    28.         float2 uv : TEXCOORD0;
    29.     };
    30.  
    31.     struct v2f
    32.     {
    33.         float2 uv : TEXCOORD0;
    34.         float4 vertex : SV_POSITION;
    35.     };
    36.  
    37.     v2f vert(appdata v)
    38.     {
    39.         v2f o;
    40.         o.vertex = UnityObjectToClipPos(v.vertex);
    41.         o.uv = v.uv;
    42.         return o;
    43.     }
    44.  
    45.     sampler2D _MainTex;
    46.     sampler2D _Ref;
    47.     fixed4 _Color;
    48.     float _ZoneX;
    49.     float _ZoneY;
    50.  
    51.     fixed4 frag(v2f i) : SV_Target
    52.     {
    53.         fixed4 zone = tex2D(_Ref, float2(_ZoneX, _ZoneY));
    54.  
    55.         fixed4 result;
    56.         fixed4 refValue = tex2D(_Ref, i.uv);
    57.         if (refValue.r == zone.r && refValue.g == zone.g && refValue.b == zone.b) {
    58.             result = _Color;
    59.         }
    60.         else {
    61.             result = tex2D(_MainTex, i.uv);
    62.         }
    63.         return result;
    64.     }
    65.         ENDCG
    66.     }
    67.     }
    68. }
    69.  
     

    Attached Files:

  2. nat42

    nat42

    Joined:
    Jun 10, 2017
    Posts:
    353
    Texture compression?

    "if (refValue.r == zone.r && refValue.g == zone.g && refValue.b == zone.b)" is not going to be tolerant of texture compression using a colour that looks similar but is a slightly different value.

    Maybe if you can keep to 256 colours use 1 channel uncompressed?

    EDIT: also quite new to Unity myself, but ReadPixels might be something to always try to avoid, at least on "textures" or what Unity thinks should be data to store in GPU memory. Have you looked to see if there is there some way to do do your colour lookup on data that's not set as something to be used for rendering?