本文给大家介绍几个Vertex Shader中常用的几何变换
如果是刚开始接触几何变换内容学起来是比较吃力的!
这种思维需要不断的磨合、锻炼
对于Shader几何变换我总结成了4个字:并行、时差
并行:
渲染管线是一系列并行的渲然流水线。通俗来说,每个顶点的计算是同时的。
时差:
每个顶点会不断的计算(包括颜色、位置等等)。
总而言之:并行是指全部顶点同时计算,时差是指每个顶点不断的计算。
接下来介绍下几个常用的几何变换
一、顶点旋转几何变换
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
//顶点旋转
Shader "Custom/RotateShader"
{
Properties
{
_RotateSpeed("RotateSpeed",range(0,500))=5
}
SubShader
{
pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
float _RotateSpeed;
struct a2v
{
float4 position:POSITION;
};
a2v vert(appdata_base v)
{
a2v paratem;
float l = length(v.vertex);
float3x3 rotateM =
{
float3(sin(l+_Time.w*_RotateSpeed),0,-cos(l+_Time.w*_RotateSpeed)),
float3(0,1,0),
float3(cos(l+_Time.w*_RotateSpeed), 0, sin(l+_Time.w*_RotateSpeed)),
};
float3 position = mul(rotateM,v.vertex);
paratem.position = UnityObjectToClipPos(position);
return paratem;
}
fixed4 frag():COLOR
{
return fixed4(0.5,0.5,0.5,1);
}
ENDCG
}
}
FallBack "Diffuse"
}
效果图:
二、地形几何变换
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
//地形
Shader "Custom/MountainShader"
{
Properties
{
_Redium("Redium",float)=5
_OriginX("OriginX",float)=5
_OriginY("OriginY",float)=5
}
SubShader
{
pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
float _Redium;
float _OriginX;
float _OriginY;
void vert(appdata_base v,out float4 position:SV_POSITION)
{
//将顶点的世界坐标转化为世界坐标
float4 wordVertex=mul(unity_ObjectToWorld,v.vertex);
//计算坡度
float height=_Redium-length(v.vertex.xz-float2(_OriginX,_OriginY));
height=height>=0?height:0;
float4 newPos=float4(v.vertex.x,height,v.vertex.z,v.vertex.w);
position=UnityObjectToClipPos(newPos) ;
}
fixed4 frag(in float4 position:SV_POSITION):COLOR
{
return fixed4(0,0.8,0,1);
}
ENDCG
}
}
FallBack "Diffuse"
}
效果图:
三、扭曲几何变换
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
//扭曲
Shader "Custom/TwistShader"
{
Properties
{
}
SubShader
{
pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
void vert(appdata_base v,out float4 position:SV_POSITION)
{
float weight=v.vertex.z+_Time.y;
v.vertex.x=v.vertex.x*(cos(weight)/8+0.5);
position=UnityObjectToClipPos(v.vertex);
}
fixed4 frag(in float4 position:SV_POSITION):COLOR
{
return fixed4(0,0.8,0,1);
}
ENDCG
}
}
FallBack "Diffuse"
}
效果图:
四、水波几何变换
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
//水波
Shader "Custom/Wave01Shader"
{
Properties
{
}
SubShader
{
pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
void vert(appdata_base v,out float4 position:SV_POSITION)
{
//改变高度
v.vertex.y=sin(_Time.y+v.vertex.x);
position=UnityObjectToClipPos(v.vertex);
}
fixed4 frag():COLOR
{
return fixed4(0,0.8,0,1);
}
ENDCG
}
}
FallBack "Diffuse"
}
效果图:略
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
//地形
Shader "Custom/Wave02Shader"
{
Properties
{
}
SubShader
{
pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
void vert(appdata_base v,out float4 position:SV_POSITION)
{
//改变高度
v.vertex.y+=0.2*sin( -length(v.vertex.xz)*2+_Time.y);
position=UnityObjectToClipPos(v.vertex);
}
fixed4 frag():COLOR
{
return fixed4(0,0.8,0,1);
}
ENDCG
}
}
FallBack "Diffuse"
}
效果图:
总结:
一、知道渲染管线流水线(并行、时差)
二、appdata_base中的v.vertex是顶点原始位置