在Unity中实现数学坐标系Shader(一)

本节教程为南京字节工坊原创文章,转载请留此信息:https://blog.csdn.net/gcj2450/article/details/104523738

南京字节工坊,专业从事各类互动软件定制开发,三维可视化应用开发定制,VR,AR类互动应用定制开发。

今天我们来学习通过Unity Shader实现数学直角坐标系的Shader,以让大家更加熟悉Unity Shader中常用的数学方法。数学坐标系由XY轴,XY轴方向的箭头以及单位网格构成。最终效果如下图

第一步我们使用基本的数学方法来绘制方格。在Unity中新建一个Unlit Shader。删除_MainTexture属性及相关的变量,定义网格shader所需的属性。属性定义如下所示

Properties
    {
        //背景色
        _BgColor("BgColor",color)=(1,1,1,1)
        //十分线颜色
        _LinesColor("LinesColor",color) = (0.70.70.7,1.0)
        //次级线颜色
        _SubLinesColor("SubLinesColor",color)=(0.950.950.95,1.0)
        //缩放
        _Scale("Scale",range(1,100)) = 10
        _Subdiv("Subdiv",range(1,10)) = 10
    }

这里的属性分别是背景色,十分线颜色,次级线的颜色,缩放值和最小刻度细分值。

在Fragment Shader中输入如下代码

               vec2 pos = i.uv;

定义一个pos变量,并将其缩放。
                pos *= _Scale;

通过取余运算,得到重复的值,加入_Scale=10,将在0-1之间重复10次
                pos=frac(pos);
               
                vec4 fragColor =  _BgColor;

通过step方法,返回左下角的值,这里step方法,相当于if判断,

step(a, x) Returns (x >= a) ? 1 : 0

               vec2 bl = step(0.01,pos);       // 左下
                vec2 tr = step(0.01,1.0-pos);   // 右上

将上面两次运算的结果相乘,就会得到全部>0的位置
                float alpha =bl.x * bl.y * tr.x * tr.y;

再通过mix方法,混合线的颜色和基础色。
                fragColor = mix(fragColor, _LinesColor, 1-alpha);
                将pos放大Subdiv倍,重复上面运算,得到十分位刻度的方格
                vec2 bl2 = step(0.01,frac(pos*_Subdiv));       // 左下
                vec2 tr2 = step(0.01,1.0-frac(pos*_Subdiv));   // 右上
                float alpha2 =bl2.x * bl2.y * tr2.x * tr2.y;
                fragColor = mix(fragColor, _SubLinesColor, 1-alpha2);
                返回最终颜色。
                
                return fragColor;

得到的最终上述效果完成后,得到最终效果如下:下图_Scale=2,_Subdive=5

完整代码如下:

Shader "Unlit/StepGrid"
{
    Properties
    {
        //背景色
        _BgColor("BgColor",color)=(1,1,1,1)
        //十分线颜色
        _LinesColor("LinesColor",color) = (0.70.70.7,1.0)
        //次级线颜色
        _SubLinesColor("SubLinesColor",color)=(0.950.950.95,1.0)
        //缩放
        _Scale("Scale",range(1,100)) = 10
        _Subdiv("Subdiv",range(1,10)) = 10
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #define vec2 half2
            #define vec3 half3
            #define vec4 half4
            #define mix lerp
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

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

            float _Scale;
            float _Subdiv;

            fixed4 _BgColor;
            fixed4 _LinesColor;
            fixed4 _SubLinesColor;


            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                vec2 pos = i.uv;
                pos *= _Scale;
                pos=frac(pos);
                
                vec4 fragColor =  _BgColor;
                vec2 bl = step(0.01,pos);       // 左下
                vec2 tr = step(0.01,1.0-pos);   // 右上
                float alpha =bl.x * bl.y * tr.x * tr.y;
                fragColor = mix(fragColor, _LinesColor, 1-alpha);
                
                vec2 bl2 = step(0.01,frac(pos*_Subdiv));       // 左下
                vec2 tr2 = step(0.01,1.0-frac(pos*_Subdiv));   // 右上
                float alpha2 =bl2.x * bl2.y * tr2.x * tr2.y;
                fragColor = mix(fragColor, _SubLinesColor, 1-alpha2);
                
                
                return fragColor;
                
            }
            ENDCG
        }
    }
}
通过上面的简单Shader,实现了一个基本的带十分刻度网格的Shader。下一节我们将继续对其进行优化。

发布了20 篇原创文章 · 获赞 0 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/gcj2450/article/details/104523738