posts - 745,  comments - 22,  trackbacks - 0
  2012年2月29日
基于苹果iOS和谷歌Andoid开放平台,《愤怒的小鸟》一举成名;同样借力开放平台,Facebook用了不到五年便成为一家世界级的公司。

 

  触手可及的成功让国内的互联网公司心动不已,纷纷出手抢蛋糕。在争夺开发者的队伍中,又新增加了网易。日前,网易对外界宣布正式推出开放式游戏开发平台“iTown”,除了提供100万元的奖金外,还规定,参与的第三方游戏只要达到上线标准便可获奖,并同时获得运营利润2:8分成(网易:游戏开发者)以及在线人数奖金奖励等。

  早在2011年,国内多家互联网公司均推出了平台战略:腾讯“全平台开放”、百度推“移动框计算服务”、淘宝网将2011年定为开放年、360发布“360°开放计划”、盛大推出麻球计划……

  热衷于开放平台的互联网大佬受到了用户多元化、个性化需求日益增长与互联网公司资源相对有限之间的矛盾所驱动。如何在一个简单、便捷的平台上很大程度满足用户的个性化需求,已成为中国互联网公司魂牵梦绕的目标。

  避免重复的底层开发

  网易游戏平台iTown最早公布于2009年中国国际数码互动娱乐产品及技术应用展览会(ChinaJoy)期间。当时,网易旗下的登山工作室开发了一个以100年后梦想生活为背景的大型3D休闲MMORPG网游,其中内置多款游戏,以客户端的形式提供给玩家。

  获得用户的不错评价后,iTown便以一个开放平台的姿态对外公布。与腾讯、盛大、百度提供的导入用户的平台策略不同,网易游戏平台主要是向游戏开发者提供了一个名为“iTownSDK”工具包,它能支持flash UI界面进行开发,支持2D和3D两种视角以及任意类型的游戏开发。为更好地吸引第三方开发者,它还提供全套的游戏解决方案和工具,供第三方团队免费使用。

  在iTownSDK中,网易除了预设游戏基础架构,提供各种游戏配套功能,第三方只需专注游戏核心玩法的设计与开发外,还向第三方开放各类美术、音乐资源,供第三方免费使用,以降低第三方的开发成本。目前,开放美术资源文件近10000个,音乐音效文件近1000个。

  网易副总裁丁迎峰解释:“这个工具对开发者免费,主要是想帮助那些中小游戏开发团队和游戏开发的初学者,避免重复的底层程序开发。”负责iTownSDK项目的登山工作室总监岑晋宇称,“这个工具包此前应用于网易旗下的多款游戏中,包括《梦幻西游》等。”
为获得开发者的支持和认可,网易还为签约开发团队部署了专门的技术人员,对他们进行一对一支持,解答开发者在开发过程中遇到的疑难问题,以使开发团队顺利、快速地实现游戏开发。

  “以前我们为其他游戏平台做开发时,既要设计聊天室、又要构架很多基础功能,占据了大量的时间和精力。为降低开发成本,让游戏尽快上线,只能缩减游戏玩法方面的内容。” Guudo game游戏CEO沈伟华告诉本刊记者,“现在为iTown做开发,只需要做好一件事情---设计一个有创意的玩法。”

  决战平台的背后

  “大家对开放平台一哄而上,有点怪怪的。”网易CEO丁磊告诉记者,他曾对开放平台领域做过研究,发现平台上产生收入的来源,大多来自不到10%的作品。

  究其原因,在于目前各公司打造的平台战略很多缺乏诚意,也不是真正意义上的开放。对此,互联网评论人士谢文曾透露,国内目前充斥着“庸俗开放论”:只要你有很多用户,不管过去是干什么的,做点开放接口,让第三方应用进来挣到钱,就算开放了,自己隐隐约约地也算中国的Facebook或者苹果了。这种开放的确比封闭进步,但服务与商业模式并无本质变化。

  这种打着开放之名行垄断之实的平台,让丁磊冒出一个想法——给开发者做一个真正的开放平台,不但可以为第三方开发者提供创业成功机会的平台,还能为中国互联网传续创新的火种。

  然而,做开放平台需要平台的搭建者是否真心愿意将自己成熟的技术转移出去,与第三方开发者分享。此外,还需要对开发者尽心帮扶,这并不是一个简单的任务。

  《IT时代周刊》在采访中了解到,作为初次创业的第三方游戏开发者,启动阶段的资金往往是遇到的第一个障碍。创业需要勇气,创业者走上这条路,不仅意味着失去了原来稳定的工作,还要承担整个创业团队的运营成本。诸多创业者在起步之初拥有万丈雄心,但最后均倒在这条路上。

  为留住开发者,网易特意启动了 “0成本”计划,解决开发者起步阶段的资金问题。具体措施是对在iTown上签订开发协议的第三方公司,网易以游戏购买的形式与其合作,向第三方进行游戏定向委托开发。协议达成后,网易根据双方协议,分期向第三方支付开发费用。最后,只要开发团队按照协议约定如期完成开发工作,就不需偿还。

  提高分成比例一方面是因为竞争加剧,另一方面是开发者难以获利。“虽然各大互联网厂商都在做开放平台,但能够通过此平台获利的开发者非常少,如何让他们挣到钱是当务之急。”业内分析师认为,“目前大多数的互联网厂商还处于一个比较低的层次,在维系第三方合作方,帮助第三方开发者赢利方面还较弱。而在那些拥有巨大用户规模公司搭建的平台上,开发者带来的大部分利润并不能收为己有,而是被平台搭建者拿走。”

  据悉,网易的利润分成在国内众多的开放平台中是最高的。

  营造公平的生存空间

  一个好的平台是什么样的?

  一个最佳的例子是Facebook。据了解,为了尊重开发者,Facebook严格执行平台和开发应用分离。比如Facebook专心负责平台建设,寄生于Facebook平台之上的Zynga则是负责游戏开发,形成一个良性循环的生态链。在这种模式下,它促使Zynga成为营收达到8.5亿美元的又一炙手可热的社交网络公司。

  而在国内却没有这样公平的生存空间。一旦有好的游戏出现,处于产业链上游的企业便会直接进入,将那些还没成长起来的小公司扼杀在摇篮中。网易是否也会走上这样的征途?对于开发者 “网易作为游戏规则的制定者将随意修改规则”的担心,丁迎峰说,“网易将以中立的身份,不会抢夺开发者的利益,更不会copy创意和游戏,网易会负责未来游戏上线后的运营推广工作,以聚拢玩家进入。”

  在丁磊看来,互联网早期的创新精神是很强的,但现在做互联网的大部分人都没有创新的意识,而是用做生意的意识来经营互联网。目前,创业者的普遍想法是,用复制模式和创意来获得现实的回报。丁磊说, iTown开放平台是在寻回真正有创意的年轻人。这或许就是他在寻找年轻时的自己。

  目前,虽说网易iTown尚在产品准备期,已聚集了近5000名开发者,在开发的作品也有200多款。

