Author Topic: Custom shaders clipping UITexture  (Read 7802 times)

Avatarchik

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
Custom shaders clipping UITexture
« on: October 04, 2013, 03:31:19 AM »
Hi! Here is my shader:

  1. Shader "Unlit/Logo (SoftClip)"
  2. {
  3.     Properties
  4.     {
  5.         _Color1 ("Color 1", Color) = (1,1,1,255)
  6.         _Color2 ("Color 2", Color) = (0,0,0,255)
  7.         _MainTex ("Base (RGB), Alpha (A)", 2D) = "white" {}
  8.         _PatternTex ("Pattern (RGB)", 2D) = "black" {}
  9.         _FrameTex ("Frame (RGB)", 2D) = "black" {}
  10.         _Logo ("Logo (RGB)", 2D) = "black" {}
  11.         _ColorLogo ("Logo Color", Color) = (1,1,1,255)
  12.     }
  13.  
  14.     SubShader
  15.     {
  16.  
  17.  
  18.         Tags
  19.         {
  20.             "Queue" = "Transparent"
  21.             "IgnoreProjector" = "True"
  22.             "RenderType" = "Transparent"
  23.         }
  24.        
  25.         Pass
  26.         {
  27.                 LOD 200
  28.             Cull Off
  29.             Lighting Off
  30.             ZWrite Off
  31.             Offset -1, -1
  32.             Fog { Mode Off }
  33.             ColorMask RGB
  34.             AlphaTest Greater .01
  35.             Blend SrcAlpha OneMinusSrcAlpha
  36.  
  37.             CGPROGRAM
  38.             #pragma vertex vert
  39.             #pragma fragment frag
  40.  
  41.             #include "UnityCG.cginc"
  42.  
  43.             sampler2D _MainTex;
  44.             sampler2D _PatternTex;
  45.             sampler2D _FrameTex;
  46.             float4 _MainTex_ST;
  47.             float4 _PatternTex_ST;
  48.             float4 _FrameTex_ST;
  49.                 float2 _ClipSharpness = float2(20.0, 20.0);
  50.             fixed4 _Color1;
  51.             fixed4 _Color2;
  52.            
  53.             struct appdata_t
  54.             {
  55.                 float4 vertex : POSITION;
  56.                 half4 color : COLOR;
  57.                 float2 texcoord : TEXCOORD0;
  58.             };
  59.  
  60.             struct v2f
  61.             {
  62.                 float4 vertex : POSITION;
  63.                 half4 color : COLOR;
  64.                 float2 texcoord : TEXCOORD0;
  65.                 float2 worldPos : TEXCOORD1;
  66.             };
  67.  
  68.             v2f vert (appdata_t v)
  69.             {
  70.                 v2f o;
  71.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
  72.                 o.color = v.color;
  73.                 o.texcoord = v.texcoord;
  74.                 o.worldPos = TRANSFORM_TEX(v.vertex.xy, _MainTex);
  75.                 return o;
  76.             }
  77.  
  78.             half4 frag (v2f IN) : COLOR
  79.             {
  80.                 float2 factor = (float2(1.0, 1.0) - abs(IN.worldPos)) * _ClipSharpness;
  81.                 half4 col = tex2D(_MainTex, IN.texcoord) * IN.color;
  82.                 half4 col2 = tex2D(_PatternTex, IN.texcoord) * IN.color;
  83.                 fixed4 mix = lerp(_Color1, _Color2, col2.a);
  84.                 col.a *= clamp( min(factor.x, factor.y), 0.0, 1.0);
  85.                 return col * mix;
  86.             }
  87.             ENDCG
  88.         }
  89.        
  90.         Pass
  91.         {
  92.                 LOD 200
  93.             Cull Off
  94.             Lighting Off
  95.             ZWrite Off
  96.             Offset -1, -1
  97.             Fog { Mode Off }
  98.             ColorMask RGB
  99.             AlphaTest Greater .01
  100.             Blend SrcAlpha OneMinusSrcAlpha
  101.  
  102.             CGPROGRAM
  103.             #pragma vertex vert
  104.             #pragma fragment frag
  105.  
  106.             #include "UnityCG.cginc"
  107.            
  108.             sampler2D _MainTex;
  109.             float4 _MainTex_ST;
  110.             sampler2D _Logo;
  111.             float4 _FrameLogo_ST;
  112.             float2 _ClipSharpness = float2(20.0, 20.0);
  113.             fixed4 _ColorLogo;
  114.            
  115.             struct appdata_t
  116.             {
  117.                 float4 vertex : POSITION;
  118.                 half4 color : COLOR;
  119.                 float2 texcoord : TEXCOORD0;
  120.             };
  121.  
  122.             struct v2f
  123.             {
  124.                 float4 vertex : POSITION;
  125.                 half4 color : COLOR;
  126.                 float2 texcoord : TEXCOORD0;
  127.                 float2 worldPos : TEXCOORD1;
  128.             };
  129.  
  130.             v2f vert (appdata_t v)
  131.             {
  132.                 v2f o;
  133.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
  134.                 o.color = v.color;
  135.                 o.texcoord = v.texcoord;
  136.                 o.worldPos = TRANSFORM_TEX(v.vertex.xy, _MainTex);
  137.                 return o;
  138.             }
  139.  
  140.             half4 frag (v2f IN) : COLOR
  141.             {
  142.                 float2 factor = (float2(1.0, 1.0) - abs(IN.worldPos)) * _ClipSharpness;
  143.                 half4 col = _ColorLogo * tex2D(_Logo, IN.texcoord) * IN.color;
  144.                 col.a *= clamp( min(factor.x, factor.y), 0.0, 1.0);
  145.                 return col;
  146.             }
  147.             ENDCG
  148.         }
  149.        
  150.         Pass
  151.         {
  152.                 LOD 200
  153.             Cull Off
  154.             Lighting Off
  155.             ZWrite Off
  156.             Offset -1, -1
  157.             Fog { Mode Off }
  158.             ColorMask RGB
  159.             AlphaTest Greater .01
  160.             Blend SrcAlpha OneMinusSrcAlpha
  161.  
  162.             CGPROGRAM
  163.             #pragma vertex vert
  164.             #pragma fragment frag
  165.  
  166.             #include "UnityCG.cginc"
  167.            
  168.             sampler2D _MainTex;
  169.             sampler2D _PatternTex;
  170.             sampler2D _FrameTex;
  171.             float4 _MainTex_ST;
  172.             float4 _PatternTex_ST;
  173.             float4 _FrameTex_ST;
  174.             float2 _ClipSharpness = float2(20.0, 20.0);
  175.            
  176.             struct appdata_t
  177.             {
  178.                 float4 vertex : POSITION;
  179.                 half4 color : COLOR;
  180.                 float2 texcoord : TEXCOORD0;
  181.             };
  182.  
  183.             struct v2f
  184.             {
  185.                 float4 vertex : POSITION;
  186.                 half4 color : COLOR;
  187.                 float2 texcoord : TEXCOORD0;
  188.                 float2 worldPos : TEXCOORD1;
  189.             };
  190.  
  191.             v2f vert (appdata_t v)
  192.             {
  193.                 v2f o;
  194.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
  195.                 o.color = v.color;
  196.                 o.texcoord = v.texcoord;
  197.                 o.worldPos = TRANSFORM_TEX(v.vertex.xy, _MainTex);
  198.                 return o;
  199.             }
  200.            
  201.      
  202.             half4 frag (v2f IN) : COLOR
  203.             {
  204.                 float2 factor = (float2(1.0, 1.0) - abs(IN.worldPos)) * _ClipSharpness;
  205.                 half4 col =  tex2D(_FrameTex, IN.texcoord) * IN.color;
  206.                 col.a *= clamp( min(factor.x, factor.y), 0.0, 1.0);
  207.                 return col;
  208.             }
  209.             ENDCG
  210.       }
  211.     }
  212.    
  213.     SubShader
  214.         {
  215.                 LOD 100
  216.  
  217.                 Tags
  218.                 {
  219.                         "Queue" = "Transparent"
  220.                         "IgnoreProjector" = "True"
  221.                         "RenderType" = "Transparent"
  222.                 }
  223.                
  224.                 Pass
  225.                 {
  226.                         Cull Off
  227.                         Lighting Off
  228.                         ZWrite Off
  229.                         Fog { Mode Off }
  230.                         ColorMask RGB
  231.                         AlphaTest Greater .01
  232.                         Blend SrcAlpha OneMinusSrcAlpha
  233.                         ColorMaterial AmbientAndDiffuse
  234.                        
  235.                         SetTexture [_MainTex]
  236.                         {
  237.                                 Combine Texture * Primary
  238.                         }
  239.                 }
  240.         }
  241. }
