碧血红天的HomePage

U3d杂谈 — Shader实现对抗路径线

有这样一个需求,需要在2点之间显示一个行军线,可以根据比列相对箭头移动展示。而且渐变得颜色也根据相对点进行分割。目前我这边简单实现了一个这样的效果。

大概在80%的位置进行分割,左边未红色,右边为绿色。分割点可以根据参数设置进行左右移动。上面的行军箭头都往分割点慢慢移动。整个效果需要一个quad的模型(最好自己做一个4个顶点的Mesh,顶点都做道原点的一边,这样缩放的时候是往一遍缩放,比较好控制)。

基本思想

需要一个4个顶点的Mesh,可以使用自带的quad模型,偶数索引顶点在左边,奇数索引顶点在右边。然后根据我们设置的分割百分比,通过UV来判断分割的位置。然后我们使用一个相对的箭头贴图,同个逻辑进行采样。为了让箭头根据长度自行分段,我们需要设置当前线的逻辑长度和基准长度,基准长度是贴图显示1个完整箭头的长度。比如我们做的Mesh,在X缩放5的时候可以刚好显示一个完整贴图的样式效果最好,我们可以设置基准长度为5,这样我们设置长度就是Transform的缩放值了。

箭头图片

因为渐变需要根据分割点进行移动,分割点的位置是2端颜色的0.5强度的叠加,所以我们需要动态的根据分割点的位置进行计算。计算的思路是把分割点定位0.5的强度,然后根据分割点的左边右边,通过uv.x计算出道分割点的长度,这样就能计算道当前uv位置相对于左边或右边颜色的强度,然后乘以0.5变成自己这一边最小强度再加上uv的当前进度强度即可。

具体的Shader实现代码如下:

Shader "Custom/ConfrontPath"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _PortCount("PortCount",Int) = 1
        _PortLeftColor("PortLeftColor",Color) = (1,1,1,1)
        _PortRightColor("PortRightColor",Color) = (1,1,1,1)
        _AimSpeed("AnimSpeed",Range(0,1)) = 0.5
        _TotalLength("TotalLength",Float) = 1
        _BaseLength("BaseLength",Float) = 1
        _Offset("Offset",Range(0,1)) = 0.5

    }
        SubShader
        {
            // No culling or depth
            Cull Off ZWrite Off ZTest Always

            Pass
            {
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag

                #include "UnityCG.cginc"
                
            half _PortCount;
            fixed4 _PortLeftColor;
            fixed4 _PortRightColor;
            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _TotalLength;
            float _BaseLength;
            float _Offset;
            float _AimSpeed;
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                fixed4 color : TEXCOORD1;
            };

            v2f vert (appdata v ,uint vid : SV_VertexID)
            {
                
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                
                if (_PortCount == 1)
                {
                    o.color = _PortLeftColor;
 
                }
                else if (_PortCount == 2)
                {
                    if (vid % 2 == 0)
                    {
                        o.color = _PortLeftColor;

                    }
                    else {
                        o.color = _PortRightColor;

                    }
                }
                

                return o;
            }

            

            fixed4 frag (v2f i) : SV_Target
            {
                float segNum = _TotalLength / _BaseLength;
                float uvSeg = 1.0 / segNum;
                float2 uv = i.uv;
                if (_PortCount == 1)
                {

                    uv.x = (uv.x % uvSeg) / uvSeg * 0.5;
                    uv.x = (uv.x - _Time.y * _AimSpeed) % 0.5;
                    if (uv.x < 0)
                    {
                        uv.x = 0.5 - uv.x;
                    }
                }
                else if (_PortCount == 2)
                {
                    if (uv.x < _Offset)
                    {
                        uv.x = (uv.x % uvSeg) / uvSeg * 0.5;
                        uv.x = (uv.x - _Time.y * _AimSpeed) % 0.5;
                        if (uv.x < 0)
                        {
                            uv.x = 0.5 - uv.x;
                        }
                    }
                    else {
                        uv.x = (1 - ((1 - uv.x) % uvSeg) / uvSeg * 0.5);
                        uv.x = 0.5+ (uv.x + _Time.y * _AimSpeed) % 0.5;
                        
                    }
                }

                fixed4 col = tex2D(_MainTex, uv);
                // just invert the colors
                fixed4 col2 = i.color;
                
                if (_PortCount == 2)
                {
                    if (_Offset == 1)
                    {
                        col2.rgb = _PortLeftColor.rgb;
                    }
                    else if (_Offset == 0)
                    {
                        col2.rgb = _PortRightColor.rgb;
                    }
                    else {
                        float t = i.uv.x - _Offset;
                        if (t <= 0)
                        {
                            float h = abs(t) / _Offset * 0.5;
                            col2.rgb = _PortLeftColor.rgb * (h + 0.5) + _PortRightColor.rgb * (1 - h - 0.5);
                        }
                        else if (t > 0)
                        {
                            float h = abs(t) / (1 - _Offset) * 0.5;
                            col2.rgb = _PortLeftColor.rgb * (1 - h - 0.5) + _PortRightColor.rgb * (h + 0.5);
                        }
                    }                
                }
                col.rgb = col.rgb * col2.rgb;
                return col;
            }
            ENDCG
        }
    }
}

