模型淡出Shader实现
来源:互联网 发布:ipadmini2怎么下载软件 编辑:程序博客网 时间:2024/06/06 01:30
一些特殊的动画,在unity中并不能使用。最近需要实现一种线条慢慢生长的过程,从无到有,还要掉头。这种动画貌似可以使用一些插件来使用,但想想更好的方案就是利用Shader来实现,虽然学习Shader很长时间了,但具体用它来做功能的项目还是比较少。这也算是个相对简单的Shader,其中用到的算法也比较初级,但基本功能也初步实现了,故mark一下。
方案
1.以空物体做标记记录关键点
如下图所示,如果模型有多个转弯的点,就可以制作多少个节点,不只局限于cube,可以是很多弯头的线。
2.以线为轴心计算相对半径
利用脚本将当前进度的点的列表传入到Shader中,然后判断是否满足渲染的要求。
3.舍去不在区域内的像素
在半径内的点渲染出来,不在半径内的点舍去
源码
using System;using UnityEngine;using System.Collections;public class ClipLine : MonoBehaviour{ public string matName; public float speed = 0.2f; public bool once = true; public float span = 0.01f; private Material mat; private float lastdistence; private float distenceAll; private float distence; private Vector4[] posList; private float[] distenceList; private int count; void Start() { Renderer render = GetComponent<Renderer>(); if (string.IsNullOrEmpty(matName)) { mat = render.material; } else { mat = Array.Find<Material>(render.materials, x => x.name == matName); } if (!mat || transform.childCount < 2) { this.enabled = false; } else { distenceList = new float[transform.childCount - 1]; for (int i = 0; i < transform.childCount; i++) { if (i > 0) { distenceList[i - 1] = Vector3.Distance(transform.GetChild(i - 1).position, transform.GetChild(i).position); distenceAll += distenceList[i - 1]; } } } } void Update() { distence += Time.deltaTime * speed; if (distence > distenceAll) { distence = 0; if (once) { mat.SetInt("_Count", 0); enabled = false; return; } } if (Mathf.Abs(distence - lastdistence) > 0.01f) { CalcutPoistionList(); OnPositionChanged(); lastdistence = distence; } } void CalcutPoistionList() { float distenceTemp = 0f; count = 1; for (int i = 0; i < distenceList.Length; i++) { count++; distenceTemp += distenceList[i]; if (distenceTemp > distence) { distenceTemp -= distenceList[i]; break; } } posList = new Vector4[20]; int index = 0; for (; index < count - 1; index++) { posList[index] = transform.GetChild(index).localPosition; posList[index].w = 1; } posList[index] = Vector4.Lerp(transform.GetChild(index - 1).localPosition, transform.GetChild(index).localPosition, (distence - distenceTemp) / distenceList[index - 1]); } void OnPositionChanged() { mat.SetInt("_Count", count);#if UNITY_5_6_OR_NEWER mat.SetVectorArray("_Pos", posList);#elif UNITY_5_3_OR_NEWER for (int i = 0; i < posList.Length; i++) { mat.SetVector("_Pos" + i, posList[i]); }#endif }}
Shader "Unlit/ClipLine"{Properties{_Color("Color",Color) = (1,1,1,1)_MainTex("Texture", 2D) = "white" {} _Round("Round",Float) = 0}SubShader{Tags{ "RenderType" = "Opaque" }LOD 100Pass{Cull BackCGPROGRAM#pragma vertex vert#pragma fragment fragbool IsInsidePosList(float4 vec);#include "UnityCG.cginc"sampler2D _MainTex;float4 _MainTex_ST;float4 _Color;float _Round;int _Count;uniform vector _Pos[20];int _Index;//区域struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;float4 op :TEXCOORD1;};v2f vert(appdata v){v2f o;o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);o.op = v.vertex;return o;}fixed4 frag(v2f i) : SV_Target{fixed4 col = tex2D(_MainTex, i.uv); if (!IsInsidePosList(i.op)){clip(-1);} return col * _Color;}///在指定的区域内bool IsInsidePosList(float4 vec){if (_Count == 0) return true;for (int i = 0; i < _Count -1; i++){float3 dir1 = vec.xyz - _Pos[i + 1].xyz;float3 dir2 = vec.xyz - _Pos[i].xyz;float3 dirtemp = _Pos[i].xyz - _Pos[i + 1].xyz;float dot1 = dot(dir1, dirtemp);float dot2 = dot(dir2,-dirtemp);if (dot1 * dot2 > 0){float angle = acos(dot1 / (length(vec.xyz - _Pos[i + 1].xyz) * length(_Pos[i].xyz - _Pos[i + 1].xyz)));float dis = length(vec.xyz - _Pos[i + 1].xyz)*sin(angle);if (dis < _Round){return true;}}}return false;}ENDCG}}}
说明
1.距离问题
如果模型本身带有缩放,那么shader中的距离需要相应的调整
2.版本问题
新版本(5.6.0)的Shader格式不一样,需要将首行重写
3.点集问题
5.6.0传一组数据,长度要和Shader中一样
阅读全文
0 0
- 模型淡出Shader实现
- 用Shader实现标准光照模型
- unity shader (4)--实现漫反射模型
- unity shader (5)--实现半兰伯特模型
- Unity3d 模型的淡入淡出
- 游戏模型模糊高亮边缘效果实现shader
- unity shader (6)--实现高光反射光照模型
- Shader自学笔记 2.1.3 半兰伯特光照模型实现
- Unity实现标准光照模型的Shader代码
- 实现淡入淡出效果
- jquery实现淡入淡出
- Unity3d Shader光照模型
- <Shader> 自定义光照模型
- Shader--模型从上到下消失
- Axure实现淡入淡出效果,axure实现淡入淡出
- VB实现窗体淡入淡出
- JavaScript实现淡入淡出效果
- Java实现淡入淡出窗口
- SGM调试小记
- C++类继承CD练习
- 详细讲述 SQL SERVER&nb…
- 浅谈SQL Server 对于内存的管理
- **openpyxl修改表格中的公式自动求和autoSUM
- 模型淡出Shader实现
- SQL Server连接中的四个最常…
- python
- 网络术语解释
- 硬件能力与智能AI-Zoomla!逐浪CMS2 x3.9.2正式发布
- Linux硬件信息查询
- mysql关于连接数的操作
- Mysql主从集群部署
- Mysql利用mysql_multi配置一台主机…