Unity | Shader基础知识(第二十集:应用-简易流光、LOD)

目录

一、前言

二、LOD

1.什么是LOD

2.代码如何调节LOD

三、流光

1.资源准备 

2.uv移动 

3.获取图片中的uv

4.改变uv去取流光的颜色(时间的应用)

5.图片叠加

6.透明图片的叠加

四、纯净代码

五、作者的碎碎念


一、前言

有小伙伴问,它总看见LOD,LOD是什么意思?

所以我们今天的文章分成两部分:

1.LOD的讲解

2.图像的扭曲

二、LOD

目前不想知道可以跳过,知道是可以删的东西就行了。

1.什么是LOD

我们经常在shader里面看见LOD,那LOD是干什么的呢?

示例如下。

        Tags { "RenderType"="Opaque" }
        LOD 100

答:区分到底哪些shader渲染,哪些shader不渲染。 

因为每个人的电脑和手机是不一样的,所以同样是游戏,他也会有不同的画质,例:王者荣耀画质选择。(如图1所示)

图1 王者荣耀

不同的画质,本质上就是运行的shader不一样。

内置着色器等级划分如下:

VertexLit着色器= 100
贴花,反射性顶点光= 150
漫射= 200
漫反射细节,反射凹凸未照明,反射凹凸VertexLit = 250
凹凸,镜面反射= 300
凹凸镜面反射= 400
视差= 500
视差镜面反射= 600

总结:就是数字高一点,加一点显示效果,最开始只有基本物体,然后加反光,再加漫反射.....等

2.代码如何调节LOD

在unity里有一行代码,可以直接调节LOD。

Shader.globalMaximumLOD = 100;

翻译:所有Shader最大的LOD是100。

那么此时此刻,你设置的其他200、300之类的shader都不会被执行。

其实,在我们学习的时候,可以无视它。 

三、流光

之前我们写好的shader都是固定的,换句话说,只要我手不动,我的shader就不会动。但流光明显是随着时间而不停变化的。(如图2所示)

图2 流光

全部过程(了解全部过程,这样就胸有成竹啦):

1.我们有两张图,一张放下面,一张放上面,下面是柠檬,上面是流光。

2.我们要获取图片的uv,因为图片大,流光小,我们需要流光从头走到尾。

3.按照图片的uv在流光上取颜色。

4.每次取到图片uv之后,把uv+时间,再按照新的uv去取流光的颜色。

5.因为时间是一直在变的,所以uv+时间也会一直改变,所以取到的颜色位置也会一直改变,这样流光就形成了。

1.资源准备 

流光其实是一个斜的半透明的图。(如图3所示)没有可以去ppt里画一个,还是挺简单的。

图3 流光透明贴图
2.uv移动 

流光的移动,并不是我们平时写代码里面的位置,它是uv的移动。(如图4所示)

图4 移动uv

这个移动实际上是颜色采样的移动,本来左上角的坐标,只会去图片的左上角去取颜色,但现在它往中间去取颜色,那我们看到的图片位置就会变。

3.获取图片中的uv

获取图片uv的方法。

   //按照V中的uv来获取图片中的uv     
TRANSFORM_TEX(v.uv, _MainTex)
                     //图片叫MainTex

但是用到这个方法,必须要引用float4 _MainTex_ST,这个是用来保证uv采样是对的。 因为我们采样的是_MainTex才是_MainTex_ST,如果是采样的别的,就是别的_ST

想要了解具体原理可以自己百度哇~

这样我们就会获得图片的uv,改变这个uv,图片就会移动。

Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            
            //结构体appdata
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };
            
            //结构体v2f
            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            sampler2D _Tex;
            //虽然没有用,但必须要有
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                //获取图片的uv,放到结构体中
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);

                return o;
            }
            ENDCG
        }
    }