22 评论

  1. Great paintings! This is the kind of information that are meant to be shared around the web. Shame on the seek engines for no longer positioning this post upper! Come on over and talk over with my web site . Thanks =)

  2. Very interesting info !Perfect just what I was searching for! “The only gift is a portion of thyself.” by Ralph Waldo Emerson.

  3. It¦s really a nice and helpful piece of info. I am glad that you simply shared this useful information with us. Please stay us informed like this. Thanks for sharing.

  4. I hope to give something back and help others like you helped me.

    hibawaftravaux.com

  5. Hello there I am so glad I found your website, I really found you by accident, while I was searching on Yahoo for something else, Nonetheless I am here now and would just like to say thank you for a fantastic post and a all round interesting blog (I also love the theme/design), I don’t have time to look over it all at the moment but I have saved it and also added in your RSS feeds, so when I have time I will be back to read more, Please do keep up the awesome job.

  6. Great V I should certainly pronounce, impressed with your web site. I had no trouble navigating through all tabs and related info ended up being truly easy to do to access. I recently found what I hoped for before you know it in the least. Quite unusual. Is likely to appreciate it for those who add forums or anything, site theme . a tones way for your client to communicate. Excellent task..

  7. Today, while I was at work, my sister stole my iPad and tested to see if it can survive a 40 foot drop, just so she can be a youtube sensation. My iPad is now destroyed and she has 83 views. I know this is entirely off topic but I had to share it with someone!

  8. Im not sure the place you are getting your information, but great topic. I must spend some time studying more or working out more. Thank you for fantastic info I was searching for this info for my mission.

  9. Hi there! This post couldn’t be written any better! Reading through this post reminds me of my previous room mate! He always kept talking about this. I will forward this article to him. Pretty sure he will have a good read. Thank you for sharing!

  10. Some really excellent information, Sword lily I found this.

  11. I’ve been absent for some time, but now I remember why I used to love this website. Thank you, I will try and check back more often. How frequently you update your web site?

  12. Hi, Neat post. There is an issue along with your website in web explorer, might check this?K IE nonetheless is the market leader and a large element of other people will leave out your magnificent writing due to this problem.

  13. I have been browsing on-line more than 3 hours these days, yet I by no means found any fascinating article like yours. It¦s pretty worth sufficient for me. In my view, if all website owners and bloggers made just right content material as you probably did, the web will likely be a lot more helpful than ever before.

  14. Hi, I think your blog might be having browser compatibility issues. When I look at your blog in Chrome, it looks fine but when opening in Internet Explorer, it has some overlapping. I just wanted to give you a quick heads up! Other then that, amazing blog!

  15. Wow! Thank you! I continuously wanted to write on my blog something like that. Can I take a part of your post to my site?

  16. Pretty component to content. I just stumbled upon your blog and in accession capital to say that I acquire in fact enjoyed account your weblog posts. Anyway I’ll be subscribing in your augment or even I fulfillment you get entry to persistently rapidly.

  17. Some truly interesting information, well written and loosely user friendly.

  18. Great delivery. Sound arguments. Keep up the amazing work.

    https://tldrlegal.com/users/MacQuoid/ – tldrlegal.com

  19. I am pleased that I detected this website, just the right info that I was looking for! .

  20. I am impressed with this internet site, rattling I am a fan.

  21. propecia timeline Full outline of UnResponsiveness score versus Glasgow Coma Scale in children with nontraumatic impairment of consciousness

发表评论