unity shader 着色器实例 代码+详解注释 【模型顶点抖动,顶点无节操的随机升降抖动效果】

筅森魡賤 提交于 2020-01-28 05:36:17

如果代码中有什么不清楚请查看以下基础知识

Shader基础知识
unity3d 中 七种坐标知识详解

随机抖动的效果

该效果随机上下抖动顶点,适合给静态模型增加动感。类似小时候我们看的一些定格动画或剪纸的效果。有些2d游戏也会使用类似的功能,这是3d版本,2d同理。

shader的随机数

shader中没有随机函数。所以需要我们自己编写。代码中出现的随机数实现方式是网上摘抄的,由于发现了很多帖子都有这段代码,所以没法注明出处。有人知道原版是谁的请告诉我,我好注明出处。
在这里插入图片描述



Shader "Unlit/simple"
{
    //变量接口
    Properties
    {
        //线段长度
        _LineLength("Length",float) = 1.
        //线段颜色
        _LineColor("Color",COLOR) = (0,1,0,1)
    }
    //着色器正文
    SubShader
    {
        //着色器程序块
        Pass
        {
            Tags { "RenderType" = "Opaque" }
            LOD 200
 
            CGPROGRAM
                #pragma target 5.0
                //顶点着色器,用于处理位置信息
                #pragma vertex vert
                //片元着色器,用于处理颜色
                #pragma fragment frag
                //几何着色器,DirectX 10新增的,介于顶点和片元着色器之间的可选着色器
                #pragma geometry geo
                //引入空间转换宏
                #include "UnityCG.cginc"
 
                float _LineLength;
                fixed4 _LineColor;
                //输入到顶点着色器的数据
                struct v2g
                {
                    //顶点位置
                    float4  pos       : POSITION;
                    //法线
                    float3  normal    : NORMAL;
                    //纹理坐
                    float2  tex0        : TEXCOORD0;
                };
                //输入到片元着色器的数据
                struct g2f
                {
                    //像素位置
                    float4  pos       : POSITION;
                    //纹理
                    float2  tex0        : TEXCOORD0;
                };

                //噪点/随机数发生器
                float random (float n) {
                    return frac(sin(dot(n, float2(12.9898,78.233)))*43758.5453123);
                }
                //顶点着色器,这里是顶点浮动的核心部分,可以直接移植到任何地方
                v2g vert(appdata_base v)
                {
                    v2g o;      
                    o.normal = v.normal;
                    o.tex0 = v.texcoord;
                    //模型坐标转为世界坐标,因为要计算绝对位置
                    o.pos = mul(unity_ObjectToWorld, v.vertex);
                    //获取随机噪点值,这里使用的因子是原x+时间长度
                    float noise = random(o.pos.x +  _Time.y * 0.4);
                    //顶点的高度 = 原顶点高度+ sin(随机噪点)* 幅度
                    o.pos.y = o.pos.y + noise * 0.8;     
                    //将坐标转为裁剪空间,否则就无法正常可视化
                    o.pos = mul(UNITY_MATRIX_VP, o.pos);
                    return o;
                }

                //几何着色器,放在顶点和片元之间。
                //maxvertexcount设置从顶点着色器到几何着色器每次输出最大顶点数量
                //输入修饰有point、line、triangle、lineadj、triangleadj分别对应点、线、三角形、有临接的线段、有邻接的三角形
			    //inout输出修饰类型有PointStream、LineStream、TriangleStream,分别显示顶点、线段、三角面
                //输入顶点的信息,inout这里是将一个数据传入函数,在函数中的修改会返回到函数外的数据
                //一次接受triangle的3个顶点数据,输出为LineStream的3条线段
                [maxvertexcount(3)]
                void geo(triangle v2g vg[3], inout LineStream<g2f> ls)
                {
                    //轮询一个片元的三个顶点
                    for (int i = 0; i < 2; i++)
                    {
                        //初始化一个像素信息
                        g2f g2f_1;
                        //获取每个顶点的位置
                        g2f_1.pos = vg[i].pos;
                        //初始化纹理
                        g2f_1.tex0 = float2(0.0f, 0.0f);
                        //将点压入线条数据
                        ls.Append(g2f_1);
                    }
                    //即使点不够,也会终止一个循环,并重新开始
				    ls.RestartStrip();
                }
 
                //片元着色器,用于上色
                fixed4 frag(g2f input) : COLOR
                {
                    return _LineColor;
                }
            ENDCG
        }
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!