取决于什么wwWee141CoM谁知道,游戏登入福建安全教育平台时ee141体现毗邻干事器失踪效

&figure&&img src=&https://pic4.zhimg.com/v2-89a620e5e89aa3db2df4_b.jpg& data-rawwidth=&933& data-rawheight=&402& class=&origin_image zh-lightbox-thumb& width=&933& data-original=&https://pic4.zhimg.com/v2-89a620e5e89aa3db2df4_r.jpg&&&/figure&&p&在准备这篇文章的时候,无意之中发现了一个讲不同渲染通道(Rendering Path)的文章,讲了Forward,Deferred 和 Forward+ 三种渲染的流程,而且还附了特别详尽的代码,于是就浪费掉了两个晚上去学习/(ㄒoㄒ)/~~。&/p&&p&千万别错过,要是我当年看过这篇文章说不定就可以把大神们秒了,趁热打铁,那我们就先上算法吧。&/p&&h2&&b&渲染通道(Rendering Path)&/b&&/h2&&p&(这部分的图片均来自以下网站)
&/p&&p&&a href=&https://link.zhihu.com/?target=https%3A//www.3dgep.com/forward-plus/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Forward+ Rendering&/a&&/p&&p&&b&向前(Forward)&/b& : 简单粗暴的蛮力算法。对于屏幕上的每个像素,映射到对应物体上,得到投影点,材质,法线以及一系列的数据。然后遍历灯光,计算所有灯光对于该点的作用的光照的数据(简单来说就是一个颜色值),然后进行线性叠加,最后得到该像素点颜色。当然真实的计算中并不是这么简单,还需要考虑反射光等等情况,这里需要用到光线跟踪的技巧,就不展开了。&/p&&p&&b&延迟(Deferred)&/b& : 这个算法核心的思想就是对场景进行预处理。把每个像素点对应的实体物体(opaque objects)上的深度(depth),法线(normal),颜色(diffuse),亮度(specular)和发光环境光(Light Accumulation)等等系数计算好,存放在若干张缓存图中(这里使用的是经典的漫反射模型),&u&由于缓存图的寄存器等级比较高,那么就把多次读取物体信息的时间给省下来了&/u&。还有一个简化思想是,灯光是有影响范围的,把超过影响范围的空间(光强度过小)内的物体剔除掉。比如点光源的影响空间就可以视为一个球,球外面的物体视为不被该光源影响。&/p&&p&值得一提的是在对透明物体(Transparent Objects)的渲染中,该方法退回到向前渲染。&/p&&p&参考网站:&a href=&https://link.zhihu.com/?target=https%3A//learnopengl.com/%23%21Advanced-Lighting/Deferred-Shading& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Learn OpenGL, extensive tutorial resource for learning Modern OpenGL&/a&&/p&&p&&b&向前加(Forward+) :&/b& 对向前算法的优化。&u&这个算法的基本思想就是给像素点分组,给每组像素进行统一的光线剔除,这样就把在一个组内的像素判断是否被某光源影响的时间给省掉了,并且可以进行并行计算&/u&。这个算法首先把屏幕上的像素点切分成一些列的网格(grid),大概是这样:&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-be0d7e446eae354f755f6_b.jpg& data-rawwidth=&900& data-rawheight=&666& class=&origin_image zh-lightbox-thumb& width=&900& data-original=&https://pic4.zhimg.com/v2-be0d7e446eae354f755f6_r.jpg&&&/figure&&p&&br&&/p&&p&然后对于每一个大块的网格,分透明和不透明物体进行渲染深度的计算,也就是在这个网格对应的网格视锥(Grid Frustum,也就是这个网格的面和视点连起来然后反向无线延伸形成的一个无限延伸的棱锥)里,需要渲染物体的所有物体的最近和最远的深度(也就是眼睛在这个网格上能看到的物体的最近和最远的距离)。下图中蓝色是不透明物体,黄色是光源,灰色区域是该网格视锥需要考虑的渲染范围。左图是不透明物体,右图是透明物体。&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-0889dea3ee234c38a00963eed6bf9ec0_b.jpg& data-rawwidth=&500& data-rawheight=&241& class=&origin_image zh-lightbox-thumb& width=&500& data-original=&https://pic4.zhimg.com/v2-0889dea3ee234c38a00963eed6bf9ec0_r.jpg&&&/figure&&p&&br&&/p&&p&参考延迟渲染的部分,每个光源都是有一个作用范围的。对于每个网格,遍历光源,若是某个光源作用范围进入到了该网格的渲染范围(上图灰色的部分),则该光源被列入该网格的光源列表里。最后对于每个网格内的像素,只用该网格的光源列表进行向前渲染的计算。&/p&&p&(在文章中还有一些存储格式,空间几何算法的说明,这里就不再赘述了)&/p&&p&&b&复杂度&/b&&/p&&p&最后考查一下各个算法的复杂度,光源数为L,物体数为O,屏幕像素数为P×P。&/p&&p&Forward : LOPP&/p&&p&Deferred:(L+O)PP&/p&&p&Forward+:(最坏)LOPP (最好) L+O&/p&&p&&br&&/p&&p&Forward+其实是一个并不是很稳定的算法,但越是复杂的场景,小灯光越多越能够体现Forward+的优势。另外由于算法的原理,Forward+实际上对于方向光源是没有优化的。&/p&&p&以下是实测数据:&/p&&p&对于大灯光为主的场景,延迟(Deferred) 和 向前加(Forward+)的效率相当,比向前(Forward)效果明显的更好。&/p&&p&对于小光源多的场景,向前加(Forward+)的效果明显更好,注意上图的横坐标的数字是指数增加的,用Forward +可以把灯光堆到5000个,我的天!&/p&&p&PS : 根据 Charlie 的评论,这里再给出一个Deferred Rendering的优化:TBDR&/p&&p&这个博客好像写得也比较详细了,我就不再赘述,直接上链接:&/p&&p&&a href=&https://link.zhihu.com/?target=https%3A//chengkehan.github.io/TBDR.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Jim's GameDev Blog&/a&&/p&&p&&br&&/p&&h2&&b&光照烘焙&/b&&/h2&&p&把场景中各个物体设置为静态(static),至少是光照贴图静态(light map static)。&/p&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-82b100a9edd_b.jpg& data-rawwidth=&714& data-rawheight=&275& class=&origin_image zh-lightbox-thumb& width=&714& data-original=&https://pic2.zhimg.com/v2-82b100a9edd_r.jpg&&&/figure&&p&设置场景的光源属性为烘焙。这里以场景中的方向光源(directional light)为例。设置如下:&/p&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-07baa12d6c295732cdf20489_b.jpg& data-rawwidth=&706& data-rawheight=&557& class=&origin_image zh-lightbox-thumb& width=&706& data-original=&https://pic1.zhimg.com/v2-07baa12d6c295732cdf20489_r.jpg&&&/figure&&p&&b&Mode :&/b& 渲染模式。可选的模式为Realtime, Baked, Mixed. Realtime即为实时渲染,Baked为影响烘焙,Mixed为同时影响烘焙和实时。&/p&&p&&b&Indirect Multiplier&/b&: 就是前几个版本里的 bounce intense。在渲染的时候,物体会接收到一些不是直接从光源发射出来的光线,比如从其他物体反射过来的光线。这些光线叫做Indirect light。对这种光线的计算会在一定程度上的影响效率。这里可以把Indirect Multiplier设为0避免这种反射光的计算,然后用其他技术来补充环境反射光。&/p&&p&&b&Shadow Type: &/b&有No shadow, Hard Shadow 和 Soft Shadow三个选项。&u&我们这里选择Soft Shadow, 并且把下面的Baked Shadow Angle 设为15。&/u&由于实际生活中的阳光/灯光并不是方向光/点光源,而是某种体积光,所以会产生软阴影,原理大概如下:&/p&&figure&&img src=&https://pic1.zhimg.com/v2-cb705e7b8fb999c747a356_b.jpg& data-rawwidth=&530& data-rawheight=&283& class=&origin_image zh-lightbox-thumb& width=&530& data-original=&https://pic1.zhimg.com/v2-cb705e7b8fb999c747a356_r.jpg&&&/figure&&p&(图片出处&a href=&https://link.zhihu.com/?target=https%3A//www.cs.unc.edu/%7Edm/UNC/COMP236/LECTURES/SoftShadows.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://www.&/span&&span class=&visible&&cs.unc.edu/~dm/UNC/COMP&/span&&span class=&invisible&&236/LECTURES/SoftShadows.pdf&/span&&span class=&ellipsis&&&/span&&/a&)&/p&&p&投影的计算方法比较有名的有Shadow volume和Shadow mapping。提供一个解释Shadow mapping的传送门:&/p&&p&&a href=&https://link.zhihu.com/?target=https%3A//learnopengl.com/%23%21Advanced-Lighting/Shadows/Shadow-Mapping& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Learn OpenGL, extensive tutorial resource for learning Modern OpenGL&/a&&/p&&p&然后打开光照设置窗口,Windows=&Lighting=&Settings&/p&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-bf8fcc7c289e1a88cb23d68_b.jpg& data-rawwidth=&508& data-rawheight=&899& class=&origin_image zh-lightbox-thumb& width=&508& data-original=&https://pic3.zhimg.com/v2-bf8fcc7c289e1a88cb23d68_r.jpg&&&/figure&&p&在弹出窗口的Scene框下,设置如上图。&/p&&p&&b&Mixed Lighting - Lighting Mode &/b&这个选项共有四个,分别对应了场景在多大的程度上使用Light Map。比如Backed Indirect表示所有的静态和动态物体都用实时光,Subtractive表示静态和动态物体都用烘焙光(表达不准确,但是大概是这个意思)。下面的链接提供了关于这四个选项的详细说明。&/p&&p&&a href=&https://link.zhihu.com/?target=https%3A//forum.unity3d.com/threads/lighting-modes-in-5-6-beta-2.447337/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Lighting Modes in 5.6 Beta 2&/a&&/p&&p&&b&Lightmap Resolution&/b& 这个选项决定了光照烘焙的清晰度,要是觉得烘焙光照锯齿严重,可以调高这个参数。&/p&&p&&b&Ambient Occlusion &/b&环境遮挡,这个技术的概念就是,物体的表面会由于其物理上的凹凸导致接收到光线强度的变化。原理如下图所示,在P点接收到的光线由于附近物理表面的遮挡而减少了。&/p&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-cefd6b7791_b.jpg& data-rawwidth=&329& data-rawheight=&211& class=&content_image& width=&329&&&/figure&&p&其效果嘛,简单来说,就是给物体加上一层阴影,使其棱角更加清晰,明暗交界的部分更加的明显。AO一般分为Object Space和Screen Space两种实现。Object Space 有通过材质贴图的(比如上一节讲的PBR中的AO贴图),或者光照贴图。这里计算的就是Object Space Ambient Occlusion中光照贴图的部分。&/p&&p&其下的参数,distance表示了检测的范围。Indirect Contribution和Direct Contribution分别表示环境光和光源的影响系数。&/p&&p&&b&Final Gather &/b&&u&这个选项需要打开,并且把Ray Count调高到一个合适的数值。&/u&Final Gather 是一个计算非直接光源(也就是环境光,indirect light)的一个技巧。它的主要原理是在受到光照的点向不同角度发射一定数量的射线,计算射线方向的光强度然后求平均。其直观效果是能够增加光照贴图的分辨率。这里找到一篇在Maya里的FG分析的文章,勉强凑合一下吧:&/p&&p&&a href=&https://link.zhihu.com/?target=http%3A//www.interstation3d.com/tutorials/mentalray_gi_rev2/indoor01.htm& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&interstation3d.com/tuto&/span&&span class=&invisible&&rials/mentalray_gi_rev2/indoor01.htm&/span&&span class=&ellipsis&&&/span&&/a&&/p&&p&这里的Ray Count 就是指射线的数量了。&/p&&p&点击最下面的按钮Generate Lighting。等待数分钟后场景的光照贴图便生成好了。&/p&&p&最终效果如下:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-dbae1b9f2b5_b.jpg& data-rawwidth=&1208& data-rawheight=&618& class=&origin_image zh-lightbox-thumb& width=&1208& data-original=&https://pic4.zhimg.com/v2-dbae1b9f2b5_r.jpg&&&/figure&&p&&/p&&p&&/p&&p&&/p&
在准备这篇文章的时候,无意之中发现了一个讲不同渲染通道(Rendering Path)的文章,讲了Forward,Deferred 和 Forward+ 三种渲染的流程,而且还附了特别详尽的代码,于是就浪费掉了两个晚上去学习/(ㄒoㄒ)/~~。千万别错过,要是我当年看过这篇文章说不定就…
&figure&&img src=&https://pic4.zhimg.com/v2-89a620e5e89aa3db2df4_b.jpg& data-rawwidth=&933& data-rawheight=&402& class=&origin_image zh-lightbox-thumb& width=&933& data-original=&https://pic4.zhimg.com/v2-89a620e5e89aa3db2df4_r.jpg&&&/figure&&p&十块钱买房?在Unity里面搭个场景就好了呀。&/p&&p&也不知道是从什么时候起,圈内就流行一种说法,说Unity适合做手机游戏,Unreal适合做大作。多年从事Unity游(jiao)戏(ge)开(zuo)发(y的我,真想替Unity报个不平。以绝大多数游戏团队的努力程度,还没到要拼引擎的地步!!!对熟练的开发者来说,用Unity做次时代画面的游戏也不是什么难事。&/p&&p&所以今天就从最简单的室内场景入手,扒一扒Unity的渲染机制吧。&/p&&p&(Unity版本 5.6.1f1)&/p&&h2&模型导入&/h2&&p&模型来自于asset store上的一个资源,链接如下&/p&&p&&a href=&https://link.zhihu.com/?target=https%3A//www.assetstore.unity3d.com/cn/%23%21/content/41772& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Asset Store&/a&&/p&&p&当然,这种家具模型资源网上是出奇的多,免费资源很容易找到,这里就不详细介绍了。&/p&&p&这里需要说一下模型导入的选项。在Project窗口里面点选模型文件(*.obj,*.fbx),就会在Inspector里面出现如下信息:&/p&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-d4e4dec3be22f51ba79ab5c_b.jpg& data-rawwidth=&495& data-rawheight=&605& class=&origin_image zh-lightbox-thumb& width=&495& data-original=&https://pic1.zhimg.com/v2-d4e4dec3be22f51ba79ab5c_r.jpg&&&/figure&&p&&b&Scale Factor&/b& 影响的是导入场景后物体的比例,比如原来一个物体Scale Factor是1,导入场景后Transform里的Scale是(1,1,1),要是这里调成10,导入场景的物体就会变大10倍,但是其scale的数值不变,仍为(1,1,1)。&/p&&p&&b&File Scale&/b& 有时候会发现有些.fbx文件会莫名其妙的特别小,因为.fbx默认的scale为0.01,而.obj,.ma这种默认的是1。在前几个版本里面这个scale是改不了的,需要在Maya导出模型文件的时候注意一下设置。这个版本可以选择把File Scale去掉,算是给程序员一个贴心的设计吧。&/p&&p&&b&Mesh Compression&/b& 是对存储数据的位数进行压缩,并不是网格简化。&/p&&p&&b&Read/Write Enabled&/b& 关闭了以后就不能通过代码修改模型的节点位置信息了。Unity的Mesh.triangles之类的接口是会有可能会出现,在运行时把工程里的模型覆盖掉的情况的。这大概就是针对这点进行一个的保护措施。&/p&&p&&b&BlendShape &/b&可以用作简单的插值动画。建议程序员学一学,用来做一些随机性的简单动画(像场景中的花花草草这种)特别好用。&/p&&p&&b&Generate Collider&/b& 用于Mesh Collider&/p&&p&&b&Keep Quads&/b& 对于需要用到Dx11 Tessellation技术的一些模型可能需要勾选。下面有一个关于Tessellation技术的介绍:&/p&&p&&a href=&https://link.zhihu.com/?target=http%3A//www.nvidia.com/object/tessellation.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&DirectX 11 Tessellation&/a&&/p&&p&或者直接看看asset store里面的shader(免费)&/p&&p&&a href=&https://link.zhihu.com/?target=https%3A//www.assetstore.unity3d.com/cn/%23%21/content/37322& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Asset Store&/a&&/p&&p&感觉Bump Mapping和Smooth都是比较牛逼,可惜只有DirectX支持(Mac党233333)&/p&&p&&b&&u&Generate Lightmap UVs&/u&&/b& 很关键的一点,Generate Lightmap UVs一定要勾上(当然如果有美工姐姐给做好了的可以不勾)。只有这个选项勾上之后,烘焙的光才有作用。&/p&&p&嗯嗯,大概点了和没点的差别如下:&/p&&figure&&img src=&https://pic1.zhimg.com/v2-948128bfff197c3b7a07d141b14ba06c_b.jpg& data-rawwidth=&308& data-rawheight=&244& class=&content_image& width=&308&&&/figure&&figure&&img src=&https://pic1.zhimg.com/v2-4d1b14d24aba54d48a7aff4_b.jpg& data-rawwidth=&265& data-rawheight=&260& class=&content_image& width=&265&&&/figure&&p&&b&Normal &/b&就是法线,法线的计算方法就是三个点确定一个面,一个面再取正向的法线。分享一篇说法线的文章&/p&&p&&a href=&https://link.zhihu.com/?target=http%3A//schemingdeveloper.com//better-method-recalculate-normals-unity/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&A better method to recalculate normals in Unity - The Scheming Developer&/a&&/p&&p&&b&Tangent &/b&这里涉及一个切线空间的概念,好像知乎上已经有大神对这个做了总结了,在这里放个链接:&/p&&p&&a href=&https://www.zhihu.com/question/& class=&internal&&为什么要有切线空间(Tangent Space),它的作用是什么?&/a&&/p&&p&Tangent 选项涉及到bump map相关的效果,下面两张图片上图是没有计算切线空间的,下图是有计算切线空间的,可以明显看到上图在边缘处光照强度以及纹理分布不合理。&/p&&figure&&img src=&https://pic4.zhimg.com/v2-dccd81fb4bcc6c18b6d7a9_b.jpg& data-rawwidth=&425& data-rawheight=&343& class=&origin_image zh-lightbox-thumb& width=&425& data-original=&https://pic4.zhimg.com/v2-dccd81fb4bcc6c18b6d7a9_r.jpg&&&/figure&&figure&&img src=&https://pic3.zhimg.com/v2-15cdd4ce1be4dfea11afad_b.jpg& data-rawwidth=&395& data-rawheight=&363& class=&content_image& width=&395&&&/figure&&h2&摆放模型&/h2&&p&按照个人喜好来布置房间里的家具,我做的如下:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-2e74cb04a_b.jpg& data-rawwidth=&1190& data-rawheight=&625& class=&origin_image zh-lightbox-thumb& width=&1190& data-original=&https://pic4.zhimg.com/v2-2e74cb04a_r.jpg&&&/figure&&h2&&b&导入材质&/b&&/h2&&figure&&img src=&https://pic2.zhimg.com/v2-8e89fffc05a_b.jpg& data-rawwidth=&1208& data-rawheight=&630& class=&origin_image zh-lightbox-thumb& width=&1208& data-original=&https://pic2.zhimg.com/v2-8e89fffc05a_r.jpg&&&/figure&&p&给模型贴上材质。这里需要对应的材质的贴图。比如沙发的材质是这样的:&/p&&figure&&img src=&https://pic1.zhimg.com/v2-452adfe72e235adf1a00b0f_b.jpg& data-rawwidth=&487& data-rawheight=&560& class=&origin_image zh-lightbox-thumb& width=&487& data-original=&https://pic1.zhimg.com/v2-452adfe72e235adf1a00b0f_r.jpg&&&/figure&&p&Unity 的新版本更新了材质系统,算是跟目前主流的PBR(Physically Based Rendering,既物理渲染)渲染技术接轨了。因为如此,可以看到材质上出现了的Metallic和Smoothness这样的系数。&/p&&p&主流的PBR技术使用的一个很重要的物理学光照模型(数学模型)叫做BRDF,全名叫Bidirectional Reflective Distribution Funtion,正是应为这个函数的出现使得物理渲染有了重大的突破。&/p&&p&对于BRDF的公式有很多不同的版本,流传比较好的应该是这个版本:&/p&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-97a2f69d4cd2c_b.jpg& data-rawwidth=&482& data-rawheight=&74& class=&origin_image zh-lightbox-thumb& width=&482& data-original=&https://pic1.zhimg.com/v2-97a2f69d4cd2c_r.jpg&&&/figure&&p&&br&&/p&&p&图形学的基本概念就是,不考虑透明物体的情况下,对于屏幕中的每一个像素点,从屏幕发射一个射线到场景中,对于射到的第一个物体上的交点,进行一系列乱七八糟的数学计算,最后得到的颜色值显示在屏幕上。当屏幕上所有的像素点都计算完之后,自然就会得到一个关于该场景的渲染图。而上面这个公式就是这一系列乱七八糟的数学计算中的一个很重要的部分。&/p&&p&&br&&/p&&p&等式左边为光线强度,也可以粗略的等同为反射光的颜色。其中v为视角方向向量,l为光线方向向量,N为法线向量,h叫做中途向量,就是下面这个东西:
&/p&&figure&&img src=&https://pic3.zhimg.com/v2-0da5f20f6a76f974dc9c_b.jpg& data-rawwidth=&141& data-rawheight=&71& class=&content_image& width=&141&&&/figure&&p&有图应该更好理解:&/p&&p&其中的函数:&/p&&p&F(v,h) :Fresnel equation 菲涅尔效应,不知道大家还记不记得这个出现在中学物理里面的名词。生活中的例子是从不同角度看水看到的图像是不同的,垂直着水面能看到水里的东西,而斜着看会看到更多的倒影。这个效应在不透明物体的表面也会存在,这一项就是来描述这个效应的。&/p&&p&G(l,v,h):Geometry function 反映了由于物体表面的凹凸不平导致的光线的损失。看下下面这图就明白了。&/p&&p&D(h):Normal distribution function 这就是讨论得比较多的高光函数了, 这个函数决定了高光的分布,不同的高光系数大概就是产生这样的效果。&/p&&p&有这个公式计算出来的可以理解为是specularity,再和diffuse color相加即可得到物体在该像素点的成色。diffuse color 可以简单的理解成是物体的带明暗的固有色。当然,实际的渲染中还需要考虑环境对于物体的影响,这部分就不展开了。&/p&&p&(PBR部分的图片的出处均在以下两个网站)&/p&&p&&a href=&https://link.zhihu.com/?target=https%3A//learnopengl.com/%23%21PBR/Theory& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Learn OpenGL, extensive tutorial resource for learning Modern OpenGL&/a&&/p&&p&(这个文章用丰富的图片作为例子解释了最主流的BRDF的计算过程,文章的最后给了一个Albedo+Normal+Metallic+Roughness+AO的例子)&/p&&p&&a href=&https://link.zhihu.com/?target=http%3A//www.jordanstevenstechart.com/physically-based-rendering& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Jordan Stevens - Technical Artist&/a&&/p&&p&(给出BRDF模型的Unity shader实现,以及各种不同的核函数,读后感觉十分震撼)&/p&&p&这样一来,Shader里的&b&Albedo,Normal,Metallic,Smoothness&/b&和&b&Occlusion&/b&就不难理解了。&/p&&p&&b&Height Map&/b&:作为辅助normal map 的更加高级的贴图,效果(右)是比normal 贴图(中) 好不少。&/p&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-9e660fb2345901cfc1efde23ed8d3f87_b.jpg& data-rawwidth=&850& data-rawheight=&312& class=&origin_image zh-lightbox-thumb& width=&850& data-original=&https://pic3.zhimg.com/v2-9e660fb2345901cfc1efde23ed8d3f87_r.jpg&&&/figure&&p&&br&&/p&&p&&b&Emission&/b& 让物体发光。这里的发光是会记录到光照的渲染流程里的(foward rendering慎用)。当然,和Maya的发光不同,这里的发光是不会自带那种模糊特效的,想要做好看的霓虹效果还是老老实实的加bloom吧。&/p&&p&&b&Secondary Map &/b&会叠加在第一层的纹理上,一般是用来做细节的。看下图就懂了:&/p&&p&&b&Render Queue &/b&这个东西早应该放到这里了。渲染队列,简单来说,数字大的会盖住数字小的。注意检测深度的最大渲染队列数是2500。&/p&&p&嗯,由于没有美工妹子帮忙做Metallic 和 Smoothness贴图,所以材质部分就马马虎虎的过了吧。&/p&&p&&b&==未完待续==&/b&&/p&&p&终于把场景搭好了,可是现在的场景还是别样的丑呢。之后还有光线烘焙和加特效的环节,希望大家继续关注哦。&/p&
十块钱买房?在Unity里面搭个场景就好了呀。也不知道是从什么时候起,圈内就流行一种说法,说Unity适合做手机游戏,Unreal适合做大作。多年从事Unity游(jiao)戏(ge)开(zuo)发(y的我,真想替Unity报个不平。以绝大多数游戏团队的努力程度,还没到要拼引擎的…
&figure&&img src=&https://pic1.zhimg.com/v2-3eeaf3c7fad9e4964dce676ea52b3aee_b.jpg& data-rawwidth=&1191& data-rawheight=&634& class=&origin_image zh-lightbox-thumb& width=&1191& data-original=&https://pic1.zhimg.com/v2-3eeaf3c7fad9e4964dce676ea52b3aee_r.jpg&&&/figure&&p&上两节慢吞吞的补了很多技术实现的细节,感觉要是把用到的所有技术细节都过一遍可能还需要若干篇文章。所以决定先把整体的流程这篇好玩的写了,以后再慢慢补技术细节的部分。&/p&&h2&&b&模型导入&/b&&/h2&&p&导入房间,沙发,雕像和电视机模型,同时还有相对应的贴图。&/p&&figure&&img src=&https://pic3.zhimg.com/v2-fc6ac328a7abc192d7d7d2_b.png& data-rawwidth=&495& data-rawheight=&605& class=&origin_image zh-lightbox-thumb& width=&495& data-original=&https://pic3.zhimg.com/v2-fc6ac328a7abc192d7d7d2_r.jpg&&&/figure&&p&导入时,导入选项的Generate Lightmap UVs打钩。&/p&&h2&&b&摆放模型&/b&&/h2&&p&按照个人喜好来布置房间里的家具,我做的如下:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-b08bf719d845a4fa69be73dfd4d4d22b_b.jpg& data-rawwidth=&1190& data-rawheight=&625& class=&origin_image zh-lightbox-thumb& width=&1190& data-original=&https://pic4.zhimg.com/v2-b08bf719d845a4fa69be73dfd4d4d22b_r.jpg&&&/figure&&p&&br&&/p&&h2&&b&设置材质&/b&&/h2&&p&给模型贴上材质。这里需要对应的材质的贴图,我使用了下载的模型自带的贴图。比如沙发的材质是这样的:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-452adfe72e235adf1a00b0f_b.png& data-rawwidth=&487& data-rawheight=&560& class=&origin_image zh-lightbox-thumb& width=&487& data-original=&https://pic4.zhimg.com/v2-452adfe72e235adf1a00b0f_r.jpg&&&/figure&&p&嗯,其实材质在搭场景的时候还是很重要的,但是这部分内容比较美工向一些,这里就不展开了。我用的是Unity标准的材质,贴图用的是通用的棉布的Albedo +Normal 贴图。&/p&&p&这里安利一下我的上一篇文章,里面讨论了关于材质的内容:&/p&&p&&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&【如何用十块钱买房】Unity室内场景 + 光照练习 I&/a&&/p&&p&想要效果好一点的话可以使用substance painter。&/p&&p&&a href=&http://link.zhihu.com/?target=https%3A//www.allegorithmic.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Allegorithmic&/a&&/p&&p&贴好材质后的场景如下:&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-ab9b249d74aa56c2738f_b.jpg& data-rawwidth=&1197& data-rawheight=&636& class=&origin_image zh-lightbox-thumb& width=&1197& data-original=&https://pic4.zhimg.com/v2-ab9b249d74aa56c2738f_r.jpg&&&/figure&&p&&br&&/p&&h2&&b&烘焙光线&/b&&/h2&&p&把场景中各个物体设置为静态(static),至少是光照贴图静态(light map static)。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-82b100a9edd_b.png& data-rawwidth=&714& data-rawheight=&275& class=&origin_image zh-lightbox-thumb& width=&714& data-original=&https://pic2.zhimg.com/v2-82b100a9edd_r.jpg&&&/figure&&p&设置场景的光源属性为烘焙。这里以场景中的方向光源(directional light)为例。设置如下:&/p&&figure&&img src=&https://pic2.zhimg.com/v2-07baa12d6c295732cdf20489_b.png& data-rawwidth=&706& data-rawheight=&557& class=&origin_image zh-lightbox-thumb& width=&706& data-original=&https://pic2.zhimg.com/v2-07baa12d6c295732cdf20489_r.jpg&&&/figure&&p&把项目设置为线性颜色空间(可选项,看各自项目需求)&/p&&p&在Edit=&Project Settings=&Player Settings 下,Color Space 选项调节为Linear&/p&&figure&&img src=&https://pic3.zhimg.com/v2-3a8eb7d07ed604b01d322_b.png& data-rawwidth=&475& data-rawheight=&349& class=&origin_image zh-lightbox-thumb& width=&475& data-original=&https://pic3.zhimg.com/v2-3a8eb7d07ed604b01d322_r.jpg&&&/figure&&p&然后打开光照设置窗口,Windows=&Lighting=&Settings,在弹出窗口的Scene框下,设置如图。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-bf8fcc7c289e1a88cb23d68_b.png& data-rawwidth=&508& data-rawheight=&899& class=&origin_image zh-lightbox-thumb& width=&508& data-original=&https://pic1.zhimg.com/v2-bf8fcc7c289e1a88cb23d68_r.jpg&&&/figure&&p&点击最下方Generate Lighting按钮,最终效果如下:&/p&&p&&br&&/p&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-dbae1b9f2b5_b.jpg& data-rawwidth=&1208& data-rawheight=&618& class=&origin_image zh-lightbox-thumb& width=&1208& data-original=&https://pic2.zhimg.com/v2-dbae1b9f2b5_r.jpg&&&/figure&&p&经过烘焙,物体的阴影变得更加柔和,场景也变得明亮,显得舒服多了。不过仔细观察,还是可以发现比如沙发底下地板过亮,电视机屏幕没有反射显得死板等等毛病。&/p&&h2&&b&添加反射&/b&&/h2&&p&GameObject =& Light =& Reflection Probe,给场景添加一个反射探测球。&/p&&p&在场景中出现一个灰色的球。选中Reflection Probe(灰色的球),把它移到房间正中。调节Box Size使其刚好覆盖房间内所有对反射光线比较敏感的物体(电视+木板+雕像)。调节属性Resolution志512或者更高。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-ee331386bcb63affae97d_b.png& data-rawwidth=&1197& data-rawheight=&616& class=&origin_image zh-lightbox-thumb& width=&1197& data-original=&https://pic2.zhimg.com/v2-ee331386bcb63affae97d_r.jpg&&&/figure&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-7b094a2b028e7c5ff95ee3ea97df789a_b.png& data-rawwidth=&489& data-rawheight=&582& class=&origin_image zh-lightbox-thumb& width=&489& data-original=&https://pic3.zhimg.com/v2-7b094a2b028e7c5ff95ee3ea97df789a_r.jpg&&&/figure&&p&调节好后,点击Bake。&/p&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-2f4becb39975_b.jpg& data-rawwidth=&1198& data-rawheight=&626& class=&origin_image zh-lightbox-thumb& width=&1198& data-original=&https://pic2.zhimg.com/v2-2f4becb39975_r.jpg&&&/figure&&p&&br&&/p&&p&烘焙成功后,球会变成一个带场景反射贴图的球。&/p&&figure&&img src=&https://pic4.zhimg.com/v2-3bd95de9ff0fd8ad9e67ae7_b.jpg& data-rawwidth=&1207& data-rawheight=&630& class=&origin_image zh-lightbox-thumb& width=&1207& data-original=&https://pic4.zhimg.com/v2-3bd95de9ff0fd8ad9e67ae7_r.jpg&&&/figure&&p&&br&&/p&&p&上图添加了反射的场景。嗯,好像也没什么变化。。。其实这一步是为了下面添加Image Effect做准备的。注意到右侧的电视屏幕出现了反射光。&/p&&h2&&b&特效美化&/b&&/h2&&p&场景搭的好坏50%靠材质,50%靠特效,当然,这是建立在物品摆放+打光基本没问题的基础之上。&/p&&p&Unity 5.5 官方推出了一个免费的特效插件Post Processing Stack,这个插件涵盖了这篇文章之后讲的所有特效,基本上是收录了所有常见的3D真实感场景渲染需要用到的效果,功能很强大,其中一些的效果甚至比付费插件还要好(毕竟是亲儿子)。&/p&&p&&a href=&http://link.zhihu.com/?target=https%3A//www.assetstore.unity3d.com/cn/%23%21/content/83912& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Asset Store&/a&&/p&&p&但是在这里我还是想用传统的方法,逐个添加特效。&/p&&p&一般特效添加顺序:&/p&&ol&&li&Screen Space Reflection&/li&&li&Screen Space Ambient Occlusion&/li&&li&Depth of Field&/li&&li&Motion Blur&/li&&li&Bloom&/li&&li&Tonemapping&/li&&li&LUT/Color Grading&/li&&li&Anti Aliasing&/li&&/ol&&p&使用的特效插件:&/p&&p&&a href=&http://link.zhihu.com/?target=https%3A//www.assetstore.unity3d.com/cn/%23%21/content/51515& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Asset Store&/a& (官方的特效包)&/p&&p&&a href=&http://link.zhihu.com/?target=https%3A//www.assetstore.unity3d.com/cn/%23%21/content/17324& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Asset Store&/a&(一个效果比较好的Bloom插件)&/p&&h2&SSR (Screen Space Reflection)&/h2&&p&这个特效是给场景的物体添加反射,用特效取代实际的渲染,而获得廉价但是效果十分不错的反射效果。&/p&&p&选中主相机,添加脚本Screen Space Reflection。设置Camera的Rendering Path 为Deferred,并且关掉 Allow MSAA。注意Screen Space Reflection要求相机使用延迟渲染(Deferred Rendering),但是相机自带的抗锯齿为MSAA,要求向前渲染(Forward Rendering)。所以添加SSR后,场景中的锯齿会骤然变多。之后进行的抗锯齿阶段会进行修复。&/p&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-6a6bc0fba5fe3c313b64aafe644fc06a_b.png& data-rawwidth=&494& data-rawheight=&734& class=&origin_image zh-lightbox-thumb& width=&494& data-original=&https://pic3.zhimg.com/v2-6a6bc0fba5fe3c313b64aafe644fc06a_r.jpg&&&/figure&&p&&br&&/p&&p&添加SSR后,木地板和电视玻璃可以明显的看到反射,整个场景变得立体了。&/p&&figure&&img src=&https://pic4.zhimg.com/v2-ce26f4bbba127a5a91fcf_b.jpg& data-rawwidth=&1204& data-rawheight=&630& class=&origin_image zh-lightbox-thumb& width=&1204& data-original=&https://pic4.zhimg.com/v2-ce26f4bbba127a5a91fcf_r.jpg&&&/figure&&p&&br&&/p&&h2&SSAO (Screen Space Ambient Occlusion)&/h2&&p&这个特效是给场景的一些小旮旯添加阴影,强化物体投影与物体暗部的分界线,使物体更加立体。画过素描的可以理解为给物体和投影的分界线加深几笔(嗯,老师会骂的,但是效果很好情不自禁的就画了呀)&/p&&p&给相机添加SSAO脚本。在Asset Store上有一个叫SSAO Pro的插件,但是用了几次感觉有些莫名其妙的Bug。Unity 官方出的SSAO比较稳定,所以还是用免费的这个吧。&/p&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-1b6d12d2d3b5a91ee7ca_b.jpg& data-rawwidth=&489& data-rawheight=&199& class=&origin_image zh-lightbox-thumb& width=&489& data-original=&https://pic3.zhimg.com/v2-1b6d12d2d3b5a91ee7ca_r.jpg&&&/figure&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-963bc5e154a6_b.jpg& data-rawwidth=&1204& data-rawheight=&632& class=&origin_image zh-lightbox-thumb& width=&1204& data-original=&https://pic3.zhimg.com/v2-963bc5e154a6_r.jpg&&&/figure&&p&&br&&/p&&p&可以看到沙发底部,电视机背面和天花板缝隙等地方的阴影加深了,场景主体更加凸显。&/p&&h2&DoF(Depth of Field)&/h2&&p&简单来说就是达到照相机的对焦的效果,把前景和远景虚化。想想玩单反的同学发的高逼格照片,嗯,就是那种效果。&/p&&p&给相机添加Depth of Field脚本。点击Visulize,可以看到场景变成了黑白色,黑色表示清晰,白色表示模糊。调节Focal Distance和Focal Size来调节需要聚焦和虚化的部分。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-876c93aeed6af4a8d68ebfd1_b.jpg& data-rawwidth=&1205& data-rawheight=&627& class=&origin_image zh-lightbox-thumb& width=&1205& data-original=&https://pic2.zhimg.com/v2-876c93aeed6af4a8d68ebfd1_r.jpg&&&/figure&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-3a6dfae65ebebe50c15e41_b.png& data-rawwidth=&491& data-rawheight=&368& class=&origin_image zh-lightbox-thumb& width=&491& data-original=&https://pic2.zhimg.com/v2-3a6dfae65ebebe50c15e41_r.jpg&&&/figure&&p&最后效果如下,我特意把参数调得夸张了一些:&/p&&figure&&img src=&https://pic1.zhimg.com/v2-effeb597b668ab598ba904_b.jpg& data-rawwidth=&1206& data-rawheight=&629& class=&origin_image zh-lightbox-thumb& width=&1206& data-original=&https://pic1.zhimg.com/v2-effeb597b668ab598ba904_r.jpg&&&/figure&&h2&Motion Blur&/h2&&p&主要用于快速移动的物体以及摄像机快速移动时产生动态模糊的效果。由于这里的场景是静态的所以就不考虑这个特效了。&/p&&h2&Bloom&/h2&&p&这个特效是让场景比较亮的部分发光。通常用于霓虹灯,阳光,光球等效果。个人感觉在发光物体和周围场景有一点区分度的场景中效果比较好。另外这个效果葉可以用于给场景添加模糊以遮盖部分瑕疵。&/p&&p&给相机添加SE Natural Bloom And Dirty Lens,由于这个场景对于发光的要求不高,所以用这个插件遮一下瑕疵。在免费的特效里,Bloom Optimzed的效果也是不差的。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-513bea17ddff7e8a725d994_b.jpg& data-rawwidth=&1198& data-rawheight=&629& class=&origin_image zh-lightbox-thumb& width=&1198& data-original=&https://pic1.zhimg.com/v2-513bea17ddff7e8a725d994_r.jpg&&&/figure&&p&画面稍微柔和一些。&/p&&h2&Tonemapping & Color Grading&/h2&&p&基本上等同于Photoshop里的拉曲线+调色调,Final Cut 里面调色板的功能,或者说是美图秀秀里面的各种滤镜。&/p&&p&给相机添加Tonemapping Color Grading的特效,调节各部分属性至理想效果。&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-5d8ff5ab21e5f9cc5a7c53_b.jpg& data-rawwidth=&496& data-rawheight=&904& class=&origin_image zh-lightbox-thumb& width=&496& data-original=&https://pic4.zhimg.com/v2-5d8ff5ab21e5f9cc5a7c53_r.jpg&&&/figure&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-0b71fa7fc30e4f4dd8171e_b.jpg& data-rawwidth=&1207& data-rawheight=&629& class=&origin_image zh-lightbox-thumb& width=&1207& data-original=&https://pic3.zhimg.com/v2-0b71fa7fc30e4f4dd8171e_r.jpg&&&/figure&&p&通过色彩的调整可以做出各种不同氛围的场景,我这里调了一个偏温馨感觉的色调。&/p&&h2&Anti Aliasing&/h2&&p&抗锯齿,即把物体粗糙的边缘变得平滑。目前感觉效果最好的还是Camera自带的MSAA(特别是这个场景中后半部分的门窗部分,这种规整细长的框架解构,特别明显。无奈与SSR冲突。所以在使用DOF+Bloom把后半部分的门窗虚化后已经不那么明显了。)&/p&&figure&&img src=&https://pic4.zhimg.com/v2-efcb6a74e3537114feb69f_b.jpg& data-rawwidth=&491& data-rawheight=&177& class=&origin_image zh-lightbox-thumb& width=&491& data-original=&https://pic4.zhimg.com/v2-efcb6a74e3537114feb69f_r.jpg&&&/figure&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-5bb0716cbb0c1038dfbc_b.jpg& data-rawwidth=&1207& data-rawheight=&627& class=&origin_image zh-lightbox-thumb& width=&1207& data-original=&https://pic1.zhimg.com/v2-5bb0716cbb0c1038dfbc_r.jpg&&&/figure&&p&沙发的边缘变得光滑,抗锯齿效果非常好。后面的的门窗部分依然有锯齿,但是并不影响整体效果。&/p&&p&&br&&/p&&h2&收尾&/h2&&p&给三个门窗加上区域光,使其正好覆盖在门窗上。&/p&&figure&&img src=&https://pic4.zhimg.com/v2-08e978f35f712a805d67e430bb78fdfb_b.jpg& data-rawwidth=&1195& data-rawheight=&630& class=&origin_image zh-lightbox-thumb& width=&1195& data-original=&https://pic4.zhimg.com/v2-08e978f35f712a805d67e430bb78fdfb_r.jpg&&&/figure&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-3f4a6280e0bdbbf0da5230ed49fef7db_b.png& data-rawwidth=&424& data-rawheight=&513& class=&origin_image zh-lightbox-thumb& width=&424& data-original=&https://pic4.zhimg.com/v2-3f4a6280e0bdbbf0da5230ed49fef7db_r.jpg&&&/figure&&p&在Lighting 的窗口内点击Generate Lighting,重新生成一张光照贴图。&/p&&p&检查帧率,FPS为70+&/p&&figure&&img src=&https://pic3.zhimg.com/v2-e3fdd1cf5c53c8d64cfd616_b.jpg& data-rawwidth=&1195& data-rawheight=&702& class=&origin_image zh-lightbox-thumb& width=&1195& data-original=&https://pic3.zhimg.com/v2-e3fdd1cf5c53c8d64cfd616_r.jpg&&&/figure&&p&最后对场景进行微调,一个午后喝茶的场景就做好啦~&/p&&figure&&img src=&https://pic3.zhimg.com/v2-3eeaf3c7fad9e4964dce676ea52b3aee_b.jpg& data-rawwidth=&1191& data-rawheight=&634& class=&origin_image zh-lightbox-thumb& width=&1191& data-original=&https://pic3.zhimg.com/v2-3eeaf3c7fad9e4964dce676ea52b3aee_r.jpg&&&/figure&&p&再来对比一下Unreal做的类似的场景:&/p&&figure&&img src=&https://pic1.zhimg.com/v2-c5d8ce863b9bc_b.jpg& data-rawwidth=&1075& data-rawheight=&605& class=&origin_image zh-lightbox-thumb& width=&1075& data-original=&https://pic1.zhimg.com/v2-c5d8ce863b9bc_r.jpg&&&/figure&&p&你们真的觉得这两个引擎的差距很大?&/p&&p&&br&&/p&&p&最后安利一波这个系列的前两篇文章,对于用到的一些技术的细节进行讨论。&/p&&p&&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&【如何用十块钱买房】Unity室内场景 + 光照练习 I&/a&&/p&&p&&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&Unity室内场景 + 光照练习 II&/a&&/p&&p&如果有时间的话会把特效部分的技术细节讨论补上。&/p&&p&希望喜欢的朋友点个赞 ~&/p&
上两节慢吞吞的补了很多技术实现的细节,感觉要是把用到的所有技术细节都过一遍可能还需要若干篇文章。所以决定先把整体的流程这篇好玩的写了,以后再慢慢补技术细节的部分。模型导入导入房间,沙发,雕像和电视机模型,同时还有相对应的贴图。导入时,导入…
&p&&b&作为一个在中国生活十几年,在游戏行业工作八九年的歪果仁,我从09年就开始使用Unity 3d,并对技术美术做了还算深的研究。由于中文水平不够完美,我还是用英文来和大家分享一下技术美术的经验。PS:&/b&&b&我申请了一个QQ群,有关Shader, Level Design, Game Music都可以加进来&/b&&/p&&br&&p&My name is David and I am a founder of Mechanist Games(梦加网络). Our company made City of Steam(蒸汽之城) and Dream Raiders(盗梦英雄),
and of course have projects in development too.&/p&&br&&p&Shader coding is still a new field in the world, and even
younger in China, so I’ll make this article more about advice, not technical
details. The hardest thing is just knowing how to begin. And that’s all I can
briefly cover here.&/p&&br&&p&&b&Who should do shader
coding, art or coder?&/b&&/p&&br&&p&Last San Francisco GDC at the tech-artist round table, this
same question came up.&/p&&p&Neither. A tech artist should do shader coding. But don’t
worry both artists and coders can become tech artists.&/p&&br&&p&Remember that tech artists in the west are a complete mixed
group, specializing in complex animation rigging, performance optimization,
creating tools for a large art pipeline and coding shaders. In China, the
amount of human resources gaming companies can use usually means that some of
these things be solved by basically just hiring more people or making them work
harder. Western companies have to achieve more with less people, so tech
artists are more than Chinese.&/p&&br&&p&A tech artist needs both sound logic and artistic knowledge
to code good shaders. These are both things you can learn the same way I did
(see below).&/p&&br&&p&&b&How do western
companies do shaders?&/b&&/p&&br&&p&Shaders are a core technology of a game. They have a huge
impact on the visual style of a game. The kind of shaders that need to be used
would be decided very early, when determining the art style of a game.&/p&&br&&p&A tech artist would find out how to achieve the art style,
develop prototype shaders and other assets to realize the desired look and feel
with the art director.&/p&&br&&p&Then, if the game prototype passes a company evaluation, the
tech artist would then begin creating tools and pipeline workflow documents to
teach the other artists in the team how to make the assets required for this
style.&/p&&br&&p&Toward the end of the project, the tech artist would be
mainly focused on optimizing GPU performance and trying to solve compatibility
issues for rendering on different types of target platform.&/p&&br&&p&Even giant European companies like CD Projekt Red only have
a few tech artists, so not all their time can be focused on shaders. Other US
companies like Volition are known to have more tech artists compared to their
size, but these people are still incredibly rare. Many people with tech artist
knowledge go on to develop game engines too.&/p&&br&&p&&b&How do you study how
to write shaders?&/b&&/p&&br&&p&Firstly, have you got what it takes?&/p&&p&There are two core abilities needed to make shaders: Logic
and creativity. If you have these in any amount, it’s possible for you to learn
shader coding.&/p&&br&&p&There is an experience requirement, too. I’d say it’s about
3 years, but it may vary greatly. You really need to know the engine you are
going to use very deeply.&/p&&br&&p&And lastly, there is an English language requirement. If
your English is excellent, you will have access to more study materials and lots
of experienced professionals through the unity asset store.&/p&&br&&p&&b&What language should you learn?&/b&&br&&/p&&br&&p&In China, learn Cg (not CG).
That is Nvidia’s “C for graphics” language. It doesn’t stand for “Computer
Graphics”. It is supposed to be like other C languages, but I don’t really
think it is.&/p&&br&&p&If you learn unity’s shaderlab
or GLSL shader languages, you’re always going to limit yourself. Unity
can compile your Cg shaders for any platform you like, anyway.&/p&&br&&p&Since China is mobile
dominated, Cg is the best choice because it is the most efficient for OpenGL
platforms like Androids or iOS devices. The advantages of getting into GLSL to
benefit from Apple’s Metal API are barely worth it right now, and you’d have to
be doing something really advanced to even need it.&/p&&br&&p&In the future, if mobile
devices become powerful enough that we can start using surface shaders, then
learning will be really easy if you are already a master of Cg shaders.&/p&&br&&p&盗梦英雄’s
shaders are all in Cg, and the performance is excellent. I built all the levels
myself to benefit from the optimized shaders and the results are pretty
satisfactory. I had a good teacher, which helped. Most scenes are ~40k-100k
vertices, which is high for a mobile game. Plus, I learned some good tricks we
are using in our next game too.&/p&&br&&p&&b&What tools do I need?&/b&&br&&/p&&p&You need to be proficient in Photoshop,
3dsMax, and Unity3d. There are many alternative programs like Blender and Maya
too.&br&&/p&&br&&p&There are visual tools like
shaderforge that can be used to create shader code, but unfortunately, these
are useless for mobile devices. The code they produce is likely to be many times
less efficient than Cg, and usually result in thermal issues and poor FPS on
the target device.&/p&&p&Aside from unity MonoDevelop
for writing the shaders, there are lots of choices. And it really is just
preference. Unlike other coding language tools (Visual Studio for example),
shaders don’t have error catching helpers. When there is a mistake in your
code, you won’t get warnings –it will just fail to compile, or compile with
visual errors. There are so many ways to do things in a shader, and different language
syntaxes, so there still isn’t any good solution for this. You just have to
hunt the bugs down with your own eyes, or hope Unity’s console can point you to
the offending line of code (it often does not, though).&/p&&br&&p&One thing you will probably
need soon if you plan to get really serious about doing shader animation or
special effects is a vertex painting tool. Vertices of a model can have color
properties. These colors are not visible in the game (unless you specifically
make them), and are used behind the scenes to do things like moving plants,
wind blowing hair, rolling waves in the sea, and so on. Use the asset store to
get one.&/p&&br&&p&Buy things in the asset store.
The developers of these little tools and plugins are so helpful. This is how
you get introduced to pros who are really experienced and specialized. All of
my teachers were people I purchased tools and plug-ins and assets from. And
many are now my friends too.&/p&&br&&p&&b&Shader theory&/b&&br&&/p&&p&You need to understand the
basic theory first, otherwise you won’t make it very far. Let me make a really
simple breakdown. For Unity3d vertex+fragment shaders (Cg, like you asked for)…&br&&/p&&br&&br&&figure&&img src=&https://pic3.zhimg.com/fe0c67daa17ce232ebd156_b.jpg& data-rawwidth=&895& data-rawheight=&392& class=&origin_image zh-lightbox-thumb& width=&895& data-original=&https://pic3.zhimg.com/fe0c67daa17ce232ebd156_r.jpg&&&/figure&&br&&br&&p&Of course, this is not a
complete shader yet. But it’s how every shader you write will be structured,
and understanding how it works is fundamentally important. You need to know how
these bits work. And you can just read the internet to work this out.&/p&&br&&p&&b&Copy some shaders&/b&&br&&/p&&p&When collecting shader code,
the best thing to do is buy shader packages on the unity asset store. Make sure
you get Cg and not surface shaders –one or two reviews will tell you if it’s
worth buying. If somebody says it’s slow on mobile, don’t buy it.&/p&&br&&p&Look at the shader code. Start
with really simple ones, 50 lines or less. Edit things, change things, see the
results. Experiment.&/p&&br&&p&Make small goals for yourself. For
example, add a slider that can make the object lighter or darker. Add a tint
color. Remove a property. Change small things to build up your confidence.&/p&&br&&p&&b&Write your own shaders&/b&&br&&/p&&br&&p&Trying to write your own
shaders needs to start with small steps. The best guides I had were these, in
English. I can understand these might be daunting to a Chinese native. Does
anyone know a Chinese translation of them?&br&&/p&&br&&p&&a href=&//link.zhihu.com/?target=https%3A//www.youtube.com/watch%3Fv%3DhDJQXzajiPg& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://www.&/span&&span class=&visible&&youtube.com/watch?&/span&&span class=&invisible&&v=hDJQXzajiPg&/span&&span class=&ellipsis&&&/span&&/a&&/p&&p&&a href=&//link.zhihu.com/?target=http%3A//en.wikibooks.org/wiki/Cg_Programming/Unity/Minimal_Shader& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Cg Programming/Unity/Minimal Shader&/a&&/p&&br&&p&Aside from these two, my
knowledge came from a hundred tiny details and facts that I found all over the
net, and as advice from friends and teachers. Everything you can read will be
useful, as long as you can apply it to practice.&/p&&br&&p&When you start, avoid copy
pasting stuff. It will be harder to remember how to do it if you copy paste.
You’re going to copy paste lots of your own code later, so it’s good to know
what you’re actually reproducing. If you’re in the habit of assembling stuff
from different sources online, you are going to have a very hard time making
all the pieces fit.&/p&&br&&p&Once you can write your own
basic shader, your journey to become a shader coder has begun.&/p&&p&Honestly, the rest is downhill,
and gets increasingly more interesting and cooler as you go. You can start
adding more and more things to shaders like lighting, shadows, bumpmaps,
outlines, colors and other things.&/p&&br&&p&Training under someone skilled
is certainly the best situation. That’s how I learned. If you are lucky enough
to have a tech artist in your company, then try to apprentice yourself. If not,
you either have to change company or try to learn on your own. It’s very
uncommon for companies to give people time during work to study new tools or
skills, so you will have to be creative about it or very busy after hours.&/p&&br&&p&I hope that China GDC can also
have a tech artist round table some time soon.&/p&&br&&p&By the way, I’m hiring both
experienced and intern positions to study under me right now in Xiamen, so if
you are interested you can add
我申请了一个QQ群,有关Shader, Level Design, Game Music都可以加进来&/p&
作为一个在中国生活十几年,在游戏行业工作八九年的歪果仁,我从09年就开始使用Unity 3d,并对技术美术做了还算深的研究。由于中文水平不够完美,我还是用英文来和大家分享一下技术美术的经验。PS:我申请了一个QQ群,有关Shader, Level Design, Game Music…
&figure&&img src=&https://pic1.zhimg.com/v2-47dcbbf1471c7bdb130538_b.jpg& data-rawwidth=&800& data-rawheight=&413& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&https://pic1.zhimg.com/v2-47dcbbf1471c7bdb130538_r.jpg&&&/figure&&p&&b&提要&/b&&br&&/p&&br&&p&一说到开放世界,沙盒,第一个想到的技术点就是Procedual Generation。贴个Wiki上的定义&/p&
&p&&i&术语“过程化”是指计算一个特定&a href=&https://link.zhihu.com/?target=https%3A//zh.wikipedia.org/wiki/%25E5%2587%25BD%25E6%& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&函数&/a&的过程,如&a href=&https://link.zhihu.com/?target=https%3A//zh.wikipedia.org/wiki/%25E5%E5%25BD%25A2& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&分形&/a&。过程化生成常用于生成贴图、多边形网格、声效、语音合成和音乐制作等。过程化生成的好处是衹要很小的函数和源数据,便可以制造出很多和源数据有关或类似但存在不同的新数据。电子游戏借助它可出现许多(接近无限)个关卡。这可以缩短开发时间,也可以减小软件的文件大小。&/i&&/p&
&p&很多游戏都有用到Procedual Generation的技术,或多或少,但是对于能够将Procedual Generation和GamePlay融合的最好的,当然是Minecraft的了。&/p&&p&所有代码均出自forge,ver10.2(加上一部分人肉反编译) 。部分图片来自minecraft wiki。&/p&&p&&b&所有代码的使用均需遵循开源协议!&/b&&/p&&a href=&https://link.zhihu.com/?target=https%3A//github.com/MinecraftForge/MinecraftForge/blob/1.10.x/LICENSE-new.txt& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&github.com/MinecraftFor&/span&&span class=&invisible&&ge/MinecraftForge/blob/1.10.x/LICENSE-new.txt&/span&&span class=&ellipsis&&&/span&&/a&&h2&&b&线性同余随机数生成器&/b&&/h2&
&p&为什么同样的种子能够生成完全一致的地形,利用的就是伪随机数。&/p&&p&LCG 算法数学上基于公式:&/p&&p&X(n+1) = (a * X(n) + c) % m&br&&/p&
&p&其中,各系数为:&/p&
&p&模&b&m&/b&,
&p&系数&b&a&/b&,
0 & a & m&/p&
&p&增量&b&c&/b&,
0 &= c & m&/p&
&p&原始值(种子) 0 &= X(0) & m&/p&
&p&其中参数&b&c, m, a&/b&比较敏感,或者说直接影响了伪随机数产生的质量。&/p&
&p&假设a = 2, c = 3, m = 10,初始值Xo = 5,写一下代码&/p&
&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&int lcgRandom(int seed)
return (2 * seed + 3) % 10;
void Start() {
int seed = 5;
for (int i = 0; i & 10; i++)
seed = lcgRandom(seed);
Debug.Log(seed);
&/code&&/pre&&/div&&br&&p&得到的结果就是&/p&
&p&5 3 9 1 5 3 9 1 5 3...&/p&
&p&可以发现会有一个循环周期,这是因为取模运算而造成的,在随机数理论里,这个周期称为&/p&
&p&&b&period of
the sequence&/b& 。对于随机数生成,这个周期当然是越大越好,这样让人感觉随机的随机程度就越高,通常情况下m越大,这个周期就越大。同时a和c也对周期有一定的影响,有些参数能够将m内的数都生成出来,这时候,这个生成器就是 Full-Cycle Linear Congruential Generator 。&/p&
&p&一些随机数生成算法直接将c设置为0,因为c只是一个常数&/p&
aXn-1 mod m&/p&
&p&这样的生成器称为 &b&pure multiplicative generator&/b&. 这样的生成器有一个问题是没法生成0.&/p&
&p&对与,m和a的取值,有个最小标准一说。由Park 和Miller 提出,m = 2,147,483,647 and a = 16,807 ,如果是要提出更好的算法,不能比这个组合差。&/p&
&p&一般而言,高LCG的m是2的指数次幂(一般2^32或者2^64),因为这样取模操作截断最右的32或64位就可以了。多数编译器的库中使用了该理论实现其伪随机数发生器rand()。&/p&&p&看一下Minecraft中的随机数生成器:&/p&
&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&void GenLayer::initChunkSeed(int x, int z)
m_ChunkSeed = m_WorldGenS
m_ChunkSeed *= m_ChunkSeed * 6793005L + 8963407L;
m_ChunkSeed +=
m_ChunkSeed *= m_ChunkSeed * 6793005L + 8963407L;
m_ChunkSeed +=
m_ChunkSeed *= m_ChunkSeed * 6793005L + 8963407L;
m_ChunkSeed +=
m_ChunkSeed *= m_ChunkSeed * 6793005L + 8963407L;
m_ChunkSeed +=
int GenLayer::nextInt(unsigned int range)
unsigned int r = (unsigned int)(m_ChunkSeed && 24) %
m_ChunkSeed *= m_ChunkSeed * 6793005L + 8963407L;
m_ChunkSeed += m_WorldGenS
&/code&&/pre&&/div&&br&&p&
m_ChunkSeed用64位来存,这里没有看到取模运算,对于unsigned整型溢出,C的规范是有定义的——“溢出后的数会以2^(8*sizeof(type))作模运算&/p&
&h2&&b&程序生成流水线&/b&&/h2&
&p&类似于富x康的iphone装配流水线,Minecraft中,从一个随机数种子到在游戏中显示的地形,有着自己的一条生成流水线。&/p&
&p&整体的生成流水线如下图&/p&
&figure&&img src=&https://pic3.zhimg.com/v2-348cdd6f713d648a2d167f_b.jpg& data-rawwidth=&732& data-rawheight=&651& class=&origin_image zh-lightbox-thumb& width=&732& data-original=&https://pic3.zhimg.com/v2-348cdd6f713d648a2d167f_r.jpg&&&/figure&&p&简单流程的介绍可以参考这个&a href=&https://www.zhihu.com/question/& class=&internal&&Minecraft 的地形生成算法是什么?&/a&&/p&&br&&h2&矿道生成&/h2&&p&Minecraft中结构类的生成发生在洞穴峡谷生成之后,生成的结构主要包括废弃矿坑,村庄,要塞,地牢等。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-f1cd4acfe156cb7b6641cd_b.jpg& data-rawwidth=&800& data-rawheight=&424& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&https://pic2.zhimg.com/v2-f1cd4acfe156cb7b6641cd_r.jpg&&&/figure&&br&&figure&&img src=&https://pic1.zhimg.com/v2-be99b300dc51e10b904c_b.jpg& data-rawwidth=&1440& data-rawheight=&900& class=&origin_image zh-lightbox-thumb& width=&1440& data-original=&https://pic1.zhimg.com/v2-be99b300dc51e10b904c_r.jpg&&&/figure&&p&Structure生成流程&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-85c91f41fb2_b.jpg& data-rawwidth=&556& data-rawheight=&420& class=&origin_image zh-lightbox-thumb& width=&556& data-original=&https://pic1.zhimg.com/v2-85c91f41fb2_r.jpg&&&/figure&&br&&br&&p&相关的结构UML图&/p&&figure&&img src=&https://pic1.zhimg.com/v2-af65a4a1b0a10c4c0b1fb364e68b1008_b.jpg& data-rawwidth=&1138& data-rawheight=&764& class=&origin_image zh-lightbox-thumb& width=&1138& data-original=&https://pic1.zhimg.com/v2-af65a4a1b0a10c4c0b1fb364e68b1008_r.jpg&&&/figure&&br&&p&简单的描述&/p&&ol&&li&在生成Chunk的时候检测是否适合生成当前结构;&br&&/li&&li&生成中心建筑,矿坑的话就是一个Room,村庄的话就是一个水井;&br&&/li&&li& 检测中心建筑的四个方向是否可以随机生成新的结构和建筑;&br&&/li&&li&如果可以生成,则检测是否可以基于这个Component去生成可以连接的新的Component&br&&/li&&li&重复4&br&&/li&&li&Populate阶段将各个Component进行方块填充,还有刷怪龙,宝箱,村民等。&br&&/li&&/ol&&br&&p&先来讲一个&b&随机生成地牢的算法&/b&。&br&&/p&&p&如果要生成一个地牢,我们首先定义出一些地牢中的一些基本组件,它们有:&/p&&p&&b&房间&/b&:它有一个或者多个出口;&br&&b&走廊&/b&:它是一个很窄很长的区域,拥有两个出口,它也可能是一个斜坡;&br&&b&连接处&/b&:是一个有着三个以上出口的小的空间;&br&&/p&&p&下面是几个简单的组件模型,每个组件都有一个包围盒用于防止在生成的时候组件穿插,在每个组件的出口,都有一个mark,标记了位置和旋转量,用于组件的匹配.&/p&&figure&&img src=&https://pic2.zhimg.com/v2-7baa15c61bbdae40e707b9f_b.jpg& data-rawwidth=&936& data-rawheight=&459& class=&origin_image zh-lightbox-thumb& width=&936& data-original=&https://pic2.zhimg.com/v2-7baa15c61bbdae40e707b9f_r.jpg&&&/figure&&p&现在只要将它们遵循一定的规则拼接在一起,就可以生成地牢了,这些规则有:&/p&&ol&&li& 房间只能链接走廊;&br&&/li&&li&走廊链接房间或者连接处;&br&&/li&&li&连接处只能连接走廊;&br&&/li&&li&组件之间不能有穿插(利用Bounding Box)。&br&&/li&&/ol&&br&&p&&br&接下来是生成算法的详细描述&br&&/p&&ol&&li&初始化一个启示模块(可以选择有最多出口数的模块);&br&&/li&&li&对每个未连接的出口生成一个符合条件的模块;&br&&/li&&li&重新建立一个目前未连接的出口的列表;&br&&/li&&li&重复步骤2和步骤3.&br&&/li&&/ol&&p&下图分别是初始状态,迭代三次和迭代六次的结果&br&&/p&&br&&figure&&img src=&https://pic3.zhimg.com/v2-42b8bebd4c123da662dbc4aeb182da8c_b.jpg& data-rawwidth=&1042& data-rawheight=&552& class=&origin_image zh-lightbox-thumb& width=&1042& data-original=&https://pic3.zhimg.com/v2-42b8bebd4c123da662dbc4aeb182da8c_r.jpg&&&/figure&&p&&figure&&img src=&https://pic1.zhimg.com/v2-52caa776a0dcad6fc004dc0_b.jpg& data-rawwidth=&1044& data-rawheight=&554& class=&origin_image zh-lightbox-thumb& width=&1044& data-original=&https://pic1.zhimg.com/v2-52caa776a0dcad6fc004dc0_r.jpg&&&/figure&上面的随机算法只是生成了地牢的框架,还需要生成很多其他的地牢要素,比如在地上可以打碎的罐子,墙上忽明忽暗的火炬,还有突然从身后窜出来的史莱姆。这些要素的生成的方法和前面的大同小异,简单的说就是在组件的地面或者墙上标记上一些mark点,在这些mark点上随机的去生成一些匹配的要素即可,下面是两个程序生成的房间的例子。&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-7c18a8b5cb291a3f9e749_b.jpg& data-rawwidth=&692& data-rawheight=&356& class=&origin_image zh-lightbox-thumb& width=&692& data-original=&https://pic1.zhimg.com/v2-7c18a8b5cb291a3f9e749_r.jpg&&&/figure&&figure&&img src=&https://pic2.zhimg.com/v2-8854deb19e9c746cc6a29a8c4d47c8e5_b.jpg& data-rawwidth=&704& data-rawheight=&377& class=&origin_image zh-lightbox-thumb& width=&704& data-original=&https://pic2.zhimg.com/v2-8854deb19e9c746cc6a29a8c4d47c8e5_r.jpg&&&/figure&&p&按照上面的算法,废弃矿坑的基本组件就是Room,Corridor,Stair,Cross。在StructureMineshaftStart的构造函数中,起始的组件是一个Room,Room的对象里面包含了一个连接到自己的组件的BoundingBox列表。&/p&&p&看一下Room的buildComponent函数&/p&&figure&&img src=&https://pic3.zhimg.com/v2-46c300a27bf295e30e68e_b.jpg& data-rawwidth=&607& data-rawheight=&125& class=&origin_image zh-lightbox-thumb& width=&607& data-original=&https://pic3.zhimg.com/v2-46c300a27bf295e30e68e_r.jpg&&&/figure&&br&&p&代码大家可以自己去搭建一下forge的环境跑一些,这里就不详细解释了。&/p&&br&&p&&b&小结&/b&&/p&&p&结构生成只是MC的生成流水线中非常简单的一环,有兴趣的朋友还可以自己参考forge去学习更多的生成算法,比如生成洞穴峡谷,生成各种生态地形等等,minecraft里面生成部分的代码都还算清晰,所以对程序生成算法感兴趣的同学非常建议你去看看。&/p&&br&&p&&b&参考&/b&&/p&&a href=&https://link.zhihu.com/?target=http%3A//mc-server.xoft.cz/docs/Generator.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Generating terrain in Cuberite&/a&&a href=&https://link.zhihu.com/?target=http%3A//minecraft.gamepedia.com/Biome& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Biome - Official Minecraft Wiki&/a&&a href=&https://link.zhihu.com/?target=https%3A//en.wikipedia.org/wiki/Perlin_noise& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Perlin noise - Wikipedia&/a&&a href=&https://link.zhihu.com/?target=https%3A//en.wikipedia.org/wiki/Simplex_noise& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Simplex noise - Wikipedia&/a&&a href=&https://link.zhihu.com/?target=https%3A//www.reddit.com/r/gamedev/comments/16yyqw/how_does_minecraft_generate_structures_especially/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&How does Minecraft generate structures? (Especially rivers) o r/gamedev&/a&&a href=&https://link.zhihu.com/?target=http%3A//blog.csdn.net/xfgryujk/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Minecraft的世界生成过程(六)村庄 - El Psy Congruu - 博客频道 - CSDN.NET&/a&&a href=&https://link.zhihu.com/?target=https%3A//gamedevelopment.tutsplus.com/tutorials/bake-your-own-3d-dungeons-with-procedural-recipes--gamedev-14360& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Bake Your Own 3D Dungeons With Procedural Recipes&/a&
提要 一说到开放世界,沙盒,第一个想到的技术点就是Procedual Generation。贴个Wiki上的定义
术语“过程化”是指计算一个特定的过程,如。过程化生成常用于生成贴图、多边形网格、声效、语音合成和音乐制作等。过程化生成的好处是衹要很小的函数…
----------------------------&br&&br&本文同时发在我的 Blog,在那里或可获得更好的阅读体验:&br&&a href=&//link.zhihu.com/?target=http%3A//gulu-dev.com/post/-open-world& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&[知乎] 开放世界游戏中的大地图背后有哪些实现技术?&/a&&br&&br&----------------------------&br&&br&首先肯定一下,这是一个非常有趣的问题。在这个答案里,我将尝试先回答主干问题,再对补充说明里的几个问题简单说一下。&br&&br&下面是本文将涉及到的一些相关技术的列表,(需要说明的是,这些技术单独来看并不复杂,实际动手实现并理解各种取舍以后,在项目当中针对具体的需求去设计和搭配才是关窍之所在)&br&&br&----------------------------&br&&br&&b&一、程序技术篇:算法和架构(Programming Algorithms & Architecture)&/b&&br&1. 无限循环的平铺地图(Infinite Tiling)&br&2. 可预测随机数和无限宇宙(Predictable Random)&br&3. 精度问题解决方案(Precision Problem Solving)&br&4. 超大地形的处理 (Terrain Visualization)&br&
4.1 古典算法(从 GeoMipMapping,Progressive Mesh 到 ROAM) &br&
4.2 层次的艺术(Quadtree 和 Chunked LOD)&br&
4.3 以GPU为主的技术(Paging,Clipmap 到 GPU Terrain)&br&5. id tech 5 的 megatexture (超大地表上的非重复性海量贴图)&br&6. 过程式内容生成 (Procedural Content Generation)&br&
6.1 过程式纹理(Procedural Texturing)&br&
6.2 过程式建模(Procedural Modeling)&br&&br&&b&二、内容制作篇:设计和创造(Content Design & Creation)&/b&&br&1. 随机地图类游戏 (Diablo II) 中地图的拼接&br&2. 无缝大世界 (World of Warcraft) 中区域地图的拼接&br&3. 卫星地质数据的导入,规整化和再加工(一些飞行模拟类游戏)&br&4. 超大地图的协同编辑:并行操作,数据同步,手动和自动锁的运用&br&&br&&b&三、异次元篇:我们的征途是星辰大海&/b&&br&1. 终极沙盒(EVE):当规模大到一定程度——宇宙级别的混沌理论与蝴蝶效应&br&2. 打通两个宇宙(EVE & Dust):发现更广阔的世界——宇宙沙盒游戏和行星射击游戏联动&br&&br&----------------------------&br&&br&## 一、程序技术篇:算法和架构(Programming Algorithms & Architecture)&br&&br&### 1. 无限循环的平铺地图(Infinite Tiling)&br&&br&我们就从最平淡无奇的无限循环平铺地图说起吧。这应该是最原始,也是最没有技术含量的开放世界构筑方式了。&br&&br&技术上由于过于朴素,也没什么好说的,就是在同一个坐标系内像铺地砖那样展开,坐标对齐即可,就是接头处需要注意一下,不要穿帮就行。但是千万别因为简单就小看这个技术哟,上面列表里面的不少技术都是在循环平铺的基础上发展起来的,下面我们就来瞧一瞧吧。&br&&br&按照维度的不同,循环平铺有下面三大类:&br&&br&a. 在一维方向上扩展的横版卷轴游戏(以动作类游戏为主)和纵版卷轴游戏(以射击类游戏为主)。这些类型的游戏里,为了避免循环平铺给玩家带来的重复的疲劳,卷轴游戏会添加一些随机或动态的元素,比如超级玛丽里的背景上云朵的位置,分出多个层次以不同速率卷动的背景层,等等。&br&&br&&figure&&img src=&https://pic2.zhimg.com/ba1ab15421cdadd00a30dd3c736e997d_b.jpg& data-rawwidth=&392& data-rawheight=&220& class=&content_image& width=&392&&&/figure&&br&&br&&br&b. 在二维方向上循环平铺的固定视角2D游戏。这一类游戏里,比较典型的就是 Diablo。暗黑中的随机地图生成,在本质上,就是叠加了一定的随机性,约束和边界条件的循环平铺效果。&br&&br&&figure&&img src=&https://pic3.zhimg.com/47a0c8c78f1adf3afcee_b.jpg& data-rawwidth=&550& data-rawheight=&413& class=&origin_image zh-lightbox-thumb& width=&550& data-original=&https://pic3.zhimg.com/47a0c8c78f1adf3afcee_r.jpg&&&/figure&&br&&br&&br&c. 在 3D 游戏里循环平铺高度图,形成连绵不断的地形效果。这在早期的模拟飞行射击类游戏里比较常见,现在已经很难搜到图了,我在上大学的时候写的第一个地形渲染 demo 就是平铺的,可惜刚刚翻硬盘已经找不到了555。这一类游戏,在平铺时适当地辅以一些贴图的变化,可以在很省内存的条件下,做出非常不错的效果。&br&&br&找不到游戏内的图,拿下面这个高度图来凑数吧。请大家脑补一下,把下面这个灰度图立体化之后,一块一块像地砖一样循环平铺以后,3D渲染出来的连绵起伏的直抵地平线(好吧,直抵远裁剪面)的山脉的壮观效果吧。&br&&br&&figure&&img src=&https://pic2.zhimg.com/b9c4ebfd28bccc8475ac1d_b.jpg& data-rawwidth=&512& data-rawheight=&512& class=&origin_image zh-lightbox-thumb& width=&512& data-original=&https://pic2.zhimg.com/b9c4ebfd28bccc8475ac1d_r.jpg&&&/figure&&br&&br&----------------------------&br&&br&### 2. 可预测随机数和无限宇宙(Predictable Random)&br&&br&(本节内的描述和算法,部分参考了《Game Programming Gems I》 [“2.0 Predictable Random Numbers”](&a href=&//link.zhihu.com/?target=http%3A//www.gameenginegems.net/gemsdb/article.php%3Fid%3D75& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Graphics and Game Gems Database&/a&) 一文,请感兴趣的同学自行查找原文通读)&br&&br&有个传说中的游戏叫 Elite ,不知道有没有同学玩到过。据说这游戏运行在32K内存的机器上,其中16K还是只读的ROM。这游戏据说拥有难以匹敌的游戏深度:近乎无限个行星,每一个都有各自的名字和特征。&br&&br&可预测随机数本身是游戏内运用非常广泛的一个技术,这里我们着重谈一下它在为游戏提供(微观上)更丰富的细节和(宏观上)更广阔的世界的作用。这一技术的最重要原则是,为了在一个游戏世界中给出无限空间的幻觉,我们需要满足两个分解条件,可以把它们成为宏无限(macro-infinite)和微无限(micro-infinite)”。前者涉及到问题的空间规模,后者则任意一个对象所支持的最小细节层次级别。&br&&br&----------------------------&br&&br&从实现上来说,如何设定随机种子是这个技术的核心。由于给定一个随机种子,生成的随机序列是完全可预测的,那么根据游戏内的一些时空的设定,通过对随机种子进行一些定制,得到在游戏内任意某个时刻和某个空间点上完全可预测的行为就是可行的了。&br&&br&最简单的是使用以下几个元素与随机种子配合计算:&br&1. 世界坐标(即 X Y Z 值,既可以表示空间中的某个点,也可以表示某个区域)&br&2. 系统时间(可以用真实时间,也可以用游戏内设计者定义的时间,如果是前者的话需要考虑离线时的处理)&br&3. 正态分布(在游戏里建一个查找表即可,这是最廉价的方案)&br&&br&这些因素加上对应的随机序列,已经可以营造出宏观上比较有深度的一个宇宙空间了。理论上,如果所有的随机性都是由给定的随机种子产生,而这些随机种子要么是游戏定义的常量,要么是查表得到,要么是均匀流逝,要么是由更高层次的随机种子生成,那么这样一层一层上溯到尽头的话,任何一个游戏内的宇宙,都可以归因到一个初始的种子,这个种子,就是决定论中经典物理学的所谓的&b&第一推动&/b&吧。其实如果真做到了这一点,我们大可以把这个种子交给玩家,在首次进入游戏的时候掷一个 2^64 骰子。这是真正的上帝创世的感觉,想象一下,上帝说,要有光,于是掷出了骰子,第一推动怦然落地,整个时空的巨大齿轮开始运转,在不同的时间点和空间点上,更多的随机序列被生成出来...&br&&br&&figure&&img src=&https://pic1.zhimg.com/50bde2249146cce4ea9c_b.jpg& data-rawwidth=&640& data-rawheight=&517& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&https://pic1.zhimg.com/50bde2249146cce4ea9c_r.jpg&&&/figure&&br&&br&&br&这幅图来自于游戏 Frontier:Elite II(出自[这篇文章](&a href=&//link.zhihu.com/?target=http%3A//rakanalysis.wordpress.com//from-the-archive-frontier-elite-ii-a-retrospective-review/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&rakanalysis.wordpress.com&/span&&span class=&invisible&&//from-the-archive-frontier-elite-ii-a-retrospective-review/&/span&&span class=&ellipsis&&&/span&&/a&)),下面配的字样是:&b&“This picture doesn't even begin to show the scale of the universe.”&/b& 大家感受一下。&br&&br&----------------------------&br&&br&微观上本质上也是一样的,只是把发散的过程倒过来,变成了逐级收敛的过程。为了在某一个点上放大时,能得到尽可能细致,准确和一致的表现,我们需要对较低层次的世界定义更丰富的规则和约束,比如黑洞对周围的影响情况,双星体系的轨道,恒星的种类与行星个数之间的对应关系,不同恒星系结构下行星表面的大气构成,等等。这样才能较好地平衡多样性和独特性,带来更真实的模拟效果和更令人信服的游戏体验。&br&&br&----------------------------&br&&br&### 3. 精度问题解决方案&br&&br&当足够大尺度的世界被创建出来时,就会自然而然地遇到精度的问题。同时这也是补充说明中提到的一个问题,这里我们简单介绍一下几种实践中的解决方案。&br&&br&先描述一下问题吧,我们知道,IEEE754 中规定的32位浮点数中,有23位是用来表示尾数的。也就是说,对于接近1的浮点数,可能会带来 2E-24 左右的误差(大约是 0.)以现实单位计算的话,如果游戏世界是边长为100km的正方形,那么在这个正方形的最远角落里,我们的最小空间单位是约 7.8 毫米;而如果是中国这么大的面积的话,空间误差将达**半米**左右。那么可以想象一下,如果是宇宙级别的游戏,采用32位浮点数作为全地图精度,那么实际误差可能会有多么大。&br&&br&在实践中,这种误差可能会带来以下这些影响:&br&&br&1. &b&无法将相邻的对象对齐&/b&。这种情况,场景美术(关卡设计师)应该会比较头疼,这对于游戏的编辑器来说是大问题了。物件没法在引擎编辑器里对齐;在不同的平台上,对齐也不一样;甚至不同的编译器,同一个编译器的不同版本编出来的引擎;对齐都不一样 ... 所以说处女座不要做 LD :P。&br&2. &b&模型间的穿插和裂缝&/b& 本来封闭的墙角可能漏个洞,本来放在地上的石头变成了悬浮在空中。这实际上是上一种的变种。&br&3. &b&骨骼动画的抖动&/b& 由于世界矩阵往往参与骨骼动画的运算,误差可能会被逐级放大,在那些最远离根骨骼的骨头上(也是玩家最容易注意到的地方),抖动可能会发生得非常剧烈。&br&4. &b&物理模拟失真&/b& 一些柔体的模拟可能会直接失败,而刚体也可能会产生怪异的运动。碰撞系统也可能无法正常工作。&br&&br&所有这些一旦发生,都是很容易觉察的。一旦你发现在一个很大的坐标上有这些问题,而接近原点处问题却消失了,那么很有可能就是精度在作怪。而需要注意的是,出现这种问题,只和游戏中出现的数字的规模和跨度有}

我要回帖

更多关于 cloud华为云服务登入 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信