Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by KniF0rz · Nov 05, 2015 at 09:11 PM · shadertexturemasking

Help Shader: Texture mask using sliced mask and tiled texture.

Sorry the title might be confusing .... I'll try to be more clear. alt text

So I got, on the right, a sliced texture which is the black outline representing a button or a panel ... whatever.

I want the tiled texture to fill the inside of the button and remove the extras (top left corner / bottom right corner)

So I thought .... let's do a shader.

The image on the right is what I got so far. I got a mask applied to every tiles ....

so My question is ... How can I get that mask to be applied once to remove only 2 cornes of the whole image instead of removing every corners of every tiles?

here is my shader so far :

 Shader "UI/TextureMask" 
 {
     Properties
     {
         _MainTex("Albedo (RGB)", 2D) = "white" {}
         _OpacityTex("Opacity (A)", 2D) = "white" {}
     }
 
     SubShader
     {
         Tags{ "Queue" = "transparent" "RenderType" = "transparent" }
         Blend SrcAlpha OneMinusSrcAlpha
         Lighting Off
 
         Pass
         {
             CGPROGRAM
             #pragma vertex vert
             #pragma fragment frag
             #include "UnityCG.cginc"
 
             sampler2D _MainTex;
             sampler2D _OpacityTex;
 
             uniform float4 _MainTex_ST;
 
             struct v2f 
             {
                 float4  pos : SV_POSITION;
                 float2  uv : TEXCOORD0;
             };
 
             v2f vert(appdata_base v)
             {
                 v2f o;
                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
 
                 // Texture offset - GOOD
                 o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
                 return o;
             }
 
             half4 frag(v2f i) : COLOR
             {
                 fixed4 c = tex2D(_MainTex, i.uv);
                 half opacity = tex2D(_OpacityTex, i.uv).a;
 
                 if (opacity == 0)
                 {
                     c.a = c.a;
                 }
                 else
                 {
                     c.a = 0;
                 }
 
                 return c;
             }        
             ENDCG
         }
     }
 }



I have a feeling this is because I'm using the tiled Texture's uvs instead of the border's uv.. but I'm not too sure how to achieve that.

Any help is welcome.

Thanks

Vince

  • Update ---

here are the textures I'm currently using.

Textures

untitled.png (136.7 kB)
textures.zip (1.8 kB)
Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image KniF0rz · Nov 06, 2015 at 03:24 AM 0
Share

By the way, if there is a way to do it WITHOUT shaders, I'm totally open as well.

avatar image jmgek · Nov 06, 2015 at 04:42 AM 0
Share

I would suggest using a GUI texture, you are over complicating it :) Sorry if this is in the answer section I keep trying to do it as a reply.

avatar image KniF0rz · Nov 06, 2015 at 05:49 AM 0
Share

@jmgek, thanks for your reply. I figured there must be some other way to do this. GUITexture? isn't that deprecated? Unless you mean the new UI Image?

Would you $$anonymous$$d giving me more details? Are you suggesting editing the texture data manually using GetPixel and SetPixel through script???

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by helarts · Nov 06, 2015 at 02:54 PM

The problem is that you use the same uvs for both textures, not tested but it should work (some details as comments in the code):

 Shader "UI/TextureMask" 
  {
      Properties
      {
          _MainTex("Albedo (RGB)", 2D) = "white" {}
          _OpacityTex("Opacity (A)", 2D) = "white" {}
      }
  
      SubShader
      {
          Tags{ "Queue" = "transparent" "RenderType" = "transparent" }
          Blend SrcAlpha OneMinusSrcAlpha
          Lighting Off
  
          Pass
          {
              CGPROGRAM
              #pragma vertex vert
              #pragma fragment frag
              #include "UnityCG.cginc"
  
              sampler2D _MainTex;
              sampler2D _OpacityTex;
  
              uniform float4 _MainTex_ST;
             // Needed by TRANSFORM_TEX
              uniform float4 _OpacityTex_ST;
 
              struct v2f 
              {
                  float4  pos : SV_POSITION;
                  float2  uv : TEXCOORD0;
                // "declare" a new set of uvs will be passed from the vertex to the fragment shader
                  float2  uvOpacityTex : TEXCOORD1;
              };
  
              v2f vert(appdata_base v)
              {
                  v2f o;
                  o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
  
                  // Texture offset - GOOD
                  o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
                  // "bind" your new uvs with the OpacityTex tile and offset properties you can find in the material
                  o.uvOpacityTex = TRANSFORM_TEX(v.texcoord, _OpacityTex);
                  return o;
              }
  
              half4 frag(v2f i) : COLOR
              {
                  fixed4 c = tex2D(_MainTex, i.uv);
                  // Use your OpacityTex uvs to map the texture
                  half opacity = tex2D(_OpacityTex, i.uvOpacityTex).a;
  
                 // sorry but this seems to be garbage
                 // if (opacity == 0)
                 // {
                 //     c.a = c.a;
                 // }
                 // else
                 // {
                 //     c.a = 0;
                 // }
 
                 // multiply _MainTex and _OpacityTex alpha 
                  c.a *= opacity;
                  return c;
              }        
              ENDCG
          }
      }
  }