责编:李琦E-mail: liqi@itime.com.cn  美编:陈汉燕 校对:媚子


资讯仅供参考,不代表本站(GameRes.com)观点,此信息由sea_bug提交。 

发布日期:2012-2-28 13:11:00
posted @ 2012-02-29 13:10 oayx 阅读(71) 评论(0) 编辑

导读:最近,在国外知名问答网站Quora上有个讨论,原意是:“Facebook是如何做自动化测试的,他们是怎样测试才能保证每周的升级都可以不出差错的呢?” 引发了开发者们的激烈讨论。

来自Facebook的Steven Grimm很好地回答了这个问题,觉得还不错,这里以第一人称翻译了一下。

  • 对于PHP的代码,我们写了非常多的基于PHPUnit测试框架的测试类,这些测试类覆盖范围比较大,从简单的判读真假的单元测试到大规模的后端服务的集成测试。开发人员把运行这些基于PHPUnit的测试用例作为他们工作中的一部分,同时这些用例也在一些专用的设备上不停地被运行(注:持续集成模式)。当开发人员对一些代码做了比较大的修改时,在开发机器上的自动化工具会运行这些测试用例的同时也会生成相应的代码覆盖率数据,对于需要提交到代码库的diff,在做代码review的时候回自动地产生一份带有覆盖率的测试报告。
  • 对于前端的代码,我们使用Waitir(注:Waitir是前端UI的自动化测试框架)做了基于浏览器的界面自动化测试。这些测试用例涵盖了网站页面的功能,特别是针对隐私方面,比如:“用户X发布了Y,而Y应该/不应该被用户Z看到”,有着大量的基于浏览器级别的这种用例。(这些隐私规则当然也会使用一些更低级别的方法被测试到,但是这些规则的实现是必须要严格执行的,并有着非常高的优先级,因此这部分必须要有足够的测试用例来覆盖)
  • 除了一些使用watir的全自动化用例以外,我们也有一些半自动化的测试。这些测试也使用了waitir技术,这样可以使一些表格填充或者点击button来完成整改界面上的流程的测试不太单调乏味,而且我们可以很清楚地检查和验证当前的步骤或流程是否正确合理。
  • 我们也在尝试开始使用JSSpec (注:JavaScript单元测试框架)去做一些JavaScript代码的单元测试,但当前也是刚刚开始做。
  • 对于后端服务的测试,根据不同的服务特性我们采用了许多不同的测试框架与方法。对于一些需要开源发布的项目,我们会使用开源的测试框架,像Boost和JUnit测试框架(注:Boost是针对C++/JUnit是针对Java的测试框架);对于另外一些项目,可能永远都不会发布到外界,我们就是使用内部开发的可以很紧密地与我们build系统集成在一起的C++测试框架。还有少数项目会使用项目级别的测试工具。多数后端服务的测试都会紧紧地和持续集成/Build系统结合在一起,这些持续集成的build系统会不停地针对源代码自动地运行测试用例并生成测试结果,测试结果在存储在数据库的同时会发送到通知系统中去。
  • HipHop(注:HipHop for PHP是Facebook的PHP项目)有一套类似的持续集成系统,HipHop的单元测试和所有基于PHPUnit的测试都会被运行。所有的这些测试结果会和基于普通的PHP解释器的结果做对比,从而可以看到不同PHP上的行为的不同;

Facebook的测试工具将测试结果存储在数据库的同时会发送一份通知邮件,这个邮件会包含执行失败的信息并且邮件的接收范围是开发同学可以自己调整的。(例如,你可以选择只有在测试连续失败一段时候的时候才接收到通知邮件,或者当一个用力失败的时候立刻收到通知)。在浏览器UI上,测试结果和 缺陷/开发任务跟踪系统会结合在一起,可以很容易的将测试失败与开发任务关联起来。

测试中一个非常重要的现象是“导致阻塞”,也就是一个测试用例失败有可能会阻止发布(在Facebook,有发布工程师会来评估是否可以将带有问题的代码发布到生产环境,发布工程师在必要的情况下会得到授权去阻止产品的发布)。阻止产品发布上线的事情是被认为是非常严重的问题,因为在Facebook大家对于这种快速发布的模式是深深引以为豪的。

我所在的团队是测试工程部门,主要职责是打造通用基础工具,这些工具会被上述的所有人用到,同时我们也在维护测试框架,像PHPUnit和Watir。Facebook没有专职的测试团队,所有的工程师都需要为他们的代码写自动化测试用例,并维护这些测试用例,保证产品代码改变的同时这些测试代码可以正确地运行。

Facebook的测试还处于一个初期起步尝试阶段,上面的介绍都只是我们在当前运行的方法而已。

posted @ 2012-02-29 13:09 oayx 阅读(64) 评论(0) 编辑
  2012年2月7日

发现这个阴影技术几乎没有中文版的详细讲解,姑且完整翻译一遍论文。

 

 

Variance Shadow Maps

WilliamDonnelly   Andrew Lauritzen

Waterloo大学,计算机科学,图形实验室

Winger_w

水平有限,错误指出欢迎指出

QQ:379404629

Figure1:各向异性过滤对比。上:普通shadow map,利用PCF。下:Varianceshadow map利用mipmapping16x的各项异性过滤。

摘要

在实时渲染中,Shadowmaps是一种被广泛采用的阴影技术。此技术的一个主要缺点是,像普通纹理那样采样,会产生严重的锯齿。本文介绍一种新的实时渲染阴影算法——variance shadow maps。不同于传统的shadow map保存一个深度值,我们将保存深度和深度的平方,利用他们可以计算纹理采样区域的方差。利用方差,我们可以计算出一个像素被遮挡的概率上限。我们会看到,这个概率值,非常接近现实的软阴影,并且可以用于实时渲染。我们的算法很容易在GPU上运行,只需额外的存储一点点数据。

