课时27 Vertex Shader - 顶点数据的输入与输出 1

  • 课时27 Vertex Shader - 顶点数据的输入与输出 1

1.一个函数有多个重复语义输出会报错,如果需要多输出的话,除了POSITION和COLOR,float2格式的TEXCOORD系列也可以。

2.POSITION语义的向量,第四个分量不能为0。

3.语义是为了方便函数间传递信息,函数内部可以对不同语义但相同类型的变量进行操作。

  • 课时28 Vertex Shader - 顶点数据的输入与输出 2

Shader "Custom/Lesson28"
{
	//课时28 Vertex Shader - 顶点数据的输入与输出 2
	SubShader
	{
		Pass
		{
			CGPROGRAM  
			#pragma vertex vert
			#pragma fragment frag 

			//需要使用前定义
			//可以使用c语言风格,一般用不到
			typedef struct{
				float4 pos:PoSITION;
				float2 objPos:TEXCOORD0;
				fixed4 col:COLOR;
			}v2f;
			//返回值为自定义结构体时,不需要语义
			v2f  vert (in float2 objPos:POSITION)
			{
				v2f o;
				o.pos=float4(objPos,0,1);
				o.objPos=float2(1,0);
				o.col=float4(0,1,0,1);
				return o; 
			}
			 
			fixed4 frag (v2f IN):COLOR
			{
				return IN.col;
			} 
			//片元程序可以不用v2f结构接收也可以(输入输出语义相同即可)
			//接收一个顶点程序没有赋值的参数,比如COLOR,会收到默认值白色
			fixed4 frag111 (in float2 opos:TEXCOORD0, in float4 col:COLOR):COLOR  
			{
				// col=(0,0,0,1);
				// return col;
				return col;
				return fixed4(opos,0,1);
			} 
			
			ENDCG
		}
	}
}

效果:

  • 课时29 Vertex Shader - 更好的数据组织方式struct

Shader "Custom/Lesson29"
{
	//课时29 Vertex Shader - 更好的数据组织方式struct
	SubShader
	{
		Pass
		{
			CGPROGRAM  
			#pragma vertex vert
			#pragma fragment frag 

			//需要使用前定义
			//可以使用c语言风格,一般用不到
			//一般不会定义在cginc中
			typedef struct{
				float4 pos:PoSITION;
				float2 objPos:TEXCOORD0;
				fixed4 col:COLOR;
			}v2f;

			//可以声明在自定义cginc文件中(UnityCG.cginc已包含appdata_base,appdata_tan,appdata_full)
			struct appdata_base{
				float2 pos:POSITION;
				float4 col:COLOR;
			};

			//顶点函数的输入和输出都可以用结构体
			v2f  vert (appdata_base v)
			{
				v2f o;
				o.pos=float4(v.pos,0,1);
				o.objPos=float2(1,0);
				o.col=v.col;//使用模型顶点颜色(默认白色)作为返回
				return o; 
			}
			 
			fixed4 frag (v2f IN):COLOR
			{
				return IN.col;
			} 
			ENDCG
		}
	}
}

效果:

  • 课时30 Vertex Shader - Uniform 与 properties属性

Shader "Custom/Lesson30"
{
	//课时30 Vertex Shader - Uniform 与 properties属性
	Properties{
		_MainColor("Main Color",color)=(1,1,1,1)
		// _MainTex("Texture",2D)="white"{}
	}
	SubShader
	{
		Pass
		{
			CGPROGRAM  
			#pragma vertex vert
			#pragma fragment frag 
			
			//需要在CG代码块中重新声明
			//类型需要变化
			float4 _MainColor;
			//uniform需要在C#中赋值,默认黑色
			//赋值语句:GetComponent<Renderer>().material.SetVector("_SecondColor",new Vector4(1,0,0,1));
			uniform float4 _SecondColor;


			//需要使用前定义
			//可以使用c语言风格,一般用不到
			//一般不会定义在cginc中
			typedef struct{
				float4 pos:PoSITION;
				float2 objPos:TEXCOORD0;
				fixed4 col:COLOR;
			}v2f;

			//可以声明在自定义cginc文件中(UnityCG.cginc已包含appdata_base,appdata_tan,appdata_full)
			struct appdata_base{
				float2 pos:POSITION;
				float4 col:COLOR;
			};

			//顶点函数的输入和输出都可以用结构体
			v2f  vert (appdata_base v)
			{
				v2f o;
				o.pos=float4(v.pos,0,1);
				o.objPos=float2(1,0);
				o.col=v.col;//使用模型顶点颜色(默认白色)作为返回
				return o; 
			}
			 
			fixed4 frag (v2f IN):COLOR
			{
				// return _MainColor*_SecondColor;
				// return _MainColor*0.5+0.5*_SecondColor;
				return lerp(_MainColor,_SecondColor,0.7);
			} 
			 
			ENDCG
		}
	}
}

