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
}
}
}
博客园Jason_c微信打赏码
如果本篇文档对你有帮助,打赏Jason_c根华子吧,他的私房钱被老婆没收了,呜呜!

浙公网安备 33010602011771号