3D优化之ShadowGun系列一:旗子飘扬效果实现方法及shader注解
先看效果:
飘动全是使用shader偏移顶点
的位置做的
几个点:
1、顶点数据的alpha值,标识了受风的权重。alpha越大,受风越厉害。
通过观察模型可以看出这点。而shader里这句也有说明。
以_Time作为参数,使用frac来取模,形成周期性的动画。
下面是注释后的shader
// - Unlit
// - Per-vertex (virtual) camera space specular light
// - SUPPORTS lightmap
Shader "MADFINGER/Environment/Lightmap + Wind" {
Properties {
_MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
_Wind("Wind params",Vector) = (1,1,1,1)
_WindEdgeFlutter("Wind edge fultter factor", float) = 0.5
_WindEdgeFlutterFreqScale("Wind edge fultter freq scale",float) = 0.5
}
SubShader {
Tags {"Queue"="Transparent" "RenderType"="Transparent" "LightMode"="ForwardBase"}
LOD 100
Blend SrcAlpha OneMinusSrcAlpha
Cull Off ZWrite Off
CGINCLUDE
#include "UnityCG.cginc"
#include "TerrainEngine.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
samplerCUBE _ReflTex;
#ifndef LIGHTMAP_OFF //lightmap是否开启。如果没有关闭lightmap。就给lightmap支持下。
float4 unity_LightmapST;
sampler2D unity_Lightmap;
#endif
float _WindEdgeFlutter; //风导致旗帜震动的振幅
float _WindEdgeFlutterFreqScale; //风的时间流逝速度,影响频率,控制旗子反复摆动的周期
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
#ifndef LIGHTMAP_OFF //开启lightmap的时候,要使用
float2 lmap : TEXCOORD1;
#endif
fixed3 spec : TEXCOORD2;
};
inline float4 AnimateVertex2(float4 pos, float3 normal, float4 animParams,float4 wind,float2 time)
{
// animParams stored in color
// animParams.x = branch phase
// animParams.y = edge flutter factor
// animParams.z = primary factor
// animParams.w = secondary factor
float fDetailAmp = 0.1f;
float fBranchAmp = 0.3f;
// Phases (object, vertex, branch)
float fObjPhase = dot(_Object2World[3].xyz, 1); //这一行直接写1也行,_Object2World[3],一般情况下应该是0,0,0,1
float fBranchPhase = fObjPhase + animParams.x; //由于animParams.x是0,这个也是1
float fVtxPhase = dot(pos.xyz, animParams.y + fBranchPhase); //根据x,y,z,和振幅+1点乘。离远点越远,这个值越大。受振幅影响
// x is used for edges; y is used for branches
float2 vWavesIn = time + float2(fVtxPhase, fBranchPhase ); //vWavesIn第一项是点的相位*时间流逝率,第二项就是时间+1.
// 1.975, 0.793, 0.375, 0.193 are good frequencies
float4 vWaves = (frac( vWavesIn.xxyy * float4(1.975, 0.793, 0.375, 0.193) ) * 2.0 - 1.0); // 将结果乘以频率,对一取模,然后乘以2,再减一
vWaves = SmoothTriangleWave( vWaves ); //一个优化的正弦波计算。
float2 vWavesSum = vWaves.xz + vWaves.yw; //振幅叠加,以免太正弦了。
// Edge (xz) and branch bending (y)
float3 bend = animParams.y * fDetailAmp * normal.xyz; //沿法线方向根据振幅和参数缩放一个值
bend.y = animParams.w * fBranchAmp; //y根据受风能力,乘以一个参数
pos.xyz += ((vWavesSum.xyx * bend) + (wind.xyz * vWavesSum.y * animParams.w)) * wind.w; //再次根据受风能力进行影响。
// Primary bending
// Displace position
pos.xyz += animParams.z * wind.xyz; //根据受风能力,再次扩大。
return pos;
}
v2f vert (appdata_full v)
{
v2f o;
float4 wind;
float bendingFact = v.color.a;
wind.xyz = mul((float3x3)_World2Object,_Wind.xyz); //风的方向转为物体坐标。wind参数的xyz表示风的世界坐标的方向。_Wind为风的个方向强度
wind.w = _Wind.w * bendingFact; //每个顶点的颜色的alpha值表示此点受风变化的强度。旗子底部这个值较大。wind参数的w表示风力
float4 windParams = float4(0,_WindEdgeFlutter,bendingFact.xx); //0,旗子振幅,每个顶点的受风强度值
float windTime = _Time.y * float2(_WindEdgeFlutterFreqScale,1); //风的时间流逝速度
float4 mdlPos = AnimateVertex2(v.vertex,v.normal,windParams,wind,windTime); //计算受风之后的位置
o.pos = mul(UNITY_MATRIX_MVP,mdlPos);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
o.spec = v.color;
#ifndef LIGHTMAP_OFF
o.lmap = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
#endif
return o;
}
ENDCG
Pass {
CGPROGRAM
#pragma debug
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest //片元着色器选择低精度的计算方式。5.0以后抛弃掉 fragmentoption的声明。
fixed4 frag (v2f i) : COLOR
{
fixed4 tex = tex2D (_MainTex, i.uv);
fixed4 c;
c.rgb = tex.rgb;
c.a = tex.a;
#ifndef LIGHTMAP_OFF
fixed3 lm = DecodeLightmap (tex2D(unity_Lightmap, i.lmap));
c.rgb *= lm;
#endif
return c;
}
ENDCG
}
}
}
中间多次根据风力进行修正的地方,作者写的蛮复杂,不写那么复杂,效果看起来也还行。
3D优化之ShadowGun系列一:旗子飘扬效果实现方法及shader注解相关推荐
- 查看linux内存优化,Linux性能优化和监控系列(三) 分析Memory使用状况
Linux性能优化和监控系列(三) 分析Mem 分析Memory使用状况 内存是影响服务器性能的一个主要因素, 当进程已经驻留内存或者系能够分配给进程足够的内存给它, CPU能顺利自如的运行. 如果发 ...
- 数值优化(Numerical Optimization)学习系列-惩罚和增广拉格朗日方法(Augmented Lagrangian Methods)
原文地址为: 数值优化(Numerical Optimization)学习系列-惩罚和增广拉格朗日方法(Augmented Lagrangian Methods) 概述 求解带约束的最优化问题,一类很 ...
- NVIDIA显卡3D设置 让你的游戏得到最佳效果
NVIDIA显卡3D设置 让你的游戏得到最佳效果 来源:电脑软硬件应用网 编辑: 黄燕飞 发布时间: 12-02-24 很多朋友的n卡(NVIDIA英伟达,简称N卡) ,都是在wi ...
- Atitit 发帖机系列(7) 词法分析的方法attilax大总结)
Atitit 发帖机系列(7) 词法分析的方法attilax大总结) 1.1. 词法分析貌似俩大方法,一个直接根据状态图转换,一个根据dfa1 1.2. switchcase或者ifelse 最原始方 ...
- Labview加载3D模型(.wrl)出现内存不足的解决方法
Labview加载3D模型(.wrl)出现内存不足的解决方法 最近,由于项目的要求,需要做一个上位机,用于实时采集装备的状态信息.最终方案采用Labview数据流的方式构建应用程序.在加载wrl3D模 ...
- AREngine深度图优化之一基于两基带统计的补洞方法
我们都知道AREngine返回的深度图质量并不高,大概率是直接返回的tof深度图,跟ARCORE返回的深度图差距还是比较大的.在我们当前AR云渲染项目中,需要用到AREngine返回的深度图,这就需要 ...
- UA SIE545 优化理论基础 函数凸性的一些有趣的判断方法
UA SIE545 优化理论基础 函数凸性的一些有趣的判断方法 Convex function f:S→Rf:S \to \mathbb{R}f:S→R where SSS is a nonempty ...
- Py之urllib2:Python库之urllib、urllib2、urllib3系列简介、安装、使用方法之详细攻略
Py之urllib2:Python库之urllib.urllib2.urllib3系列简介.安装.使用方法之详细攻略 目录 urllib2简介 urllib2安装 urllib2使用方法 urllib ...
- STM系列单片机中文参考手册下载方法
在使用STM单片机编程的时候有时候需要查阅芯片手册,英文手册查阅起来比较麻烦,而搜索中文手册时,好多网站下载时需要注册或者需要积分,下载起来比较麻烦.现在就来说一下,如何在官方网站下载各个系列单片机的 ...
- Java之List系列--ArrayList保证线程安全的方法
原文网址:Java之List系列--ArrayList保证线程安全的方法_IT利刃出鞘的博客-CSDN博客 简介 本文介绍Java中的ArrayList.LinkedList如何进行线程安全的操作.为 ...
最新文章
- java对象的访问定位_2、JVM-Java对象的创建、对象结构、对象访问定位-Go语言中文社区...
- exe文件添加为服务
- jQuery UI应用--滑块Slider
- 如何躲开技术人员35岁魔咒?【有惊喜系列】
- mysql 5.6 json查询_mysql5.6及以下版本如何查询数据库里的json
- 对于HTTP过程中POST内容加密的解决方案
- tipask mysql调取dedecms_如何实现dedecms外部数据库调用
- 百度手机输入法,如何使用五笔98版?
- transition animation
- java指定浏览器_java程序中指定某个浏览器打开的实现方法
- 你以为你在利用碎片化时间,实际上你的时间被碎片化了
- 曾用心并深度参与的一款游戏今天发布了关服通知,回顾一下我最初的工作日报
- java 数字大小写转换工具类--适用于打印收据
- 计算机中文件夹怎么上密码,怎样设置电脑文件夹密码
- 位图(BMP)文件格式(一)
- python x=[random.randint(0,100) for i in range(50)]什么意思?列表解析
- mac 下配置安装rz,sz
- CSDN积分获取方法(转载)
- 西门子精智屏下载触摸屏程序时提示缺少面板映像怎样解决?
- 切图工具GraphicsMagick安装