效果:

  • 课时31 Vertex Shader - 几何变换 —MVP矩阵变换 1

Shader "Custom/Lesson31"
{
	//课时31 Vertex Shader - 几何变换 —MVP矩阵变换 1
	SubShader
	{
		Pass
		{
			CGPROGRAM  
			#pragma vertex vert
			#pragma fragment frag 
			#include "unitycg.cginc"
			
			float4x4 mvp;//uniform可有可无
			 
			struct v2f{
				float4 pos:PoSITION; 
			};
 
			//顶点函数的输入和输出都可以用结构体
			v2f  vert (appdata_base v)
			{
				v2f o;
				//变换矩阵,见https://docs.unity3d.com/Manual/SL-BuiltinFunctions.html
				// o.pos=UnityObjectToClipPos(v.vertex);
				o.pos=mul(mvp,v.vertex);
				return o; 
			}
			  
			fixed4 frag ():COLOR
			{  
				return fixed4(1,1,1,1);
			} 
			 
			ENDCG
		}
	}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//自己写MVP变换
public class MVPTransform : MonoBehaviour {
	// Update is called once per frame
	void Update () {

		// Matrix4x4 mvp=transform.localToWorldMatrix*Camera.main.worldToCameraMatrix*Camera.main.projectionMatrix;
		//正确顺序:与uniform中相反
		Matrix4x4 mvp=Camera.main.projectionMatrix*Camera.main.worldToCameraMatrix*transform.localToWorldMatrix;
		GetComponent<Renderer>().material.SetMatrix("mvp",mvp);
	}
}

效果:场景视图的效果不正确,不用管,因为代码中用的是游戏摄像机进行变换。

  • 课时32 Vertex Shader - 几何变换 —MVP矩阵变换 2

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/Lesson32"
{
	//课时32 Vertex Shader - 几何变换 —MVP矩阵变换 2
	SubShader
	{
		Pass
		{
			CGPROGRAM  
			#pragma vertex vert
			#pragma fragment frag 
			#include "unitycg.cginc"
			
			float4x4 mvp;//uniform可有可无
			float4x4 rm;//旋转矩阵
			float4x4 sm;//缩放矩阵
			 
			struct v2f{
				float4 pos:PoSITION; 
			};
 
			//顶点函数的输入和输出都可以用结构体
			v2f  vert (appdata_base v)
			{
				v2f o;
				o.pos=mul(rm,v.vertex);//绕y轴旋转
				o.pos=mul(sm,o.pos);//缩放
				// o.pos=mul(mvp,o.pos);
				o.pos=UnityObjectToClipPos(o.pos);
				return o; 
			}
			  
			fixed4 frag ():COLOR
			{  
				return fixed4(1,1,1,1);
			} 
			 
			ENDCG
		}
	}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//自己写MVP变换
//使模型渲染过程中自旋转
public class MVPTransform_Lesson32 : MonoBehaviour {
	// Update is called once per frame
	void Update () {

		//旋转矩阵,绕y轴旋转。注:shader中不能用四元数
		Matrix4x4 RM=new Matrix4x4();
		RM[0,0]=Mathf.Cos(Time.realtimeSinceStartup);
		RM[0,2]=Mathf.Sin(Time.realtimeSinceStartup);
		RM[1,1]=1;
		RM[2,0]=-Mathf.Sin(Time.realtimeSinceStartup);
		RM[2,2]=Mathf.Cos(Time.realtimeSinceStartup);
		RM[3,3]=1;

		//缩放矩阵
		Matrix4x4 SM=new Matrix4x4();
		SM[0,0]=Mathf.Sin(Time.realtimeSinceStartup)/4+0.5f;
		SM[1,1]=Mathf.Cos(Time.realtimeSinceStartup)/8+0.5f;
		SM[2,2]=Mathf.Sin(Time.realtimeSinceStartup)/6+0.5f;
		SM[3,3]=1;


		//MVP矩阵
		Matrix4x4 mvp=Camera.main.projectionMatrix*Camera.main.worldToCameraMatrix*transform.localToWorldMatrix;

		GetComponent<Renderer>().material.SetMatrix("rm",RM);//设置自定义旋转矩阵
		GetComponent<Renderer>().material.SetMatrix("sm",SM);//设置自定义缩放矩阵
		// GetComponent<Renderer>().material.SetMatrix("mvp",mvp);//设置自定义mvp
	}
}

效果:

  • 课时33 Vertex Shader - 几何变换 —顶点颜色变换 1


Shader "Custom/Lesson33"
{
	//课时33 Vertex Shader - 几何变换 —顶点颜色变换 1
	SubShader
	{
		Pass
		{
			CGPROGRAM  
			#pragma vertex vert
			#pragma fragment frag 
			#include "unitycg.cginc"
			
			float4x4 mvp;//uniform可有可无
			float4x4 rm;//旋转矩阵
			float4x4 sm;//缩放矩阵
			 
			struct v2f{
				float4 pos:PoSITION; 
				fixed4 color:COLOR;
			};
 
			v2f  vert (appdata_base v)
			{
				v2f o;
				// o.pos=mul(rm,v.vertex);//绕y轴旋转
				// o.pos=mul(sm,o.pos);//缩放
				// o.pos=mul(mvp,o.pos);
				o.pos=UnityObjectToClipPos(v.vertex);

				//-------指定模型空间位于模型坐标中心两侧的颜色--------
				// if(v.vertex.x>0)
				// {
				// 	o.color=fixed4(1,0,0,1);
				// }else
				// {
				// 	o.color=fixed4(0,0,1,1);
				// }
				//-------end--------

				//-------指定模型空间某个顶点的颜色--------
				if(v.vertex.x==0.5 && v.vertex.y==0.5 && v.vertex.z==0.5)
				{
					o.color=fixed4(_SinTime.w/2+0.5,_CosTime.w/2+0.5,_SinTime.y/2+0.5,1);//_SinTime.w范围-1~1
				}else
				{
					o.color=fixed4(0,0,1,1);
				}
				//-------end--------

				//-------指定世界空间位于原点两侧的颜色--------
				// float3 wpos=mul(unity_ObjectToWorld,v.vertex);//新版unity中, _Object2World 替换为 unity_ObjectToWorld
				// if(wpos.x>0)
				// {
				// 	o.color=fixed4(1,0,0,1);
				// }else
				// {
				// 	o.color=fixed4(0,0,1,1);
				// }
				//-------end--------

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

效果:

  • 课时34 Vertex Shader - 几何变换 —顶点颜色变换 2


Shader "Custom/Lesson34"
{
	//课时34 Vertex Shader - 几何变换 —顶点颜色变换 2
	SubShader
	{
		Pass
		{
			CGPROGRAM  
			#pragma vertex vert
			#pragma fragment frag 
			#include "unitycg.cginc"

			float dis;//uniform可有可无
			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;
				if(x>dis && x<dis+r)
				 	o.color=fixed4(1,0,0,1);
				else if(x>=1)
					o.color=fixed4(0,0,1,1);
				else
					o.color=fixed4(x/2+0.5,x/2+0.5,x/2+0.5,1);
				//--------end--------
				return o; 
			}
			  
			fixed4 frag (v2f IN):COLOR
			{  
				return IN.color;
			} 
			 
			ENDCG
		}
	}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SetFloat : MonoBehaviour {
	private float dis=-1;
	private float r=0.1f; 
	// Update is called once per frame
	void Update () {
		dis+=Time.deltaTime*0.1f;
		GetComponent<Renderer>().material.SetFloat("dis",dis);
		GetComponent<Renderer>().material.SetFloat("r",r);
	}
}

效果:

  • 课时35 Vertex Shader - 几何变换 —顶点位移


Shader "Custom/Lesson35"
{
	//课时35 Vertex Shader - 几何变换 —顶点位移
	Properties{
		_R ("R" , range(0,5))=1
		_OX("OX",range(-5,5))=0
	}
	SubShader
	{
		Pass
		{
			CGPROGRAM  
			#pragma vertex vert
			#pragma fragment frag 
			#include "unitycg.cginc"

			float dis;
			float r;
			float _R;
			float _OX;

 			struct v2f{
				float4 pos:PoSITION; 
				fixed4 color:COLOR;
			};
 
			v2f  vert (appdata_base v)//参数传递用的值拷贝
			{
				//顶点变换要在齐次变换之前进行
				float4 wpos=mul(unity_ObjectToWorld,v.vertex);//求得世界空间坐标值
				
				float2 xy=wpos.xz;//xy是世界空间二维向量
				float d=_R-length(xy-float2(_OX,0));//求得与世界坐标系原点的距离的反比

				d=d<0?0:d;
				float height=1*d; 
				float4 uppos=float4(v.vertex.x,height,v.vertex.z,v.vertex.w);//求得模型坐标系下改变y轴的值

				v2f o; 
				o.pos=UnityObjectToClipPos(uppos);//齐次空间坐标 

				o.color=fixed4(uppos.y,uppos.y,uppos.y,1);

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

效果:几个拼接的模型做顶点位移

  • 课时36 Vertex Shader - 几何变换 —扭曲


Shader "Custom/Lesson36"
{
	//课时36 Vertex Shader - 几何变换 —扭曲
 	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) 
			{
				v2f o; 
				float angle=length(v.vertex)*_SinTime.w;

				//---------------常规旋转计算---------------------
				// 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);
				//----------------end--------------------

				//----------------简化后的旋转计算--------------------
				// float x=cos(angle)*v.vertex.x+sin(angle)*v.vertex.z;
				// float z=cos(angle)*v.vertex.z-sin(angle)*v.vertex.x;
				// v.vertex.x=x;
				// v.vertex.z=z;
				//----------------end--------------------

				//---------------常规缩放计算---------------------
				// 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);
				//----------------end--------------------

				//---------------简化后的缩放计算---------------------
				angle=v.vertex.z+_Time.y;
				v.vertex.x=(sin(angle)/8+0.5)*v.vertex.x;
				//----------------end--------------------

				o.pos=UnityObjectToClipPos(v.vertex);//齐次空间坐标 

				o.color=fixed4(0,1,1,1);

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

效果:

  • 课时37 Vertex Shader - 几何变换 —波

课前知识准备:正弦曲线可表示为y=Asin(ωx+φ)+k,定义为函数y=Asin(ωx+φ)+k在直角坐标系上的图象,其中sin为正弦符号,x是直角坐标系x轴上的数值,y是在同一直角坐标系上函数对应的y值,k、ω和φ是常数(k、ω、φ∈R且ω≠0)

A——振幅,当物体作轨迹符合正弦曲线的直线往复运动时,其值为行程的1/2。

(ωx+φ)——相位,反映变量y所处的状态。

φ——初相,x=0时的相位;反映在坐标系上则为图像的左右移动。

k——偏距,反映在坐标系上则为图像的上移或下移。

ω——角速度, 控制正弦周期(单位弧度内震动的次数)。

Shader "Custom/Lesson37"
{
	//课时37 Vertex Shader - 几何变换 —波
 	SubShader
	{
		Pass
		{
			CGPROGRAM    
			#include "unitycg.cginc" 
			#pragma vertex vert
			#pragma fragment frag

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

 
			v2f  vert (appdata_base v) 
			{
				//=============常规缩放方式(y轴为0,无效)====================
				// float up=sin(v.vertex.x)+_Time.y;
				// float4x4 m={
				// 	float4(1,0,0,0),
				// 	float4(0,sin(up)/8+0.5,0,0),
				// 	float4(0,0,1,0),
				// 	float4(0,0,0,1)
				// };
				// v.vertex=mul(m,v.vertex);
				//============end=====================

				//=============正弦波横波方式====================
				// v.vertex.y+=0.2*sin(v.vertex.z*2+_Time.y);
				//============end=====================

				//=============正弦波中心点向外扩散方式====================
				// v.vertex.y+=0.2*sin(-length(v.vertex.xz)+_Time.y);
				//============end=====================

				//=============正弦波xz方向分布式方式====================
				v.vertex.y+=0.2*sin(-length(v.vertex.x+v.vertex.z)+_Time.y);
				v.vertex.y+=0.3*sin(-length(v.vertex.x-v.vertex.z)+_Time.w);
				//============end=====================


				v2f o; 
				o.pos=UnityObjectToClipPos(v.vertex);//齐次空间坐标 

				o.color=fixed4(v.vertex.y,v.vertex.y,v.vertex.y,1);

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

效果:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值