When the fields _Color1,_Color2,_PatternTex ...
uiTexture.material.SetTexture("_PatternTex",patternTex);
uiTexture.material.SetColor("_Color1", colorOne);
uiTexture.MarkAsChanged();
Changes for some reason, do not take effect...
Enter into force after the play button is off...

keysosaurus

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 13
    • View Profile
Re: Custom shaders clipping UITexture
« Reply #1 on: October 04, 2013, 05:13:53 AM »
Think you may be having the same problem as I am, materials don't update at runtime.

http://www.tasharen.com/forum/index.php?topic=6002.0

http://www.tasharen.com/forum/index.php?topic=4135.0

Seems to work fine in older versions of NGUI, just not 3.0  :(

Avatarchik

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
Re: Custom shaders clipping UITexture
« Reply #2 on: October 04, 2013, 06:00:51 AM »
I have version 2.7 and 2.6.4 (
« Last Edit: October 04, 2013, 06:14:48 AM by Avatarchik »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Custom shaders clipping UITexture
« Reply #3 on: October 04, 2013, 09:25:09 PM »
NGUI creates copies of materials in order to make things draw in a proper order. You can no longer modify material properties like that.

You can do what you're trying to do by using global shader variables instead of per-material ones. Have a look at Unity's documentation for functions like Shader.SetGlobalFloat.

nwsx

  • Guest
Re: Custom shaders clipping UITexture
« Reply #4 on: October 06, 2013, 05:08:59 AM »
UISprite class should have a link to material instance.
just like unity meshes, they have "sharedMaterial" and "material"(instance)

nwsx

  • Guest
Re: Custom shaders clipping UITexture
« Reply #5 on: October 06, 2013, 07:57:00 AM »
i found a way to refresh sprite material. iam calling UIPanel.Refresh() in UIPanel that contains animated sprite every frame :D
i bet its clonning shitload of material instances. we need better solution (reference to material instances in UISprite class) :o

nwsx

  • Guest
Re: Custom shaders clipping UITexture
« Reply #6 on: October 06, 2013, 08:46:12 AM »
i found a better way to do that  ;D
i had to make mMat public (in UIDrawCall class)

then just sprite.drawCall.mMat.SetWhateverYouWant();

enjoy my solution  8)

----------------------------
also you should do setting of material/shader properties in LateUpdate instead of Update
and put your script in ProjectSettings/ExecutionOrder after UIPanel
otherwise you will get strange flickering.
« Last Edit: October 06, 2013, 09:24:24 AM by nwsx »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Custom shaders clipping UITexture
« Reply #7 on: October 06, 2013, 10:13:42 PM »
I've added a "dynamicMaterial" property to the draw call class that you will be able to use in the next version onwards so you won't have to make "mMat" public.

Avatarchik

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
Re: Custom shaders clipping UITexture
« Reply #8 on: October 07, 2013, 08:14:04 AM »
I UITexture with these methods do not work,
I have a bunch of T-shirts with this shader, and I need to ask each T-shirt color and texture

keysosaurus

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 13
    • View Profile
Re: Custom shaders clipping UITexture
« Reply #9 on: October 07, 2013, 12:15:24 PM »
@nwsx Thanks a million, works like a charm!  :)