Edit: I think you'll have to invert the alpha of your OpacityTex or change

 c.a *= opacity; 
 by:
 c.a *= 1-opacity;
Comment
Add comment · Show 7 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image KniF0rz · Nov 06, 2015 at 03:12 PM 0
Share

I get the same result as my own implementation. Lol yeah that opacity condition was garbage.. trying stuff.

I think this is too complicated to do... The mask needs to be sliced just like the border button.

$$anonymous$$aybe I'm doing this wrong too. I got 3 textures ... Border, filling and $$anonymous$$ask. Border and mask are 9-slice texture and filling is tileable.

the way it's setup in the editor is : I got a Gameobject which has a button component. It uses the border image set to sliced mode. then I added another image as a child of the button which has the material using this shader with the filling and the mask.

So basically, the mask has no way to know the size of the sliced border ...I think that's my problem here,..

avatar image helarts KniF0rz · Nov 06, 2015 at 04:16 PM 0
Share

Sorry I am not really a UI guy but if I understand well your mask texture is called _OpacityTex in the shader, right ? Then you should be able to slice your tileable texture like you want with the alpha of _OpacityTex. What I get:

http://helarts.com/stock/unityforum/screenshot1.jpg

with these textures:

http://helarts.com/stock/unityforum/tileablesquare.tga

http://helarts.com/stock/unityforum/mask.tga

PS: be sure you don't have 2 shaders with the same name ( Shader "UI/Texture$$anonymous$$ask" )

avatar image KniF0rz · Nov 06, 2015 at 06:37 PM 0
Share

Dammit dude... I think I'll have to ask you how you set it up to get that result .. It just won't behave properly...

Are you using an image? You set the source image with the mask.tga then set the shader with the TileableSquare and it's mask?

avatar image helarts KniF0rz · Nov 06, 2015 at 06:57 PM 0
Share

I hope it helps: http://helarts.com/stock/unityforum/UIslicedTileable.jpg

avatar image KniF0rz · Nov 06, 2015 at 07:30 PM 0
Share

Ok I got it working in a new project ... that's weird.. But it doesn't fullfill all my wishes unfortunately....

Ur example is scaling the image if I make the button bigger. what I want is to be able to use the "Sliced" mode. Like keep the angled border the same and scale the center parts... like the image at the top.

That's the biggest issue I think alt text

avatar image KniF0rz · Nov 07, 2015 at 03:34 AM 0
Share

ahhhhhh $$anonymous$$an! Thanks ! That's clever!! I was building a texture containing the grid itself.. ins$$anonymous$$d of just creating it from plain texture.

thanks alot!

avatar image KniF0rz · Nov 07, 2015 at 03:35 AM 0
Share

alt text

The top image is sliced vs the shader ... I want these angles to be the same no matter what size I use.

compare.png (55.7 kB)

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Unmask a sprite with a quad mesh in runtime 1 Answer

Cullingmask issue. 0 Answers

Textures missing after extended gameplay on Playstation game,Missing Textures after extended play on Playstation 4 game 1 Answer

How do you return to the default rendering mode after installing the lightweight-scriptable render pipeline? 1 Answer

Is it possible to use a movie texture as a normal map, or as a mask to hide a texture in a shader? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges