基于过程渲染的小地图shader

小地图中有很多标志物,大量的对象一直显示在屏幕中,所以想了一种优化方式,优化点这部分的性能

优点: 
1. 只需要一个DrawCall,全部渲染到一张图片,就可以渲染出小地图 
2. 不需要生成大量的标志物实例 
3. 规则图形直接使用代码计算生成来代替采样(一般小地图上的很多标志物都是采样图片) 
4. 
缺点: 
小地图的每个像素经过了大量的运算。

总结: 
测试这样到底会不会真的优化了性能,只是小地图的另一种实现方式,不过由于GPG的高并发计算能力,可能这样会使性能得到优化。如果有人测试了性能,希望告知

效果如下:

这里写图片描述

代码如下:

Shader "Unlit/MinMap"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
        _PointTex("Point Texture", 2D) = "white" {}
        _CircleColor("Point Col",Color) = (1,1,1,1)
        _CircleColor2("Point Col2",Color) = (1,1,1,1)
        _Angle("Angle",float)=0
        _Parameters("Parameters",Vector) = (0,0,0,0)
    }
        SubShader
    {
        Tags { "RenderType" = "Opaque" }
        LOD 100

        Pass
        {
            Blend SrcAlpha  OneMinusSrcAlpha

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag


            #include "UnityCG.cginc"
            //渲染圆点
            fixed4  circle(float2 pos, float2 center, float radius, fixed3 color, float antialias) {
                float d = length(pos - center) - radius;
                float t = smoothstep(0, antialias, d);
                return fixed4(color, 1.0 - t);
            }
            //混合操作
            fixed4  mix(fixed4 col1, fixed4 col2,  fixed alpha) {

                return fixed4(col1.rgb*(1 - alpha) + col2.rgb*alpha ,max(col1.a,col2.a));
            }
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

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

            sampler2D _MainTex;
            sampler2D _PointTex;
            float4 _MainTex_ST;
            float4 _PointTex_ST;
            //一共渲染20个点,分为两部分
            float4 _Pos[20];
            float4 _RolePos;
            //渲染的点的颜色,这个也可以使用C#代码传入,在没一点的信息里记录,目前只记录了位置
            fixed4 _CircleColor;
            fixed4 _CircleColor2;
            float4 _Parameters;
            float _Angle;
            v2f vert(appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                //构造旋转矩阵
                float cosA = cos(_Angle);
                float sinA = sin(_Angle);
                float3x3 _Matrix = {
                    cosA,-sinA,0,
                    sinA,cosA,0,
                    0,0,1,
                };

                o.uv2 = TRANSFORM_TEX(v.uv, _PointTex);
                o.uv2 = mul(_Matrix, o.uv2-float2(0.5,0.5)) + float2(0.5, 0.5);
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
                fixed4 col2 = tex2D(_PointTex, i.uv2);
                //代码看起来可能比较low,为了不使用循环,我也没办法了,希望有改进的意见
                fixed4 layer0 = circle(i.uv, _Pos[0], _Pos[0].z, _CircleColor.rgb, _Parameters.w);
                fixed4 layer1 = circle(i.uv, _Pos[1], _Pos[1].z, _CircleColor.rgb, _Parameters.w);
                fixed4 layer2 = circle(i.uv, _Pos[2], _Pos[2].z, _CircleColor.rgb, _Parameters.w);
                fixed4 layer3 = circle(i.uv, _Pos[3], _Pos[3].z, _CircleColor.rgb, _Parameters.w);
                fixed4 layer4 = circle(i.uv, _Pos[4], _Pos[4].z, _CircleColor.rgb, _Parameters.w);
                fixed4 layer5 = circle(i.uv, _Pos[5], _Pos[5].z, _CircleColor.rgb, _Parameters.w);
                fixed4 layer6 = circle(i.uv, _Pos[6], _Pos[6].z, _CircleColor.rgb, _Parameters.w);
                fixed4 layer7 = circle(i.uv, _Pos[7], _Pos[7].z, _CircleColor.rgb, _Parameters.w);
                fixed4 layer8 = circle(i.uv, _Pos[8], _Pos[8].z, _CircleColor.rgb, _Parameters.w);
                fixed4 layer9 = circle(i.uv, _Pos[9], _Pos[9].z, _CircleColor.rgb, _Parameters.w);
                fixed4 layer10= circle(i.uv, _Pos[10], _Pos[10].z, _CircleColor2.rgb, _Parameters.w);
                fixed4 layer11= circle(i.uv, _Pos[11], _Pos[11].z, _CircleColor2.rgb, _Parameters.w);
                fixed4 layer12= circle(i.uv, _Pos[12], _Pos[12].z, _CircleColor2.rgb, _Parameters.w);
                fixed4 layer13= circle(i.uv, _Pos[13], _Pos[13].z, _CircleColor2.rgb, _Parameters.w);
                fixed4 layer14= circle(i.uv, _Pos[14], _Pos[14].z, _CircleColor2.rgb, _Parameters.w);
                fixed4 layer15= circle(i.uv, _Pos[15], _Pos[15].z, _CircleColor2.rgb, _Parameters.w);
                fixed4 layer16= circle(i.uv, _Pos[16], _Pos[16].z, _CircleColor2.rgb, _Parameters.w);
                fixed4 layer17= circle(i.uv, _Pos[17], _Pos[17].z, _CircleColor2.rgb, _Parameters.w);
                fixed4 layer18= circle(i.uv, _Pos[18], _Pos[18].z, _CircleColor2.rgb, _Parameters.w);
                fixed4 layer19= circle(i.uv, _Pos[19], _Pos[19].z, _CircleColor2.rgb, _Parameters.w);

                fixed4 fragColor = mix(col, layer0, layer0.a);
                fragColor = mix(fragColor, layer1, layer1.a);
                fragColor = mix(fragColor, layer2, layer2.a);
                fragColor = mix(fragColor, layer3, layer3.a);
                fragColor = mix(fragColor, layer4, layer4.a);
                fragColor = mix(fragColor, layer5, layer5.a);
                fragColor = mix(fragColor, layer6, layer6.a);
                fragColor = mix(fragColor, layer7, layer7.a);
                fragColor = mix(fragColor, layer8, layer8.a);
                fragColor = mix(fragColor, layer9, layer9.a);
                fragColor = mix(fragColor, layer10, layer10.a);
                fragColor = mix(fragColor, layer11, layer11.a);
                fragColor = mix(fragColor, layer12, layer12.a);
                fragColor = mix(fragColor, layer13, layer13.a);
                fragColor = mix(fragColor, layer14, layer14.a);
                fragColor = mix(fragColor, layer15, layer15.a);
                fragColor = mix(fragColor, layer16, layer16.a);
                fragColor = mix(fragColor, layer17, layer17.a);
                fragColor = mix(fragColor, layer18, layer18.a);
                fragColor = mix(fragColor, col2, col2.a);//显示在最上面
                return fragColor;
            }
            ENDCG
        }
    }
}

   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135

shader代码一共就这些,实现了npc的移动,玩家的移动和旋转,npc通过计算得到(使用了圆形,当然也可以使用其他的形状,修改圆形的代码即可),玩家通过采样图片(一般游戏这样区别玩家和npc) 
C#代码 
比较简单,传递玩家旋转信息和npc的位置信息,玩家的位置信息不需要传递,只需要让玩家保持在小地图中心,代码调整image的缩放和偏移即可

    public void SetM(Vector4[] _pos, float angle)
    {
        pos = _pos;
        m.SetVectorArray("_Pos", pos);
        m.SetFloat("_Angle", angle);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值