@ArenMook Cheers, I'll change over to the new "dynamicMaterial" when its working, but for now I'm delighted and relieved!  ;)

@Avatarchik Sounds like we are doing something similar, but we split our t-shirt assets into layers and use UISprite.color to tint each layer individually.
It's only one draw call for each atlas (thanks again ArenMook!)

Avatarchik

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
Re: Custom shaders clipping UITexture
« Reply #10 on: October 08, 2013, 10:39:43 AM »
Is there a way to update a specific UITexture? :)
Option with UISprite not suitable...

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Custom shaders clipping UITexture
« Reply #11 on: October 09, 2013, 08:59:43 AM »
Same as any other widget -- UIWidget.drawCall.dynamicMaterial property is accessible from the UITexture as well, but if you don't have the latest Pro version you will need to add an accessor for it in UIDrawCall.
  1. /// <summary>
  2. /// Dynamically created material used by the draw call to actually draw the geometry.
  3. /// </summary>
  4.  
  5. public Material dynamicMaterial { get { return mMat; } }

Ferazel

  • Full Member
  • ***
  • Thank You
  • -Given: 1
  • -Receive: 2
  • Posts: 150
    • View Profile
Re: Custom shaders clipping UITexture
« Reply #12 on: October 09, 2013, 10:15:28 AM »
This might be a different question, but is there a way to have a UITexture use a custom mesh (instead of a square)? This would allow you to decrease the fill rate if a lot of the texture is invisible? If so, what recommendations would you have to do that?

