Search Unity

  1. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Let us know a bit about your interests, and if you'd like to become more directly involved. Take our survey!
    Dismiss Notice
  4. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

How to overlay a texture on a polygon not based on UVs?

Discussion in 'Unity UI & TextMesh Pro' started by nikescar, Aug 13, 2018.

  1. nikescar

    nikescar

    Joined:
    Nov 16, 2011
    Posts:
    76
    Looking for a nudge in the right direction.

    First of all, I'm not sure what graphics/shader terms I should be using to describe what I'm trying to do. What I would like to is overlay a texture onto an arbitrarily shaped UI polygon that has vertices that will change positions at runtime without distorting the texture. So it would have to be done without UVs.

    I'm not sure if that is very clear but here is an illustration of what I would like to accomplish:


    On the right is the texture, on the left is the polygon that I would like the texture applied to.

    If I can answer any questions that would provide further clarification, please ask. Thank you
     
  2. nikescar

    nikescar

    Joined:
    Nov 16, 2011
    Posts:
    76
    Alrighty, so the term that I was looking for is "screen space".

    I've modified the Default UI shader to apply the texture based on the screen space position of the pixels. This works with tileable textures.



    The problem as you can see in the above screenshot is the texture isn't moving with the object. How can I add/subtract the object's position from IN.screenPos in the shader below to compensate for that?

    Code (CSharp):
    1.  
    2. Shader "UI/ScreenSpaceTexture"
    3. {
    4.     Properties
    5.     {
    6.         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    7.         _Color ("Tint", Color) = (1,1,1,1)
    8.        
    9.         _StencilComp ("Stencil Comparison", Float) = 8
    10.         _Stencil ("Stencil ID", Float) = 0
    11.         _StencilOp ("Stencil Operation", Float) = 0
    12.         _StencilWriteMask ("Stencil Write Mask", Float) = 255
    13.         _StencilReadMask ("Stencil Read Mask", Float) = 255
    14.  
    15.         _ColorMask ("Color Mask", Float) = 15
    16.        
    17.         _Tiling ("Tiling", Float) = 0
    18.     }
    19.  
    20.     SubShader
    21.     {
    22.         Tags
    23.         {
    24.             "Queue"="Transparent"
    25.             "IgnoreProjector"="True"
    26.             "RenderType"="Transparent"
    27.             "PreviewType"="Plane"
    28.             "CanUseSpriteAtlas"="True"
    29.         }
    30.        
    31.         Stencil
    32.         {
    33.             Ref [_Stencil]
    34.             Comp [_StencilComp]
    35.             Pass [_StencilOp]
    36.             ReadMask [_StencilReadMask]
    37.             WriteMask [_StencilWriteMask]
    38.         }
    39.  
    40.         Cull Off
    41.         Lighting Off
    42.         ZWrite Off
    43.         ZTest [unity_GUIZTestMode]
    44.         Blend SrcAlpha OneMinusSrcAlpha
    45.         ColorMask [_ColorMask]
    46.  
    47.         Pass
    48.         {
    49.         CGPROGRAM
    50.             #pragma vertex vert
    51.             #pragma fragment frag
    52.             #include "UnityCG.cginc"
    53.            
    54.             struct appdata_t
    55.             {
    56.                 float4 vertex   : POSITION;
    57.                 float4 color    : COLOR;
    58.                 float2 texcoord : TEXCOORD0;
    59.             };
    60.  
    61.             struct v2f
    62.             {
    63.                 float4 vertex   : SV_POSITION;
    64.                 fixed4 color    : COLOR;
    65.                 half2 screenPos : TEXCOORD1;
    66.             };
    67.            
    68.             fixed4 _Color;
    69.             fixed _Tiling;
    70.  
    71.             v2f vert(appdata_t IN)
    72.             {
    73.                 v2f OUT;
    74.                 OUT.vertex = UnityObjectToClipPos(IN.vertex);
    75.                 OUT.screenPos = ComputeScreenPos(IN.vertex);
    76. #ifdef UNITY_HALF_TEXEL_OFFSET
    77.                 OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
    78. #endif
    79.                 OUT.color = IN.color * _Color;
    80.                 return OUT;
    81.             }
    82.              
    83.             sampler2D _MainTex;
    84.  
    85.             fixed4 frag(v2f IN) : SV_Target
    86.             {
    87.                 half4 color = tex2D(_MainTex, IN.screenPos * _Tiling * .001) * IN.color;
    88.                 clip (color.a - 0.01);
    89.                 return color;
    90.             }
    91.         ENDCG
    92.         }
    93.     }
    94. }
    95.  
    If there is anything I can do to improve this modification, please let me know.