Unity Shader 之 简单实现折叠平面(翻书)的效果
目录
Unity Shader 之 简单实现折叠平面(翻书)的效果
一、简单介绍
Shader Language的发展方向是设计出在便携性方面可以和C++、Java等相比的高级语言,“赋予程序员灵活而方便的编程方式”,并“尽可能的控制渲染过程”同时“利用图形硬件的并行性,提高算法效率”。
本文介绍,实现在Y 方向上,被地面吸收或者从地面生成的简单效果。
二、实现原理
1、首先确定一个折叠位置点
2、然后根据圆的参数方程公式:x=a+rcosθ,y=b+rsinθ(θ∈[0,2π))(a,b)为圆心坐标,r为圆半径,θ为参数,求得 x ,y
3、分两个 pass 通道渲染前面和背面
三、注意事项
1、好像只有 Plane 好使;(使用 Quad,和RawImage 和Image,把 y 改为 z 效果也不是很对)
2、效果根据实际情况调整
四、效果预览
五、实现步骤
原理图示:
具体步骤:
1、打开Unity,新建一个工程
2、在工程中,新建一个Shader,并新建对应材质,导入两张图片
3、场景中添加一个 plane
4、把材质赋给 Plane ,并添加对应图
5、运行场景,效果如上
六、关键代码
Shader "Unlit/ShaderPaperFold"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_BackTex("背景图",2D)="white"{}
_FoldPos("折叠位置", float) = 5
_FoldAngle("折叠角度",Range(1,180)) = 90
[Toggle(ENABLE_DOUBLE)]_DoubleFold("是否进行双面折叠", float) = 0
}
SubShader
{
Tags{"Queue"="Transparent" "RenderType"="Transparent"}
pass{
ZWrite on
Cull Back
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature ENABLE_DOUBLE
#include "UnityCG.cginc"
struct v2f{
float4 vertex:SV_POSITION;
float2 uv:TEXCOORD0;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _FoldPos,_FoldAngle;
v2f vert(appdata_base v){
float angle = _FoldAngle;
float r = _FoldPos - v.vertex.x;
#if ENABLE_DOUBLE
if(r<=0){
angle = 360 - _FoldAngle;
}
#else
if(r<=0){
angle = 1;
}
#endif
v.vertex.x = _FoldPos + r * cos(angle * UNITY_PI/180);
v.vertex.y = r * sin(angle * UNITY_PI / 180) ;
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
fixed4 frag(v2f i):SV_Target{
fixed4 col = tex2D(_MainTex, i.uv);
return col;
}
ENDCG
}
pass{
ZWrite on
Cull Front
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature ENABLE_DOUBLE
#include "UnityCG.cginc"
struct v2f{
float4 vertex:SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _BackTex;
float4 _BackTex_ST;
float _FoldPos,_FoldAngle;
v2f vert(appdata_base v){
float angle = _FoldAngle;
float r = _FoldPos - v.vertex.x;
#if ENABLE_DOUBLE
if(r<=0){
angle = 360 - _FoldAngle;
}
#else
if(r<=0){
angle = 1;
}
#endif
v.vertex.x = _FoldPos + r * cos(angle * UNITY_PI/180);
v.vertex.y = r * sin(angle * UNITY_PI/180);
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX( v.texcoord, _BackTex);
return o;
}
fixed4 frag(v2f i):SV_Target{
fixed4 col = tex2D(_BackTex,i.uv);
return col;
}
ENDCG
}
}
FallBack "diffuse"
}