Unity Shader (四)顶点程序示例

1、在顶点函数中实现凸起效果

 

Shader "Custom/Example" {

        properties
        {
            _R("R",range(0,5))=1 //圆的半径,也是凸起的范围
            _OX("OX",range(-5,5))=1 //x轴
        }
        SubShader
        {
            pass{
                CGPROGRAM
                #pragma vertex vert 
                #pragma fragment frag
                #include "unitycg.cginc"

                float _R;
                float _OX;

                struct v2f{
                    float4 pos:POSITION;
                    float4 color:COLOR;
                };
                v2f vert(appdata_base v)
                {
                    float4 wpos=mul(unity_ObjectToWorld,v.vertex);//将顶点转换为世界坐标
                    float2 xy=wpos.xz;//获取顶点的x轴和z轴
                    float d=_R-length(xy-float2(_OX,0));//length用于求向量的模长

                    d=d<0?0:d;

                    float4 uppos=float4(v.vertex.x,d,v.vertex.z,v.vertex.w);

                    v2f o;
                    o.pos=UnityObjectToClipPos(uppos);//等于mul(UNITY_MATRIX_MVP,uppos)
                    o.color=fixed4(uppos.y/_R,uppos.y/_R,uppos.y/_R,1);
                    return o;
                }
                fixed4 frag(v2f IN):COLOR
                {
                    return IN.color;
                }

                ENDCG
            }
        }
}

 2、渐变及溜光效果

Shader "Custom/Example_1" {
    properties
    {
        _r("R",range(0,1))=0.1
    }
    Subshader
    {
        pass{
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "unitycg.cginc"

            float dis;
            float _r;

            struct v2f{
                float4 pos:POSITION;
                fixed4 color:COLOR;
            };
            v2f vert(appdata_base v)
            {
                v2f o;
                o.pos= UnityObjectToClipPos(v.vertex);
                float x=o.pos.x/o.pos.w;
                dis=_SinTime.y*2;
                if(x>dis&&x<dis+_r)
                    o.color=fixed4(1,0,0,1);
                else
                    o.color=fixed4(x/2+0.5,x/2+0.5,x/2+0.5,1);

                return o;
            }
            fixed4 frag(v2f IN):COLOR
            {
                return IN.color;
            }
            ENDCG
        }
    }
}

 3、顶点扭曲效果

Shader "Custom/Example_2" {
    Subshader
    {
        pass{
            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag
            #include "unitycg.cginc"

            struct v2f
            {
                float4 pos:POSITION;
                fixed4 color:COLOR;
            };

            v2f vert(appdata_base v)
            {
                

//                float angle=length(v.vertex)*_SinTime.w;
//                //绕Y轴旋转矩阵
//                float4x4 m=
//                {
//                    float4(cos(angle),0,sin(angle),0),
//                    float4(0,1,0,0),
//                    float4(-sin(angle),0,cos(angle),0),
//                    float4(0,0,0,1),
//                };
//                v.vertex=mul(m,v.vertex);//旋转矩阵去影响顶点

//                //优化绕Y轴旋转的矩阵,除去0与其他项相乘的项
//                float x=cos(angle)*v.vertex.x+sin(angle)*v.vertex.z;
//                float z=-sin(angle)*v.vertex.x+cos(angle)*v.vertex.z;
//                v.vertex.x=x;
//                v.vertex.z=z;

                //边界波纹效果
                float angle=v.vertex.z+_Time.y;
                float4x4 m=
                {
                    float4(sin(angle)/8+0.5,0,0,0),
                    float4(0,1,0,0),
                    float4(0,0,1,0),
                    float4(0,0,0,1),
                };
                v.vertex=mul(m,v.vertex);

                v2f o;
                o.pos=UnityObjectToClipPos(v.vertex);
                o.color=fixed4(0,1,1,1);
                return o;
            }
            float4 frag(v2f IN):COLOR
            {
                return IN.color;
            }

            ENDCG
        }
    }
}

 4、各种波

