///////////////////////////////////////////////卷轴//////////////////////////////////////////////////
实现原理:
还记得中学数学中圆的公式吗,就是利用这个公式计算坐标,然后实时的平移坐标轴,来完成一个圆的平移
具体做法:
1. 在一个圆中,假设圆心为坐标轴原点,那么,一个弧长对应的角度的正弦和余弦值分别可以表示水平和垂直方向上面的分量
2.角度的求法, 弧长 / 半径 = 弧度 弧度 / 2π = 角度 / 360 幸运的是,在CG函数中本来就是用的弧度作为输入参数的,所以这部分可以忽略
3.坐标轴原点的平移。将坐标轴原点作为一个变量,其实就是水平方向X上面的变量实时的计算,垂直方向Y上面不变。
using UnityEngine;
using System.Collections;
using DG.Tweening;
public class CreatPlane : MonoBehaviour
{
public Texture2D texture;
public Texture2D texture2;
public int sizeX;
public int sizeY;
public float radius;
private Material m_Material;
// Use this for initialization
void Start ()
{
Vector3[] vertices = new Vector3[sizeX * sizeY];
Vector2[] UV = new Vector2[sizeX * sizeY];
for (int y = 0; y < sizeY; y++)
{
for (int x = 0; x < sizeX; x++)
{
vertices[y * sizeX + x] = new Vector3(x * 10.0f / (sizeX - 1), 0, y * ((float)sizeY/sizeX) *10.0f / (sizeY - 1));
UV[y * sizeX + x] = new Vector2(x * 1.0f / (sizeX - 1), y * 1.0f / (sizeY - 1));
}
}
Mesh mesh = new Mesh();
mesh.vertices = vertices;
mesh.triangles = GetTriangles();
mesh.uv = UV;
gameObject.AddComponent
m_Material = new Material(Shader.Find("Unlit/Test"));
m_Material.SetTexture("_MainTex", texture);
m_Material.SetTexture("_SecTex", texture2);
m_Material.SetFloat("_Radius", radius);
m_Material.SetFloat("_MaxX", 10.0f);
gameObject.AddComponent
Vector3[] vertexs = GetComponent
}
private int[] GetTriangles()
{
int index = 0;
int[] tPolys = new int[(sizeX - 1) * (sizeY - 1) * 6];
for (int y = 0; y < sizeY - 1; y++)
{
for (int x = 0; x < sizeX - 1; x++)
{
tPolys[index++] = (y * sizeX) + x;
tPolys[index++] = ((y + 1) * sizeX) + x;
tPolys[index++] = (y * sizeX) + x + 1;
tPolys[index++] = ((y + 1) * sizeX) + x;
tPolys[index++] = ((y + 1) * sizeX) + x + 1;
tPolys[index++] = (y * sizeX) + x + 1;
}
}
return tPolys;
}
// Update is called once per frame
void Update ()
{
}
public void SetValue(float value)
{
m_Material.DOFloat(value, "_Progress", 1);
}
}
Shader "Unlit/Test"
{
Properties
{
_MainTex ("MainTex", 2D) = "white" {}
_SecTex ("SecTex", 2D) = "white" {}
_Radius("Radius",float) = 0
_Progress("Progress",Range(0,1)) = 0
_MaxX("MaxX",float) = 0
}
SubShader
{
Tags
{
"Queue" = "Transparent"
"RenderType"="Transparent"
}
Pass
{
Blend SrcAlpha OneMinusSrcAlpha
Cull Back
ZWrite On
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _Radius,_Progress,_MaxX;
v2f vert (appdata_base v)
{
float primeter = 2 * UNITY_PI * _Radius;
float x = v.vertex.x;
float centerX = _MaxX * _Progress * 0.9;
if(x < centerX && centerX < primeter)
{
float radian = (centerX - x)/_Radius;
v.vertex.x = centerX - sin(radian) * _Radius;
v.vertex.y = _Radius - cos(radian) * _Radius;
}
else if(x < centerX && centerX > primeter)
{
if(x < centerX - primeter)
{
v.vertex.x = centerX;
}
else
{
float radian = (primeter - (x - (centerX - primeter)))/_Radius;
v.vertex.x = centerX - sin(radian) * _Radius;
v.vertex.y = _Radius - cos(radian) * _Radius;
}
}
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
float s;
float c;
sincos(radians(90),s,c);
float2x2 rotate={
c,-s,
s,c
};
// sample the texture
fixed4 col = tex2D(_MainTex, mul(rotate,i.uv));
return col;
}
ENDCG
}
Pass
{
Blend SrcAlpha OneMinusSrcAlpha
Cull Front
ZWrite On
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _SecTex;
float4 _SecTex_ST;
float _Radius,_Progress,_MaxX;
v2f vert (appdata_base v)
{
float primeter = 2 * UNITY_PI * _Radius;
float x = v.vertex.x;
float centerX = _MaxX * _Progress * 0.9;
if(x < centerX && centerX < primeter)
{
float radian = (centerX - x)/_Radius;
v.vertex.x = centerX - sin(radian) * _Radius;
v.vertex.y = _Radius - cos(radian) * _Radius;
}
else if(x < centerX && centerX > primeter)
{
if(x < centerX - primeter)
{
v.vertex.x = centerX;
}
else
{
float radian = (primeter - (x - (centerX - primeter)))/_Radius;
v.vertex.x = centerX - sin(radian) * _Radius;
v.vertex.y = _Radius - cos(radian) * _Radius;
}
}
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _SecTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
float s;
float c;
sincos(radians(90),s,c);
float2x2 rotate={
c,-s,
s,c
};
// sample the texture
fixed4 col = tex2D(_SecTex, mul(rotate,i.uv));
return col;
}
ENDCG
}
}
}
/////////////////////////////////////////////////////////橡皮效果////////////////////////////////////////////////////////////////////
堡垒之夜,里面敲击建筑时有橡皮那种弹弹弹的效果
最终效果
思路
源代码
[AppleScript] 纯文本查看 复制代码
?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
|
脚本
[AppleScript] 纯文本查看 复制代码
?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
|
/////////////////////////////////////////////////////////Shader能量护盾////////////////////////////////////////////////////////////////////
利用场景的深度信息——能量护盾
利用场景的深度信息可以做一些很有趣的效果,比如 能量护盾~ 这个效果虽然不算复杂但是很多游戏里面有有应用,看起来也够炫酷。而利用深度信息还可以做很多其他的效果。以后有空慢慢更新吧………… 下面正题 这个效果分为三个部分: 半透效果 最简单的一部分,但需要一些关于shader的常识性知识。 shader设置 逐句分析: Cull Off 关闭背面剪裁。因为是要半透的自然可以看到背面,因此需要关闭背面剪裁 ZWrite Off 关闭Z缓存写入。因为护盾本身是不会“遮挡”到其他物体的,因此关闭。这里的遮挡需要理解渲染管线的Z缓存原理。 ZTest On 开启Z缓存测试。护盾需要被其他物体所“遮挡”。同上需要理解Z缓存。 Blend SrcAlpha OneMinusSrcAlpha 混合方式 Alpha混合。意思是用Alpha的值来控制计算颜色和颜色缓存中的值进行混合。(混合的方法有很多具体可查阅相关文档) 然后在ps里瞎鸡儿做个护盾样子的图采样就行了~(其实可以弄个GrabPass然后加个噪音扰动弄出能量扭曲空间的效果)。这里偷个懒就不搞了~ 护盾贴图 边缘高亮 法线方向和视角的方向差异越大就说明越靠近边缘,再加个参数用来调整。
ps:可以在顶点着色器里获得法线和视角方向以减少计算量,在片段着色器里使用的时候记得归一化。
获取法线和视角方向 相交高亮 这就是关键了。 现在顶点着色器里获得对应的场景坐标 随后在片段着色器里用场景坐标对深度图进行采样
需要注意的是:这里的_CameraDepthTexture需要在前面提前声明。 我们用自身的坐标和场景深度相减。得到的值小于一定范围就认为是和场景相交的部分了。 最后使用高亮的系数对根据贴图采样的颜色和高亮的颜色进行插值得到了最终的颜色值。 下面是代码: [AppleScript] 纯文本查看 复制代码 ?
|