引言

Shadow maps [Williams 1987]和阴影体(shadow volumes)[Crow 1977]是两个常见的阴影渲染算法。Shadow maps相对于阴影体有很多优点;例如,他更容易的被执行,对模型复杂度不太敏感,并且没有特殊的几何空间要求。

  不幸的是,就像大多数纹理一样,shadow maps如果过滤不当,会产生显眼的锯齿。现代显卡支持一些过滤方式来减少普通纹理产生的锯齿,他们是:mip mapping和各项异性过滤。这些技术不适用于标准的shadow maps,因为他只会简单的将shadow map中的深度值与周围几个点做线性插值。典型的实时渲染做法是,取当前相邻几个点的深度值,依次比较,将结果取平均值。这种做法的代价是昂贵的,因为显卡没有对此做优化。

  为了有效解决shadow maps的过滤问题,我们注意到标准的shadow map只保存了单独一个点的深度信息。方差shadow maps的每个像素将保存区域深度信息。为了用尽量少的数据来描述这个信息,我们存储两个数据:深度和深度的平方。这样做的主要优点是我们可以用它来近似描述一个区域深度信息。(这句话,有太好翻译,原文如下:One major advantage of this representation is that we canapproximate the average of two distributions by averaging the moments.

  在采样方差shadow map时,我们用这两个数据来计算当前像素所在区域的一个散列值界限。我们会看到,这个界限值会很好的模拟出每个光源投射到任意表面的软阴影。

  因为这两个数据能被插值,我们可以像普通纹理采样那样,基于硬件的支持做一个大范围的过滤来减少锯齿。

相关研究

Williams 介绍了shadow maps这样一个有效的阴影算法。然而,他指出普通的颜色纹理过滤技术不适用于shadow maps

 PCF(Percentage closer filtering)[Reeves et al.1987]提供了一个解决方案。他的实质是将深度信息做多次比较。这需要多次纹理采样才能消除锯齿。

 Deep shadow maps[Lokovic and Veach 2000]保存区域的多个深度值来替代单一点的深度信息。Deep shadow maps很难在显卡上高效运行,有两个原因:每个像素shade需要大量深度数据,同时,求平均值也会消耗额外的时间。

 Opacity shadow maps [Kim and Neumann 2001] 也类似Deep shadow maps存储区域深度信息,不过他通过存储固定数量的信息来实现。这个算法有相对较高的效率。(没研究过这个算法,原文讲的也含糊不清,列出:Opacity shadow maps [Kim and Neumann 2001] encode a

distribution of depths, but use a fixedamount of storage per pixel. Each pixel stores a function just as in deepshadow maps, but instead the function is constructed from its values at a fixedset of points. Thus the algorithm can take advantage of the speed of graphicshardware. The price to pay for this flexibility is extreme quantization ofdepths, so the technique is mostly suitable for rendering of dense volumetric objectssuch as hair and fur.)

  另一种解决shadow map锯齿的方法是改变投影矩阵。他们是adaptive shadow maps[Fernando et al.2001], Perspective shadow maps [Stamminger and Drettakis 2002],Light space perspective shadow maps [Wimmer et al.2004], trapezoidal shadowmaps [Martin and Tan 2004].这些算法与上述算法是互补的,因为他们并没有对投影矩阵做任何要求。

  一些显卡支持shadow maps,比如OpenGL”GL_ARB_Shadow”。但是这个特性并不能做插值或者mipmapping。一些NVIDIA 显卡处理器支持双线性过滤[Everitt et al.2000],但是据我所知,没有显卡支持三线性或者各向异性过滤用在shadowmaps上。

算法概述

在传统的shadowmapping中,我们先在光源处渲染场景,保存距离光源的深度;在variance shadow maps中,我们渲染一个有两个通道的缓冲区,保存深度和深度的平方。虽然常规的shadow map不会利用任何纹理过滤方式来采样深度值,但是在variance shadow map中,我们将得益于此。

  曾经我们对shadow map做了一些过滤处理。包括生成mipmaps [Willliams1983] 或者计算累加区域内的数据(summedarea tables)[Crow 1984]。现在,我们的variance shadow maps同样可以通过模糊处理来柔化阴影。

  我们保存深度和深度的平方到纹理中,这两个信息在采样时就会被过滤。(注:过滤实际上就是一种求平均值)我们将这两个通道的值定义为M1 M2,如下所示:

通过他们我们可以计算出方差:

  方差可以理解为一个描述区域信息的值。我们可以利用方差来计算一个大于某一变量的概率界限。Chebyshev公式做了具体描述。

x为一个在过滤区域中变化的随机深度值,再设t > μ

  上述公式中的P,描述了区域内大于某个值的概率,具体的,如果这个t就是我们需要比较的当前深度值,那么,P就可以理解为处于阴影中的概率。

  虽然,公式5只给出了一个上限,但是,他可以很好的近似描述出软阴影效果。

3.1 平面阴影遮挡

考虑这样的情况,一个平面遮挡物,深度为d1,他投射阴影到另一个平面,此平面的深度为d2(注解:平面深度固定就表面他们是平行的,且垂直于光源视线,他们两个平面深度的插值可认为是mipmap)。假设没有被遮挡时,d1,d2有混合参数pmipmap混合),然后我们可以得到:

通过公式5,我们可以计算出:

  我们可以看到,在这种简单情况下,Chebyshev不等式给出的值就等于我们的过滤参数。

  虽然这是一种很特殊的情况,但是他提供了一个近似值,适用于大多数场景。在一个只有单独阴影遮挡物和接受物的场景中,我们只需少量采样投射物或者接受物的深度,因为他们的误差非常小。这种情况下,公式5并没有提供一个精确值,但是误差已经足够小了。这样,我们可以认为pmax是一个理想的近似值。

具体实现

我们在Geforce6800GT上实现VSM

 Geforce6系列显卡支持16位浮点纹理,我们利用硬件支持的mipmapping和各项异性过滤来实现vsm。我们的实现步骤大致如下:

1.  以光源为视点,渲染一个16位浮点纹理,他保存深度和深度的平方。

