诺亚传说昵称符号奥林巴斯游戏里面哪些符号是触发爆奖的必要条件?

&figure&&img src=&https://pic4.zhimg.com/v2-a703e96e1dddbdac112f78_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&https://pic4.zhimg.com/v2-a703e96e1dddbdac112f78_r.jpg&&&/figure&&p&
相信大家在生活中有这样的体验:从地平线初生的月亮会显得十分巨大,但是当月上枝头,月亮就恢复了正常的大小。这一个现象被称为月亮错觉 ( Moon illusion )。人们创建了多种理论试图解释这个现象,但是至今都没有一个令人满意的答案。&/p&&figure&&img src=&https://pic3.zhimg.com/v2-40df49e727ca61c73dff91_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&237& data-rawheight=&400& class=&content_image& width=&237&&&/figure&&p&
在维基百科中,有一段话提到了:&/p&&p&&b&&i&The size of a viewed object can be measured objectively either as an angular&br&size (the visual angle that it subtends at the eye, corresponding to the&br&proportion of the &a href=&https://link.zhihu.com/?target=https%3A//en.wikipedia.org/wiki/Visual_field& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&visual field&/a& that it occupies), or as physical size ( its real size measured in, say, metres). Perceived size is only loosely related to these concepts, however.&/i&&/b&&/p&&p&&b&&i&
在我们的眼中,一个物体的「大小」可以用角大小(它对向眼睛的角度)或实际大小(真实的大小测量,像是公尺)来量度。但是我们认知的大小和两者的关联并不大。&/i&&/b&&/p&&p&&br&&/p&&p&
这一句提到了很关键的一点,就是人类知觉(Perception)认知不等于现实 。它是客观物体作用于感官而在头脑中产生的对事物整体的认识。那么在游戏中,玩家会在什么情况下经历月亮错觉,并且游戏开发者提供了怎样的解决方案呢?首先我们来看这段视频:&/p&&figure&&img src=&https://pic2.zhimg.com/v2-e66fb3352e5becd8feecd83c5a2d5d56_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&600& data-rawheight=&338& data-thumbnail=&https://pic2.zhimg.com/v2-e66fb3352e5becd8feecd83c5a2d5d56_b.jpg& class=&origin_image zh-lightbox-thumb& width=&600& data-original=&https://pic2.zhimg.com/v2-e66fb3352e5becd8feecd83c5a2d5d56_r.jpg&&&/figure&&p&
随着玩家前进,NPC 头顶的 UI 元素会感觉像是在缩小。尤其是如果当你注意文字的右侧边缘,你会明显发现整个 UI 元素的相对运动。&/p&&p&
另一个比较明显的例子是: &a href=&https://link.zhihu.com/?target=https%3A//www.bilibili.com/video/avFfrom%3Dsearch%26seid%3D& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&暗影之枪传奇0.3内测主城一览 应该是内测中最美的一个版本了_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili&/a& ( 02:55 - 03:00)。你会发现,NPC 的图标元素随着玩家的靠近,在快速缩小。但如果你用尺子测量图标在屏幕上的长度,你会发现图标至始至终大小都没有变过。在这里,我们就经历了游戏中类似于月亮错觉的情况。而我个人倾向用&b&相对大小假说&/b&来解释上述两个例子。&/p&&figure&&img src=&https://pic4.zhimg.com/v2-c4cd03e988b0e324dd506d50e037a3e9_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&220& data-rawheight=&319& class=&content_image& width=&220&&&/figure&&p&
这种情况阐明了一个物体的大小不仅是它在视网膜上的大小,还与他周遭的物体大小有关。在游戏中,当玩家看到 In-game UI 元素(存在于游戏 3D 世界中)时,我们的大脑会倾向使用 UI 元素周围的物体进行比较。如下面两帧对比图:图一中,NPC 的 UI 元素右侧是超出了后方类似于矩形的平板,我们会认为该元素大于其平板。在图二中,因为玩家的靠近,此时 UI 元素的右边缘已经在平板的范围以内。此时,当我们比较 UI 元素和平板的大小,结论将会和图一相反。&/p&&figure&&img src=&https://pic3.zhimg.com/v2-e33614caabc661d20ff6f443d2d36948_b.jpg& data-size=&normal& data-rawwidth=&662& data-rawheight=&372& class=&origin_image zh-lightbox-thumb& width=&662& data-original=&https://pic3.zhimg.com/v2-e33614caabc661d20ff6f443d2d36948_r.jpg&&&figcaption&图一 文字右侧边缘超出了平板范围&/figcaption&&/figure&&figure&&img src=&https://pic3.zhimg.com/v2-c3d07f58a25f290a0c916a2f188b0010_b.jpg& data-size=&normal& data-rawwidth=&662& data-rawheight=&370& class=&origin_image zh-lightbox-thumb& width=&662& data-original=&https://pic3.zhimg.com/v2-c3d07f58a25f290a0c916a2f188b0010_r.jpg&&&figcaption&图二 文字右侧边缘在平板范围以内&/figcaption&&/figure&&p&请注意,为何我会反复强调右侧边缘。这就涉及到消除该错觉的解决方案。其实如果大家留心的话,可能会思考为何 NPC UI 图标的布局和文字是左右而不是上下?&/p&&figure&&img src=&https://pic3.zhimg.com/v2-fd39ae9a8bbf22f8aa061d0a_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&485& data-rawheight=&328& class=&origin_image zh-lightbox-thumb& width=&485& data-original=&https://pic3.zhimg.com/v2-fd39ae9a8bbf22f8aa061d0a_r.jpg&&&/figure&&p&
我个人的猜测是:如果我们使用上下布局的话,当玩家前后移动的时候,左右两个边缘都会和背景中的物体产生相对位移。但如果是左右布局的话,当玩家前后移动,右侧边缘仍会和背景中的物体产生相对位移,但是左侧物体由于贴近中间的图标,即整个 UI 元素的中轴位置,所以相对位移的情况会减弱很多。如果是正中位置,将不会产生任何相对位移(前提是玩家正面NPC沿着直线靠近)。同时,左右的布局也符合人阅读信息从左到右的习惯。&/p&&p&
我在制作《COD:WWII》的时候,分別用两种布局做了实验。最后测试结果显示左右布局能在某种程度上削弱月亮错觉。当然,最理想的办法,就是实时根据玩家和 In-Game UI 元素的位置,相应调整其大小,保证 UI 元素的大小符合人的认知尺寸。这可以完美消除月亮错觉,但是会增加更多的损耗。&/p&&p&
以上就是我个人的分析和猜想,欢迎各位指正和补充。&/p&&p&&br&&/p&&p&&b&Reference&/b& &/p&&p&&a href=&https://www.zhihu.com/question/& class=&internal&&月亮错觉(moon illusion)是什么?&/a& &/p&&p&&a href=&https://link.zhihu.com/?target=https%3A//en.wikipedia.org/wiki/Moon_illusion& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Moon illusion - Wikipedia&/a& &/p&&p&&/p&&p&&/p&&p&&/p&
相信大家在生活中有这样的体验:从地平线初生的月亮会显得十分巨大,但是当月上枝头,月亮就恢复了正常的大小。这一个现象被称为月亮错觉 ( Moon illusion )。人们创建了多种理论试图解释这个现象,但是至今都没有一个令人满意的答案。 在维基百科中,有一…
&p&&a href=&http://link.zhihu.com/?target=https%3A//github.com/CppCon/CppCon2014/blob/master/Presentations/How%2520Ubisoft%2520Montreal%2520Develops%2520Games%2520for%2520Multicore/How%2520Ubisoft%2520Montreal%2520Develops%2520Games%2520for%2520Multicore%Before%2520and%2520After%B%252B11%Jeff%2520Preshing%CppCon%.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&How Ubisoft Montreal Develops Games for Multicore - Before and After C++11 - Jeff Preshing - CppCon 2014&/a&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-64f28ef06d14fecf9f723df30893dab0_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic1.zhimg.com/v2-64f28ef06d14fecf9f723df30893dab0_r.jpg&&&/figure&&p&05年后多核CPU逐渐成为主流&/p&&p&&br&&/p&&p&Part 1&/p&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-cbb40c1c47f_b.jpg& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic2.zhimg.com/v2-cbb40c1c47f_r.jpg&&&figcaption&硬件的多线程进化史&/figcaption&&/figure&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-ffaa8d40ea3e1a59_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic2.zhimg.com/v2-ffaa8d40ea3e1a59_r.jpg&&&/figure&&p&单线程模型&/p&&figure&&img src=&https://pic3.zhimg.com/v2-bef027292_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic3.zhimg.com/v2-bef027292_r.jpg&&&/figure&&p&Ubi三种线程模型&/p&&ul&&li&Pipeline work&/li&&/ul&&p&2个thread互相之间lock step的执行&/p&&ul&&li&Dedicated thread&/li&&/ul&&p&1个线程连续的执行任务&/p&&ul&&li&Task schedulers&/li&&/ul&&p&目前的大部分Engine做法&/p&&figure&&img src=&https://pic3.zhimg.com/v2-efef2d97c4f424b401caea_b.jpg& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic3.zhimg.com/v2-efef2d97c4f424b401caea_r.jpg&&&figcaption&并发的对象&/figcaption&&/figure&&p&Pipeline work&/p&&figure&&img src=&https://pic2.zhimg.com/v2-e67af4eaaf39b4e8cc8f78d_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic2.zhimg.com/v2-e67af4eaaf39b4e8cc8f78d_r.jpg&&&/figure&&p&(主)线程来处理大部分逻辑,另外一个线程来处理图形。需要一些同步机制(信号量)来同步两个线程,告诉渲染线程何时开始(主线程逻辑准备好之后),告诉主线程逻辑不要运行到N+2帧(N的渲染loop结束后才能开始)&/p&&figure&&img src=&https://pic2.zhimg.com/v2-b76dc91d09bbc273ffefed_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic2.zhimg.com/v2-b76dc91d09bbc273ffefed_r.jpg&&&/figure&&p&那么N~N+1的跨度就带来一个问题,对于每个GameObject,如何避免在渲染的时候惨遭主线程毒手的修改。&/p&&p&1. Double buffer&/p&&p&每个GO两份,分给N和N+1帧&/p&&p&2. GraphicObject&/p&&p&每个GO单独抽象出一个Graphic的Ojbect,对于渲染线程Consume ReadOnly&/p&&p&&br&&/p&&p&Dedicated threads&/p&&figure&&img src=&https://pic4.zhimg.com/v2-3b03aebbd144b0b21f0e8a23a8e81d47_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic4.zhimg.com/v2-3b03aebbd144b0b21f0e8a23a8e81d47_r.jpg&&&/figure&&p&对于加载游戏内容,有一个Loading线程&/p&&figure&&img src=&https://pic4.zhimg.com/v2-daa76aee4ea5a672ec43_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic4.zhimg.com/v2-daa76aee4ea5a672ec43_r.jpg&&&/figure&&p&大部分情况,loading线程无事可做在sleep。如果player从一个区域move到另外一个区域,那么主线程会发给loading线程一个请求,加载新区域的内容。Loading线程一般是IO bound而不是computing bound。Loading线程不需要和主线程进行lockstep的同步,所以大部分情况下使用queue把任务扔进loading的队列即可。&/p&&p&*多说两句,记得之前看过一些资料,说IO&br&bound的loading一般不要开太多的线程去做,因为并不是开多了threads就可以load更快,反而在寻道磁盘类型的硬盘上增加开销时间。其中一个做法是开一个专门io的进程来集中处理io业务,进程的好处是在多开客户端时,可以公用IO上的loading request,当然通信和编码也更麻烦一些。&/p&&p&*另外,loading线程也不是全然没有同步的,资源加载完成后还需要回调进行处理,这些逻辑大部分需要在主线程进行,所以每帧的开始或者结束需要主线程轮询或者用信号量等进行通知。有一些需要实时加载的逻辑,比如音效、碰撞检测,如果不加载资源进来就无法继续进行游戏。&/p&&figure&&img src=&https://pic4.zhimg.com/v2-4d0e02e9ad12c0dc54bfa3_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic4.zhimg.com/v2-4d0e02e9ad12c0dc54bfa3_r.jpg&&&/figure&&figure&&img src=&https://pic4.zhimg.com/v2-0f1dce38517bb0aeb5be40d4c25a6dcf_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic4.zhimg.com/v2-0f1dce38517bb0aeb5be40d4c25a6dcf_r.jpg&&&/figure&&p&Improve on the queue&/p&&p&1. cancel&/p&&p&2. interrupt&/p&&p&3. re-prioritize&/p&&p&&br&&/p&&p&Task scheduler&/p&&figure&&img src=&https://pic3.zhimg.com/v2-b5a08ded852_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic3.zhimg.com/v2-b5a08ded852_r.jpg&&&/figure&&p&细化任务(jobification)&/p&&figure&&img src=&https://pic4.zhimg.com/v2-3c89f07e9d3ad07f8503_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic4.zhimg.com/v2-3c89f07e9d3ad07f8503_r.jpg&&&/figure&&p&把jobs放在每个worker thread去做&/p&&figure&&img src=&https://pic2.zhimg.com/v2-1a54dcca00ba9decdbe4c83c5b2f3151_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic2.zhimg.com/v2-1a54dcca00ba9decdbe4c83c5b2f3151_r.jpg&&&/figure&&figure&&img src=&https://pic1.zhimg.com/v2-30d91bb7b224c79b906f8_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic1.zhimg.com/v2-30d91bb7b224c79b906f8_r.jpg&&&/figure&&p&把job分组&/p&&figure&&img src=&https://pic3.zhimg.com/v2-dffd395f49f9d778fde9d66_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic3.zhimg.com/v2-dffd395f49f9d778fde9d66_r.jpg&&&/figure&&p&相当于从job池里去取任务来执行&/p&&figure&&img src=&https://pic1.zhimg.com/v2-68b8f515ae9cc_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic1.zhimg.com/v2-68b8f515ae9cc_r.jpg&&&/figure&&p&每个worker thread所处理的task&br&groups可能会有所不同&/p&&figure&&img src=&https://pic1.zhimg.com/v2-bcb6a68b52af62da459dc00_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic1.zhimg.com/v2-bcb6a68b52af62da459dc00_r.jpg&&&/figure&&p&管理任务依赖&/p&&figure&&img src=&https://pic4.zhimg.com/v2-36efcdbc5e7fc95c12c5f_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic4.zhimg.com/v2-36efcdbc5e7fc95c12c5f_r.jpg&&&/figure&&p&做完最后一个job的线程去issue下一个taskGroup&/p&&figure&&img src=&https://pic2.zhimg.com/v2-871ee632b5_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic2.zhimg.com/v2-871ee632b5_r.jpg&&&/figure&&p&可以做很多自定义的优化&/p&&p&*多说两句,个人还是觉得Ubi的这个taskScheduler不如Naughty Dog的,个人认为worker线程+主线程的job逻辑有缺点:主线程负责调度,避免不了自身的sleep,worker线程也一样,worker的while循环相当于不停的spin,为了避免浪费cpu计算资源肯定会设计wait的逻辑来让渡。这样会造成大量线程的context switch,并且这个cs是kernel层面的,thread state从sleep-&ready-&run并且会有大量的等待时间来等待os分配cpu time slice,无形中又增加了时间。另外从cache的角度考虑,每一次cs都会再次需要预热cache,造成大量cache&br&miss,fine-grained的jobs更增加了这个成本。Naughty Dog的解决方案思想是没有主线程的概念,所有的线程都是affinity到每个物理core上的,不进行kernel层面的线程调度,让所有线程一直处于run state,这样的话需要进入fiber的yeild进行类似callback的回调,利用这种方法来manage task,类似拓扑排序的方式来进行所有的任务,这个等以后有空在另开一篇吧&/p&&p&&br&&/p&&p&Atomic Operations&/p&&figure&&img src=&https://pic1.zhimg.com/v2-e5f167eb0681fccceb5689bddc054744_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic1.zhimg.com/v2-e5f167eb0681fccceb5689bddc054744_r.jpg&&&/figure&&p&可见上世代的atmoic…&/p&&p&Fence&/p&&figure&&img src=&https://pic3.zhimg.com/v2-ab1f7effcb94ff7d6d2efa_b.jpg& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic3.zhimg.com/v2-ab1f7effcb94ff7d6d2efa_r.jpg&&&figcaption&Memory Order&/figcaption&&/figure&&figure&&img src=&https://pic4.zhimg.com/v2-13891cbb93eec05bb26c067_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic4.zhimg.com/v2-13891cbb93eec05bb26c067_r.jpg&&&/figure&&p&平台之间的差异&/p&&figure&&img src=&https://pic2.zhimg.com/v2-93b95fc687cff704cb6bf7b203b59605_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic2.zhimg.com/v2-93b95fc687cff704cb6bf7b203b59605_r.jpg&&&/figure&&figure&&img src=&https://pic2.zhimg.com/v2-ce664e916be5a2e401aeb2fcfffad8b1_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic2.zhimg.com/v2-ce664e916be5a2e401aeb2fcfffad8b1_r.jpg&&&/figure&&figure&&img src=&https://pic2.zhimg.com/v2-bca0db019_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic2.zhimg.com/v2-bca0db019_r.jpg&&&/figure&&p&MemoryOrder的bug,在XBOX这种weakly ordered机器上,上图两种reorder的方式都会造成read的item还没有被push。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-dc7e3d6d2cfc74ebdaa9c_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic1.zhimg.com/v2-dc7e3d6d2cfc74ebdaa9c_r.jpg&&&/figure&&p&解决方法加入order fence&/p&&p&这个还是Herb讲的好一些,下次在写&/p&&p&搞笑的Q&A来了,有个人问什么情况下会使用memory order sequentially-consistent,结果人家说目前在Ubi mtrl没有一个人知道这是啥。。。&/p&&p&&br&&/p&&p&Part 2&/p&&p&C++11 Atomic Library&/p&&figure&&img src=&https://pic1.zhimg.com/v2-8de9d1cfac7ca126f876f8_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic1.zhimg.com/v2-8de9d1cfac7ca126f876f8_r.jpg&&&/figure&&p&嗯,实话&/p&&figure&&img src=&https://pic3.zhimg.com/v2-6dafc9e316_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic3.zhimg.com/v2-6dafc9e316_r.jpg&&&/figure&&p&Keep it simple&/p&&figure&&img src=&https://pic4.zhimg.com/v2-866bd45f31c1bd73b416943_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic4.zhimg.com/v2-866bd45f31c1bd73b416943_r.jpg&&&/figure&&p&主要是CPU single instruction r/w数据大小造成的问题&/p&&figure&&img src=&https://pic2.zhimg.com/v2-c8b14e5a7dd5abf19d52179_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic2.zhimg.com/v2-c8b14e5a7dd5abf19d52179_r.jpg&&&/figure&&p&Legacy code…话说volatile保证不了原子性吧&/p&&figure&&img src=&https://pic3.zhimg.com/v2-bbaddb4fcb2_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic3.zhimg.com/v2-bbaddb4fcb2_r.jpg&&&/figure&&p&Java volatile…&/p&&figure&&img src=&https://pic2.zhimg.com/v2-660ed2a7cf4ff96c8b7f80d_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic2.zhimg.com/v2-660ed2a7cf4ff96c8b7f80d_r.jpg&&&/figure&&p&排列组合&/p&&figure&&img src=&https://pic4.zhimg.com/v2-acbec69fda58e_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic4.zhimg.com/v2-acbec69fda58e_r.jpg&&&/figure&&p&因为没有memory order,被reorder了&/p&&figure&&img src=&https://pic1.zhimg.com/v2-cbacf0e7b2fc284a2f2e136e5ef277b8_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic1.zhimg.com/v2-cbacf0e7b2fc284a2f2e136e5ef277b8_r.jpg&&&/figure&&p&default arg&/p&&figure&&img src=&https://pic3.zhimg.com/v2-0fa_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic3.zhimg.com/v2-0fa_r.jpg&&&/figure&&p&排列组合again&/p&&figure&&img src=&https://pic2.zhimg.com/v2-d239ee0ab89c18ee42bfed_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic2.zhimg.com/v2-d239ee0ab89c18ee42bfed_r.jpg&&&/figure&&p&Ubi14年还没用Atomic Lib&/p&&figure&&img src=&https://pic4.zhimg.com/v2-0d06ab328bb5d7f23638b_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic4.zhimg.com/v2-0d06ab328bb5d7f23638b_r.jpg&&&/figure&&p&对于low-level的模型,可以想象成每个线程都有自己的一份数据拷贝,跟每个core都有自己的L1 cache一样,只不过同步cache需要时间&/p&&figure&&img src=&https://pic3.zhimg.com/v2-ae50b8c2d5d7bcdbee06512_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic3.zhimg.com/v2-ae50b8c2d5d7bcdbee06512_r.jpg&&&/figure&&p&Ubi有自己的migration对应&/p&&figure&&img src=&https://pic2.zhimg.com/v2-26f00a70e9b7c4ab0ee7ed_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic2.zhimg.com/v2-26f00a70e9b7c4ab0ee7ed_r.jpg&&&/figure&&p&Low-level atomics example&/p&&figure&&img src=&https://pic2.zhimg.com/v2-676f08b7c7f95f7740179_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic2.zhimg.com/v2-676f08b7c7f95f7740179_r.jpg&&&/figure&&figure&&img src=&https://pic1.zhimg.com/v2-9209f0eedbccf9d3dd42c_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic1.zhimg.com/v2-9209f0eedbccf9d3dd42c_r.jpg&&&/figure&&p&这儿我不是很懂,fence不是compiler层面的吗,只会保证在编译器没有reorder,怎么会在运行期sync,是什么特殊的CPU instruction吗,求大神指点…&/p&&figure&&img src=&https://pic3.zhimg.com/v2-1fbc4e4d451ba6a2d794dfe_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic3.zhimg.com/v2-1fbc4e4d451ba6a2d794dfe_r.jpg&&&/figure&&p&相同的写法&/p&&figure&&img src=&https://pic4.zhimg.com/v2-d28faa3b100f7dd087a6a71f81c93857_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&554& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic4.zhimg.com/v2-d28faa3b100f7dd087a6a71f81c93857_r.jpg&&&/figure&&p&SC到底做了什么会这么慢,求大神赐教。。。以我的理解,aquire/release语义首先在compiler层面保证不被reorder,其次可能会强迫刷新同步cache,这两项可能会带来流水线的penalty和latency。但是sc语义不清楚,具体实现如何为啥这么慢。。。&/p&&p&&/p&&p&&/p&&p&&/p&
05年后多核CPU逐渐成为主流 Part 1 单线程模型Ubi三种线程模型Pipeline work2个thread互相之间lock step的执行Dedicated thread1个线程连续的执…
&figure&&img src=&https://pic2.zhimg.com/v2-360c5be6dd7d0eb1e5a148c_b.jpg& data-rawwidth=&619& data-rawheight=&411& class=&origin_image zh-lightbox-thumb& width=&619& data-original=&https://pic2.zhimg.com/v2-360c5be6dd7d0eb1e5a148c_r.jpg&&&/figure&&p&之前看了 &a class=&member_mention& href=&http://www.zhihu.com/people/bfca9bb51cd129cb& data-hash=&bfca9bb51cd129cb& data-hovercard=&p$b$bfca9bb51cd129cb&&@陈灼&/a& 在&/p&&a href=&https://www.zhihu.com/question/& data-draft-node=&block& data-draft-type=&link-card& class=&internal&&游戏关卡设计师是一种怎样的工作?&/a&&p&下贴的Bobby Ross的《The Visual Guide for Multiplayer Level Design》&/p&&p&我认为文章写得很系统、很有趣,有一定的启发意义,便发邮件给原作者Ross先生,请求授权翻译并在互联网上公开,供中文游戏开发者参考之用。&br&Ross先生很慷慨地应允了我的请求,并将他当时写作时的源文件发给了我,遂有这篇翻译。&/p&&p&译者水平有限,如有翻译不当之处敬请指出。&/p&&p&邮箱:&/p&&p&Ross的英语原文链接:&a href=&http://link.zhihu.com/?target=http%3A//bobbyross.com/library/mpleveldesign& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&bobbyross.com/library/m&/span&&span class=&invisible&&pleveldesign&/span&&span class=&ellipsis&&&/span&&/a&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-d6828acc23db11cd43c10811_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&700& data-rawheight=&1730& class=&origin_image zh-lightbox-thumb& width=&700& data-original=&https://pic2.zhimg.com/v2-d6828acc23db11cd43c10811_r.jpg&&&/figure&&figure&&img src=&https://pic2.zhimg.com/v2-947ec079b6bef779d4b7ce5_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&700& data-rawheight=&1435& class=&origin_image zh-lightbox-thumb& width=&700& data-original=&https://pic2.zhimg.com/v2-947ec079b6bef779d4b7ce5_r.jpg&&&/figure&&figure&&img src=&https://pic3.zhimg.com/v2-95ba9bad8cc4c38d43baee_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&700& data-rawheight=&3496& class=&origin_image zh-lightbox-thumb& width=&700& data-original=&https://pic3.zhimg.com/v2-95ba9bad8cc4c38d43baee_r.jpg&&&/figure&&figure&&img src=&https://pic1.zhimg.com/v2-c980b829f822ef81bb60_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&700& data-rawheight=&3976& class=&origin_image zh-lightbox-thumb& width=&700& data-original=&https://pic1.zhimg.com/v2-c980b829f822ef81bb60_r.jpg&&&/figure&&figure&&img src=&https://pic4.zhimg.com/v2-ac47c5a1a36d6ad07c263_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&698& data-rawheight=&3709& class=&origin_image zh-lightbox-thumb& width=&698& data-original=&https://pic4.zhimg.com/v2-ac47c5a1a36d6ad07c263_r.jpg&&&/figure&&figure&&img src=&https://pic3.zhimg.com/v2-d66b352f8da7cdd4ade56_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&700& data-rawheight=&2175& class=&origin_image zh-lightbox-thumb& width=&700& data-original=&https://pic3.zhimg.com/v2-d66b352f8da7cdd4ade56_r.jpg&&&/figure&&figure&&img src=&https://pic3.zhimg.com/v2-de8d45b2ee6db437d128806fbec96af2_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&700& data-rawheight=&2499& class=&origin_image zh-lightbox-thumb& width=&700& data-original=&https://pic3.zhimg.com/v2-de8d45b2ee6db437d128806fbec96af2_r.jpg&&&/figure&&figure&&img src=&https://pic1.zhimg.com/v2-742c1ca5f7ddf7be7fe9cc351f70e1e8_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&800& data-rawheight=&3806& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&https://pic1.zhimg.com/v2-742c1ca5f7ddf7be7fe9cc351f70e1e8_r.jpg&&&/figure&&figure&&img src=&https://pic1.zhimg.com/v2-1edf88aa984782cfb126c_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&800& data-rawheight=&4344& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&https://pic1.zhimg.com/v2-1edf88aa984782cfb126c_r.jpg&&&/figure&&figure&&img src=&https://pic2.zhimg.com/v2-7abe70bf92a5b_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&800& data-rawheight=&3855& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&https://pic2.zhimg.com/v2-7abe70bf92a5b_r.jpg&&&/figure&&figure&&img src=&https://pic3.zhimg.com/v2-e97d62bf822a69bf544036e_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&700& data-rawheight=&760& class=&origin_image zh-lightbox-thumb& width=&700& data-original=&https://pic3.zhimg.com/v2-e97d62bf822a69bf544036e_r.jpg&&&/figure&&figure&&img src=&https://pic4.zhimg.com/v2-cb160a0eac2aa26ee0cff_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&700& data-rawheight=&1715& class=&origin_image zh-lightbox-thumb& width=&700& data-original=&https://pic4.zhimg.com/v2-cb160a0eac2aa26ee0cff_r.jpg&&&/figure&&figure&&img src=&https://pic3.zhimg.com/v2-bc3fcb971d583f6b7e9aba_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&700& data-rawheight=&962& class=&origin_image zh-lightbox-thumb& width=&700& data-original=&https://pic3.zhimg.com/v2-bc3fcb971d583f6b7e9aba_r.jpg&&&/figure&&figure&&img src=&https://pic1.zhimg.com/v2-6edd5e3eb2d95e72460d4_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&700& data-rawheight=&1165& class=&origin_image zh-lightbox-thumb& width=&700& data-original=&https://pic1.zhimg.com/v2-6edd5e3eb2d95e72460d4_r.jpg&&&/figure&&figure&&img src=&https://pic1.zhimg.com/v2-58b970f409cacdad0fb02880_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&700& data-rawheight=&1763& class=&origin_image zh-lightbox-thumb& width=&700& data-original=&https://pic1.zhimg.com/v2-58b970f409cacdad0fb02880_r.jpg&&&/figure&&p&&/p&
在下贴的Bobby Ross的《The Visual Guide for Multiplayer Level Design》我认为文章写得很系统、很有趣,有一定的启发意义,便发邮件给原作者Ross先生,请求授权翻译并在互联网上公开,供中文游戏开发者参…
&p&追加一个有意思的链接:&/p&&p&&a href=&https://www.zhihu.com/question/& class=&internal&&如何应对「披萨不就是个大饼铺点肉」、「寿司不就是放块鱼在米饭上」这种言论?&/a&&/p&&p&&br&&/p&&p&其实真的阅人多了,你会发现有很多很多衡量的办法,我就说最简单实惠的两个点好了。&/p&&p&&b&如果一个策划特别喜欢“xxx不就是ooo么”(xxx和ooo通常是2个名词),这个人的水平一定不行,不论他是不是策划,这个人就不咋的(不幸的是现代中国人有90%是这样的货色)&/b&。为什么一个人会说“xxx不就是ooo么”,其实这是一种下意识的表达,通常这样的人不仅是性格更是能力上存在两大障碍:&/p&&p&1,无法上进,既不会读书也不会去读书,更别提和人交流了。这种人只能听到、看到和学到他认同的东西,而不认同的东西全然当做愚蠢的存在。很多东西在他心里面已经有了答案了,别人不论说什么,他都必定强扭到自己想听到的东西上,如果拗不过来,就是别人说的不对。这样的人通常是学不到的东西的,因为学习东西和阅读一样,都是要过滤掉自己认可的,去看自己不认可的然后进行反思来增加理解。&/p&&p&2,不会分析事物本质,爱做危险的类比。通常这样的现象,也可能是拿到了一把锤子,看世界都是钉子。在他们看来,一件事情只要有一个点符合另一件事情,那这件事情就可以是另外一件事情——他们可以认为用电吉他的不就是摇滚乐么,因为摇滚乐的确用的是电吉他;他们可以认为寿司不就是饭团上放片鱼么,因为的确生鱼片是鱼也放在了饭团上。这种思路也被科学的称为“滑坡谬误”,通常这样的人他看不见事物本质是什么,更不可能去分析藏在一件事、一个设计背后的调性是什么,看不懂,也不想看懂。&/p&&p&所以这种动不动就是“xxx不就是ooo么”的人,他肯定是一个没水平的人,不仅做不了策划,连做个人都很辛苦了。&/p&&p&那么对于一个谦虚好学的人来说,他的水平我又如何看呢?&/p&&p&我会首先告诉他我的Buff机制,其实这套机制非常好理解(&a href=&https://www.zhihu.com/question/& class=&internal&&如何设计一个易扩展的游戏技能系统?&/a&),当然只是告诉他,教会他这样一种思路,是想告诉他你能想到,就一定有简单的办法做到。&b&之后我会多跟他交流技能制作,就能看出这个人的水平&/b&。注意是制作,策划层面的制作包括了设想-&脑洞-&收回-&定性-&实现-&落实6个步骤。&/p&&p&设想层是一个人开始收集自己的知识信息,寻找可用的知识,这层可以看出这个人的知识面,尤其是游戏知识面,包括游戏经验等。&/p&&p&脑洞层是一个人开始基于知识面发挥想象力去创作的一层,这层可以看出一个人的思维灵活性,游戏感的灵性。&/p&&p&收回层是一个人开始把脑洞的结果根据游戏的调性进行筛选,选出一批符合调性的东西来,这一层同样看游戏灵性,也看一个人的产品感觉对不对。&/p&&p&定性层是一个人的决策能力,需要结合实现“破坏性”(通常是指对原有的设计框架的破坏性和突破程度)来进一步筛选设计。这可以看出一个人的脚踏实地性。&/p&&p&实现层是一个人开始思考设计的东西如何用最好的方式去实现,很多策划会止步于这层,一来是他们接受的熏陶问题,二来是责任心缺乏,认为实现是别人的事情,却不去思考。我是鼓励思考的,因为这层思考,可以看出一个人的逻辑灵活性。&/p&&p&落实层是一个人真的动手把它做出来,其实作为策划只要写出逻辑思维就行了(多被称为“伪代码”),编程主要是逻辑思维+Coding,这层主要还是看他的逻辑思维严谨性。&/p&&p&这些正是我评价一个策划有没有天赋、有没有成长性和有没有能力的关键,天赋x成长性x能力=水平。&/p&&p&其实我一直有一个有意思的比喻——我的buff机制在游戏设计领域是一把绝世好剑,当然好的铸剑师(程序员)可以把它打造的更轻盈,却不改变其外观。而策划就是剑客,绝世好剑在剑圣手里,可以舞出惊世骇俗的效果来;但是绝世好剑对于一个只会挥舞甘草叉的战斗力不足5的农民来说,只不过是一块重量较大的废铁而已。”剑本凡铁,因执拿而通灵,因心而动,因血而活,因非念而死“。&/p&
追加一个有意思的链接: 其实真的阅人多了,你会发现有很多很多衡量的办法,我就说最简单实惠的两个点好了。如果一个策划特别喜欢“xxx不就是ooo么”(xxx和ooo通常是2个名词)…
&p&总算可以回答这个问题了,专栏连载了三篇文章,为了节省读者的阅读时间,只选取最后一篇。如果您在阅读过程中发现个别概念很模糊,我前两篇文章都有澄清并不会妨碍阅读。&/p&&p&&b&面向全文本的实验性作品&/b&&/p&&p&现在《艾迪芬奇的记忆》已经不需要仅仅因为步行模拟游戏这一重身份就感到尴尬了,如果传统的游戏类型中有注重完整而紧凑的场景设计的作品,也有将数值系统开发到极致的作品(例如p社),也有将玩家的心理体验作为游戏设计的最初动机、最高目标以及工作原则的作品(例如任天堂的玩家中心式原则),那么作为具有实验性质的步行模拟类游戏并没有任何的身份危机,如果有恐怕就只有没钱危机,当文学领域还在纠结文学的界限,而电影领域还在为文字过多溢出的电影感到深深苦恼,那么游戏与其纠结于这些旋绕的概念,不如敞开自己面向文本(在上篇中我有所阐释),即面向任何能表达内容的符号载具而不是固守疆埸。市场能裁决哪些游戏是“成功”的,但理论几乎不可能严格界定哪些“游戏”是不“游戏”的。&/p&&p&面向文本的游戏并不仅仅因为步行模拟游戏而一炮走红,实际上在游戏历史上怎么去扩大游戏的叙事空间,提升游戏的文本符号与游戏机制的内在关联以及怎样创新游戏的设计惯例(例如“类魂”与“类无双”中的这个“类”)是每一个游戏都会自发或自主去探索的,例如《生化奇兵》的电影播放以及《上古卷轴5》系列的成堆书籍,只不过它们只是自发而非自主地利用了一些跨媒介手段。&/p&&figure&&img src=&https://pic4.zhimg.com/50/v2-4eac0a3da98eccd3da126_b.jpg& data-rawwidth=&554& data-rawheight=&336& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic4.zhimg.com/50/v2-4eac0a3da98eccd3da126_r.jpg&&&/figure&&p&被市场默认保留的就成为了“类”,而那些没有与游戏机制连接的文本符号,本身就是游戏边界的迷雾,这团迷雾的背后是什么没有人知道。哪怕有人天资聪慧被“训练有素的医生”所救,有才赋且有能力开创新的连接空间扩展耕地,但还是可能会因为过于激进与实验而面对游戏市场的玩家中心惩罚,最后要么逆流孤独花消烛央,要么自娱自乐无法达成场域内部交换而成为名副其实的“自耕农”(确定说的难道不是我的文章?),去玩家中心的游戏在游戏产业化条件下目前几乎是不可能的,这也是为什么我对游戏的理解和其他我见过的所有游戏定义都不同的原因,后者大多是游戏产业化的定义,其本身就将游戏限定在玩家中心(或体验中心)这种规范意义上的陈述:例如游戏是满足玩家体验的媒介,而这种陈述无法去定义在它定义辖域中的那些“失败的”游戏,因为这种陈述可能做出这样的陈述:它们(那些因不像游戏而失败的游戏)要么不是我们定义辖域下的游戏,要么不是我们定义辖域下的“游戏”(没有写错哦)。&/p&&p&在游戏产业化条件下,游戏的规范取向是:游戏-做给别人玩的-做给第三人称玩的。而在全球化语境下游戏产业化被最大化地赋予陌生化语境的规范取向:游戏-做给别人玩的-做给第三人称玩的-这个第三人称最好是全球化语境下的最大多数人-最大多数人当然相对于第一人称自然是陌生的,也因此对于最大多数陌生人做的游戏最好尽量削弱第一人称的价值观,私人化体验与独特的修辞惯例-尽量让游戏去政治批判(因为政治批判本身就是一种不愿也不能被普遍化收编的规范态度)。&/p&&figure&&img src=&https://pic3.zhimg.com/50/v2-bcaefcbfd9b4_b.jpg& data-rawwidth=&554& data-rawheight=&310& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic3.zhimg.com/50/v2-bcaefcbfd9b4_r.jpg&&&/figure&&p&当然这是一个极端工业化的理想版本,每一个游戏针对自己的受众有不同的举措与设计原则,这个中立化的商业趋势实际上我并不反感,但这种极端商业化的版本的创新源泉很可能来自于那些溢出的部分(例如宫崎英高这些设计者个人的气质以及《纪念碑谷2》这些商业环境内站得住脚的文艺作品),那些溢出的部分就像经济学家熊彼特(Joseph&br&Alois Schumpeter)所描述的间断与偶然地打破市场均衡状态的具有冒险气质的企业家(entrepreneur),或者像社会学家马克斯韦伯(Max Weber)所描述的卡里斯玛(Charisma),是可重复化理性模式成功之下溢出的创新点。能够既维持商业全球化语境又留有一些足够修辞表达的创新空间本身就是很多走入产业化后的媒介表达形式都在走的路。&/p&&figure&&img src=&https://pic3.zhimg.com/50/v2-ef24_b.jpg& data-rawwidth=&477& data-rawheight=&273& class=&origin_image zh-lightbox-thumb& width=&477& data-original=&https://pic3.zhimg.com/50/v2-ef24_r.jpg&&&/figure&&p&&b&《艾迪芬奇记忆》的总览:退回到观视视角与跨主体&/b&&/p&&p&既然《艾迪芬奇的记忆》走到了去核心化资本,去数值化冲突以及去技能化训练,并向全文本开放,我觉得即便按照商业逻辑来考虑都没有不接受的理由,因为没有一个人能挟受众而令此类游戏不游戏,这就是商业逻辑的“优雅”(流氓):一款游戏能够在商业逻辑下存活就没有理由按照商业逻辑让这款游戏不是游戏,因为(1)没有人能取代玩家全体,商业逻辑下的玩家群体始终是一个被悬设的全称符号(2)按照商业逻辑的标准存活下来的都是玩家全体这个全称符号默可的对象,没有任何私人化宣言能在商业逻辑下改变全称宣言。&/p&&p&那么本篇文章作为《艾迪芬奇的记忆》系列的尾篇,我将开始围绕游戏的全文本开放的核心探索游戏在文本的铺设的有意思的地方,那么没有看过前两篇的读者我在这里先补充一下:&/p&&p&(1)《艾迪芬奇的记忆》与魔幻现实主义关系不大并且魔幻现实主义并不仅仅指一种叙事层面的技术活,即便纯粹提炼叙事技法再冠上魔幻现实主义之名,也与魔幻现实主义不符。&/p&&p&(2)《艾迪芬奇的记忆》动用了一些大家耳熟能详的元游戏手段,但并没有过多消费元游戏手段痕迹,实际上元游戏本身只是一个中性化的运用技巧(就像街舞里的“breaking”),不要刻意拔高与矮化这个中性化的工具化的概念。&/p&&p&(3)《艾迪芬奇的记忆》的故事仍然是一桩一桩被彼此分隔开的事件,和传统游戏的叙事手法相比并无明显特色,其最大的优势在于去掉累进化的数值、反复练习的身体倾向(每个人物都在操作上有特色)等核心资本后剩下的没有资本包袱的主体,因此任何一个没有资本包袱的主体只会被看做跟电影中的某些角色一样的叙事角色,而很难被看成在游戏里的资本化角色(这个NPC有什么用能帮我加什么点,它有什么技能),让人物全部回归叙事角色而不是资本化角色后游戏可以全副身心地讲故事,在沉浸体验上直接免除了部分叙事性与游戏机制的割裂(你头上竟然有根血条233~)的困扰,从而扩大了游戏叙事的可能性,尽量用故事深度来弥补冲突化与资本累进的人类朴素的权力欲望(果然朴素这个词比低级读来舒服好多,这两个词可以互换的,例如朴素唯物主义之类的~)。&/p&&figure&&img src=&https://pic2.zhimg.com/50/v2-537df7e0a1cdae7bbcb81_b.jpg& data-rawwidth=&554& data-rawheight=&120& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic2.zhimg.com/50/v2-537df7e0a1cdae7bbcb81_r.jpg&&&/figure&&p&(4)除此以外,《艾迪芬奇的记忆》在削弱了塑造角色的核心资本的成本的过程中可以随时放弃此刻主体而投入到其他主体视角,文学的POV视角(POV(Point-of-View),视点人物写作手法,即一部作品由多视角人物叙事构成)和电影中的视觉切换的原理也是如此。&/p&&p&文学和电影可以主动地拥抱POV视角其中的原因就是文学与电影是视角叙事而不是体验叙事,文学的视角叙事的冲突感主要体现在剧情中,而电影的视角叙事的冲突感除了在剧情之中外还体现在镜头话语的权力配比中(而在《艾迪芬奇》中,这种镜头话语术可以说有诸多借鉴),不论是文学还是电影的视角叙事都主要满足人的观视,因此在POV视角下主体承担了一个相对于全局的观视位置、观视权力关系与观视范围的角色,光依靠此刻人物永远不能澄清整个故事全貌(当然限定在POV视角下),此刻人物随时都可以被撤销、抹除和置换,在POV视角每一个观视主体都是一个局部叙事,而全局叙事要么是由一段一段跨主体构成的,要么全局叙事就完全碎裂在局部叙事中成为诸多局部叙事争夺的对象。例如《罗生门》中的主角们对全局叙事的争夺-谁才是杀人者。更典型的是王家卫导演的风格,主体之间的旁白拉开了全局叙事的可能空间,让全局叙事无限胀大,以至于你不可能脱离开主体的旁白而单独谈论电影中的全局叙事。&/p&&figure&&img src=&https://pic4.zhimg.com/50/v2-ad133d3c55bdf_b.jpg& data-rawwidth=&554& data-rawheight=&301& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic4.zhimg.com/50/v2-ad133d3c55bdf_r.jpg&&&/figure&&p&传统的游戏的设计理念是让每一个主体都尽量承担功能与机制上的全方位角色,例如《仙剑》中的柳梦璃必须能打,这样作为可控且有技能深度的角色才会在游戏进程中承担一个体验中心,没有技能深度、不可控、没有过多资本负担的角色,例如任务里的待救的NPC以及《勇者斗恶龙》系列里的村民们,实际上在游戏中不可能成为一个体验中心,传统的游戏设计理念需要在体验中心上铺展剧情深度,一个不是体验中心的主体很难完成一段剧情中心。&/p&&figure&&img src=&https://pic4.zhimg.com/50/v2-490b42b402a02b4fb7fb_b.jpg& data-rawwidth=&550& data-rawheight=&309& class=&origin_image zh-lightbox-thumb& width=&550& data-original=&https://pic4.zhimg.com/50/v2-490b42b402a02b4fb7fb_r.jpg&&&/figure&&p&让我们思考一下《尼尔:机械纪元》(NieR:Automata),如果不给9s提供一个体验中心,整部作品就几乎没法反应2B与9s之间的情感关系,二者在剧情铺展上应该是对称且相互对抗的(在拥抱与拒绝之间),直到这种对抗关系出现微妙的不平衡(2B动情)时,整个故事就制造了剧情张力与悬念。反之,如果体验中心全在2B视野中,全局叙事完全被看成2B眼中的他者,而2B的性格又决定了她会收敛自己的情感,那么整个剧情就会一直走向收敛化与平直化,最终这个收敛括弧无法张开。9s的体验中心让玩家既能全方位地领会这个人物(而不是电影和文学一样视角化的领会),因为游戏里的可控角色的核心资本作为透明信息完全向玩家敞开,玩家会一边领略这个人物的技能深度也会同时领会这个人物的叙事内容。&/p&&p&但我们知道,打造这样一个既能承担数值化与技能化包袱,又能承担叙事视角的人物成本是非常高的,大型3A类游戏的双主体已经是砸钱玩的公子哥玩法了,要么你集中焦点拓宽角色样板将技能与数值做到模板化,使其容纳更多的角色量(法师,魔法师,战士这些角色模板),要么你就自断一臂放弃将角色核心资本化,从而将角色拉退到和电影一样的观视视角,注重故事深度而不是游戏机制的深度(这也是步行模拟类游戏的叛逆),因为后者是要数值化呈现、技能化打造与资本化联结的。&/p&&p&(5)退回到观视视角的《艾迪芬奇的记忆》比起其他同样是观视视角的步行模拟类游戏来说,它又往前走了一步,即实现了跨主体叙事。没有主体资本负担的角色可以说是跨主体叙事的天堂,去除核心资本要件后步行模拟类游戏除了要让玩家沉浸于故事与环境氛围以外几乎没别的事可干了,这种情况下任何主体在叙事要求下当然可以做到被置换、撤销与更易,只要“叙事有要求,主体可以变成狗”~(不要笑,Molley的七十二变肯定会载入步行模拟游戏的史册)。&/p&&p&&b&《艾迪芬奇》主体结构:空间驱动时间&/b&&/p&&p&《艾迪芬奇的记忆》这个在两个小时左右就能体验完的游戏,实际上整个故事的叙事结构是非常清晰,颇有一些动漫短片之风,我将这种叙事结构叫做空间驱动时间型。空间驱动时间型叙事结构可以这样被表述:当叙事中围绕固定空间而呈现随时间流动与迭代的事件时,此叙事结构可称为空间驱动时间型。当然,这是一个模糊版本的概念,在这个版本之上可以有:&/p&&p&固定一空间-次生一跨时间事件&/p&&p&固定多空间-次生一跨时间事件&/p&&p&固定一空间-次生多跨时间事件&/p&&p&固定多空间-次生多跨时间事件。&/p&&p&&br&&/p&&p&与其相类似的叙事结构,时间稍远一点例如奥斯卡获奖动漫短片《回忆积木小屋》(つみきのいえ),这部由日本Robot Communications公司于2008年制作的动画短片(由我最喜欢的动漫短片导演加藤久仁生操刀)可以说完美诠释空间驱动时间的叙事理念,甚至全篇的展开仿佛就是整个概念的展开。&/p&&figure&&img src=&https://pic3.zhimg.com/50/v2-c86b5ef2198_b.jpg& data-rawwidth=&500& data-rawheight=&333& class=&origin_image zh-lightbox-thumb& width=&500& data-original=&https://pic3.zhimg.com/50/v2-c86b5ef2198_r.jpg&&&/figure&&p&随时间而漫升的海水使得人们的住房=人们的存在空间不断向积木一样往高处层层累升,从故事开头动画就引入了时间(海水)-空间(积木小屋)这样一种几乎不可调和的视觉结构,而这种视觉结构也是动画以后围绕的叙事结构,请注意这是一层绝对结构,这层绝对结构是作者先赋的,处于不可置疑的对立层:海水上涨-人们再往上累积房屋,这种预先固定的结构就是整个动画剧情的桩,就像数学里的公理(axiom)一样享有不予后退的地位,如果怀疑这种预定结构则叙事几乎开展不下去。&/p&&p&《艾迪芬奇》的主结构是多空间驱动多跨时间事件,再进一步澄清其实就是每个独属空间分割每个独属此空间的跨时间事件。而《回忆积木小屋》也是如此,夕阳的辉光与海洋的蔚蓝分割了这个世界的两大界限,一边是淡然的余生,伴随着路路海鸥、沉沉夕阳与冗闷的电视余响,这一处逼仄的空间是时间逝去之下无可挽回的抗争结果,是人自我生存空间的体现。一边是那些早已陷入大海的簇簇积木小屋,它们相抱成团,俨然已经成为了与当前判然分离的过往,即便在同一个空间位面,但却因为陷于海水的漫浸中而成为了与此处逼仄的空间相对的被空间化的过去。而被时间(海水)逼仄到空间越发狭小的老人,其本身的存在价值也像空间一样被不断逼缩,慢慢变得空无、沉闷、孤独、重复,成为了在岁月的逼迫下抗争的微小个体。&/p&&figure&&img src=&https://pic3.zhimg.com/50/v2-5c2afebeb3c_b.jpg& data-rawwidth=&554& data-rawheight=&370& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic3.zhimg.com/50/v2-5c2afebeb3c_r.jpg&&&/figure&&p&直到他常年的老伙计(称用的烟斗)在某次搬家过程中不慎掉入海洋下,他才开始披上潜水服一层一层地搜集自己的过往,打捞在每一个空间里发生的每一个时间性回忆,而烟斗作为好莱坞叙事里熟稔的触发机制本身自然没什么值得说的,余下的为了保证剧情的完整不在剧透(每次看一遍都要流泪的什么的我绝对不会说!)&/p&&p&当然不同点在于,在《艾迪芬奇的记忆》中多空间驱动多时间是并列式结构,那张布满家庭人员的家谱图也早已暗示了这种结构,每一个空间驱动独属于此空间的此人物的故事,这样子围绕家谱图空间-时间-人物三层都分别得到了立体的结构化呈现。即(1)空间的结构化就是整栋立体化的老宅,它的里里外外的装饰布局呈现了一个完整的游戏设计场景与故事发生背景。(2)时间的结构化是围绕空间结构与家谱结构的人物所在的时间位置,它们刚好构成了回忆发生的故事的前后顺序以及整个时间序列。(3)人物的结构化本身就内嵌于空间-时间的结构中,每一个人物都能从特定空间与时间中找到其存在的过往。这样子每一个事件或者说每一个故事几乎是牵一发动全结构,给玩家的会是不断地体验处于不同时间空间下不同人的心理感受与生命遭历,那么游戏所需要的引人入胜的沉浸体验就在这一段一段的观景体验中得到了好奇一般的舒畅感,这一点本身再配合跨主体叙事可以说相得益彰。&/p&&figure&&img src=&https://pic2.zhimg.com/50/v2-aeadc93d4be969f31f269ab_b.jpg& data-rawwidth=&510& data-rawheight=&284& class=&origin_image zh-lightbox-thumb& width=&510& data-original=&https://pic2.zhimg.com/50/v2-aeadc93d4be969f31f269ab_r.jpg&&&/figure&&p&然而并列式结构比起《积木小屋》的递进式结构缺少了一个质量的提升:叙事高潮。《积木小屋》的时间是递进的:越来越到年轻的回忆,而空间是递进的:越到越到积木小屋底层。当底层的叙事空间与年轻的叙事时间发生交互时音乐声起,故事天衣无缝地过度到高潮:&/p&&p&那棵大树&/p&&p&我们互相认识的&/p&&p&那棵大树&/p&&p&我们互相追赶着的&/p&&p&那棵大树&/p&&p&我们互相拥抱着的&/p&&p&那棵大树&/p&&p&那时还没有海洋&/p&&p&也没有时间&/p&&p&(诗是我瞎写的,凑合着看吧。)&/p&&figure&&img src=&https://pic4.zhimg.com/50/v2-d8e631e49c36ab54a3b7e2fc6c3eb654_b.jpg& data-rawwidth=&554& data-rawheight=&309& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic4.zhimg.com/50/v2-d8e631e49c36ab54a3b7e2fc6c3eb654_r.jpg&&&/figure&&p&紧接着是一段描写情侣双双依偎的平静音乐,而后音调突低,老人的回忆被打破,在音乐的低潮部分面对着触手而不可及的回忆,在余响中收束整个场景叙事,音乐与叙事完美贴合,作为动漫短片的情感爆发力在朴实的行为描述与贴恰的音乐中完美谢幕,一段起伏完整而深刻,这样子每一个空间-时间-事件序列其实都不能严格地算独立的,而是为情感浪潮奠定情感材料,如果你并没有跟着老人去倒叙一遍自己家庭的一生,也就不会在音乐中得到情感爆发。&/p&&figure&&img src=&https://pic1.zhimg.com/50/v2-485d677c610bcd5886daea978ecd8522_b.jpg& data-rawwidth=&554& data-rawheight=&281& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic1.zhimg.com/50/v2-485d677c610bcd5886daea978ecd8522_r.jpg&&&/figure&&p&《艾迪芬奇》在并列空间驱动时间结构中没有了这种优势,转而专注以独特的方式讲述每个角色独特的故事,而独特的方式不仅在于跨主体,还在于向全文本开放,比如在Babara剧情中漫画、文本、声音多媒介交错,营造了一种多媒介互动奇观,实际上这是游戏作为程序载体其本身的机制功能允许它具有相当强大的媒介包容力,然而这实际上并没有在质量上提高Babara故事的内涵,多媒介奇观本身就是为了让这一个独立的故事焕发声色,由于并列式故事必须单独拿来陈说,也因此每个故事都是相对的闭合结构,这一个故事的成功不足以影响下一个故事的发生发展,这一个故事的失败却足以导致整部游戏在叙事评价上的坍塌。&/p&&p&每一段故事都具有足够强大的叙事压力,在这样的叙事压力下游戏不得不用短片态度来讲述故事,每一个故事都必须要至少有一两点(不论是叙事技法上还是故事深度上)能达到玩家的赞誉线上,这使得所有的叙事资源非常的紧缺,以至于不可能构造出精致的结构完备的故事,怎么补救呢?《艾迪芬奇》的方法是如下几个个。&/p&&p&&b&《艾迪芬奇》的叙事特色&/b&&/p&&p&1.那就是构造游戏的跨媒介与视角奇观,几乎每个人物都有视角奇观,这一点我们接下来铺开论述。&/p&&p&(1)Molly的跨主体叙事&/p&&p&与意识流式小说不同,当进入梦幻状态时意识流小说会以间断的、不连续的语言团构成一段一段自我独白,甚至有的时候会有自我否定、重复语气、强调怀疑等等内心戏,例如詹姆斯·乔伊斯的《尤利西斯》(Ulysses)的角色莫莉在第18章中长达几十页的自言自语,其中充满着非连续性的语言段落,各种反复、延宕、省略、强调、怀疑、自反、否定等都会让自我独白显得不稳定,这种内心独白其实是处于不稳定状态下人类心理的自然体现。&/p&&figure&&img src=&https://pic2.zhimg.com/50/v2-003b0d07293d8dbdfab62f100d1a5044_b.jpg& data-rawwidth=&554& data-rawheight=&306& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic2.zhimg.com/50/v2-003b0d07293d8dbdfab62f100d1a5044_r.jpg&&&/figure&&p&而Molly本身在游戏中的自述状态却是非常稳定的,并且就像念台本一样阐述自己的前言后行与一举一动,直至自己在幻想的各种动物视角中的变换时也能准确地描述自己的行为。暂且不论这种叙事手法的刻意之处,之所以需要这样稳定而完整的自白语言是因为这些自白语言必须得到视觉化呈现,那么这里就会遇到一个大问题,在电影中我们如何表达丰富的人物的内心独白?不论你需不需要庞大的独白台词,电影永远不会回避人物自身在独白时的唯一能压过小说的优势-人物表情,如果小说能凭借其完全去中心化文字描述完成复杂的心理,那电影的剪辑天生地达不到文字描写的断裂速度,而电影唯一能利用的就是摄影构图、人物光影以及人物表情的整体呈现来捧起人物独白,这样子就会完成视觉化呈现人物独白的工作。&/p&&p&可是Molly在第一人称视野下其实是无表情的,这就糟糕了,游戏设计方不得不让人物独白成为稳定的独白层,而不是乱七八糟的心灵呓语,然后再将幻想的画面与自白语言稳稳地联系在一起。为了做到这一步,Molly的语言多带动词,并且有明确的指示:“我变成了…此刻我在…我想要…我抓住了…我又变成了…我吃掉了” 这样子的动词加宾语能够方便游戏画面在跨主体中稳定地捕捉到旁白,并且不会让玩家感觉到视觉疲劳(因为玩家控制的猫、鹰、鲨鱼、蛇其实因为独白层的动作陈述其实也是一直在动的,玩家会不断感受着视觉惊喜与新的动作体验),所以用独白层的动词+明确指向+完整句式完成了游戏体验的完整、多变、深刻与紧凑,那牺牲的自然不用多说,牺牲的是人自身情感的突变、复杂、彷惑以及不稳定。而Molly的死亡叙事手法本身就想完成一个循环自指(这跟她真实的死因无关),叙事方本想让Molly在吃的欲望幻想中最后反噬自己的生命,营造一种死亡错像(跟真实的死因无关),从而让诅咒显得煞有介事,从而完成基本的叙事圈套,然而这个圈套的合并是非常不自然的,一个充满着稳定独白层的人的幻想却反噬自我是一个很突兀的跨越。&/p&&p&(2)跨媒介奇观&/p&&p&就像上文所说,整个家族的诅咒-死亡究竟是不是一个诅咒这真的是个庸人自扰的问题,这其实就跟问诺兰的《盗梦空间》那个陀螺会不会停下来一样,不论死亡究竟是不是一个诅咒,它本身就完成了自己在叙事结构上的功能。死亡将处于不同时空节点的家族串联在同一个叙事主轴上,实际上硬性地将这些任务捆绑在一个命运共同体上,因为并列式空间驱动时间的硬伤-无递进感与无连续感却因为死亡这条诅咒线(不论是不是个诅咒)而得到了串联,不然整个家族的并列式故事的叙事就很难找到一个中心点用以回溯整个家庭。《艾迪芬奇》叙事的最终目标是要从这些并列式人物中抽象出整个家族的家族内涵,而将这个家族的家族内涵赋予艾迪芬奇的孩子“我”之上,这个家族内涵可以是某种诅咒,也可以是人终有一死的思考,也可以是活出自己的存在的证据,甚至可以是死亡的荒诞演绎方式等等这都不重要(这里没有唯一的解释,有才怪了)。&/p&&p&而具体到个人,Babara的死亡方式可以说也在某种程度上是一种荒诞式地自指,她成于自己的尖叫(她有一副令人惊叹的尖叫嗓音)也淹没于自己的尖叫中,她到底是亡于连环杀人犯还是本身就是亡于自我幻想的反噬我并不太关心,甚至可以说她正因死而得生(她在死前重新寻得了自己认可的存在价值)。&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/50/v2-d12dabe13c002_b.jpg& data-rawwidth=&554& data-rawheight=&323& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic4.zhimg.com/50/v2-d12dabe13c002_r.jpg&&&/figure&&p&&br&&/p&&p&&br&&/p&&p&这样交相利用漫画、动画、旁白、文字以及声音来刻画这段诡异的死亡本身就在荒诞的故事中再添上更加荒诞的色彩,&/p&&p&除此以外Calvin,利用的是摄影中的摇晃感,在荡秋千中加大摇晃幅度构造了危险步步逼近的危机感。而Sam则在门中门中(玩家的游戏画面是第一个框,照相机镜头是第二个框),不仅给了玩家玩弄镜头的体验,而且还强调了Sam死时那个正在用照相机的主体(也就是玩家控制的主体)对Sam死亡信息的完全接收,摄影中的门中门的效果就是赋予门框内信息以足够的权力比重,那么玩家控制的主体也就完全目睹Sam的死亡的巨细,可以说其心灵的内在冲击与创伤感必然是致命的。&/p&&p&(3)环境叙事&/p&&p&这个就不用多讲了,每一个房间的布置环境大多可以找到这个主体及其死亡的补足信息,例如在Lewis的房间里就可以找到他幻想的原型《The King in Yellow》,以及一大堆暗示死亡、循环、重复的普鲁斯特的著作。&/p&&p&(4)权力分离&/p&&p&Gregory的故事是游戏重新将完整的玩家体验分割开的尝试,作为婴儿的Gregory在游戏中被剥夺了可控制权但保留了观察权,而用澡玩具青蛙则重新被赋予了控制权,游戏的旁白(声音)则控制了叙述权,这样一个将一个完整的游戏权力主体三权分立后所得到的不仅是令玩家前所未见的欣喜感受,而且重新模糊主体的归属,在这种情况下主体本身就是不定的,你的观察主体视角与操作主体视角重新戏谑化地调整了游戏的模式化规则,伴随着青蛙的阵阵滑稽的高跳动作,玩家重新寻得了无忧无虑的徜徉般的童趣。&/p&&p&(5)并列交叉补足&/p&&p&Edile实际上是在其他并列叙事的人物中被交叉补足的人物,严格来说她没有自己独立的时空事件,但却在各种并列事件中作为侧影被时常提及,除此以外Edith的母亲也是如此。&/p&&p&(6)元游戏震惊与操作重复&/p&&p&Gus的风筝玩弄字幕以及Walter的字幕重砸都是游戏元游戏的运用技巧,毋庸赘言。但是Walter故事部分多了行为重复,Walter因为对家族诅咒心生恐惧而常年居住在地下室中,郁郁寡欢,并且不断地给予自我负面暗示。为了反映常年反复的焦虑生活,游戏设计了一段重复的开罐动作,这种行为重复并不是调戏玩家,每一次重复的行为都是一段逐渐淡出的强调。与电影中的长镜头运用一样是一种有风险的设计投资,稍微不注意就会令人视觉疲劳,当然极端概念化与实验性的作品除外(《都灵之马》选择笑而不语)。我们没有任何标准能判断长镜头与游戏中的操作重复的合理性界限在哪里,这完全是取决于设计者与导演本人想要将此文段提升到怎样一个权力位置,电影中的长镜头是用场景停留在视野的时间长短提升此段文本叙事的权力,随着时间的流逝,长镜头的景别在为观者记忆后淡出。而操作重复则是在画面与操作上双重地让玩家进行痕迹记忆,让玩家用身体习性去习惯-游戏主体的习惯,从而增进了叙事与玩家操作的同步性,更重要的是在操作延续中完成了时间流逝的体验性,同样与元游戏一样作为中性化的工具手段则在Lewis剧情中得到了集大成的发挥。&/p&&p&而关于Lewis,在以后的将来我会重新思考整个故事段落,也许会和其他游戏中的某些桥段对比来谈,毕竟这段叙事如果让我单独来谈论的话肯定又是一篇臭长文,这一点请读者原谅我。&/p&&p&《艾迪芬奇的记忆》系列于本文彻底完结,如果您是读完整个系列的文章的读者,我首先为浪费了您的时间而羞愧(尽管我正在努力地不那么做),我得感谢您,因为您的阅读就是我创作下去的动力,希望我们能共同探索游戏的边界&/p&
总算可以回答这个问题了,专栏连载了三篇文章,为了节省读者的阅读时间,只选取最后一篇。如果您在阅读过程中发现个别概念很模糊,我前两篇文章都有澄清并不会妨碍阅读。面向全文本的实验性作品现在《艾迪芬奇的记忆》已经不需要仅仅因为步行模拟游戏这一重…
&figure&&img src=&https://pic3.zhimg.com/v2-f800cf874fc064ae761fbad_b.jpg& data-rawwidth=&1920& data-rawheight=&1080& class=&origin_image zh-lightbox-thumb& width=&1920& data-original=&https://pic3.zhimg.com/v2-f800cf874fc064ae761fbad_r.jpg&&&/figure&&h2&0x00 前言&/h2&&p&本文是《有趣的深度图》的第二篇文章,上一篇文章《&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&有趣的深度图:可见性问题的解法&/a&》中已经和大家介绍了深度图在解决可见性问题中的应用。其实,利用深度信息我们可以实现很多有趣而又显得“高大上”的效果。&br&不过这些效果虽然看上去高大上,但是一旦了解了原理就会发现实现这种效果其实是十分简单的。&br& 那么本文会包括以下四个有趣的效果在Unity中的实现:&/p&&ul&&li&有点科幻的扫描网&/li&&li&透过墙壁绘制背后的“人影”&/li&&li&护盾/能量场效果&/li&&li&边缘检测&/li&&/ul&&br&&h2&0x01 获取深度信息&/h2&&p&为了利用深度信息来实现若干效果,我们首先需要获取场景的深度信息。在移动游戏开发中常用的前向渲染路径(Forward Rendering)下,我们需要手动设置相机,让它提供场景的深度信息。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&camera.depthTextureMode = DepthTextureMode.D
&/code&&/pre&&/div&&p&如果在延迟渲染路径(Deferred Lighting)下,由于延迟渲染需要场景的深度信息和法线信息来做光照计算,所以并不需要我们手动设置相机。&/p&&p&这样我们就可以在shader中访问&b&_CameraDepthTexture&/b&来获取保存的场景的深度信息,之后再利用&b&UNITY_SAMPLE_DEPTH&/b&这个宏来处理_CameraDepthTexture的值,这样我们就获取了某个像素的深度值。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&float depth = UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture, uv));
&/code&&/pre&&/div&&p&但是正如上一篇文章中所说,此时的深度值并非是线性的,因此我们常常需要利用另一个内建的方法&b&Linear01Depth&/b&将结果转化为线性的。这样,我们就能将场景的深度信息渲染为一张灰度图。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&float linear01Depth = Linear01Depth(depth);
&/code&&/pre&&/div&&figure&&img src=&https://pic3.zhimg.com/v2-daf6cea2c2fc939f04baa_b.png& data-rawheight=&638& data-rawwidth=&800& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&https://pic3.zhimg.com/v2-daf6cea2c2fc939f04baa_r.jpg&&&/figure&&br&&br&&h2&0x02 有点科幻的扫描网&/h2&&p&不知道有没有小伙伴玩过《无人深空》这款游戏,当初ps4版预售时我就用行动支持了这款看上去很有吸引力的沙盒游戏,当然第二天挂闲鱼就是后话了。虽然这款游戏让人感到有些失望,但是其中的一些画面效果还是很有趣的,而且也和这篇文章的主题相关——利用场景的深度信息来实现一些科幻效果——比如说,在星球上用扫描仪进行扫描的效果。&/p&&figure&&img src=&https://pic3.zhimg.com/v2-eecdb9f7d37ac372d3d531d_b.jpg& data-rawheight=&462& data-rawwidth=&637& data-thumbnail=&https://pic2.zhimg.com/v2-eecdb9f7d37ac372d3d531d_b.jpg& class=&origin_image zh-lightbox-thumb& width=&637& data-original=&https://pic2.zhimg.com/v2-eecdb9f7d37ac372d3d531d_r.jpg&&&/figure&&p&我们也可以在Unity中实现类似的效果,关键就是利用场景的深度信息。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-cb053dbea_b.jpg& data-rawheight=&1240& data-rawwidth=&1662& data-thumbnail=&https://pic3.zhimg.com/v2-cb053dbea_b.jpg& class=&origin_image zh-lightbox-thumb& width=&1662& data-original=&https://pic3.zhimg.com/v2-cb053dbea_r.jpg&&&/figure&&p&因此如果项目使用了前向渲染路径,我们就必须在脚本中手动将相机的depthTextureMode 设置为DepthTextureMode.Depth,如果是延迟渲染则不需要我们手动设置。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&camera.depthTextureMode = DepthTextureMode.D
&/code&&/pre&&/div&&p&其次,这种全屏效果常常作为屏幕特效(image effect)来实现,也就是说我们需要摄像机先将场景渲染成一副图片,之后对这张图片的像素做处理。设想一下如果不这样做的话,我们不仅要计算场景内所有被渲染对象和摄像机的距离,还需要至少两个pass,其中一个返回被渲染物体的正常颜色,另一个则来实现和扫描颜色的叠加。如果场景内被渲染的对象很多的话,这样的操作效率就变得十分低下了。&/p&&p&所以,在cs脚本中我们还会用到&b&OnRenderImage&/b&这个回调以获取摄像机渲染的场景图像。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&void OnRenderImage(RenderTexture src, RenderTexture dst)
&/code&&/pre&&/div&&p&再次,随着时间的流逝扫描网逐渐扫描整个场景显然是一个动态的效果。因此我们还需要把时间这个因子也引入,时间影响了扫描网和起点的距离。当然,我们既可以在shader文件中考虑时间的影响,也能在cs文件中考虑时间的影响。&/p&&p&如果我们要直接在shader中获取时间的信息的话,就需要用到unity的内置变量&b&float4 _Time : Time (t/20, t, t*2, t*3)&/b&了。它的4个分量分别表示了t/20、t、t*2、t*3。因此,在shader中我们使用_Time.y就可以获取当前的时间,根据时间我们就能算出扫描网当前移动的大概距离了。&/p&&p&除此之外,我们当然也可以在cs文件中直接利用Time类和&b&Update&/b&方法直接计算扫描网的移动距离,然后再将结果传入shader。这样,我们就完成了一个超级简单的cs脚本:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span& /*
* Created by Chenjd
* http://www.cnblogs.com/murongxiaopifu/
using UnityE
using System.C
public class ScannerEffect : MonoBehaviour
#region 字段
public float velocity = 5;
private bool isS
#endregion
#region unity 方法
void Start()
Camera.main.depthTextureMode = DepthTextureMode.D
void Update()
if (this.isScanning)
this.dis += Time.deltaTime * this.
//无人深空中按c开启扫描
if (Input.GetKeyDown(KeyCode.C))
this.isScanning =
this.dis = 0;
void OnRenderImage(RenderTexture src, RenderTexture dst)
mat.SetFloat(&_ScanDistance&, dis);
Graphics.Blit(src, dst, mat);
#endregion
&/code&&/pre&&/div&&p&至于shader?那就更简单了,现在我们获取了相机渲染之后的场景图,这样图上的每个像素只需要获取自己的深度信息:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&
float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv_depth);
float linear01Depth = Linear01Depth(depth);
&/code&&/pre&&/div&&p&然后再和扫描网现在的位置做个对比——当然我们还可以加入扫描网的宽度这个概念——符合条件的像素颜色和扫描网的颜色进行叠加就可以了。最后为了更完美一点,我们还需要判断一下深度值是否比1小,因为深度值在[0,1]这个区间内,而1对应的是远裁切面,因此如果不判断1的话,整个远方最后都会被扫描网的颜色进行叠加。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&if (linear01Depth & _ScanDistance && linear01Depth & _ScanDistance - _ScanWidth && linear01Depth & 1)
float diff = 1 - (_ScanDistance - linear01Depth) / (_ScanWidth);
_ScanColor *=
return col + _ScanC
&/code&&/pre&&/div&&p&完整的项目可以到这里到这里下载:&a href=&http://link.zhihu.com/?target=https%3A//github.com/chenjd/UnitySpecialEffectWithDepth& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&UnitySpecialEffectWithDepth&/a&&/p&&br&&br&&h2&0x03 透过墙壁绘制背后的“人影”&/h2&&p&透过障碍物看到障碍物后的高亮目标,国内外很多游戏都会用到类似的效果。&figure&&img src=&https://pic4.zhimg.com/v2-cf4ab072fedbec22e73927_b.jpg& data-rawheight=&698& data-rawwidth=&1240& class=&origin_image zh-lightbox-thumb& width=&1240& data-original=&https://pic4.zhimg.com/v2-cf4ab072fedbec22e73927_r.jpg&&&/figure&&/p&&p&这个看上去很有高大上的视觉效果,其实从创建一个unity的Unlit shader文件到最后完成这个效果只需要大概30s。&/p&&p&原理很简单,即根据目标是否被遮挡返回不同的颜色即可。目标被障碍物遮住的部分其深度值必然要大于障碍物,因此我们可以用一个pass处理当深度值大于障碍物的时也就是目标被障碍物遮住的部分的颜色——例如我们返回红色。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&
ZTest Greater
fixed4 frag (v2f i) : SV_Target
fixed4 col = fixed4(1, 0, 0, 1);
&/code&&/pre&&/div&&p&再用另一个pass处理目标未被遮挡住的部分,也就是深度值小于障碍物时返回目标的正常颜色。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&
ZTest Less
fixed4 frag (v2f i) : SV_Target
fixed4 col = tex2D(_MainTex, i.uv);
return col
&/code&&/pre&&/div&&p&&figure&&img src=&https://pic3.zhimg.com/v2-e692a494b3ef3f8591a61_b.jpg& data-rawheight=&1240& data-rawwidth=&1662& data-thumbnail=&https://pic2.zhimg.com/v2-e692a494b3ef3f8591a61_b.jpg& class=&origin_image zh-lightbox-thumb& width=&1662& data-original=&https://pic2.zhimg.com/v2-e692a494b3ef3f8591a61_r.jpg&&&/figure&不过墙后的敌人如果只是显示一个红色是否有点太单调了呢?还有很多游戏,它的透视效果是下面这样的:目标身上多了一些描边。&br&&figure&&img src=&https://pic2.zhimg.com/v2-515cba66a08c42e0d61a3d_b.jpg& data-rawheight=&698& data-rawwidth=&1240& class=&origin_image zh-lightbox-thumb& width=&1240& data-original=&https://pic2.zhimg.com/v2-515cba66a08c42e0d61a3d_r.jpg&&&/figure&这个效果的实现其实也很简单。我们可以根据观察方向和目标多边形的法线方向的夹角来判断目标的边缘——毕竟目标面向我们的面的法线和我们观察方向的夹角相对较小,而边缘部分的面的法线和我们的观察方向的夹角显然更大——这里的边缘判断用到了观察方向,下文我们还会聊聊跟观察方向无关的边缘检测。&figure&&img src=&https://pic1.zhimg.com/v2-bdaf196b5654bbf8e3d47684_b.png& data-rawheight=&495& data-rawwidth=&800& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&https://pic1.zhimg.com/v2-bdaf196b5654bbf8e3d47684_r.jpg&&&/figure&&/p&&p&所以,给墙后的目标描边这件事就又变得十分简单了。我们只需要在处理被遮挡部分的那个pass中返回的红色变为与法线和观察方向的夹角相关的一个值就好了。&br& 为了实现这个目标,我们首先要获取法线和观察方向的信息。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&o.normal = UnityObjectToWorldNormal(v.normal);
o.viewDir = normalize(_WorldSpaceCameraPos.xyz - mul(unity_ObjectToWorld, v.vertex).xyz);
&/code&&/pre&&/div&&p&之后再计算法线和观察方向的夹角信息:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&float NdotV = 1 - dot(i.normal, i.viewDir) ;
&/code&&/pre&&/div&&p&最后,只需要把这个值当作影响最后颜色输出的因素就好了。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&return _EdgeColor * NdotV;
&/code&&/pre&&/div&&p&&figure&&img src=&https://pic3.zhimg.com/v2-ec56c06143dd47eaf5fcecb5_b.jpg& data-rawheight=&488& data-rawwidth=&654& data-thumbnail=&https://pic2.zhimg.com/v2-ec56c06143dd47eaf5fcecb5_b.jpg& class=&origin_image zh-lightbox-thumb& width=&654& data-original=&https://pic2.zhimg.com/v2-ec56c06143dd47eaf5fcecb5_r.jpg&&&/figure&完整的项目可以到这里到这里下载:&a href=&http://link.zhihu.com/?target=https%3A//github.com/chenjd/UnitySpecialEffectWithDepth& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&UnitySpecialEffectWithDepth&/a&&/p&&br&&br&&h2&0x04 护盾/能量场效果&/h2&&figure&&img src=&https://pic1.zhimg.com/v2-a378ca9ccbf34d_b.png& data-rawheight=&630& data-rawwidth=&1200& class=&origin_image zh-lightbox-thumb& width=&1200& data-original=&https://pic1.zhimg.com/v2-a378ca9ccbf34d_r.jpg&&&/figure&&p&很多科幻游戏也有这种能量场或者护盾的效果。例如暴雪的守望先锋中的猩猩温斯顿的屏障发射器、光环系列的圣堂防卫者的能量护盾甚至一些手游中也有类似的效果,比如网易的光明大陆。&br&&figure&&img src=&https://pic1.zhimg.com/v2-a4e765f20d14_b.png& data-rawheight=&698& data-rawwidth=&1240& class=&origin_image zh-lightbox-thumb& width=&1240& data-original=&https://pic1.zhimg.com/v2-a4e765f20d14_r.jpg&&&/figure&这个效果的实现和原理其实也并不复杂。简单的说可以分为以下这几个部分:&/p&&ul&&li&半透明效果&/li&&li&相交高亮,主要指能量场和别的物体相交的地方是高亮显示&/li&&li&表面扭曲&/li&&li&一个和观察方向相关的描边效果&/li&&/ul&&p&首先我们要开启透明混合并指定渲染队列为透明。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&SubShader
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
&RenderType& = &Transparent&
&Queue& = &Transparent&
&/code&&}

我要回帖

更多关于 炉石传说战吼触发两次 的文章

更多推荐

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

点击添加站长微信