[Shader] cropping NGUI UISprite and UITexture, nguiuisprite

Source: Internet
Author: User

[Shader] cropping NGUI UISprite and UITexture, nguiuisprite
Due to the recent busy schedule, many blog posts I posted elsewhere have not been synchronized here. I will try again later. Sorry for the readers who followed my blog!

All rights reserved. The source must be indicated for reprinting!
Those who like Firefox, Java, unity3D, and game development can join the Q group in muye village: 379076227
0. You can chat about Shader for two days at home during the Spring Festival this year. But he has a deep liking for Shader. Attracted by its charm.
But what we usually do is the development of the server and client, which is logically oriented. So we haven't touched Shader for a long time.
However, someone discussed in A group yesterday that NGUI cannot crop Sprite. For example, a square is displayed as a circle. For example:

This should be quite common. Maybe you will say that art can help you cut the circle directly. Sometimes, sometimes. When will it not work? When you use square shape in some parts of the game, and round shape in some parts. At this time, no art can help you cut. Otherwise, there will be no more than two resources.

It is recommended that you already know how to use NGUI to create an atlas and use its UISprite and UITexture.


The testing environment is as follows:
System: Win7 X64 engine: Unity3D V4.3.3

Plug-in: NGUI 3.5.7

1. Start

As a person who has studied Shader for two days, I think it should be hard for me. As a result, I immediately joined the U3D Project panel. Create a Shader.


