ShadowGun shader 解析(1)

ShadowGun shader 解析(1)

小弟初来咋到,不对的地方请大家海涵。

去年的时候就从网上下了这个工程,虽然只有一个场景和一些shader,不过这些已经足够了。像这样公司能将自己项目的一部分放在网上供大家学习真是难能可贵的,对于untiy移动平台的开发人员更是重要的学习资料。

大家可能打开项目之后无从下手,虽然ShadowGun的效果更现在次时代游戏比起来还是有差距的,不过在当时的移动平台上可是赚足了眼球。其实的优化方法值得大家学习。本文希望有一定shader基础的人来阅读,我怕误人子弟,对别人的代码上理解上可能有些偏差。请大家提出宝贵意见,共同学习共同进步。

这个项目我在itouch4上测试过,平均30-40帧,最多3万个三角形。其实30-40帧是不够的,游戏里还要加上动画脚本AI等等,把他们融合在一起才是游戏。对于开发者来说平衡他们之间的关系变得尤为重要。

大家看到上面这张图了么,这是shadowgun游戏里的第一个场景,我要更大家讲的就是,人物的材质,地面的材质,雕像的材质,体积光的材质等等这些。本文不是教程,不会由浅入深为大家讲解,所以会把一些有趣的shader先展示给大家,我认为对大家更有帮助。

项目下载网站

http://blogs.unity3d.com/2012/03/23/shadowgun-optimizing-for-mobile-sample-level/

1.红旗飘飘

我先来讲讲这个彩旗飘飘的效果,我们的美术想要这个效果,我就研究了一下。发觉很有意思。

Shader里关键的代码在这里

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);
float fBranchPhase = fObjPhase + animParams.x;
float fVtxPhase = dot(pos.xyz, animParams.y + fBranchPhase);
// x is used for edges; y is used for branches
float2 vWavesIn = time  + float2(fVtxPhase, fBranchPhase );
// 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);
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;
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;
}


加上风的偏移量,最后就完成了。
总结:
建议大家可以参考gpugems3上的文章,看更多的材料可以帮大家更好的理解,这个方法,我认为也是不错的。植被,简单的布料,旗帜,都可以用。虽然简单但很有效,完全用gpu计算,用于大量使用的话更有效的。
大家打开TerrainEngine.cginc文件在.../Unity\Editor\Data\CGIncludes这个目录下面,里面有个AnimateVertex函数,大家就可以知道这函数从哪里来的。这还没完,如果有人看过GPU GEMS 3 里面有一篇Chapter 16. Vegetation Procedural Animation and Shading in Crysis 讲crysis的植被特效。建议大家看看,不要以为是老技术,其实技术没有新旧,只是看能不能为我所用。Crysis中的这个方法,用VS来完成摆动动画,节约了很多资源。可以腾出更多的性能空间。尤其是手持设备更应该注意的问题。
没想到shadowgun改都没改就拿过来用了,连注释都一样,如果不知道出处根本就不知道是什么。当然shadowgun的牛人是理解的,因为权重是写在模型顶点颜色上的,不知道这个怎么做的出效果。不过下面这段代码在这个效果里其实没什么用,因为_Object2World[3].xyz是000,本来是用来做向位移的。为了做风吹过以后的层次感。


// Phases (object, vertex, branch)
float fObjPhase = dot(_Object2World[3].xyz, 1);
float fBranchPhase = fObjPhase + animParams.x;
float fDetailAmp = 0.1f;
float fBranchAmp = 0.3f;




就是振幅
// x is used for edges; y is used for branches
float2 vWavesIn = time  + float2(fVtxPhase, fBranchPhase );




Crysis里叶子的边用了x,叶子当中的茎干用y,shadow gun里旗子本身的摆动用了y,边上的摆动用了x。其实都差不多,就是你有时想不到这么用。
// 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);




是将两个频率映射成4个,不知道大家能否理解,这样就有了4个不同的频率。
vWaves = SmoothTriangleWave( vWaves );


这里用了三角波,就是为了不用sin cos 为了一点效率,很有借鉴,不过还要看实际测试。
float2 vWavesSum = vWaves.xz + vWaves.yw;


将两个频率合并,为了看上去没有规律。
// Edge (xz) and branch bending (y)
float3 bend = animParams.y * fDetailAmp * normal.xyz;
bend.y = animParams.w * fBranchAmp;
pos.xyz += ((vWavesSum.xyx * bend) + (wind.xyz * vWavesSum.y * animParams.w)) * wind.w; 


这里就是融合的部分,animParams.y叶子的权重从顶点色的绿色获得,fDetailAmp 振幅,normal法线叶子是按法线方向飘动的。下面也是一样的道理。
pos.xyz += animParams.z * wind.xyz;


加上风的偏移量,最后就完成了。
总结:
建议大家可以参考gpugems3上的文章,看更多的材料可以帮大家更好的理解,这个方法,我认为也是不错的。植被,简单的布料,旗帜,都可以用。虽然简单但很有效,完全用gpu计算,用于大量使用的话更有效的。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值