2.  如果喜欢的话,我们可以用第二个pass将纹理进行高斯模糊。

3.  OpenGL会自动生成Mipmaps

4.  正常渲染场景。我们读取shadow map中的M1(深度),M2(深度平方)。如果depth< μ(平均深度,即M1),则此像素不在阴影中。否则,我们利用M1M2计算方差,利用公式5pmax来调适光照。

我们还利用32位浮点纹理来保存shadow map。因为我们的硬件还不支持在这个精度上进行过滤,所以,我们在像素shader里进行双线性差值。理论上,我们还可以在shader中进行mipmapping和各项异性过滤;然而,他运行的非常缓慢。

  我们也可以按照以下方法执行一些比较来过滤shadow map。他们基于一张没进过过滤的16位浮点纹理。

1.  简单的利用周围相邻点做深度比较。

2.  取四个相邻点做比较,并进行双线性插值。

3.  将四个相邻点的比较值,用高斯模糊化。

4.  取四点比较,每个点进行双线性插值,然后进行高斯模糊。

结论

Figure2 展示了利用mipmapping时的结果。就像普通纹理那样,mipmapping有效的减少了阴影锯齿。各项异性过滤也可用于vsm,当视角很平时,也能够有效消除锯齿(如figure 1)。

Figure2:无Mipmapping(左) Mipmapping(右)

Figure3:从左到右:1)标准shadowmapping25x5 PCF35x5双线性过滤PCF4VSM利用5x5高斯模糊

Figure4当过滤区域的方差很大时,光照渗透现象将会出现。车的圆形区域(此图实在太模糊,看不清~~~)应该是一个彻底(Solid)的黑影。注意到这来的深度差异很大,所以光照渗透现象很容易看出来

 

 Figure3 展示了利用各种过滤方式的vsm效果对比。可以看出vsm的效果要好很多。

