崩坏三人物渲染分析
来源:互联网 发布:网络视频安防监控系统 编辑:程序博客网 时间:2024/04/27 20:09
申明:本文的所有的算法以及资料版权归原公司所有,仅供学习,严禁商业使用!转载请注明链接!
背景
崩坏三的图形渲染是近年来手游卡通渲染的标杆,目前市面上的卡通类手游很少能望其项背。通常一款受欢迎的游戏出来很快就有大批同类型的游戏跟进,但是近一年的时间过去了,还没有出现效果能媲美崩坏的游戏,追根溯源还是因为其渲染技术不能被模仿。作为一个爱好者,为了学习其中的奥秘,特带着敬意去分析其渲染方法。采用的方法是采用工具抓取了其中一帧数据,然后人肉翻译了其shader算法,进而探求其中的奥秘。选取了芽衣这个角色来分析,因为做了很多subshader,在不同性能的设备上表现效果是不一样的,本篇使用的是小米5作为设备。
贴图模型分析
在人物渲染中,采用了高光以及两层阴影来模拟光照信息,同时,阴影之间不是采用重合来表现的,采用两层交错示(显示了阴影一就没有显示阴影二)。
整个渲染使用了两张贴图,一张是主纹理图,另一张是lightmap;这张lightmap的三个通道分别存储了高光mask、阴影mask以及高光信息;
阴影mask作用是根据其灰度值来控制阴影的交错显示,在这张阴影mask图中,灰度值最大的为138,这有点迷茫,为了配合算法?
模型是自带了顶点色的,这个顶点色不是为了调色之类的,而是用来控制阴影的显示,观察游戏主界面中人物的模型,可以发现人物脸上的光照只在某些地方显示,有些地方是不会出现,这些地方都是使用了顶点色来调节阴影强度,使其更平滑更真实。详情可以参考米哈游技术总监在unite 2017大会上的 [ 演讲报告 ].
第一层阴影
第一层阴影是根据half lambert光源,顶点色以及阴影mask共同作用的结果,算法如下:
fixed mask = lightMapColor.y * i.color.x;mask += saturate(i.halfLambert);mask = mask *0.5 +(-_LightArea) + 1;intlightStep = step(1,mask);mainCol.xyz = tex2D(_MainTex,i.uv).rgb;fixed3 firstShadow = mainCol.xyz * _FirstShadowMultColor.rgb;if(lightStep!=0) firstShadow = mainCol.xyz;else firstShadow = firstShadow ;
lightMapColor.y直接显示控制了阴影显示的区域,当其灰度值较小时,即显示第一层阴影。通过参数LightArea来调节显示阴影的区域大小。同时,为了根据视角的方向来变化阴影,特意加入了half Lambert光源强度值,就是为了根据视角来控制阴影的变化。定点色的i.color.x数值用来调节是否显示阴影。如上分析的那样, 有些区域比如脸部,某些部位是没有阴影的,那么这里就可以使用顶点色来抑制阴影。
第二层阴影
同理,根据第一层阴影的方法,可以获得第二层阴影:
fixed3 secondShadow = mainCol.xyz * _SecondShadowMultColor.rgb;fixed secMask = i.color.x * lightMapColor.y + saturate(i.halfLambert);secMask = secMask *0.5 + (-_SecondShadow)+1;lightStep = step(1, secMask);if(lightStep !=0) secondShadow= mainCol.xyz;else secondShadow= secondShadow;
为了使两层阴影之间实现过渡,则需要将进行交错显示,而不是叠加显示,代码如下:
fixed sep = i.color.x * lightMapColor.y + 0.9;int sepMask = step(1,sep);fixed3finalColorif(sepMask != 0) finalColor= firstShadow;else finalColor= secondShadow;
高光
高光的计算方式如下:
float3 viewDir = -i.worldPos + _WorldSpaceCameraPos.xyz;viewDir = normalize(viewDir);float3 halfView = viewDir + normalize(_WorldSpaceLightPos0.xyz);halfView = normalize(halfView);float shinPow = pow(max(dot(normalize(i.worldNormal.xyz), halfView), 0), _Shininess);float oneMinusSpec = 1 - lightMapColor.z;oneMinusSpec = oneMinusSpec - shinPow;int specMaslk = step(0,oneMinusSpec);fixed3 specColor = _SpecMulti * _LightSpecColor.xyz;specColor = lightMapColor.x * specColor;if(specMaslk!=0) specColor = 0;else specColor = specColor;
效果分析
直接上结果:
对与我这个对美术十窍通了九窍的人来说,实在调不出满意的颜色(囧o(╯□╰)o);但其阴影效果以及高光效果已经能随着角色的转动而变化。再看一下面部:
这张图是没对顶点色处理的图,可以看到,脸部的阴影变化很不自然。为了改变这种别扭的效果,可以通过修改顶点色值,建立mask来抑制不必要的光影;修改顶点色的方法,一是可以通过模型软件来修改,但这样很难立即看到修改后的效果,还有一种方式是直接unity中编写一个修改顶点色的工具,这样能更直观的修改顶点色;下面的效果是修改顶点色后的结果:
可以看到,脸部的阴影效果变得更加自然;
总结
在崩坏三的角色渲染中,并没有采用很多高深的渲染技术,而是通过各种非常技巧性的方法来进行渲染的;这让人联想到图形学上的至理:如果它看上去是对的,那么它就是对的。其没有使用很多复杂的算法来表现出满意效果,而是通过各种trick来实现想要的结果,尤其是在卡通渲染中,更是各种采用奇技淫巧来实现效果。后续文章中,将继续这款游戏中的各种渲染技术。
- 崩坏三人物渲染分析
- 崩坏3角色渲染分析
- 崩坏
- ROSCORE崩坏
- 《射雕英雄传》中人物分析
- 人物分析第二集
- 成功人物分析
- CM 人物分析
- FBReader源码分析(三)---启动到渲染流程
- 《奋斗》人物的性格分析
- 职场人物类型分析
- [game]崩坏3
- 基于.NET 2.0的GIS开源项目SharpMap分析手记(三):地图渲染分析
- 基于.NET 2.0的GIS开源项目SharpMap分析手记(三):地图渲染分析
- 使用Ogre渲染生成的人物行走4-8图
- 三、渲染元素
- Android 颜色渲染(三) Shader颜色渲染
- Android 颜色渲染(三) Shader颜色渲染
- 数据结构的栈与队列
- WCF学习过程和心得(一)
- ImageView自定义圆形图片
- 数据库连接池原理(一)
- 邻接表-数组的实现
- 崩坏三人物渲染分析
- spring之jdbcTemplate
- 非常简单封装Okhttp
- keil5中新建一个STM32工程
- 贪吃蛇
- 网页授权获取微信用户信息错误40029:微信会发出两次提交 不合法的oauth_code
- Spark MLlib — Word2Vec
- SQL语句参考,包含Access、MySQL 以及 SQL Server
- python2.x 与python3.x之d.keys()返回类型的区别