4.改变uv去取流光的颜色(时间的应用)
            fixed4 frag (v2f i) : SV_Target
            {
                //获取到之前传入的图片的uv
                float2 flashUV = i.uv;
                //加上时间
                flashUV.x += _Time.y;
                //用修改过的uv提取了流光的颜色中的透明度
                fixed flashAlpha = tex2D(_Tex, flashUV ).a;
            }

备注:

_Time是程序运行时间,这个时间的意思是,从点击开始程序后,_Time是0,然后就一直往上加....1、2、3、4、5、6、7、8.....等等。

但是在用这个时间时,有时会觉得太大了,有时会觉得太小了,所以封存了一些算法在里面。

_Time.x        表示t / 20,
_Time.y        表示t,
_Time.z        表示t * 2,
_Time.w        表示t* 3 

这时,如果你觉得时间太快,你可以用 _Time.x,它就是累计时间/20,反之,当你觉得太慢,你也可以用_Time.z 或者_Time.w。

当然,你也可以自己做乘除运算,例:_Time.y/10。

还有其他常用的Time:

_SinTimefloat4xyzw分别是:Sin (t/8, t/4, t/2, t).
_CosTimefloat4xyzw分别是: Cos(t/8, t/4, t/2, t).
unity_DeltaTimefloat4xyzw分别是:unity_DeltaTime (dt, 1/dt, smoothDt, 1/smoothDt).

本次我们就用_Time.y,但为了自己能调节速度,我们加了一个可以调节速度的参数。

    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Tex ("Texture", 2D) = "white" {}
        //速度
        _Speed("Speed",float) = 0.5
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

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

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

            sampler2D _MainTex;
            sampler2D _Tex;
            float4 _MainTex_ST;
            float _Speed;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);

                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float2 flashUV = i.uv;
                                        //乘一个参数
                flashUV.x += _Time.y*_Speed;
            }
            ENDCG
        }
    }
5.图片叠加

这里的流光是白色,所以我们就用float4(1,1,1,1)来表示了。白色乘上对应的透明度,就是我们的流光图片。

正常的图片就正常取样,把他们加起来,就是我们最后的流光图片了。

为了能改变流光的强度,我也多增加了一个参数:_Level

fixed4 frag (v2f i) : SV_Target
            {
                float2 flashUV = i.uv;

                flashUV.x += _Time.y*_Speed;

                fixed flashAlpha = tex2D(_Tex, flashUV ).a * _Level;
                //颜色相加
                fixed4 col= tex2D(_MainTex, i.uv) + float4(1,1,1,1)*flashAlpha;

                return col;
            }
6.透明图片的叠加

顶点和片元着色器需要叠加透明图片,必须开混合模式,就是Blend,这个未来再讲,我们先知道要加一个:Blend SrcAlpha OneMinusSrcAlpha就可以了。

四、纯净代码

Shader "Unlit/016"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Tex ("Texture", 2D) = "white" {}
        _Speed("Speed",float) = 0.5
        _Level("Level",Range(0,1)) = 0.5
    }
    SubShader
    {
        Blend SrcAlpha OneMinusSrcAlpha

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

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

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

            sampler2D _MainTex;
            sampler2D _Tex;
            float4 _MainTex_ST;
            float _Speed;
            float _Level;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);

                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float2 flashUV = i.uv;

                flashUV.x += _Time.y*_Speed;

                fixed flashAlpha = tex2D(_Tex, flashUV ).a * _Level;

                fixed4 col= tex2D(_MainTex, i.uv) + float4(1,1,1,1)*flashAlpha;

                return col;
            }
            ENDCG
        }
    }
}

五、作者的碎碎念

这样我们简单的流光就做好啦,有什么我没讲到或者讲错的地方,欢迎在评论区留言,我会改正的。

如果你觉得有用,给我点个赞吧,ღ( ´・ᴗ・` )比心~

  • 17
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菌菌巧乐兹

希望能给大家写更多有用的文章~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值