除了注销电脑还有什么方法消减win10已提交内存存

面试了成百上千人,其中不乏五年以上工作经验的人,我常常会问面试者,你日常如何构建自己的技术知识体系,如何让自己更高更快更强?多数人并没有深入地思考过这个问题,基本上是零敲碎打,随机性大,俗话说脚踩西瓜皮滑到哪里算哪里。&br&&br&我会建议他们,都已经coding了这么多年了,你不妨按我讲的这个体系练练:&br&&blockquote&&strong&第一阶段 认真构建完整的知识体系&br&&/strong&&br&十几年前我投身软件行业的时候,光是讲解数据库原理、操作系统、TCP/IP、组网、算法等等基础知识的英文原版书摞起来就等身,认认真真看完,各种上手实践,入行后,读遍 C++ 各种经典著作,读遍各种协议原文,认认真真打基础。&br&很多工程师都说自己平常就是在某些 IT 门户上看看推荐的博文或新闻,我说这属于典型的零敲碎打,不够刺激。&br&聊到这时,我会举一个例子,为什么要阅读长篇小说,因为中短篇小说就像用针扎你,而长篇小说就像把你装进一个沙袋里吊起来,从四面八方用狼牙棒打你,酣畅淋漓。构建可用的知识体系,就得读书,书是有体系结构的,你关心不关心,现阶段你用到用不到,它都讲到了,从头到尾看几遍,针扎得透透的。&br&&br&何谓知识体系?&br&几年前,前支付宝架构师姚建东曾经在我们公司做过技术人员如何规划自己的分享讲座,他是这么论述的:&br&技术与技巧包括:&br&&ul&&li&计算机基础理论&/li&&ul&&li&计算机模型:内存/IO/时钟/CPU……&/li&&li&算法&/li&&li&专项技术领域:&/li&&ul&&li&数据挖掘&/li&&li&数据管理&/li&&li&智能推荐&/li&&li&搜索&/li&&li&……&/li&&/ul&&/ul&&li&语言与工具&/li&&ul&&li&语言与相关体系&/li&&li&开发工具,分析工具,代码管理工具&/li&&li&HTML/CSS/JS/Ajax&/li&&li&常用框架与第三方类库&/li&&/ul&&li&调试与测试&/li&&ul&&li&调试方法和哲学&/li&&li&定位问题&/li&&li&BUG管理工具&/li&&li&单元测试&/li&&li&集成测试&/li&&li&性能测试&/li&&li&安全测试&/li&&li&兼容性测试与方法&/li&&li&JS/Ajax测试与方法&/li&&li&服务层测试&/li&&li&Web层测试&/li&&/ul&&li&网络与系统&/li&&ul&&li&TCP/IP协议与模型,HTTP/SMTP等协议&/li&&li&Linux系统,网络分析工具,系统分析工具&/li&&li&容量,流量与负载均衡&/li&&li&应用部署、规范、规划&/li&&li&安全&/li&&li&监控与故障分析&/li&&li&磁盘与存储&/li&&li&Shell&/li&&li&DNS与域名&/li&&li&缓存,反向代理&/li&&li&图片服务器(海量小文件)&/li&&/ul&&li&需求挖掘与分析&/li&&ul&&li&需求文档格式&/li&&li&需求访谈&/li&&li&需求分析方法,需求分析工具&/li&&li&领域知识与经验&/li&&/ul&&li&系统分析与设计&/li&&ul&&li&UML语言与模型&/li&&li&分析模式&/li&&li&设计模式,领域驱动&/li&&li&系统分析文档格式&/li&&li&系统设计文档格式&/li&&li&功能性需求与非功能性需求&/li&&/ul&&li&数据与系统&/li&&ul&&li&数据库&/li&&li&可伸缩策略,扩展策略,备份,容灾,性能,安全,高可用……&/li&&li&数据设计与范式,SQL/NoSQL,Cache,分布式文件&/li&&/ul&&li&架构设计&/li&&ul&&li&架构模式,典型互联网公司架构演进历史&/li&&li&架构原则,常用策略&/li&&li&架构设计方法&/li&&li&非功能性理解&/li&&ul&&li&扩展性&/li&&li&伸缩性&/li&&li&稳定性&/li&&li&一致性&/li&&li&性能&/li&&li&吞吐量&/li&&/ul&&li&容量预测与规划&/li&&li&架构体系与相关技术&/li&&/ul&&li&过程与管理&/li&&ul&&li&分析过程&/li&&li&研发过程&/li&&li&评审过程&/li&&li&测试过程&/li&&li&发布过程&/li&&li&回滚过程&/li&&li&文档管理&/li&&li&知识管理&/li&&li&项目管理&/li&&/ul&&/ul&以上其实就是一份从业基础知识清单,你可以按图索骥,阅读相关书籍。&br&&br&&strong&第二阶段 顺着一个Topic钻进去,锻炼自己的预研能力&br&&/strong&&br&无论公司业务还是自己喜欢做的事,都可以抽象出通用性课题,然后以做论文的方式杀进去。这个事情得反复操练,有意识操练。&br&做事方式为:&br&&ol&&li&抽象出 Topic——如分布式锁,分布式并行计算引擎,防CSRF的FormToken自动生成框架,定时任务管理与调度平台,分布式跟踪,等等&/li&&li&向功课好的学生学习——有针对性地深入了解业界其他公司是如何分析问题和解决问题的,汇总各种方案,站在巨人的肩膀上&/li&&li&分析特定应用场景,技术选型&/li&&li&兼顾高可用性和可伸缩,做设计评审&/li&&li&做测试自证靠谱,梳理知识点,开技术分享会&/li&&li&上线商用,总结经验教训,开经验分享会&/li&&/ol&&br&其中一个重点是汇总和分享。05年时,应电信级统一消息业务需要,我去研究了 SIP 协议,做了各种试验,分析报文,写了一系列的幻灯片,做了公开分享,一时间还颇受欢迎:&br&&ol&&li&SIP_to_Freshman_by_zhengyun.ppt&/li&&li&SIP之穿越NAT_by_zhengyun.ppt&/li&&li&SIP体系架构讲义及消息交互演示_by_zhengyun.ppt&/li&&li&SIP多方会话消息之实例讲解_by_zhengyun.ppt&/li&&li&SIP安全框架之认证[NTLM和Kerberos]_by_zhengyun.ppt&/li&&li&SIP消息之逐项讲解_by_zhengyun.ppt&/li&&/ol&为什么要写出来、讲出来呢?&br&因为有一个学习金字塔理论,如下图所示:&br&&figure&&img src=&https://pic2.zhimg.com/50/90a9f19f5aece2838327c_b.jpg& data-rawwidth=&664& data-rawheight=&368& class=&origin_image zh-lightbox-thumb& width=&664& data-original=&https://pic2.zhimg.com/50/90a9f19f5aece2838327c_r.jpg&&&/figure&&br&&br&我们读过的事情能够记住学习内容的10%,&br&我们听过的事情能够记住20%,&br&我们看过的事情能够记住30%,&br&我们听过和看过的事情能够记住50%——如看影像/看展览/看演示/现场观摩,&br&我们说过的事情能够记住70%——如参与讨论/发言,&br&&strong&我们说过和做过的事情能够记住90%——如做报告,给别人讲,亲身体验,动手做。&/strong&&br&这也就是我在《窝窝研发过去几年做对了哪些事》中阐述的管理方法:我们从入职之后就有意识地训练大家,让大家能够公开陈述、清晰表达。所以,试用期内,新人必须做一次技术分享和一次技术评审,面对各方的 challenge;预研的中间和结尾都要有分享会;平时也要定期组织技术讲座。&br&&br&&strong&第三阶段 疯狂回答技术问题&br&&/strong&&br&知识体系慢慢构建,与业务相关的抽象 Topic 也在探索中。&br&但这还不够。&br&因为你亲身接触到的世界太小,可能不足以构成挑战,你可能意识不到自己缺多少知识和技能,不利于你分析问题、提出问题和解决问题的能力培养。&br&所以,要主动出击:&br&&strong&疯狂回答问题&/strong&。&br&&br&我曾经在入行的头几年里几乎把我关注的垂直领域(包括语言领域和业务领域)里的所有问题都回答了一遍。我对外宣扬知无不言言无不尽,放出邮件地址和 MSN(那时候 MSN 很高大上),很多网友都会发邮件或者加我好友,问各种开发疑难问题,平均每天都有几个,然后我把解决问题的过程写成微软 KB(KnowledgeBase) 文体发表在我的博客上。&br&你想想看,工作中的问题你平均每隔几天才能遇到一个,而这么做,每天你都会遇到几个乃至于十几个,第一让你脑力激荡,第二接触到更多新知。&br&&br&05年到06年期间,我因工作需要学习了 JavaME(或古老的称呼 J2ME),早年间 Symbian 手机上的客户端开发。那段时间我天天扫中文论坛的帖子,力求回答所有问题,尤其是那些 BUG 或故障。对于那些暂时没有人解决的,如流媒体实时播放,如仿 OperaMini 二级菜单界面,都上下求索,最后放出思路以及源码。&br&同时,我经常整理常见问题,梳理成册并发布。譬如我整理过的 J2ME 疑难问题:&br&&ol&&li&[J2ME Q&A]真机报告MontyThread -n的错误之解释&/li&&li&[J2MEQ&A]WTK初始化WMAClient报错XXX has no IP address的解释&/li&&li&[J2ME Q&A]untrusted domain is not configured问题回应&/li&&li&[J2ME]“Cannot open socket for LIME events”错误解决&/li&&/ol&几个月后,我成为 J2ME 中文论坛超级版主。通过这个历程,我想告诉大家,回答网友问题,技巧得当的话,比如别老是重复回答新手问题,试着攻克那些疑难问题,或者离奇故障,绝对不会浪费你的时间。&br&为什么?&br&因为你要信奉:&br&你学过的每一样东西,你遭受的每一次苦难,都会在你一生中的某个时候派上用场。&br&——佩内洛普·菲兹杰拉德 《离岸》&br&&br&Everything that you've learnt and all the hardships you've suffered will all come in handy at some point in your life.&br&&br&&strong&第四阶段 RCA/总结&br&&/strong&&br&现在是你把经验教训变为财富的时刻了。&br&什么是好的技术 Leader?&br&随便一个业务需求或业务场景讲出来,你立刻把它抽象为几个模块/系统/Topic,然后侃侃而谈,业界都是怎么解决的,我们以前又是怎么分析怎么解决的,现在咱们这种情况下应该如何设计,可能会遇到什么问题,我们应该做哪些预防设计,blabla。&br&&br&怎么做到这一点?&br&第一,写 RCA 报告。&br&我以前说过,『窝窝从 2011 年开始,一直坚持每错必查、错了又错就整改、每错必写,用身体力行告诉每一个新员工直面错误、公开技术细节、分享给所有人,长此以往,每一次事故和线上漏测都会变为我们的财富。这就是我们的 RCA(Root Cause Analysis)制度,截止到目前已经收集整理了近两百个详尽的 RCA 报告。』&br&RCA 报告格式为:&br&&ol&&li&背景知识(Optional)&/li&&li&问题现象&/li&&li&影响范围&/li&&li&问题原因&/li&&li&问题分析过程(Optional)&/li&&li&解决办法&/li&&li&后续处理措施:如线上脏数据如何修复,如对用户造成的影响如何弥补等(Optional)&/li&&li&经验教训&/li&&li&RCA类型:如代码问题、实施问题、配置问题、设计问题、测试问题&/li&&/ol&这样,作为一名合格的老兵,你见过了足够多的血,并且把它们变成了你的人生财富。&br&第二,写总结。&br&话说,要经常拉清单。&br&侃侃而谈得有资料,这些都得是你自己写才能印象深刻,关键时刻想得起来。&/blockquote&本文出自《&a href=&http://zhuanlan.zhihu.com/zhengyun/& class=&internal&&技术高手如何炼成 - 旁观者 - 知乎专栏&/a&》。
面试了成百上千人,其中不乏五年以上工作经验的人,我常常会问面试者,你日常如何构建自己的技术知识体系,如何让自己更高更快更强?多数人并没有深入地思考过这个问题,基本上是零敲碎打,随机性大,俗话说脚踩西瓜皮滑到哪里算哪里。 我会建议他们,都已…
&figure&&img src=&https://pic1.zhimg.com/fe00ebe7cf77aac30112_b.jpg& data-rawwidth=&652& data-rawheight=&760& class=&origin_image zh-lightbox-thumb& width=&652& data-original=&https://pic1.zhimg.com/fe00ebe7cf77aac30112_r.jpg&&&/figure&&p&第一篇文章,就以之前发在 &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Blog&/a& 上的游戏开发相关的文章汇总开始吧。此文将会作为索引,保持不定期的更新。(上次更新 [])&/p&&p&&br&&/p&&h2&游戏开发&/h2&&ul&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-occlusion-culling& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&遮挡剔除的低端解决方案&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-gtav-graphics& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&GTA V 图形分析摘要&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-ref-management& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&利用文件摘要简化游戏资源的引用管理&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-a-modal-deadlock-issue& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&一个有趣的交互 bug ——兼谈游戏的引导系统&/a&&br&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-bitcoin-and-online-game-economics& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&玩的就是资产! - 比特币与游戏货币体系&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-open-world& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&[知乎] 开放世界游戏中的大地图背后有哪些实现技术?&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-tech-evaluation& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&如何判断一个技术(中间件/库/工具)的靠谱程度?&/a&&br&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-plug-in-based-engine-design& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&基于插件的引擎设计&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-threaded-rendering& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&为什么从本质上讲,渲染逻辑不适合放到子线程中去?&/a&&/li&&/ul&&h2&VR&/h2&&ul&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/vr/-oculus-connect-3-abrash& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&VR 的未来五年 - Michael Abrash 在 Oculus Connect 3 上的回顾与展望&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-oculus-connect-2-michael-abrash-keynote& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Oculus Connect 2 首席科学家 Michael Abrash 发言实录&/a&&/li&&/ul&&h2&Unity&/h2&&ul&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/perf_assist/-unity-coroutine-optimizing& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity 协程运行时的监控和优化&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/perf_assist/-unity-string-intern& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity 游戏的 string interning 优化&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-unity-external-dll-debugging& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&(Unity) 为动态加载的 C# DLL 添加调试支持&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-profiler-support-for-code-behind-lua& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&(Unity) 为被 Lua 隔断的 C# 实现添加 Profiler 支持&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-umetalod& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity 实践系列 (3/n) UMetaLod - 一个通用的增强版 LOD 方案&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-uquadtree& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity 实践系列 (2/n) UQuadtree - Unity 下的场景资源动态管理&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-u3d-practices-and-tips& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity 项目实践点滴&/a&&/li&&/ul&&h2&网络&/h2&&ul&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-doom3-network-architecture& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&(3/3) DOOM3 网络架构&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-id-network-model-evolution& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&(2/3) DOOM/Quake I/II/III 网络模型的演化&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-doom3-bfg-notes& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&(1/3) DOOM3 技术点滴&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-nanomsg& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&nanomsg - zmq 的华丽转身&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-dynamic-prediction-and-latency-compensation& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&客户端动态预测技术和延时补偿技术&/a&&/li&&/ul&&h2&C/C++/Go&br&&/h2&&ul&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-awesome-cppcon& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&CppCon
选荐合辑&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-cpp-lua-vargs& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&类型安全的 C++/Lua 任意参数互调用&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-lvalue-rvalue& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&(C++) 快速辨别左值和右值的两个方法&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-kill-goroutine& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&(Go) 从外部结束一个 goroutine&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-std-tuple-arg-parser& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&有趣的 std::tuple - 一行代码解析命令行字符串&/a&&br&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-memory-debugging& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&[CppCon 2015] &Memory and C++ debugging at EA& 实录&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-multicast& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&一个可注销的通用多路回调列表 (C++)&/a&&br&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-cppcon14& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&CppCon2014 分类合辑 & 十大推荐阅读列表&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-emc-intro& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&[EMC] 《Effective Modern C++》要点提炼:介绍部分&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-type-deduction& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&[知乎] C++ template 为什么不能推导返回值类型?&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-zhihu-c-books& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&[知乎] C 语言学习的经典书籍有哪些?&/a&&/li&&/ul&&h2&工程实践&/h2&&ul&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-premake-android-mk& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&使用 Premake 自动化 Android 编译脚本的维护&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-legacy-code& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&[知乎] 入职后发现项目组代码异常混乱,是去是留?&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-appveyor-ci& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&利用 AppVeyor 实现 GitHub 托管项目的自动化集成&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-error-handling& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&“Abort,Retry,Fail?” - 也谈错误处理&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-tradeoff-between-dev-efficiency-and-runtime-efficiency& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&[知乎] 开发效率与执行效率,我们应该怎样斟酌?&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-unit-test-fetish-excerpt& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&[译] 单元测试之迷思 (摘要)&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-dont-lie& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&[译] 不要说谎 (Don't lie.)&/a&&/li&&/ul&&h2&游戏评论及其他随笔&br&&/h2&&ul&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-stress-free-dealing-with-info-overload& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&无压应对信息过载 - 2016 效率小结&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-time-division& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&我的时间分配变迁记 (原问题:程序员工作中占时间最长的是哪个步骤?)&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-blizzcon2015-talks& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&暴雪游戏开发趣闻 (若干则)&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-evernote-are-you-ok& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Evernote 你还好吗?&/a&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-sango-mod-blood-civil& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&“千年故纸空读尽,恨把衣冠祭九州” -小记《三国志11之血色衣冠》&/a&&br&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-microsoft-crt& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&昔时因 今日意 侃侃微软的CRT&/a&&br&&/li&&li& &a href=&https://link.zhihu.com/?target=http%3A//gulu-dev.com/post/-review-of-weixin-air-combat& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&全民打飞机 - 简评和碎碎念&/a&&/li&&/ul&
第一篇文章,就以之前发在
上的游戏开发相关的文章汇总开始吧。此文将会作为索引,保持不定期的更新。(上次更新 []) 游戏开发
&figure&&img src=&https://pic2.zhimg.com/v2-4f6f1eda3e5a020ded4fdea0b12bf05d_b.jpg& data-rawwidth=&1079& data-rawheight=&558& class=&origin_image zh-lightbox-thumb& width=&1079& data-original=&https://pic2.zhimg.com/v2-4f6f1eda3e5a020ded4fdea0b12bf05d_r.jpg&&&/figure&&p&一直忘记发一个miniblink的介绍了。&/p&&p&miniblink已开源在github上:&a href=&https://zhuanlan.zhihu.com/p/?refer=chrome& class=&internal&&大家久等了,miniblink终于开源了!! - 盟主来了 - 知乎专栏&/a& &/p&&h2&&b&miniblink是什么?&/b&&/h2&&p&Miniblink是一个全新的、追求极致小巧的浏览器内核项目,&br&其基于chromium最新版内核,去除了chromium所有多余的部件,只保留最基本的排版引擎blink。&br&Miniblink保持了10M左右的极简大小,是所有同类产品最小的体积,同时支持windows xp、npapi。&/p&&h2&&b&为什么要做miniblink?&/b&&/h2&&p&市面上作为嵌入的组件的可用的浏览器内核,不外乎这几个:webkit、cef、nwjs、electron。&/p&&p&cef:优点是由于集成的chromium内核,所以对H5支持的很全,同时因为使用的人也多,各种教程、示例,资源很多。但缺点很明显,太大了。最新的cef已经夸张到了100多M,还要带一堆的文件。同时新的cef已经不支持xp了(chromium对应版本是M49)。而且由于是多进程架构,对资源的消耗也很夸张。如果只是想做个小软件,一坨文件需要带上、超大的安装包,显然不能忍受。&/p&&p&nwjs,或者最近大火的electron:和cef内核类似,都是chromium内核。缺点和cef一模一样。优点是由于可以使用nodejs的资源,同时又自带了各种api的绑定,所以可以用的周边资源非常丰富;而基于js的开发方案,使得前端很容易上手。所以最近N多项目都是基于nwjs或electron来实现。例如vscode,atom等等。&/p&&p&原版webkit:现在官网还在更新windows port,但显然漫不在心,而且最新的webkit也很大了,超过20几M。最关键的是,周边资源很少,几乎没人再基于webkit来做开发。同时由于windows版的saferi已经停止开发了,所以用webkit就用不了他的dev tools了。这是个大遗憾。&br&&/p&&p&WKE:这是个很老的webkit内核的裁剪版了。小是小,但bug太多了。&/p&&p&&b&那么关键点来了,使用miniblink有啥好处呢??&/b&&/p&&p&首先,miniblink对大小要求非常严格。原版chromium、blink里对排版渲染没啥大用的如音视频全都被砍了,只专注于网页的排版和渲染。甚至为了裁剪大小,我不惜使用vc6的crt来跑mininblink(见我上篇文章)。这个也算前无古人后无来者了。&/p&&p&其次,miniblink紧跟最新chromium,这意味着chromium相关的资源都可以利用。在未来的规划里,我是打算把electron的接口也加上的,这样可以无缝替换electron。使用miniblink的话,开发调试时用原版electron,发布的时候再替换掉那些dll,直接可以无缝切换,非常方便。&/p&&h2&&b&miniblink如何使用?&/b&&/h2&&p&Miniblink导出了CEF、WKE的接口,可以直接无缝替换现有的CEF、WKE项目。&br&同时,正在开发electron的接口,大家拭目以待。&/p&&p&目前miniblink放出了一个小demo,从demo里可以看到,brackct这个基于cef的开源编辑器,已经顺利由miniblink跑起来了。未来如果electron的接口做好,把vscode跑起来,那就屌炸天了。&/p&&h2&&b&miniblink如何裁剪到这么小?&/b&&/h2&&p&这个比较复杂了。主要就是把blink从chromium抽离了出来,同时补上了cc层(硬件渲染层)。现在的blink,已经不是当年的那个webkit了,渲染部分全走cc层,复杂无比。我这大半年都在重写他那个蛋疼又复杂的cc层。&/p&&h2&&b&和webkit比,miniblink架构有什么优势&/b&&/h2&&p&现在的webkit版本,已经比miniblink落后太多了。blink一直在加入各种极富创造力和想象力的功能、组件。例如,blink早就加入多线程解析html token、blink gc回收器、多线程录制回放渲染机制。这些能让blink的解析渲染速度极大提升。下一次,我会先开源出blink gc组件,这东西很有意思,在c++里硬是搞出了一个垃圾回收机制,能让你像写java一样写c++。&/p&&h2&&b&miniblink有计划开源吗?&/b&&/h2&&p&&b&目前已开源在github上:&/b&&a href=&https://link.zhihu.com/?target=https%3A//github.com/weolar/miniblink49& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&weolar/miniblink49&/a&&/p&&p&&b&我会持续维护这个项目的,我相信,这个才是此项目最有价值的地方&/b&&br&更多动态可以关注我的博客:&a href=&https://link.zhihu.com/?target=http%3A//blog.csdn.net/weolar/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&炫酷的miniblink demo已上传,基于bracket&/a&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-3ad5d589d18f76f2e8d35_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1057& data-rawheight=&597& class=&origin_image zh-lightbox-thumb& width=&1057& data-original=&https://pic2.zhimg.com/v2-3ad5d589d18f76f2e8d35_r.jpg&&&/figure&&p&&/p&
一直忘记发一个miniblink的介绍了。miniblink已开源在github上: miniblink是什么?Miniblink是一个全新的、追求极致小巧的浏览器内核项目, 其基于chromium最新版内核,去除了chromium所有多余…
----------------------------&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/50/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://pic1.zhimg.com/50/47a0c8c78f1adf3afcee_b.jpg& data-rawwidth=&550& data-rawheight=&413& class=&origin_image zh-lightbox-thumb& width=&550& data-original=&https://pic1.zhimg.com/50/47a0c8c78f1adf3afcee_r.jpg&&&/figure&&br&&br&&br&c. 在 3D 游戏里循环平铺高度图,形成连绵不断的地形效果。这在早期的模拟飞行射击类游戏里比较常见,现在已经很难搜到图了,我在上大学的时候写的第一个地形渲染 demo 就是平铺的,可惜刚刚翻硬盘已经找不到了555。这一类游戏,在平铺时适当地辅以一些贴图的变化,可以在很省内存的条件下,做出非常不错的效果。&br&&br&找不到游戏内的图,拿下面这个高度图来凑数吧。请大家脑补一下,把下面这个灰度图立体化之后,一块一块像地砖一样循环平铺以后,3D渲染出来的连绵起伏的直抵地平线(好吧,直抵远裁剪面)的山脉的壮观效果吧。&br&&br&&figure&&img src=&https://pic1.zhimg.com/50/b9c4ebfd28bccc8475ac1d_b.jpg& data-rawwidth=&512& data-rawheight=&512& class=&origin_image zh-lightbox-thumb& width=&512& data-original=&https://pic1.zhimg.com/50/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://pic3.zhimg.com/50/50bde2249146cce4ea9c_b.jpg& data-rawwidth=&640& data-rawheight=&517& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&https://pic3.zhimg.com/50/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&所有这些一旦发生,都是很容易觉察的。一旦你发现在一个很大的坐标上有这些问题,而接近原点处问题却消失了,那么很有可能就是精度在作怪。而需要注意的是,出现这种问题,只和游戏中出现的数字的规模和跨度有关,和游戏选择了什么样的长度单位(如用毫米还是公里做单位)无关。&br&&br&----------------------------&br&&br&那么怎样使用有限的坐标精度来描述较大尺度的世界呢?&br&&br&最直接的方案是 &b&使用双精度浮点数 &/b&(64 位),如果这是可接受的选择,那么就不必费心引入后面讨论的复杂度了。&br&&br&其次是 &b&区域划分法&/b& 。我看到 &a data-hash=&1e2cccc3ce33& href=&//www.zhihu.com/people/1e2cccc3ce33& class=&member_mention& data-editable=&true& data-title=&@Milo Yip& data-hovercard=&p$b$1e2cccc3ce33&&@Milo Yip&/a&
同学已提到,不过这里出于完整性的考虑,再简单说一下。正如 Milo 同学所说,“把世界划分成不同的区域,在区域内的计算使用其局部坐标系统。”相对应的跨区访问,需要对应的“本地A -& 世界 -& 本地B”的坐标转换。&br&&br&还有一个方案是 &b&节点中转法&/b&。正如移动电话的基站用来承载和协调整个通信网络那样,我们在游戏的给定活动区域使用静态信标,所有的逻辑上与之相关的单位,都以该信标的坐标作为参考单位,这样也可以做到把数据访问局部化。相距足够远的两个物体(相当于上面的跨区访问)交互总是通过静态信标来完成(正如移动电话网络中发生的那样),这样的好处是相关的复杂度可以隔绝在这个中转系统的内部。&br&&br&此外
&a data-hash=&9a5b0b946e064a3a170f04c2d3563a78& href=&//www.zhihu.com/people/9a5b0b946e064a3a170f04c2d3563a78& class=&member_mention& data-editable=&true& data-title=&@凯丁& data-hovercard=&p$b$9a5b0b946e064a3a170f04c2d3563a78&&@凯丁&/a&
同学提到了一个&b&坐标转换法&/b&,“所有位置信息都以角色位置为中心做一次转换”。这正是 《Game Programming Gems IV》 [“4.0 Solving Accuracy Problems in Large World Coordinates”](&a href=&//link.zhihu.com/?target=http%3A//www.gameenginegems.net/gemsdb/article.php%3Fid%3D280& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Graphics and Game Gems Database&/a&) 文中的方案。这个方案可以解决部分问题(主要是渲染相关的问题),但是仍有一些问题需要考虑,比如:1. (上面提到的)编辑器内操作的物体,在序列化到文件中时,精度丢失的问题。2. 大部分物理模拟通常需要一个角色无关,摄像机无关的全局坐标系。等等。&br&&br&----------------------------&br&&br&### 4. 超大地形的处理 (Terrain Visualization)&br&&br&终于说到对超大地形的处理了。可以说从上世纪九十年代起,超大地形的可视化,一直是3D游戏领域热门的话题。今天我们就借着这个机会,把相关的算法和实现理一理吧。&br&&br&考虑到篇幅太长的话,俺的手指头招架不住,再一个不少对这个话题感兴趣的同学可能压根就不是程序员,一些实现细节可能我就只是简单提一下,贴代码什么的还是算了,尽量保证整篇文章的信息浓度适中吧。&br&&br&----------------------------&br&&br&总的来说,这十多年来,地形渲染技术的发展史就是一部生动的对现代GPU的开发,利用和改进史。整个过程大致可以分成三个阶段:一开始,GPU处理顶点能力很弱,这个时期的各种精巧算法(如一些VDPM和后期的ROAM),**尽力在用CPU来降低顶点的总量**,避免一不留神压垮图形系统;后来,图形系统的能力上去了,人们开始更多地考虑到**把地形系统融入到通用的场景管理**中去,如四叉树八叉树什么的就是在这个阶段被广泛应用的;再往后,GPU已经很强大了,CPU由于要承担更复杂的游戏逻辑,越来越成了整个系统的瓶颈,这个阶段,人们琢磨的更多的是,怎么**利用GPU给CPU减负**了,一直到如今,由 GPGPU 带动起来的异构计算,也都是这个路数。&br&&br&----------------------------&br&&br&由于内容比较杂,超大地形这个段落,按上面的描述,咱们分为三个小段分开来讲吧。让俺先沏上一杯碧螺春,为客官一一道来。&br&&br&#### 4.1 古典算法(从 GeoMipMapping,Progressive Mesh 到 ROAM) &br&&br&&b&GeoMipMapping&/b& 是从纹理的 MipMapping 技术演化来的一个地表处理技术,原理上是根据任何一小块地形在屏幕上显示的实际尺寸(主要跟与摄像机的距离和起伏程度有关)来选择对应密度的网格,然后把不同分辨率的网格之间以某种方式拼接起来(没有这一步的话就会有裂缝),本质上是一种比较粗糙的区域 LOD 算法。顺便说一下,由于那时候针对顶点级的处理很多,导致这种T型裂缝很常见,以至于有个专门的名字叫“T-Junction”,针对这个的处理在当时也有很多方案。&br&&br&&figure&&img src=&https://pic4.zhimg.com/50/a009ae667fd9_b.jpg& data-rawwidth=&551& data-rawheight=&398& class=&origin_image zh-lightbox-thumb& width=&551& data-original=&https://pic4.zhimg.com/50/a009ae667fd9_r.jpg&&&/figure&&br&&br&这是俺刚刚到老硬盘里刨出来的大三时写的 GeoMipMapping 代码,编了一下居然还能跑起来。有点土,别介意:P 可以看到不同的 MipMap 级别是用不同的颜色渲染的,也可以看到接头处 T 型裂缝的处理。唉,这代码勾起了俺的青葱回忆啊,那就顺便再来两张 T 型裂缝的示意图和消除过程吧。&br&&br&&figure&&img src=&https://pic1.zhimg.com/50/14d993ba8c1bdde03a2e_b.jpg& data-rawwidth=&522& data-rawheight=&535& class=&origin_image zh-lightbox-thumb& width=&522& data-original=&https://pic1.zhimg.com/50/14d993ba8c1bdde03a2e_r.jpg&&&/figure&&br&&br&----------------------------&br&&br&&figure&&img src=&https://pic4.zhimg.com/50/cd4ebdf412bfe4538a6ddd1fb7b2a3fc_b.jpg& data-rawwidth=&612& data-rawheight=&495& class=&origin_image zh-lightbox-thumb& width=&612& data-original=&https://pic4.zhimg.com/50/cd4ebdf412bfe4538a6ddd1fb7b2a3fc_r.jpg&&&/figure&&br&&br&----------------------------&br&&br&&b&Progressive Mesh&/b& 是后来很流行的技术 Simplygon 的前身,原理上基本也是一致的,就是以某种方式渐变性地化简某个给定的 Mesh。&br&&br&渐进式网格有两种:视点无关的 (View-Independent Progressive Mesh,VIPM) 和视点相关的 (View-Dependent Progressive Mesh,VDPM)。两者的区别就是,前者预先离线生成好所有的渐变过程,运行时直接用就行(也是后来 Simplygon 采用的方案),而后者随着摄像机的位置和角度的变化,生成对应的简化模型。两相对比,VIPM的好处是运行时运算开销低,简化模型的效果好,缺点是费内存(因为数据都存下来了,当然后来增量的方式能省一些),而VDPM在当时是不错的选择,因为跟VIPM相比不用费额外的内存,而且对于视点(就是摄像机)变化不剧烈的应用,不需要每帧处理和更新对应的简化模型(普通的MMO类的一般一秒一次就够了),此外由于一些简单的遮挡剔除和背面剔除,能够比VIPM裁掉多得多的顶点(一般能多裁1/3到一半吧,在当时这可是头等大事)。&br&&br&总的来说,至少在当时,两者的应用都比较广泛,而到了后来,显存越来越大,总线却越来越紧张,VDPM这种典型的刷顶点的算法(比较费总线带宽)就逐渐失去了市场,这是后话了。&br&&br&大家可以在[这里](&a href=&//link.zhihu.com/?target=http%3A//www.cbloom.com/3d/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&3d Page (www.cbloom.com/3d)&/a&)看到一些 PM 在地形渲染上的应用。图咱就不上了,大家可以到 Simplygon 的网站上去看。&br&&br&----------------------------&br&&br&&b&ROAM&/b& 可算作是上面提到的 VDPM 更进一步了。这个算法实际上借鉴了当时主流引擎的标配BSP的思路,想利用二叉树这个最简洁的空间描述数据结构,把(CPU端的)顶点消减发挥到极致。整个地表被组织成一个巨大的二叉树,有两个队列,一个是分割队列,一个是合并队列,分别用于处理摄像机移动时,增加进入视野的区域细节和消减退出视野的区域细节。精心设计的 ROAM 效果非常华丽(尤其是在线框模式下),你会看到在各种因素的影响(包括局部坡度,与摄像机的夹角,遮挡情况等等)下,各种三角形像魔术般的不断地变幻,生成和擦除超多的细节,效果非常魔幻。我印象很深的是当时连续打Quake3两个小时完全无感的我,调试这玩意的时候,每每不到十分钟眼就花了。&br&&br&网上找了两张比较典型的 ROAM 大家感受一下吧。&br&&br&&figure&&img src=&https://pic2.zhimg.com/50/07be8d1e331b9b1b7ebae1_b.jpg& data-rawwidth=&1003& data-rawheight=&749& class=&origin_image zh-lightbox-thumb& width=&1003& data-original=&https://pic2.zhimg.com/50/07be8d1e331b9b1b7ebae1_r.jpg&&&/figure&&br&&br&----------------------------&br&&br&&figure&&img src=&https://pic3.zhimg.com/50/d276affe4ed461cb33408e_b.jpg& data-rawwidth=&636& data-rawheight=&398& class=&origin_image zh-lightbox-thumb& width=&636& data-original=&https://pic3.zhimg.com/50/d276affe4ed461cb33408e_r.jpg&&&/figure&&br&&br&----------------------------&br&&br&&br&#### 4.2 层次的艺术(Quadtree 和 Chunked LOD)&br&&br&其实用于空间管理的树状结构有四叉树和八叉树(还有上面的二叉树),但地表通常以前者居多。是因为,从小范围来看,变化剧烈的地形是3D的,适合八叉树在xyz三个方向上扩展;但当尺度大到一定规模之后,地形通常退化为相对扁平的2D空间,就像摊平了的地球表面那样,在竖直的Z方向上变化相对不大,而XY平面则是可能无限延伸的。&br&&br&&b&Quadtree&/b& 四叉树很直白,具体的细节我就不讲了。值得一提的是四叉树往往也同时用于场景管理的快速剔除和查找,从理论上来讲,四叉树是一个平面上最迅速的用于剔除空间,定位一个物体,内存开销也是相对较低的数据结构。当用于地形渲染时,顶点剔除的效率也很高,我印象中仅次于高度优化的 ROAM。内存开销低主要是因为四叉树是可以完美展开到一个位数组里的,这样的话意味着整个树的利用率达到了百分之百——所有的空间都用来存储数据而不是维持结构。&br&&br&不过四叉树也不是啥都好,T型裂缝就比 GeoMipMapping 难处理,因为存在跨级的多段 T 缝,如下图:&br&&br&&figure&&img src=&https://pic4.zhimg.com/50/1b93ffaf7dfefee85af1_b.jpg& data-rawwidth=&326& data-rawheight=&311& class=&content_image& width=&326&&&/figure&&br&&br&&br&除此之外还有一些细节问题,这里就不一一说明了,地形的四叉树渲染还是有很多细节需要细心处理的,此处暂且放下不表。&br&&br&----------------------------&br&&br&&b&Chunked LOD&/b& 是一种杂合改良的 LOD,其实糅合了上面说的不少细节,本质上是一种分区块地消减细节的技术。所谓 Chunk 是批量处理的一种方式,只是一种粒度划分的单位而已,跟现在 Java 的 GC 里分区回收概念上差不多。&br&&br&下面是典型的 Chunked LOD 后的效果:&br&&br&&figure&&img src=&https://pic2.zhimg.com/50/f061aa7fd657ea01a4fbb4b5b7579c7a_b.jpg& data-rawwidth=&1015& data-rawheight=&378& class=&origin_image zh-lightbox-thumb& width=&1015& data-original=&https://pic2.zhimg.com/50/f061aa7fd657ea01a4fbb4b5b7579c7a_r.jpg&&&/figure&&br&&br&顶点多次过滤优化后的效果:&br&&br&&figure&&img src=&https://pic4.zhimg.com/50/fcaffd00ee8d67b93aa2701_b.jpg& data-rawwidth=&901& data-rawheight=&439& class=&origin_image zh-lightbox-thumb& width=&901& data-original=&https://pic4.zhimg.com/50/fcaffd00ee8d67b93aa2701_r.jpg&&&/figure&&br&&br&&br&效果在当时还是很惊艳的。通常不到50k的渲染数据量已经能有非常逼真的效果了。&br&&br&----------------------------&br&&br&#### 4.3 以GPU为主的技术(从 Paging,Clipmap 到 GPU Terrain)&br&&br&上面的基本上都是传统方案,这一节我们将逐渐过渡并挨个介绍一下以 GPU 为运算主体的算法。&br&&br&----------------------------&br&&br&所谓&b&分页&/b&(Paging)实际上是仿效虚拟内存的运行机制的一种方法。由于地表的顶点数据都是静态数据,适合常驻显存。当世界尺度较大时,显存没法一次放入所有数据,那么系统就像虚拟内存那样,把那些暂时没有用到的数据交换出去。随着游戏的进行,Paging In/Out 也在不断进行,辅以一定的异步机制,加载到显存的延迟可以被很好地掩盖。玩家的直观感受就是:哇,海量的细节。&br&&br&&figure&&img src=&https://pic4.zhimg.com/50/ea740fdbaed05c5102354_b.jpg& data-rawwidth=&996& data-rawheight=&798& class=&origin_image zh-lightbox-thumb& width=&996& data-original=&https://pic4.zhimg.com/50/ea740fdbaed05c5102354_r.jpg&&&/figure&&br&&br&----------------------------&br&&br&而 &b&Clipmap &/b&则比 Paging 更进一步,以金字塔的形式逐级把数据排列好,直接整体更新和渲染。从这里也可以看出 GPU 时代人们的思维方式的逐步变迁。从以前顶点级别(Vertex Level)的“锱铢必较”,到后来的一次多塞一点也无所谓,只要批次(Batch)少就 OK。下图可以看出 Clipmap 的基本思路。&br&&br&&figure&&img src=&https://pic4.zhimg.com/50/811bdc0e3fb8be4ab928d5_b.jpg& data-rawwidth=&1071& data-rawheight=&467& class=&origin_image zh-lightbox-thumb& width=&1071& data-original=&https://pic4.zhimg.com/50/811bdc0e3fb8be4ab928d5_r.jpg&&&/figure&&br&&br&----------------------------&br&&br&所谓的 &b&GPU Terrain Rendering&/b& 就是把高度图从内存里经由 2D Vertex Texture 搬到 VS 里去生成三角面,这样的好处是 CPU 和内存就被彻底解放出来了。只是访问上有一些限制,不像直接处理内存那样方便。具体的细节可以看这里:[GPU Gems 2: Terrain Rendering Using GPU-Based Geometry Clipmaps](&a href=&//link.zhihu.com/?target=http%3A//http.developer.nvidia.com/GPUGems2/gpugems2_chapter02.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&GPU Gems - Chapter 2. Terrain Rendering Using GPU-Based Geometry Clipmaps&/a&)&br&&br&在 GPU 上做还有个巨大的好处是可以借助 Gaussian Noise 即时生成更多的细节了。直接拿一小块预生成的高斯噪点图在需要的时候叠加一下,就能在没太大额外开销的情况下,增加各种细节。如下图所示:&br&&br&&figure&&img src=&https://pic2.zhimg.com/50/fba8d154a04fe4c1e3a8c24e4d8645fe_b.jpg& data-rawwidth=&418& data-rawheight=&194& class=&content_image& width=&418&&&/figure&&br&&br&----------------------------&br&&br&随着大家对 GPU 理解的深入,地形的处理又有很多的小技巧可以做,尤其是在 PS 里面,比如法线生成,动态uv展开,光照按需叠加/衰减什么的。不过呢据我所知没有什么非常别具一格的架构上的新思路了,所以就不再深入了。&br&&br&### 5. id tech 5 的 megatexture (超大地表上的非重复性海量贴图)&br&&br&&b&megatexture &/b&在当年(2007)是一个非常值得一提的技术。在这个技术出现之前,几乎所有的地表渲染用到的贴图都是若干张 blend 到一起后,以 tiling 的形式重复平铺在地表上的(包括比较典型的魔兽世界也是如此),这样的直接后果是图片的种类用多了耗资源,用少了又很容易感到单调和重复。而 megatexture 则是一张全局的超大贴图,从根本上避免了重复这个问题,理论上(实践上也是)能够生成非常壮丽和独特的地质风貌,是传统的刷地表无法创作出的效果。可以说这个技术让&b&真正的全景地貌&/b&成为可能。&br&&br&----------------------------&br&&br&技术上的细节puzzy老师写过一个 pdf,强烈推荐感兴趣的同学搜来看一下(可以搜“ **ID Tech 5 中&Megatexture&针对地形的D3D9
基本实现原理 - 姚勇**”),珠玉在前,我就不啰嗦了。就来一张效果图吧(好吧我知道能坚持看到这儿的同学,这图基本上肯定都看过了)&br&&br&&figure&&img src=&https://pic3.zhimg.com/50/cbca123634bdd402a1b1f_b.jpg& data-rawwidth=&845& data-rawheight=&474& class=&origin_image zh-lightbox-thumb& width=&845& data-original=&https://pic3.zhimg.com/50/cbca123634bdd402a1b1f_r.jpg&&&/figure&&br&&br&&br&全局超大贴图对一个开放性世界的价值不言而喻。想象一下,跟拿乐高积木拼接出来的视觉效果(传统的 texture blending and tiling)相比,一幅万米画卷上,每个像素都可以随意描绘,是一种什么感受。 比如,你可以相对轻松地实现“整个世界的地貌瞬间被密集核弹蹂躏了一场之后”的效果。如果你想模拟整个生态环境的变迁,在不同粒度上的整体性修改更是无价之宝。&br&&br&----------------------------&br&&br&### 6. 过程式的内容 (Procedural Content Generation)&br&&br&“过程式生成”是一个不是很恰当的翻译,实际上更贴近本意的说法是“以程序的手段生成”,这里我们简洁起见,仍使用过程式生成的字样吧。&br&&br&过程式的内容生成是随机技术的在视觉效果上的一个重要衍生。这个技术虽然到最近才被广泛应用,但实际上从技术角度讲,在很久以前就已经有比较成熟的实现了。我手头的 2003 年出版的翻译版 Game Programming Gems III 中 就有 4.16 和 4.17 连续两篇文章以“程序手段生成的纹理”作为主题。这是构建超大规模的世界的一个重要的技术工具,尤其是与上面的 megatexture 技术结合起来,可以创造出非常令人震撼的视觉复杂度。&br&&br&下面是 sourceforge 上一个开源的项目 [PCity - Procedural Modeling and Rendering of Cities](&a href=&//link.zhihu.com/?target=http%3A//pcity.sourceforge.net/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&pcity.sourceforge.net/&/span&&span class=&invisible&&&/span&&/a&)&br&&br&&figure&&img src=&https://pic3.zhimg.com/50/cbcc074d9af37573efa264_b.jpg& data-rawwidth=&500& data-rawheight=&350& class=&origin_image zh-lightbox-thumb& width=&500& data-original=&https://pic3.zhimg.com/50/cbcc074d9af37573efa264_r.jpg&&&/figure&&br&&br&&br&可以看出,对于过程式生成来讲,只要有非常小的初始数据集(meta-data),可以在宏观上达到很大尺度和复杂度的视觉效果。&br&&br&过程式生成有两大分支,一个是过程式纹理,另一个是过程式建模(上面的 PCity 属于后者),下面我们分别来谈一谈。&br&&br&#### 6.1 过程式纹理(Procedural Texturing)&br&&br&人们发现,自然界中有很多视觉效果是可以用数学公式加上一些简单的随机性来模拟的,比如云彩,水流,火焰,木纹,大理石,草地,夜空,大气等等,程序生成的纹理效果大大丰富了普通纹理能表现的效果,就好像是物理引擎给游戏增加了活力一样。一个普通的噪点图,在不同的情境下,作为辅助参数来参与生成动态纹理,可以产生出近乎无穷无尽的变化。&br&&br&这是过程式生成的云,出处在[这里](&a href=&//link.zhihu.com/?target=http%3A//www.indigorenderer.com/content/cloud-render& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&indigorenderer.com/cont&/span&&span class=&invisible&&ent/cloud-render&/span&&span class=&ellipsis&&&/span&&/a&)。&br&&br&&figure&&img src=&https://pic2.zhimg.com/50/a2d0cb4d450d87e0f78aa5_b.jpg& data-rawwidth=&640& data-rawheight=&470& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&https://pic2.zhimg.com/50/a2d0cb4d450d87e0f78aa5_r.jpg&&&/figure&&br&&br&&br&这是过程式生成的外观,使用了 Allegorithmic 公司的 Substance Designer,出处在[这里](&a href=&//link.zhihu.com/?target=http%3A//blog.mediarain.com/2013/03/procedural-textures-using-allegorithmic-substance-designer/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Procedural Textures Using Allegorithmic Substance Designer&/a&)&br&&br&&figure&&img src=&https://pic1.zhimg.com/50/d97d1b72b376c0f4a7b5_b.jpg& data-rawwidth=&600& data-rawheight=&397& class=&origin_image zh-lightbox-thumb& width=&600& data-original=&https://pic1.zhimg.com/50/d97d1b72b376c0f4a7b5_r.jpg&&&/figure&&br&&br&&br&这里是一些分解材质,相当于过程式纹理的图素,出处在[这里](&a href=&//link.zhihu.com/?target=http%3A//www.3dtotal.com/team/Tutorials/yann_vaugne/alientut_1.asp& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&3DTotal Tutorials&/a&)。&br&&br&&figure&&img src=&https://pic4.zhimg.com/50/3a78e82f759f3fa435cb6d748e1f8c8e_b.jpg& data-rawwidth=&660& data-rawheight=&289& class=&origin_image zh-lightbox-thumb& width=&660& data-original=&https://pic4.zhimg.com/50/3a78e82f759f3fa435cb6d748e1f8c8e_r.jpg&&&/figure&&br&&br&&figure&&img src=&https://pic4.zhimg.com/50/476d36fcd65a624a782c1c_b.jpg& data-rawwidth=&660& data-rawheight=&287& class=&origin_image zh-lightbox-thumb& width=&660& data-original=&https://pic4.zhimg.com/50/476d36fcd65a624a782c1c_r.jpg&&&/figure&&br&&br&&br&#### 6.2 过程式建模(Procedural Modeling)&br&&br&过程式建模特指以程序的手段动态建模。这是一个更大的话题,现在比较成熟的中间件的代表是 Speedtree,比如下面这个效果:&br&&br&&figure&&img src=&https://pic3.zhimg.com/50/4bcaa7624a40_b.jpg& data-rawwidth=&470& data-rawheight=&354& class=&origin_image zh-lightbox-thumb& width=&470& data-original=&https://pic3.zhimg.com/50/4bcaa7624a40_r.jpg&&&/figure&&br&&br&完全不同风格的纹理,模型的任意杂合,随意生成,效果也非常真实,非常适合做恐怖游戏。在 Speedtree 的网站上还可以看到长成茶壶的树之类的奇葩。我还记得有一年的GDC,在 IDV 的 Speedtree 的展台看到的一段华丽视频,就是各种藤蔓植物在几秒钟之内长满了一个峡谷内的整个大坝,电影级的效果非常震撼,不知道现在网上是否还能找到。&br&&br&----------------------------&br&&br&过程式建模是一项非常迷人的技术,我本人也曾被深深吸引,在上面投入过一段时间的精力。2010年时,我在开发一款飞行射击类的 MMO,当时接触到了 [Gamr7](&a href=&//link.zhihu.com/?target=https%3A//www.linkedin.com/company/Ftrk%3Dprof-exp-company-name& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&GAMR7 | LinkedIn&/a&) 的过程式建模技术,感觉很不错,在飞行类游戏中,地面物体的建模可以完全以程序方式生成,这个对当时的我来说吸引力太大了。那时我花了一个月把 Gamr7 的技术集成到自己的框架里,并在上海世博会期间,与 [Bernard Légaut 先生](&a href=&//link.zhihu.com/?target=https%3A//www.linkedin.com/profile/view%3Fid%3D518127& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Sign Up | LinkedIn&/a&) 一起在世博会的法国企业馆展示了合作成果。摘两张当时的 PPT 吧。&br&&br&&figure&&img src=&https://pic3.zhimg.com/50/9a64e3a7f4cf451f65046d6_b.jpg& data-rawwidth=&697& data-rawheight=&311& class=&origin_image zh-lightbox-thumb& width=&697& data-original=&https://pic3.zhimg.com/50/9a64e3a7f4cf451f65046d6_r.jpg&&&/figure&&br&&br&截图中的素材基本上都是使用了过程式自动生成的(不是美术手放上去的),树是用 speedtree 生成的。&br&&br&&figure&&img src=&https://pic4.zhimg.com/50/d703c36c8829bcd54394cceffee951f9_b.jpg& data-rawwidth=&688& data-rawheight=&486& class=&origin_image zh-lightbox-thumb& width=&688& data-original=&https://pic4.zhimg.com/50/d703c36c8829bcd54394cceffee951f9_r.jpg&&&/figure&&br&&br&总得来说,过程式建模是一项&b&潜力远远没有得到释放&/b&的技术,现有的工具还处于比较原始的阶段。在当年 PPT 的技术展望(Beyond the Tech)一节中,我写到“(过程式建模带来的)&b&更高级的抽象使我们可以控制更高的复杂度,从而带来更丰富的细节&/b& (Higher abstraction makes much more details and complexities manageable) ”时至今日,受限于技术的发展,这仍只在某个特定的主题(如 Speedtree 的植被模拟和一般的城市模拟)内有效。对于随机性的粒度,我们仍缺乏有效的手段去控制。当年展望时的两大 Expectation(一个是建立起模式和库抽象从而满足不同层次上的复用需求,另一个是如何统一过程式技术中的无序和有序,有效地控制随机性的粒度),现在据我所知仍是所缺甚多,颇为渺茫。当然了,对有志之士,这也不失为一大探索方向。&br&&br&## 二、内容制作篇:设计和创造(Content Design & Creation)&br&&br&聊完了程序方面的内容,我们来简单讲讲超大规模世界在设计和制作方面的一些情况。这方面因为我不是专家,只是做一下简单的介绍,不足之处,还请专业人士指正。&br&&br&### 1. 随机地图类游戏 (Diablo II) 中地图的拼接&br&&br&在暗黑二,暗黑三和类似的游戏“火炬之光”等游戏中,通过巧妙的拼接,理论上可以通过组合,生成近乎无限大的地图。&br&&br&这是暗黑三第二章里所有地图的可能的部件形状:&br&&br&&figure&&img src=&https://pic3.zhimg.com/50/60bec5a77fca5dc757902ca_b.jpg& data-rawwidth=&500& data-rawheight=&100& class=&origin_image zh-lightbox-thumb& width=&500& data-original=&https://pic3.zhimg.com/50/60bec5a77fca5dc757902ca_r.jpg&&&/figure&&br&&br&这是拼接之后的样子:&br&&br&&figure&&img src=&https://pic2.zhimg.com/50/5fb656b3e25e2e62b36d22fb_b.jpg& data-rawwidth=&500& data-rawheight=&138& class=&origin_image zh-lightbox-thumb& width=&500& data-original=&https://pic2.zhimg.com/50/5fb656b3e25e2e62b36d22fb_r.jpg&&&/figure&&br&&br&除了拓扑结构上可以任意排列组合以外,在每一个分片上预留足够多的通用接口也很重要。比如一扇拱门,可以是闭合不可交互的状态,也可以通向下一个直角走廊,也可以是通往一个副本的入口。&br&&br&&figure&&img src=&https://pic4.zhimg.com/50/11d07faf7de61e5a95efc42f2c0a9cad_b.jpg& data-rawwidth=&377& data-rawheight=&246& class=&content_image& width=&377&&&/figure&&br&&br&要注意标准化的组件如果太多也会让玩家觉得单调和重复感过强,火炬之光在这一点上就做得不错。下图是火炬之光生成好的地图样貌:&br&&br&&figure&&img src=&https://pic1.zhimg.com/50/bedf54acebad_b.jpg& data-rawwidth=&562& data-rawheight=&552& class=&origin_image zh-lightbox-thumb& width=&562& data-original=&https://pic1.zhimg.com/50/bedf54acebad_r.jpg&&&/figure&&br&&br&&br&可以看到效果还是很不错的,一眼看过去已经不太有重复感了。&br&&br&### 2. 无缝大世界 (World of Warcraft) 中区域地图的拼接&br&&br&无缝世界类游戏的区域拼接和上面的随机生成类游戏的区域拼接是很不一样的。&br&&br&&figure&&img src=&https://pic1.zhimg.com/50/ce2cd240a21f544ce1e575e8f3113d4e_b.jpg& data-rawwidth=&647& data-rawheight=&473& class=&origin_image zh-lightbox-thumb& width=&647& data-original=&https://pic1.zhimg.com/50/ce2cd240a21f544ce1e575e8f3113d4e_r.jpg&&&/figure&&br&&br&可以看出,不同的区域之间有着很长的接壤线和完全不规则的边缘。在这种情况下,为了简化制作,大部分边界区域以高山作为阻隔。你几乎不怎么会看到有建筑横跨两个不同的区域,原因也是在此。&br&&br&在沙盘制作时,通常的做法是在整个世界地图(对应的世界编辑器)中规划好每个区域的范围,也就是分区分块。每个区域由不同的设计师在场景编辑器中分开制作。在制作当前场景时,与该场景接壤的几个场景的最新版本都会加载上来,编辑器中可以提供一些方便的工具,便于在接壤处对齐。主要是高度的对齐和贴图的融合。前者通常的选择是高度上用 Smooth 工具平滑过渡到邻接场景,后者通常最简单的处理方法是真正的过渡点两边使用同一种贴图即可,实际的美术风格过渡(如果需要的话)在邻接地图的接壤线附近完成。&br&&br&一些贯穿不同地图的元素(如河流等)可能需要世界编辑器的参与来指定水平面的高度和区域范围之类的参数,但这一类元素通常不会太多,因为它们没有明显的 Gameplay 贡献,反而加剧了不同场景之间的耦合。&br&&br&如果游戏有动态的天气/环境氛围系统,那么不同场景之间需要做一些平滑的过渡,这些程序用普通的插值实现就可以了,设计师一般只用关心当前场景内的表现即可。当然有的游戏这个过渡做的不好,玩家体验非常生硬,也是有的。&br&&br&&figure&&img src=&https://pic3.zhimg.com/50/dd626dd98dc8a4e748f3407_b.jpg& data-rawwidth=&478& data-rawheight=&348& class=&origin_image zh-lightbox-thumb& width=&478& data-original=&https://pic3.zhimg.com/50/dd626dd98dc8a4e748f3407_r.jpg&&&/figure&&br&&br&总得来说,这一类无缝大地图的复杂度主要是在编辑器的协同方面(后面我们会再提到),实际的创作复杂度较前面的随机地图生成为低。&br&&br&----------------------------&br&&br&### 3. 卫星地质数据的导入,规整化和再加工(一些飞行模拟类游戏)&br&&br&超大规模的开放性世界地图,还有一类是直接使用卫星地质数据以加强整个世界真实性的。据我所知,育碧出品的 Tom Clancy's H.A.W.X. I & II (就是国内翻译的 鹰击长空 I & II)就是使用了 GeoEye 的商业级高分辨率卫星地图。&br&&br&既然用了真实的卫星地质数据,这一类游戏同样能生成非常震撼的效果,也就不用多说了。找两张截图大家感受一下吧:&br&&br&&figure&&img src=&https://pic1.zhimg.com/50/ec729b132d78e7ce40f14fe1efb1d8df_b.jpg& data-rawwidth=&844& data-rawheight=&472& class=&origin_image zh-lightbox-thumb& width=&844& data-original=&https://pic1.zhimg.com/50/ec729b132d78e7ce40f14fe1efb1d8df_r.jpg&&&/figure&&br&&br&这一类的缺点是不能模拟真实世界中没有的环境(当然拿去再创作的不算)。&br&&br&&figure&&img src=&https://pic4.zhimg.com/50/fd28ccd7e9a4aee822e79abe214ff119_b.jpg& data-rawwidth=&840& data-rawheight=&525& class=&origin_image zh-lightbox-thumb& width=&840& data-original=&https://pic4.zhimg.com/50/fd28ccd7e9a4aee822e79abe214ff119_r.jpg&&&/figure&&br&&br&这种真实数据的数据源就没什么好说的了,我简单说一下导入后的处理。通常导入后的贴图需要美术在色彩和明暗上二次加工一下,得到和游戏匹配的整体氛围。需要提供比较精确的工具给美术进行高度图和高分辨率纹理的拟合。此外通常这一类地质数据是没有 NormalMap 的,需要提供工具生成一下。&br&&br&还有就是,河流和湖泊这一类水体的处理,3D游戏通常在渲染效果方面对水面特效照顾得比较多。如何生成跟真实环境相匹配的河流和湖泊是一大难点。因为一般游戏里是有一个绝对水平的特效面片的,而如果给真实环境中得来的高度数据上配一个这种特效面片,通常无法跟真实的贴图相吻合(尤其是在山脉和峡谷等地形中的水体)如何提取真实的高分辨率贴图中的水面信息,自动生成对应的3D水面,也是一大话题。当然,如果不怕费事,也可以由美术直接做出来了事。&br&&br&----------------------------&br&&br&### 4. 超大地图的协同编辑:并行操作,数据同步,手动和自动锁的运用&br&&br&现在咱们回过头来聊一聊在 wow 这一类超大地图里,如何在多人团队内协同编辑的问题。&br&&br&----------------------------&br&&br&对于美术(这里专指负责场景的设计师)来说,常见的最简单做法是每人一块(或多块)区域地图,团队内维护一个公共的物件和贴图库。(物件和贴图可以由专门同事制作,需要时也可外包)在这种情况下,美术的并行化程度很大程度上取决于团队自身能力,对场景编辑器没有特殊的技术上的需求。&br&&br&超大地图的场景编辑器在加载周边邻接的区域地图时,需要显式地标示出其版本和上次修改日期,这样可以把邻接区域的修正工作量降到最低。最好的做法是能够通过版本管理软件,在有同事修改了邻接区域以后自动更新并重新加载(当然可以稍有延时,不用那么即时),这样的并行工作效率可以达到最高。&br&&br&真正的难题通常发生在策划那边,当需要编辑跨区任务或事件时,如果对 Ownership (也就是场景实体的所有权问题)管理不善。跨区系统可能会产生各种层出不穷的 bug。比如同一个 npc 承担了多个跨区职责时,其中的状态就可能会互相干扰,在杀掉某个 npc 这一类任务中更易出现,造成难以重现的 bug。这就需要提供明确的所有权管理机制,明确跨区访问的一般规则,提供简单的全局状态检测工具,在设计时就能提示出绝大多数潜在的冲突。当然,这些的先决条件是所有的区域数据,要么提供中央数据库管理,要么工具做到在团队网络内实时同步。&br&&br&----------------------------&br&&br&最后我们来说一下真正有趣的实践,就是&b&“真正的”协同编辑&/b&。也就是任意个美术和任意个策划可以工作在任意个区域里。是的,你没看错,这才是终极的开发自由度。其实如果这是一个如典型的 WOW 那样的 MMORPG 的话,这就跟“所有的玩家登录到同一个服务器一起游戏”是同一个概念了。所不同的是,这里的“玩家”实际上全部是开发团队的成员,而且他们是有能力创造和修改这个游戏世界的。&br&&br&只要想通了这个概念,实践上并不像想象中那么复杂。由于美术和策划对同一个地图关注的焦点不同,我们只要把他们工作有交集的部分处理好,他们就能一起愉快地玩耍了。实践上来看,两者的交集通常是 a. 整个区域的逻辑高度图和 b. 所有的相对碰撞关系。也就是说,美术和策划的工作内容里,只要不涉及到这两者,都可以随便搞,但如果影响到了这两者,编辑器需要有能力提示正在修改的人会影响到什么(或按默认行为自动处理),通常是不难做到的。举个例子,策划放好 npc 后,美术去调整高度,把 npc 站的广场弄成一个山坡,那么要么提示美术这么干可能会影响到策划的设计,要么自动把对应的 npc 都重新调整位置,吸附在新的地表高度(一般编辑器允许设置为吸附到地表)。&br&&br&当两个美术在修改同一区域时,就涉及到锁的问题了。锁有两种,一种是在编辑时自动触发,场景地表以区域为单位,物件以 Instance 为单位,当编辑时自动把 Owner 设为当前编辑者,提交改动到服务器时可以选择继续锁或是释放锁。一种是手动锁,就是美术框住一片区域,主动加锁,这样有些时候更方便。编辑器制作者需要考虑的一些细节有:锁住的区域在其他开发者的机器上,需要比较显眼的提示信息;保险起见总是多锁一定的范围,以方便地表平滑等工具编辑时对周边区域的影响,等等。&br&&br&----------------------------&br&&br&## 三、异次元篇:我们的征途是星辰大海&br&&br&上面两部分“程序技术篇”和“内容制作篇”已经把大规模开放世界讲得差不多了,下面的内容我取名叫“异次元篇”,也是随便侃侃,大家随便看看就好。&br&&br&### 1. 终极沙盒(EVE):当规模大到一定程度——宇宙级别的混沌理论与蝴蝶效应&br&&br&对于开放式世界来讲,如果没有真正与这个世界的尺度相配的开放式的交互,那么仍然是一个死气沉沉的世界。EVE,正是一个为了开放式交互而打造的超大的沙盒宇宙。&br&&br&&figure&&img src=&https://pic3.zhimg.com/50/388eefd9e72efe_b.jpg& data-rawwidth=&550& data-rawheight=&322& class=&origin_image zh-lightbox-thumb& width=&550& data-original=&https://pic3.zhimg.com/50/388eefd9e72efe_r.jpg&&&/figure&&br&&br&在这个宇宙中,玩家拥有很高的自由度去探索,创造,建设,摧毁(针对自然环境而言),配合,领导,同盟,背叛(针对社会环境而言)。这游戏我就不展开介绍了,有兴趣的同学可以去看一下 [EVEWiki](&a href=&//link.zhihu.com/?target=http%3A//evewiki.tiancity.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&EVEWiki&/a&)。有趣的是,当沙盒大到一定程度时,它会在很多方面展现出一种自平衡的性质,就像经济学中那只“看不见的手”,自然生态学中地球这个大型生态系统的自我调节和自我修复。在我看来,这也是开放式游戏的最大的魅力之一,也让系统的复杂度进一步接近真实世界。&br&&br&&br&### 2. 打通两个宇宙(EVE & Dust):发现更广阔的世界——宇宙沙盒游戏和行星射击游戏联动&br&&br&跟上面列举的诸多成功游戏范例不同的是,我接下来要说的,是一个虽然雄心勃勃,但却没有成功的例子。&br&&br&EVE 的制作商 CCP,是一个来自冰岛的很有趣也很有追求的工作室。在 EVE 的大尺度宇宙成功地运行了若干年后,他们选择了一个更大的挑战——设计另外一个大型多人在线游戏,把新老两个宇宙之间联系起来,让两个游戏内的玩家可以互动,相互交谈,配合,雇佣,指派任务,火力支援或其他的互动,最终打通两个宇宙,让两个大型多人在线游戏之间达到有机的协同和交互。&br&&br&&figure&&img src=&https://pic3.zhimg.com/50/1bea998ba34d78b5a3fb1_b.jpg& data-rawwidth=&640& data-rawheight=&360& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&https://pic3.zhimg.com/50/1bea998ba34d78b5a3fb1_r.jpg&&&/figure&&br&&br&CCP 从一开始就没有掩饰这个雄心勃勃的计划,这是一个令骨灰级玩家们震惊和眩晕的设计,也是一个电子游戏行业从未有过先例的构想。&br&&br&这个构想是如此令人敬畏和富有吸引力,以至于我在拿到 offer 后毫不犹豫地投身 CCP Shanghai 的怀抱。在游戏行业,我感到很幸运,能够有机会参与到这样一个项目中来。然而由于一些大大小小的原因,这个项目最终虽在 PS3 平台上线,却没有取得预期的成功。这里既然与主题无关,我就不打算谈论更多的细节了。&br&&br&在 CCP 两年间,我只是一个很普通的工程师,这里的工作经历极大地拓宽了我的眼界,让我知道了什么是真正的 fearless,对先行者们,我始终满怀敬意,对于自己有机会能参与这样的一个项目,我也始终心怀感激。&br&&br&----------------------------&br&&br&谢谢你们,让我能在晚上凝视夜空的时候,脑海中浮现出更广阔的世界。&br&&br&----------------------------&br&&br&(全文完)&br&Gu Lu&br&[]&br&&br&----------------------------&br&&br&[] 补记:一开始看这个话题有趣,想着说两句。没想到一动笔就停不下来,一口气写了七八个小时我也是蛮拼的。其间或有错漏疏敝之处,让行家笑话了。如发现错误,请不吝指正,在此先行谢过。如引发了有趣的想法,也欢迎在评论中一起讨论。&br&&br&[] 补记:今天中午有半个多小时 Blog 无法访问,后来联系 FarBox 才晓得是流量已经超上限,因为我用的是基础版,每个月100MB流量,可以用5年。结果今天一天的流量就把5年的配额全用完了……刚回到家以后亡羊补牢了一下,把 png 都换成了 jpg,省一点是一点吧 :) FarBox 反应很迅速,赞一下 :)&br&&br&另:文章无版权,可随意转载;是否注明出处,亦无要求。&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&
---------------------------- 本文同时发在我的 Blog,在那里或可获得更好的阅读体验:
---------------------------- 首先肯定一下,这是一个非常有趣的问题。在这个答案里,我将尝试先回答主干问题,…
&blockquote&&i&前端变化太快,以下内容我会不定期更新,第三方网站请不要转载,如果实在想转载,请只转载摘要,并保留原文链接,谢谢。最后更新时间:日晚&/i&&/blockquote&&p&&br&&/p&&p&网站开发开发大致分为前端和后端,前端主要负责实现视觉和交互效果,以及与服务器通信,完成业务逻辑。其核心价值在于对用户体验的追求。可以按如下思路学习系统学习:&/p&&p&&br&&/p&&h2&&b&基础&/b&&/h2&&p&一、html + css 这部分建议在 &a href=&//link.zhihu.com/?target=http%3A//www.w3school.com.cn/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&w3school 在线教程&/a& 上学习,边学边练,每章后还有小测试。 之后可以模仿一些网站做些页面。&br&二、javascript 要学的内容实在

我要回帖

更多关于 行政审批消减 的文章

 

随机推荐