当前位置: 首页 > news >正文

崩坏学园3里离摄像机近距离的头发透明效果在unity里的实现方法

最近国内崩坏3开始公测了,在看到宣传视频的时候我就对这个游戏画面很有兴趣了。然后第一时间就下来玩了。本人渣手机最低特效帧数都不稳定,好在今天更新了新版本,模拟器能正常运行了。立马就开了个模拟器最高画质来玩,效果棒棒的。网上搜了下,这个团队说是用了罪恶装备xrd的2d渲染技术,怪不得我当时看画面的时候立马就想到了罪恶装备xrd。而且这技术用得也非常到位,不管是动态的角色头发的卡通高光,还是那种动画里特有的自身阴影效果都非常到位。而现在不管是中国还是日本,大部分2d卡通渲染风格的游戏里,角色都是靠死的贴图来表现高光和阴影的。不然就是高光和阴影没有那种卡通风格的感觉。 崩坏3的这种动态效果一下就让整个角色的效果上了几个档次。


    这里我注意到了在选择角色武器的时候,由于长发角色容易把武器遮住,制作组特别给头发做了半透明效果,这点细节好评。这里我就用unity自己实现了一下这个效果。先做个笔记吧。

效果如图



   原理是在shader里比较摄像机距离和当前像素的距离,当这个距离小于某个值以后,就把某个范围内的一段像素的透明度按照一个线性的方式赋值。

这里画一个图比较好理解。


y轴代表透明度,x轴代表顶点离摄像机的距离。透明度程线性递增,透明度是1的时候则完全不透明,为0的时候则完全透明。我们高中学过直线方程为 y = a*x + b。

然后我们在模型顶点和摄像机距离小于 start的时候开始绘制线性递增的透明效果,距离大于end以外的像素透明度则都为大于等于1。

那么现在就变成了,已知直线方程为y = a*x + b,当x = start的时候 y=0,当x = end的时候,y = 1,求a b的值。

于是就有了一个方程组 

a * start + b = 1;

a * end + b = 0;

的方程组了。

解这个方程组得出 a = 1/(start - end);  b = -end/(start - end)

于是这个方程就变成了 y = x / (start - end) - end / (start - end) 了。


好了,解到这里我们已经知道了像素透明度和摄像机距离的关系了。接下来我们只要把这个公式写在shader里就可以了。

[csharp]  view plain copy
  1. Shader "Unlit/CutPixelByDistance"  
  2. {  
  3.     Properties  
  4.     {  
  5.         _MainTex ("Texture", 2D) = "white" {}  
  6.     }  
  7.     SubShader  
  8.     {  
  9.         Tags { "RenderType"="Opaque" "Queue" = "Transparent" }  
  10.         LOD 100  
  11.         Blend SrcAlpha OneMinusSrcAlpha  
  12.         Pass  
  13.         {  
  14.             CGPROGRAM  
  15.             #pragma vertex vert  
  16.             #pragma fragment frag  
  17.             // make fog work  
  18.             #pragma multi_compile_fog  
  19.              
  20.             #include "UnityCG.cginc"  
  21.   
  22.             struct appdata  
  23.             {  
  24.                 float4 vertex : POSITION;  
  25.                 float2 uv : TEXCOORD0;  
  26.             };  
  27.   
  28.             struct v2f  
  29.             {  
  30.                 float2 uv : TEXCOORD0;  
  31.                 UNITY_FOG_COORDS(1)  
  32.                 float4 vertex : SV_POSITION;  
  33.                 float lengthInCamera : TEXCOORD1;  
  34.             };  
  35.   
  36.             sampler2D _MainTex;  
  37.             float4 _MainTex_ST;  
  38.               
  39.             v2f vert (appdata v)  
  40.             {  
  41.                 v2f o;  
  42.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);  
  43.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);  
  44.                 //计算顶点和camera之间的距离  
  45.                 o.lengthInCamera = length(_WorldSpaceCameraPos - v.vertex.xyz);  
  46.                 return o;  
  47.             }  
  48.               
  49.             fixed4 frag (v2f i) : SV_Target  
  50.             {  
  51.                 // sample the texture  
  52.                 fixed4 col = tex2D(_MainTex, i.uv);  
  53.                 col.a = 1;  
  54.   
  55.                 float Start = 3;//设定开始值  
  56.                 float End = 2.5;//设定结束值  
  57.                 //如果像素和camera直接的距离小于Start则给alpha赋值  
  58.                 if (i.lengthInCamera < Start)  
  59.                 {  
  60.                     col.a =i.lengthInCamera /(Start - End) - End /(Start - End) ;  
  61.                 }  
  62.                 return col;  
  63.             }  
  64.             ENDCG  
  65.         }  
  66.     }  
  67. }  
在vert顶点函数里求出顶点和摄像机之间的距离以便在片段函数里调用。  然后片段函数frag里 当顶点和摄像机距离小于 start的时候就开始给alpha赋值, col.a就是公式里的y了,i.lengthInCamera就是公式里的x了,这样得出来的shader效果如下图。 这里我把 start和end写死了,如果把这两个值作为一个range放到shader的顶端,就可以在unity的shader面板上随意调整了。这个效果是不是很人性化呢。实现这个效果需要开启透明混合,需要多消耗一些性能了,不知道有没有其他更好的方法实现这种效果呢。


感谢群里的 LJL&PRC 大大的帮助

http://www.xdnf.cn/news/855001.html

相关文章:

  • Eclipse3.6 正式版下载地址
  • java学习网站
  • 骗子!-淘宝网上的奇热网络
  • 手把手构建基于 GBase8s 的 Flink connector
  • 《互联网周刊》封面报道:P2P——新媒体革命
  • 权力的游戏中文字幕词云图
  • WINCE 6.0 补丁下载地址
  • 如何用一张照片证明你是老网民?
  • 推荐开源项目:彩虹外链网盘 - PHP打造的全能型文件共享平台
  • 为何陆涛不爱米莱
  • iPad2 4.3.3完美越狱 超详细图文教程!
  • gdb调试之--read by other session 等待事件的重现
  • 招式繁多机关重重——实战卡巴斯基2010全功能安全软件
  • c#版本视频在线播放(通用播放器调用),支持avi,wmv,asf,mov,rm,ra,ram等
  • 使用nmap绕过防火墙进行扫描
  • 手机QQ空间装逼代码收集
  • 【生活点滴】-- 英语如何学?
  • 数据分析-SQL练习
  • 玩家开发、出售《劲舞团》外挂获刑一年半
  • 寻侠家将选择,后期家将选择经验谈
  • 卷毛机器人抢大龙_世界第一机器人卷毛杀人书25层,屠杀峡谷之巅钻一局:重演抢大龙...
  • 肥猪流码农的逆袭之路(1)
  • Windows Server 2008 Web服务器配置
  • 图像压缩算法
  • 【Nokia5800xm软件资源】
  • 模拟登陆115网盘(MFC版)
  • 2G、 3G、 4G、5G的区别
  • 丢失urlmon.dll文件导致系统程序功能异常问题
  • 计算机的k代表什么意思,电脑CPU后缀K、U、HQ、M分别代表什么你清楚吗?