Shader "Custom/Example_3" {
    Subshader
    {
        pass{
            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag
            #include "unitycg.cginc"

            struct v2f
            {
                float4 pos:POSITION;
                fixed4 color:COLOR;
            };

            v2f vert(appdata_base v)
            {
                //简谐运动公式 A*sin(w*x+t)

                //旗帜波
//                v.vertex.y+=0.2*sin(v.vertex.x+_Time.y);

                //涟漪
//                v.vertex.y+=0.2*sin(-length(v.vertex.xz)*2+_Time.y);

                //水波
                v.vertex.y+=0.2*sin((v.vertex.x+v.vertex.z)+_Time.y);
                v.vertex.y+=0.3*sin((v.vertex.x-v.vertex.z)+_Time.w);


                v2f o;
                o.pos=UnityObjectToClipPos(v.vertex);
                o.color=fixed4(v.vertex.y,v.vertex.y,v.vertex.y,1);
                return o;
            }
            float4 frag(v2f IN):COLOR
            {
                return IN.color;
            }

            ENDCG
        }
    }
}

5、漫反射+环境光

复制代码
Shader "Custom/Example_4" {
    Subshader
    {
        pass{
            tags{"LightMode"="Forwardbase"}

            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag
            #include "unitycg.cginc"
            #include "lighting.cginc"
            struct v2f
            {
                float4 pos:POSITION;
                fixed4 color:COLOR;
            };

            //利用顶点程序计算光照执行效率高,片段程序计算光照略慢但更细腻平滑
            v2f vert(appdata_base v)
            {
                v2f o;
                o.pos=UnityObjectToClipPos(v.vertex);

                float3 N=normalize(v.normal);//归一化顶点的法向量
                float3 L=normalize(_WorldSpaceLightPos0);//归一化光线

                //法向量和光向量需要处于同一个坐标空间
                N=mul(float4(N,0),unity_WorldToObject).xyz;//方案一,将法向量变换到世界空间
                N=normalize(N);//还需再规范化一下

//                L=mul(unity_WorldToObject,float4(L,0)).xyz;//方案二,将光向量变换到模型空间


                float NdotL=saturate(dot(N,L));//点乘得到向量N,L的余弦值,saturate得到0-1的值,负数为0
                o.color=_LightColor0*NdotL;//得到光照强度

                //添加点光源光照
                float3 wpos=mul(unity_ObjectToWorld,v.vertex).xyz;
                o.color.rgb+=Shade4PointLights(
                    unity_4LightPosX0,unity_4LightPosY0,unity_4LightPosZ0,
                    unity_LightColor[0].rgb,unity_LightColor[1].rgb,
                    unity_LightColor[2].rgb,unity_LightColor[3].rgb,
                    unity_4LightAtten0,
                    wpos,N
                );

                return o;
            }
            float4 frag(v2f IN):COLOR
            {
                return IN.color+UNITY_LIGHTMODEL_AMBIENT;//漫反射+环境光
            }

            ENDCG
        }
    }
}
复制代码

 6、高光

复制代码
Shader "Custom/Example_5" {
    Subshader
    {
        pass{
            tags{"LightMode"="Forwardbase"}

            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag
            #include "unitycg.cginc"
            #include "lighting.cginc"
            struct v2f
            {
                float4 pos:POSITION;
                fixed4 color:COLOR;
            };

            //利用顶点程序计算光照执行效率高,片段程序计算光照略慢但更细腻平滑
            v2f vert(appdata_base v)
            {
                v2f o;
                o.pos=UnityObjectToClipPos(v.vertex);

                float3 N=normalize(v.normal);//归一化顶点的法向量
                float3 L=normalize(_WorldSpaceLightPos0);//归一化光线

                //法向量和光向量需要处于同一个坐标空间
                N=mul(float4(N,0),unity_WorldToObject).xyz;//方案一,将法向量变换到世界空间
                N=normalize(N);//还需再规范化一下

                //Diffuse Color漫反射
                float NdotL=saturate(dot(N,L));//点乘得到向量N,L的余弦值,saturate得到0-1的值,负数为0
                o.color=_LightColor0*NdotL;//得到光照强度

                //Specular Color高光
                float3 I=-WorldSpaceLightDir(v.vertex);
                float3 R=reflect(I,N);//I为入射光,N是顶点法向量
                float3 V=WorldSpaceViewDir(v.vertex);//摄像机到顶点的方向
                R=normalize(R);
                V=normalize(V);
                float specularScale=pow(saturate(dot(R,V)),10);//向量R和向量V之间的夹角,指数形式衰减

                o.color.rgb+=_LightColor0*specularScale;
                return o;
            }
            float4 frag(v2f IN):COLOR
            {
                return IN.color+UNITY_LIGHTMODEL_AMBIENT;//漫反射+环境光
            }

            ENDCG
        }
    }
}
复制代码
原文地址:https://www.cnblogs.com/Jason-c/p/8550078.html