2. Write the first version of Shader. Double-click the Shader we created above. This is for NGUI. Then I named our Shader unwritable/Transparent Colored Mask according to NGUI's Shader.
The Shader code is as follows:
Shader "Unlit/Transparent Colored Mask"{        Properties        {                _MainTex ("Base (RGB), Alpha (A)", 2D) = "black" {}                _Mask ("Mask Alpha (A)", 2D) = "white" {}        }                SubShader        {                LOD 100                Tags                {                        "Queue" = "Transparent"                        "IgnoreProjector" = "True"                        "RenderType" = "Transparent"                }                                Cull Off                Lighting Off                ZWrite Off                Fog { Mode Off }                Offset -1, -1                Blend SrcAlpha OneMinusSrcAlpha                Pass                {                        CGPROGRAM                        #pragma vertex vert                        #pragma fragment frag                                                        #include "UnityCG.cginc"                                struct appdata_t                        {                                float4 vertex : POSITION;                                float2 texcoord : TEXCOORD0;                                fixed4 color : COLOR;                        };                                struct v2f                        {                                float4 vertex : SV_POSITION;                                half2 texcoord : TEXCOORD0;                                fixed4 color : COLOR;                                fixed gray : TEXCOORD1;                         };                                sampler2D _MainTex;                        sampler2D _Mask;                        float4 _MainTex_ST;                        float4 _Mask_ST;                                                        v2f vert (appdata_t v)                        {                                v2f o;                                o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);                                o.texcoord = v.texcoord;                                o.color = v.color;                                o.gray = dot(v.color, fixed4(1,1,1,0));                                return o;                        }                                                        fixed4 frag (v2f i) : COLOR                        {                            fixed4 col;                                                                col = tex2D(_MainTex, i.texcoord) * i.color;                                col.a = col.a * tex2D(_Mask, i.texcoord).a;                                return col;                        }                        ENDCG                }        }        SubShader        {                LOD 100                Tags                {                        "Queue" = "Transparent"                        "IgnoreProjector" = "True"                        "RenderType" = "Transparent"                }                                Pass                {                        Cull Off                        Lighting Off                        ZWrite Off                        Fog { Mode Off }                        Offset -1, -1                        ColorMask RGB                        AlphaTest Greater .01                        Blend SrcAlpha OneMinusSrcAlpha                        ColorMaterial AmbientAndDiffuse                                                SetTexture [_MainTex]                        {                                Combine Texture * Primary                        }                }        }}
The main code for cropping is:
fixed4 frag (v2f i) : COLOR{    fixed4 col;    col = tex2D(_MainTex, i.texcoord) * i.color;    col.a = col.a * tex2D(_Mask, i.texcoord).a;    return col;}
I believe it is easy for everyone to understand. Here we multiply the Alpha channel value of the Mask texture with that of the original image.
How to use it.

Create a UItexture.



Select a material. Use the Shader above. Set a Mask.

The Mask image is



We can see that the Alpha channel contains a white circle.
Remember to set the import settings for this Mask image as follows:


You can see the running effect:

3. Cheers and celebrate? Everything looks quite smooth. But can this Shader work on UISprite?
Let's try it.
Create a gallery at will. Then add a UISprite,


Then modify the material of this gallery and use our Shader.

Amount... The effect is as follows... Not right


4. Stop and think about it. Is this NGUI bug... Ah !!! Ah !!!!!
No, I have to think about it.
.........
1 minute has passed.
Why is the formula col. a = col. a * tex2D (_ Mask, I. texcoord). a incorrect effect on Sprite.
Is the range of I. texcoord not 0 ~ 1.
In this case, it seems a bit reasonable. Because NGUI makes the image to be used into an image gallery. Therefore, only a small area in the gallery is displayed on the Mesh of the UI each time.
So, I only need to remap the range of I. texcoord to 0 ~ 1. Then it is used to take the color above the Mask. Isn't it OK?
I immediately started to be witty.
Shader "Unlit/Transparent Colored Mask"{        Properties        {                _MainTex ("Base (RGB), Alpha (A)", 2D) = "black" {}                _Mask ("Mask Alpha (A)", 2D) = "white" {}                _WidthRate ("Sprite.width/Atlas.width", float) = 1                _HeightRate ("Sprite.height/Atlas.height", float) = 1                _XOffset("offsetX", float) = 0                _XOffset("offsetY", float) = 0        }                SubShader        {                LOD 100                Tags                {                        "Queue" = "Transparent"                        "IgnoreProjector" = "True"                        "RenderType" = "Transparent"                }                                Cull Off                Lighting Off                ZWrite Off                Fog { Mode Off }                Offset -1, -1                Blend SrcAlpha OneMinusSrcAlpha                Pass                {                        CGPROGRAM                        #pragma vertex vert                        #pragma fragment frag                                                        #include "UnityCG.cginc"                                struct appdata_t                        {                                float4 vertex : POSITION;                                float2 texcoord : TEXCOORD0;                                fixed4 color : COLOR;                        };                                struct v2f                        {                                float4 vertex : SV_POSITION;                                half2 texcoord : TEXCOORD0;                                fixed4 color : COLOR;                                fixed gray : TEXCOORD1;                         };                                sampler2D _MainTex;                        sampler2D _Mask;                        float4 _MainTex_ST;                        float4 _Mask_ST;                        float _WidthRate;                        float _HeightRate;                        float _XOffset;                         float _YOffset;                                                         v2f vert (appdata_t v)                        {                                v2f o;                                o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);                                o.texcoord = v.texcoord;                                o.color = v.color;                                o.gray = dot(v.color, fixed4(1,1,1,0));                                return o;                        }                                                        fixed4 frag (v2f i) : COLOR                        {                            fixed4 col;                                                                col = tex2D(_MainTex, i.texcoord) * i.color;                                col.a = col.a * tex2D(_Mask, float2((i.texcoord.x-_XOffset)/_WidthRate, (i.texcoord.y-(1-_YOffset))/_HeightRate)).a;                                 return col;                        }                        ENDCG                }        }        SubShader        {                LOD 100                Tags                {                        "Queue" = "Transparent"                        "IgnoreProjector" = "True"                        "RenderType" = "Transparent"                }                                Pass                {                        Cull Off                        Lighting Off                        ZWrite Off                        Fog { Mode Off }                        Offset -1, -1                        ColorMask RGB                        AlphaTest Greater .01                        Blend SrcAlpha OneMinusSrcAlpha                        ColorMaterial AmbientAndDiffuse                                                SetTexture [_MainTex]                        {                                Combine Texture * Primary                        }                }        }}

Okay. Then how to use this Shader. We need another script to set the shader parameter.

using UnityEngine;using System.Collections;[ExecuteInEditMode]public class ScaleTexcoord : MonoBehaviour{    private float wr;    private float hr;    private float offX;    private float offY;    private UISprite s;    void Awake()    {        s = GetComponent<UISprite>();        wr = s.GetAtlasSprite().width * 1.0f / s.atlas.spriteMaterial.mainTexture.width;        offX = s.GetAtlasSprite().x * 1.0f / s.atlas.spriteMaterial.mainTexture.width;        hr = s.GetAtlasSprite().height * 1.0f / s.atlas.spriteMaterial.mainTexture.height;        offY = (s.GetAtlasSprite().y + s.GetAtlasSprite().height) * 1.0f / s.atlas.spriteMaterial.mainTexture.height;    }    public void Update()    {        s.atlas.spriteMaterial.SetFloat("_WidthRate", wr);        s.atlas.spriteMaterial.SetFloat("_HeightRate", hr);        s.atlas.spriteMaterial.SetFloat("_XOffset", offX);        s.atlas.spriteMaterial.SetFloat("_YOffset", offY);    }}


You only need to attach this script to UISprite.


It can be found that it is normal now. NGUI gallery material becomes


Okay. We can really celebrate this time ~~

The whole effect is actually only the Shader and ScaleTexcoord. cs above.


Download the test project:


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.