I'm trying to do something similar. Mainly so that I can have a RenderTexture mapped to a UITexture and it would respect the UI depth space so I could place elements behind and in front of this texture. However, I need to have this render texture not be a square, but rather a custom shape like a circle or a hexagon.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Custom shaders clipping UITexture
« Reply #13 on: October 09, 2013, 01:44:13 PM »
UITexture? nope. But you can always derive from the UITexture script and overwrite the OnFill method. Inside you can set up your own vertices -- a circle, for example, if you are so inclined.

Ferazel

  • Full Member
  • ***
  • Thank You
  • -Given: 1
  • -Receive: 2
  • Posts: 150
    • View Profile
Re: Custom shaders clipping UITexture
« Reply #14 on: October 10, 2013, 08:07:22 AM »
Hi ArenMook,

Thanks for the reply. I looked into the process that you described and came up with the following code:

  1. public MeshFilter MeshData;
  2.         public override void OnFill (BetterList<Vector3> verts, BetterList<Vector2> uvs, BetterList<Color32> cols) {
  3.                 Color colF = color;
  4.                 colF.a *= mPanel.alpha;
  5.                 Color32 col = premultipliedAlpha ? NGUITools.ApplyPMA(colF) : colF;
  6.  
  7.                 MeshData.sharedMesh.GetIndices(0);
  8.  
  9.                 Vector3[] meshVerts = MeshData.sharedMesh.vertices;
  10.                 Vector2[] meshUVs = MeshData.sharedMesh.uv;
  11.                 for(int i = 0; i < meshVerts.Length; i++) {
  12.                         verts.Add(meshVerts[i]);
  13.                         uvs.Add(meshUVs[i]);
  14.                         cols.Add(col);
  15.                 }
  16.         }
  17.  

However, I found 2 problems. One was trying to get the mesh data as a triangle strip (as I assume that is the topology that you're using). It appeared correctly, but I ended up finding that there was rendering issues (some of the triangles were at the right depth some of them were not). The other problem that I ran across was in the UIDrawCall.Set method where it expects only quads to render. Am I understanding the code correctly there?