5.1 光照渗透问题(Light Bleeding

我们的pmax在大多数情况下是一个小范围变化的变量。但是他毕竟不是一个精确值。从公式5我们可以看出,方差肯定大于0,无论d为什么值,pmax(d)始终大于0。当方差很小时,pmax将会很快的向0逼近,所以渗透现象不那么显眼。然而,当方差很大时,就像Figure4那样,会很明显的渗透现象。(应该被遮挡显示为阴影的地方,出现了光照)

  实际上,这个问题只会发生在深度变化很大的场景中。除此之外,vsm工作良好。

 

5.2 性能

我们选择了一个单聚光灯场景用作各种shadow map效率的对比,如Figure1所示。因为所有操作都在图片空间中,所有效率与场景的几何复杂度无关。

  VSM我们采用了mipmapping3线性过滤,和16x的各项异性过滤。其他算法的过滤方式不被硬件支持,我们在shader中实现。

  我们在GeForce6800GT上,用一秒渲染的帧数来衡量性能。先看看用不同shadow map支持,渲染到1024x768的颜色缓冲区的效率对比:

再看看都采样512x512shadow map,但是不同的目标缓冲区分辨率的对比:

  我们注意到PCFshadow map的尺寸并不敏感,但是屏幕分辨率对他的影响较大。相比较的,VSM对屏幕分辨的影响和普通shadow map差不多。但是如果用一些预过滤操作,比如VSM3x3的话,屏幕分辨率对vsm的影响还是很大的。

5.3 数字稳定性(Numerical Stability

从计算方差的公式4我们可以看出一些用浮点数运算的隐患。当方差与平均深度相差很小时,容易丢失精度。在实验过程中,我们发现这种错误有时会发生在16位的浮点shadow map上,但从来没出现在32位纹理上。我们希望未来的硬件能够支持32位浮点纹理的mipmapping 已经各项异性过滤。

结论

我们已经介绍完了方差shadowmap,他是一个简单而有效的减少阴影锯齿方案。我们的计算结果基于一个区域内概率上限,他可以很好的模拟出真实的软阴影。最后,我们看到vsm非常适合于现代图形显卡,并比较了他与其他阴影技术之间的性能以及质量差异。

感谢

感谢MichaelMcCool  StefanusDuToit提供的帮助,以及ChrisIacobucci提供的车辆模型。

 

 


posted @ 2012-02-07 12:10 oayx 阅读(149) 评论(0) 编辑

Shadow Mapping已经成为当前3D游戏的标配。传统SM+PCF可以很好地实现日光环境下的Hard Shadow,但如果要实现由昏暗灯光所产生的Soft Shadow,则要么效果过于生硬(sample次数少)要么效率低下(sample次数多)。因此,越来越多的游戏开始使用能够充分利用硬件特性的软阴影算法。
这里主要总结各种Soft Shadow Mapping的算法思想和推导过程,不提及实现上的细节和具体代码,等有空再写写Demo。
本文为原创内容,转载请注明出处。

Standard Shadow Maps
Shadow Map的基本思想:Light View画一遍Depth,然后Camera View渲场景的时候,把Pixel坐标变换到Light Space,比较Depth即可(Pixel的Depth大于Shadow Map的Depth即在阴影区)。也可以直接是Screen Space对Depth Map做Post-processing。

传统方法可以用Percentage Closer Filtering解决锯齿问题,也很简单,Pixel坐标对应过去之后,比较周围的多个点,计算出阴影区的百分比。此外,还可以通过Bilinear Filter让阴影更平滑,跟PCF差不多,比较相邻的4个点,然后根据Texel的Offset做插值。值得注意的是,现在的GPU都支持Hardware Shadow Map,可以直接通过tex2Dproj( u, v, z, p )这条指令实现2x2PCF+BF。

Perspective Shadow Maps & Trapezoidal Shadow Maps
这两种方法沿用Shadow Map的基本思想。为了解决Shadow Map精度问题,对Depth Pass的变换矩阵做做手脚。

Variance Shadow Maps
VSM的想法很棒,可以说Soft Shadow是从VSM开始才往利用硬件Filter的方向发展。首先,也是Light View的Depth Pass,但是这次写入2个值,一个通道写入Depth,另一个通道写入Depth2。接着对出来的这张 [Depth, Depth2] 的Texture做Blur。直观上来讲,做Blur的结果就是取周围一定范围内的点的平均值(期望值),也就是Blur完之后得到一张 [E(Depth), E(Depth2)] 的Texture。有了这张Texture,后面便可以根据方差公式 V(Depth)=E(Depth2)-E(Depth)2 计算得到方差。

最后,根据Chebychev’s inequality(切比雪夫不等式)
P(x≥t) ≤ σ2/(σ2+(t-μ)2) 式中σ2为方差V(Depth),μ为期望E(Depth)
将Pixel坐标变换到Light Space之后的Depth代入t,即得到某个点周围一定范围内大于深度t的点的比率(注意切比雪夫不等式得到的只是一个范围≤,而这里近似的取不等式右侧的结果Pmax)。其实就是一个微分级别的PCF值,于是可以非常高效地得到平滑阴影。

很可惜的是,在Depth变化较大的区域(方差较大),VSM会有缺陷(Light bleeding)。因为根据切比雪夫不等式,在方差较大的情况下,(t-μ)必须足够大,才能让不等式右边趋于0。于是又有了LVSM来解决这个问题。

Layered Variance Shadow Maps
为了解决VSM的Light bleeding,对VSM的Shadow Map进行分层,将每一层次里面的Depth区间控制在一定范围内,也就是降低可能出现的方差值。

Convolution Shadow Maps
CSM提出了一种非常好的图形学算法思路。其推导过程比较华丽,用到了几个数学上的概念:卷积,傅里叶级数。(注意还有另外一种CSM – Cascaded Shadow Maps,两者作用是不一样的)

首先,假设xR3为某一点的世界坐标,d(x)为该点到Light Source的距离(也就是Light Space的Depth)。pR2为该点对应到Shadow Map上的坐标,z(p)为该点对应的Shadow Map上的Depth。于是可以定义一个Shadow Test函数:
s(x) = f(d(x), z(p)) 当d>z时,s为0,反之为1
为了得到软阴影,我们希望能对s进行卷积,即希望得到:
sf(x) = ∑w(q)f(d(x),z(p-q)) = [w*f(d(x), z)](p)(亮点1)
如果能对上式运用卷积定理,得到如下式的结果,则表明可以通过对z(p)做卷积而得到软阴影。(即可以利用Blur、硬件Bilinear Filter和Mipmap来达到软阴影)
[w*f(d(x), z)](p) = f(d(x), [w*z](p))
可惜的是,f(d(x), z(p))并不是线性函数(而是阶跃函数),无法对其运用卷积定理。为此,CSM转而采用数值分析方法,用傅立叶级数来逼近函数f。(亮点2)

虽然CSM的推导过程相当华丽,但是本身缺点太多(比如:内存开销较大,Shadow Map Pass需要输出的数据量太大,带宽内存都吃得太紧),导致其实用价值很低。

Exponential Shadow Maps
明白CSM的原理之后,ESM就显得相当简单了。

posted @ 2012-02-07 12:09 oayx 阅读(165) 评论(0) 编辑
  2012年2月3日
原则,故名思议则是本质的意思。所谓擒贼先擒王,研究设计模式自然要先了解设计原则,所有的模式都是在这些原则的基础之上发展起来的,有的是侧重一个,有的是多个都有所涉及。看完设计模式之后,我感觉到每个模式都有这些原则的影子,还渗透着面向对象的三大属性,也觉得这些原则也都有相通之处,,正是有了他们才使我们由代码工人转为艺术家。下面我来点评一下六大原则,望各位拍砖:


1、单一职责原则(Single Responsibility Principle,简称SRP)
      单一职责原则,就一个类而言,应该仅有一个引起它变化的原因。如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会消弱或者一直这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏。而软件设计真正要做的许多内容,就是发现职责,并把这些职责相互分离。

      一句话点评:高内聚低耦合的绝佳体现,不要乱拉关系,独善其身挺好。


2、 开放--封闭原则(The Open-Closed Principle,简称OCP)
       开放--封闭原则,是说软件实体(类、模块、函数等等)应该可以扩展,但是不可以修改。即对于扩展是开放的,对于更改是封闭的。 我们不可能做到未卜先知,在设计的时候尽可能让一个类足够好,设计好了就不要去修改了;不能完全封闭的情况下,当发生变化时,我们就创建抽象来隔离以后发生的同类变化。

      一句话点评:开放扩展,封闭更改,开合有度是一门艺术。


3、依赖倒转原则(Dependence Inversion Principle )
      依赖倒转原则,指高层模块不应该依赖低层模块,两个都应该依赖抽象;抽象不应该依赖细节,细节应该依赖抽象。说白了就是要针对接口编程,不要对实现编程。举个例子:计算机硬件中,如果内存坏了,那么只需要换一个内存条就可以了,而不需要去换一个主板,在这里内存是一个接口类,只要符合他的规格要求就行,无论是那一根。

     一句话点评:搞建筑时要做设计师,而不是砖瓦工,抽象的蓝图要靠具体的材料一点点实现。


4、里氏代换原则(Liskov Substitution Principle,简称LSP)
     里氏代换原则,子类型必须能够替换掉他们的父类型。在软件里面,把父类都替换成其子类,程序的行为不会发生变化。正是由于子类型的可替换性才使得使用父类型的模块在无需修改的情况下就可以扩展。

     一句话点评:长辈给了你继承的权利就一定要做赡养的义务,把长辈的职责都要承担起来。


5、迪米特法则(Law of Demeter
      迪米特法则,如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法时,可以通过第三者转发这个调用。类之间的耦合越弱,就越有利于复用,一个处在弱耦合的类被修改,不会对有关系的类造成波及。 主要是强调了类之间的松耦合。

     一句话点评:不要和陌生人说话,若两国交战要尽量避免正面冲突,多派使者协商调度。


6、合成/聚合复用原则(Composition/Aggregation Principle],简称CARP)
     合成聚合复用原则,尽量使用合成/聚合,尽量不使用类继承。合成聚合是“has  a”的关系,而继承是“is  a”的关系。由于继承是一中强耦合的结构,父类变,子类必变。所以不是“is  a”关系,我们一般不要用继承。优先使用合成聚合复用原则,有助于保持每个类的封装,降低继承的层次。
     一句话点评:优生优育,不要盲目繁衍。

posted @ 2012-02-03 15:28 oayx 阅读(122) 评论(0) 编辑
  2012年1月29日
转:带新人的故事

打不死的小强 http://xiaoqiang.me/

 

今年最大的收获就是带了新人,这是第一次完全把新人交给我,老大不做干预,让我自己来带。过程中经历了很多问题,做过很多sb的事情,也有了不少长进。下面把一些带人过程中的小故事分享一下,大部分都是失败的故事。

故事1:

我深知基础的执行对一个新人有多么的重要的,所以我会安排一大堆枯燥,耗时长,没什么成就感的基础工作让他做。其中有很多事情现在看来的确意义不大。一开始,他还愿意接受,但是这种事情多了,他的情绪就来了,明显表现出不情愿,不过我还是比较强硬的让他做。后来发现这些琐事严重影响到他的工作状态,我才罢手,砍掉了那些意义不大的工作内容

总结:新人需要执行来锻炼,但是别像我一样这么折腾人。对新人的情绪影响很大

故事2:

我是一个急性子,十分看重效率。但是新人做事的时候不慌不忙,经常是一件事情没做完就搞其他东西。于是我很不爽,我们俩人在会议室里争论了半天,最终决定每次安排任务的时候给一个明确的完成时间,必须在完成时间之前搞定。他是按时完成了,但是完成的质量总是很难让我满意,于总是一遍一遍的返工。后来这个时间也被废了,我最终改为较宽松的时间+不错的质量。

总结:大部分新人都有点胆小,不要给太大压力,压力大了就紧张,紧张就无法把事情做的漂亮

故事3:

他刚来的时候,我总觉得他做事情慢,总是说时间不够。所以我总问他这个事需要花你多少时间?(我的意思就是不用多少时间,你是太懒!)又一次他被我惹毛了,顶了我一句,我直接什么都没说就走了。过一会他意识到不对,找我到会议室谈谈,我们谈了很久,聊完之后豁然开朗,之前的不愉快瞬间烟消云散,而且我们之间也都更加理解对方了。

总结:矛盾市场发生,平等的,有效的沟通总是能解决所有矛盾。千万别拿身份去压人,沟通必须是平等的!

故事4

我每次写完活动方案,都会给他看一下,让他来帮忙修改一下。一开始他也提不出什么建议,不过时间长了,他总能从玩家的角度发现一些问题,提一些好的建议,甚至是一些不错活动的想法。慢慢的,一沟通起活动,他就有点来劲。在不到一年时间里,他已经能够完全自主的做活动的方案和执行了。并且效果很不错。

总结:让新人参与的决策的制定中,不要把他们当外人一样看待,虽然一开始他只能听,但是时间长了,他就会把每一件事当做自己的事情。参与并且负责人。

故事5

【小背景】我最不喜欢做的事情就是解释,把自己干的破事归咎到其他原因,摆脱责任,实在没什么意思。所以我当小弟的时候很少解释,改正,下次做好就行。

前一篇文章说过,一开始我安排过很多工作给他,有一部分的确不够合理,可能是他感觉到这些工作没什么意义,也可能是他懒,慢慢的,这些工作就做的越来越少,最后不再做了。这个过程中我没有认错,没有解释为什么可[来源:GameRes.com]以不做了。

因为我的不解释,他可能觉得其他工作也是可以偷懒的,于是其他工作也开始慢慢的缩水或者不做。一开始,我会唠叨他,让他做,但是时间长了,我唠叨烦了,效果也小了,于是就不再唠叨了。只要结果(KPI)符合预期,手段相对合理,我就没有再强烈要求他做过什么,最多就是建议和一些方式上的探讨。

总结:小弟不用给老大解释什么,但是老大要给小弟解释很多东西,让他们明白什么事情需要做,为什么,有什么好处,什么坏处。老大不能太沉默,老大沉默了就变成了不负责,不知道,可以钻空子。

故事6

他来一阵之后,团队的结构有变动,完全把一款产品交给我们2人来做,我们拥有绝对的决策权。而之前产品比较低迷,于是我想了很多办法,并制定了一条主线。然后我俩开始执行。

这个阶段,我很有热情,立志要把产品拖出低谷。我发现热情是可以传染的,那个阶段,他的工作效率和工作质量也比较高。但是之后我的热情褪去,他的热情也淡了,很多事情在执行上并没有达到我的标准,虽然结果(KPI)不错。

总结:想要下面的人有激情,自己先要有激情,把你的激情传染给别人,其过程和结果都会让人惊喜!

未完待续…

posted @ 2012-01-29 16:23 oayx 阅读(114) 评论(0) 编辑
提需求是运营人员经常干的事情,最近提需求时候很纠结,但是环境所迫,又没法说,只能在这里谈谈自己对需求的看法。

我认为提需求时,最重要的因素有3点:风险,成本,替代品



风险

风险是首要考虑的因素,如果连这一关都没过,后面就不用再浪费时间了。

风险主要有2大来源:

第一是需求操作过程的风险,例如有些需求需要动较敏感的数据库,有些需求执行过程中可能造成宕机…

另一类是需求做好后对游戏生态的影响,例如新需求的属性过于颠覆游戏本身的内容,或者新需求做好后很快有新版本,而新版本的内容跟需求内容造成冲突。

发觉风险时直接砍掉需求或者调整需求。

成本

提需求的成本主要分为2大部分:需求沟通成本,需求开发成本

沟通成本就是运营提出需求后,跟技术(策划)一起沟通,哪些要做,哪些不做,哪些需要调整的过程。

常规的需求,开发成本就2条:人力成本(谁做),时间成本(做多久)。操作的复杂程度不在成本的考虑范围内,可以归结为时间成本。

如果开发成本比较高,花一些时间在沟通上是有价值的。如果开发成本很低且无风险,却花了很多时间用来确定沟通要不要做,那就是浪费时间。

替代品

所有需求的出发点都是目的,为了实现目的,我们想到了一种手段,这个手段在实现上需要一些道具或者逻辑来支持,才有了需求。



实现一个目的的手段有很多,实现一个手段的方式有时候也可以灵活。当有风险了,当成本高了,我们不必吊死在一棵树上,想想其他办法,总能得到一个大家都开心的结局,如果在一个需求上死磕,开发被你整烦了,未来的日子会及其不好过。

所以,当沟通过程中遇到了困难,就退一步,找一些替代品,肯定会海阔天空。
posted @ 2012-01-29 16:16 oayx 阅读(58) 评论(0) 编辑
摘要: 本文主要总结创建、结束线程和WIN32 API提供的一些线程同步方法。同步方法包括用户态同步方式:InterLock、CriticalSection、SRWLock和内核态同步方式:Event、Semaphore、Mutex等。本文通过简单的例子演示API的使用,没有包含原理的说明,假定读者具有其他语言或者平台的并发编程经验。创建、结束线程WIN32 API虽然提供了CreateThead和ExitThread方法,但是在C++中,永远不应该使用这两个方法创建或结束线程。而应该使用VC++提供的_beginthread、_beginthreadex方法,相应的结束线程方法_endthread、阅读全文
posted @ 2012-01-29 10:56 oayx 阅读(143) 评论(0) 编辑
// 创建和结束线程.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <process.h>

class Obj
{
public:
    Obj()
    {
        std::cout << "Obj::Obj()" << std::endl;
    }
    ~Obj()
    {
        std::cout << "Obj::~Obj()" << std::endl;
    }
};

unsigned int WINAPI ThreadProc(void *para)
{
    std::cout << "ThreadProc:" << static_cast<char*>(para) << std::endl;
    Obj obj;
    //如果注释,则会调用析构函数
    
//::_endthreadex(2);
    return 1;
}

int _tmain(int argc, _TCHAR* argv[])
{
    /*WIN32 API虽然提供了CreateThead和ExitThread方法,但是在C++中,永远不应该使用这两个方法创建或结束线程。
    而应该使用VC++提供的_beginthread、_beginthreadex方法,相应的结束线程方法_endthread、_endthreadex。
    后者除了在内部调用CreateThread或ExitThread方法外,还负责CRT的初始化或销毁。虽然有直接结束线程的方法,
    但在C++最好通过线程方法正常返回来结束线程。直接结束线程时C++对象的析构函数不会被调用。
*/
    unsigned int nThreadID;
    char *param = "param";
    HANDLE kThread = (HANDLE)::_beginthreadex(NULL, 0, ThreadProc, param, 0, &nThreadID);

    Sleep(100);

    DWORD nExitCode;
    ::GetExitCodeThread(kThread, &nExitCode);
    std::cout << "Exit code:" << nExitCode << std::endl;

    getchar();

    return 0;
}
posted @ 2012-01-29 10:04 oayx 阅读(122) 评论(0) 编辑
  2012年1月20日
还在BETA测试中的《暗黑破坏神3》再度进行了更新,而本次更新后游戏的各项系统进行了较大的改动,为此《暗黑破坏神3》的游戏设计总监Jay Wilson在官网发布了相关说明,下面让我们一起来看看暗黑3测试服中进行了哪些改动。
暗黑破坏神3

  以下说明来自暴雪官方公告:

  系统改动 - Jay Wilson

  在制作《暗黑破坏神III》的过程中,一直有人说我们过于纠结于系统方面的细节因而浪费了太多时间:“这个游戏已经做得够好了,快出吧!”这说法可以理解,但我不觉得它是对的。我们的工作并不仅仅是推出一款游戏,更多是在推出《暗黑破坏神》系列的一个续作。人们不会去记住一款游戏是否推迟了,只有一款伟大的游戏才会让人记住你。我们相信自己可以为广大玩家提供这样一款游戏,但目前我们还没完成到这一步。这款游戏到现在都还没发售,我们也还没有公布任何发售日期,原因很简单:我们还没做好。在进一步完善和雕琢游戏内容的同时,我们也在继续对游戏的核心系统进行一些反复。因此我希望在这里向大家提供一份我们目前正在摆弄的系统的更新列表。

  我们目前正在进行的那些改动源自内部和外部测试者的反馈,内容包括物品打造、物品、核心属性和物品栏等等。在这里我们会把这些改动大致地列举一遍,并解释它们背后的原因。除此之外,我们还在对符文和技能系统进行一些大规模的改动,但目前还不是公布的时机。我能保证的是在技能和符文系统完成以前我们不可能发布这款游戏。

  先从小地方开始 – 鉴定卷轴从游戏里消失了。未鉴定的的物品以及鉴定物品的操作依然是游戏的一个重要组成部分,但现在获得一个未鉴定的物品以后,你只要右键点击它,就会出现一条代表正在检验的短暂施法条,检验完成以后,该物品就会变成已鉴定的状态。找到一件礼物然后拆开它能给人带来双重惊喜,我们很喜欢这种方式,但这不代表你需要随身带着几把剪刀。从现在开始你将可以自行鉴定所有的物品,不需要携带卷轴。因为你在《暗黑破坏神III》里的角色从来就是这样酷。

  然后是一处更小但更显著的改动 – 第五个快捷栏位移动了位置,并成为了一个药水专属按钮。在整个游戏的开发过程中,我们在是否加入专门的药水按钮的问题上反复了好几次。而最近,我们明显感到有必要让玩家能在危急情况下第一时间想起他们的药水。目前我们的战斗模型并不鼓励(甚至根本就不允许)用药水流来打怪,但它们在你一路运气不好没打出生命之球或是陷入了自己应付不了的状况时会非常有用。这项改动是最新加入的,因此在封测补丁10中还不存在专门的药水按钮。但这确实是我们的改动方向,你会在今后的封测更新中看到相关支持。

  以上是一部分简单改动。目前我们设计组的目标是重新审视所有的系统,并清除相互间的重叠冗余的部分,必要时还会移除一些无可救药的组件。出于这些理由和一些更崇高的目的,我们将删除密士这一NPC。在研究了整个物品自定义系统以后,我们发现物品强化(即密士的作用)对整个游戏没有任何助益。强化系统和插槽+宝石系统没有任何区别,只是换了个名字。除非我们想继续拖延游戏的发售时间,让这一系统回到绘图板上,然后从头设计过,否则目前最合理的方案是把这些东西暂且延后,今后再去重新讨论密士和强化系统。删除密士自然也要花一点时间,但和重新设计一套物品自定义系统要花的功夫相比就微不足道了。我们希望将来有一天她能重返你的除魔旅团,但眼下我们还是要把注意力放到游戏中已有的那些重点的自定义选项中。

  《暗黑破坏神III》已经开发了很长一段时间,其间我们也一直在研究整个系统,并审视以前基于当时的状况所作出的那些决定到了现在是否还说得通。比如我们最近加入了召回之石。它只需要一个很短的施法时间就能让你回到城里。但更早的时候我们曾说过我们不会加入城镇传送门(因为很多玩家会利用它们来在战斗中投机取巧)——这一点在目前仍然站得住脚,但同时我们也发现这个游戏依然需要一个快速旅行的方式,虽然我们增加了传送点的数量但其自由度仍然及不上城镇传送门,而现在,我们可以使用召回之石来解决所有这些问题。然而正因为召回之石的引入,我们又需要回头重新评估先前那些因为城镇传送门的消失而引入的补偿机制。经过了谨慎的评估以后,我们决定移除乔丹金炉和奈非天魔方。当初加入它们是为了让玩家可以在无法快速回城情况下就地分解和出售物品。但现在有了召回之石,我们再让这些东西继续存在只会减少玩家本该得到的收益,如出售、分解、制造物品,与镇民交流、管理物品栏等等,这些设施都是非常有用的,可以让玩家暂时脱离紧张的战斗,在回归战场之前能有时间评估自己身上的装备并使用制造功能。另外,我们决定不再自欺欺人,干脆就把召回之石的名字改为了城镇传送门,并将这一它直接嵌入到了界面上的技能栏中。

暗黑破坏神3

  分解物品的工作现在由铁匠负责。魔方被移除以后,我们当然就得在城镇中增设一个用于分解物品的设施,而由铁匠来当然这项工作是很合理也很符合逻辑的。

铁匠

  另一项重大改动是普通(白色)物品无法再被分解。我们发现原设定会导致一些物品方面的问题,但最主要的原因还是物品重要性这块上的方针变化。以前我们的想法是一个物品一旦掉落后,必须要能发挥一些作用,要不就是给你提升属性,要不就是白色物品可以被分解后重组成更好的物品。通过大量的游戏测试,我们回归了《黑暗破坏神II》的掉落方式:即让怪物掉落大量的不值得拾取的垃圾。虽然《暗黑破坏神II》会掉落大量的垃圾,大部分是箭支和弩箭,但在遇到好的装备时,这更会助长玩家“捡到宝”的喜悦,当然我们同样很喜欢物品掉一地的感觉。因此我们就需要重新平衡物品本身的价值和我们扔给玩家的物品数量之间的比重。

  由此,我们进行了另一项改动,同时这也是今天我要详细讲解的最后一项改动:

  我们将角色的核心属性改为力量、敏捷、智力和活力,而每项属性所提供的增益则被划分为:

  力量

  +野蛮人伤害

  +护甲

  敏捷

  +猎魔人伤害

  +武僧伤害

  +闪避

  智力

  +魔法师伤害

  +巫医伤害

  +生命之球补充的生命值

  活力

  +生命值

  我们取消了防御、攻击、和精准这些属性,新的护甲属性将取代原有的防御属性。我们还将加入+物理抗性来取代原有的护甲,并用+暴击几率来取代精准。很显然,这些角色属性方面的改动只是我们的另一项更巨大的改动的冰山一角,因为它要求我们对物品属性和游戏平衡进行广泛而深入的再设定。

  这些改动背后的原因之一是为了让各种属性变得更直观,但更重要的原因是解决我们目前遇到的一些物品系统的方面的问题。正如我刚才说的,我们想把物品系统改回到一大堆垃圾物品的模式,但除此之外,我们还需要加入各种各样奇葩的物品,让人看一眼就知道不适合你的角色。我们希望掉落大量的物品,并加强玩家拾取到极品时的兴奋感,因此我们就需要各种属性分配不合理的物品(对你的角色来说或是抛开特定角色来说)。通过给每个职业指定主属性,我们可以降低物品的重复性,令我们的物品库变得更多样化,并最终创造一种更明确的物品属性系统,并在你的角色发现超酷的新物品时提供足够的兴奋感。

  总体而言, 这些改动对你想追求的物品的影响非常小。你以后需要的物品依然还是你以前需要的那些。对物品的取舍依然取决第二属性和物品名称上的词缀,而我们正尽可能地将更多词缀加入游戏(我们以前也一直在这样做),以确保物品的多样性。单纯加入一些能强化特定技能的词缀就已经能对物品库作出极大的拓展,并创造出更多的可能性。

  继续,在移除了乔丹金炉和奈非天魔方,并将城镇传送门移到技能面板以后,我们现在直接把角色属性整合到了物品栏界面中。这给玩家观察不同装备对自身属性的影响提供了极大的便利。新界面将和旧有的界面提供同样详细的信息,并能提高界面的效率令其变得更加有用。虽然看起来是很小的一个改动,但产生了让我们非常满意的结果。

暗黑3变动

  我们将在最新的封测补丁中加入以上所有的改动,因此我们希望有封测资格的玩家能多多尝试它们,并到我们的封测反馈论坛上来发表你的想法。

  当然,目前我们仍有许多工作要做,我们正一如既往地对平衡性改动作出调整,这是一项非常艰巨的任务。你们可以在封测中看到一部分:如物品稀有度的改动、我们在各个等级的区域中加入的物品词缀数量以及它们的加入方式、敌方怪物的词缀数量等等。当然,还有一部分改动是你在封测中看不到的,例如对整个游戏(包括四种不同难度)的平衡、后期的各种新词缀、传说级别的物品、新的物品打造配方和物品设计图、成就以及战网的各种新功能。正如我上面提到的,我们同时还在对其余系统进行更大的改动——尤其是技能和符文方面。虽然目前还不是公布的时机,但我们希望能在将来呈现给大家。

  我们暴雪娱乐的所有员工都希望《暗黑破坏神III》能在发布的第一天就成为最佳的游戏。为了达到这一目的,我们还将继续对我们已有的设计进行反复,改变我们花了大量时间构思和设定的那些系统,或是删除早已融入游戏核心体验的那些系统。我们希望在反复的重构过程中,不断地对我们以前作出过的决策提出质疑。《暗黑破坏神III》不止要在发售时达到我们的预期,更要在之后的十年二十年里继续维持暴雪的精品要求。

  Jay Wilson是《暗黑破坏神III》的游戏设计总监,“神秘的肉”的发明者,他认为凯特·贝金赛尔 是史上最伟大的女演员。

就算世界末日,也不能阻挡我们玩游戏!就算世界末日,也不能阻挡我们玩游戏!
posted @ 2012-01-20 17:25 oayx 阅读(91) 评论(0) 编辑