想了解一下星际2 3D图像引擎的细节和技术动向吗?这篇由Blizzard员工所攥写的Course Paper绝不会让你失望的!其主要涵盖了星际2 Cut-scenes渲染的技术内容,面向中等水平技术人员,且非常口语化,强烈推荐!
SIGGRAPH 2008
Advances in Real-Time Rendering in 3D Graphics and Games Course [Part-5]
Starcraft II Effects and Techniques (.pdf, 4.2MB)
by Dominic Filion, Rob McNaughton, Blizzard Entertainment
posted @
2008-08-20 00:10 neoragex2002 阅读(117) |
评论 (2) |
编辑
随便写写,向大家介绍一下
Firefox 3中信息搜集、管理方面的杀手级功能:
Awesome Bar。众所周知,IE的那种层级式收藏夹已经过时了,没人愿意用子目录来手工整理数以百计的书签。在Firefox 3中,书签管理、标签(tags)归类的功能得到了空前强化,基本上,除共享之外,其完全可以用来替代目前流行的网络书摘应用,如
delicious、
QQ书签等;而Awesome Bar作为书签及tags查询的综合界面接口,其易用性也让人爱不释手。
基本界面:

实现原理:使用Firefox内置的
SQLite引擎存储所有的用户访问信息,其来源包括历史、收藏夹、标签、已访问的url、已访问的网页标题、页面元数据等,然后根据用户输入的关键字,对其进行实时的部分字符串匹配查询,罗列出所有匹配结果,并按照一定算法排序,从而帮助用户迅速找到所需的目标网址。简而言之,相当于是用户网页访问信息的本地搜索。
匹配信息来源:
历史url、收藏夹、标签(tags)、曾访问过的网页标题
查询排序依据:
1. 访问时效性
2. 访问频率
3. 统计访问次数
4. 字符串匹配程度
界面功能:(*为常用功能)1. (*)bar右边的下拉按钮:显示本机访问频率最高的网址列表
2. (*)bar右边的星星标记:单击—立即收藏当前网页至"未整理书签",不添加tags;双击—收藏当前网页,并指定其tags及存储位置
3. bar左边的网页标记:显示当前站点信息,包括统计访问次数、页面元数据等
4. bar右边的订阅标记:订阅当前网页中的RSS
小技巧:Q: 如何永久性删除Awesome Bar筛选出来的一些条目
A1. 用光标键在下拉列表中选中该条目,然后按Del或Shift+Del....
A2. 根据列表中星星等UI提示,判断该条目所处位置,然后从书签或历史中删除
一般资料整理方式:1. 访问网页时,仅需点一下星星即可将其迅速收藏至"未整理书签"
2. Ctrl+Shift+B,打开书签管理器,在“未整理书签“中,逐个修改收藏书签的标题,添加tags,以体现特色和分类
3. 可选:在书签管理器中新建一个”已整理书签“目录,将所有已添加了tags的书签全部移至其中,保持“未整理书签“为空
4. 接下来,用Awesome Bar来搜想要的tags、标题关键字吧!
一个典型应用实例:比方说,我希望查找某个自己曾经访问过的盟军文件格式汇总网页,该网页也许已收藏过了,也许没有;随便输入个“盟军”试试,ff列出了所有匹配结果,注意其中的匹配关键字已被加粗,有星星标记的记录是已收藏网页,星星的左边标记是其书签所关联的tags;

Ok, 把"commandos"也输进去,进一步缩小范围,注意此时只有同时具备两个关键词的记录才会被显示出来

继续添加一个关键字"文档",其结果恰好是我需要找的那个网页。地址栏居然也能当搜索栏,是不是很酷?:)
posted @
2008-06-03 05:32 neoragex2002 阅读(377) |
评论 (0) |
编辑
2008-5-29
项目未死,临时暂停,一个月后重开。
2008-5-6
Rendering架构整理;多纹理管理;Blp多重纹理调试支持;dbc数据库加载优化;ArcBall摄像机;等等。hmmm... 适当地踩踩刹车是有必要的,为了以后能开得更快
2008-5-5正确的替换纹理查询;自.mpq中自动加载.m2、所有.dbc和.blp纹理;正确的纹理切换与渲染次序;初步的Alpha混合;基本显示交互。
2008-5-3
发现.m2模型的纹理换装很麻烦,替换纹理必须从多张.dbc表(Database
Client)中进行联合查询方可得到。几乎每一张.dbc、每一条查找路径都必须用代码封装,人都累死...而且,其实目前对许多.dbc字段含义及交叉引用关系普遍理解并不完善,再加上WoW中庞大的资源组织规模,盲目地封装类显然自缚手脚...一怒之下添了个
sqlite进去,干脆8择手段一点:在
rendering之前将所需.dbc从.mpq中一次性读入内存数据库,复杂查询只需用sql语句封装一下即ok... hmmm so neat
and flexible~
2008-5-2
添加了自动从.mpq中加载.m2模型及.blp压缩贴图的支持,可以将.blp中的mipmaps导出成.png供调试
2008-5-1opengl+glut+glew。初步模型+纹理,无纹理特效、无骨骼动画、无粒子和丝带效果... 太多的无。8过8要紧...慢慢整~=)
2008-4-30
Why WoW? 原因是多方面的:1.
长久以来,Blizzard都是欧美系的一个另类典范:它一直都不以画面效果领先者自居,但有趣的是,几乎每一款BLZ的作品却总是会树立起一个标准,一
个最低限度画面技术效果(非美工...Blz美工超强...)的门槛,恩...了解什么是标准本身就很有意义;2.
作为画面效果的后进者,Blz所采用的技术相对保守,但覆盖范围全面,取舍合理,WoW发展至今,资料也相对完整;3. 兼顾固定管线和Shader,配置要求很合适,对于只有ATI
7500的吾来说....4. 资源极大丰富,且质量和规模均体现了一定工业强度... 对于爱好者而言,不比那些有美工搭档的从业者,有资源才有一切可能...
posted @
2008-05-01 21:41 neoragex2002 阅读(426) |
评论 (11) |
编辑
It's well known that the H.264 and AAC decoding has been supported by the new Flash Player 9 Update 3(9.0.115), which may mean a whole new era for high-definition video to begin. In order to witness the great power of new Flash player, I did some experiments on H.264 encoding and compared their results with the traditional FLV videos (a variant of H.263). Generally speaking, the comparing result is really impressive: Both videos of FLV and H.264 (within an encapsulated form of .mp4) could be progressively downloaded and played online. With some fine-tuning of the H.264 encoding parameters, it’s possible to shrink the video size by half and while at the same time to gain equivalent or even much better graphical quality than the FLV one! Really awesome, isn’t it?:)
Below is one of my prelimentary tests, a 9.8MB demo for starcraft 2. As you can see, the quality of this H.264 video is practically quite close to a FLV equivalent with a fairly high bit-rate of 1200 kbps, but in the matter of fact, its average bit-rate has only 550 kbps, which could be affordable for most of the typical users on Internet I think.
At the end of this article I packed up some troubles that I'd counted before, and I also provided their answers for convenience. Hope that they may also be useful for you.
= Concise F.A.Q for working with H.264 in Flash Player =
Q: Why can’t I play the demo in my browser!?
A: Adobe Flash Player 9 Update 3 (9.0.115 or above) and related plug-in are required. Plz refer to here for further information.
Q: How can I encode my video clips with H.264 codec?
A: x264 is my personal favors to do that job. It's open-source and totally free.
Q: How can I place the H.264 video clips in my web pages?
A: You‘ll need some Flash video player and embed them in your page just like a normal .swf object. As far as I know, there are 3 typical online players to choose: Vcastr (light-weight), JW Flv Player (moderate) and FlowPlayer (comprehensive). They're all free. You can also use the SWFObject library to facilitate the configuration of these embedded players.
Q: Why is my progressive H.264 video not playing in the player until entire file is downloaded?
A: One important thing about playing an H.264 video file as progressive download is that the moov atom for indexing needs to be located at the beginning of the file, or else the entire file will have to be downloaded before it begins playing. Unfortunately, tools such as FFmpeg place this information at the end of the file by default. You should use qt-faststart to fix this annoying problem.
posted @
2008-03-05 22:43 neoragex2002 阅读(226) |
评论 (1) |
编辑
2/1/2008
There is so many friends curiously think I'm only interested in Gamedevs, Graphics and Geeks (3G for abbr. ? -_-b).... As my official denial and fight-back (not so much seriously^^), I have prepared a little charming thing (which was implemented from scratch by myself) here for you guys, and I hope that you could find something more than meets the ears... Attentionl
Managed DirectSound and
.NET Framework 2.0 are required.
Download: Streaming Audio Sample (cancelled...)
2/7/2008
Today I decided to update this fun-project with an improved sample that supports essential streaming MPEG-1/3 (a.k.a. MP3) decoding. Although as far as I know DirectShow does not suit for the requirement of frame-by-frame audio splitting and decoding, which is absolutely needed for an as-neat-as-possible streaming media project, I finally found something even more interesting –
FFmpeg, one of the best multimedia projects in F/OSS world. In this following sample, the MPEG-1/3 core was ripped and slightly modified from FFmpeg, and compiled with /clr option by using VS2005. The main difficulty I have met is the terribly slow running performance when debugging a CLR decodec. It’s really hard to drive a .NET based real-time MPEG-1/3 decodec in debugging environment. The reason lies behind this is that there is no optimization at all. But when we run it directly out of the IDE, things become more better by the mercy of JIT optimizations. From a perspective of Geeks that always be in pursuit of 100% perfect, the final effect is not wonderful enough and it may need some further fine-tuning. But for an experimental try-out, it’s fairly good I think:-)
2/10/2008
Yesterday when I decided to dig somewhat
deeper into the MPEG-1/3 core to find why the debugging performance is too
slow, I was shocked. I found several strange intrinsic functions that
used some __asm blocks to try to improve the performance of native code. "Native code optimization in a managed running context", bad smell huh? In fact, that’s the REAL answer of
the whole evil question. Some further profiling show that when these “native-optimized” intrinsic
functions were called, there were so many context switches occurred between the
managed and unmanaged boundary back and forth frequently, leading the debugging
performance drop to an unbelievable low extent. After being aware of above
situation, I quickly changed the compiling option of /clr (which supports
mixing calling model) to /clr:pure (which could be applied to ensure that there
will be no native executable codes exist in the assembly anymore), and I also replaced all of these
__asm blocks with some equivalent operations by using normal C++/CLI sentences,
then rebuilt the whole project. The result was so impressive: the debugging performance in IDE
was dramatically improved over 10 times than what I got few days ago! Now there
would be no problem to drive a pure .Net MPEG-1/3 core with all IDE debugging
functions enabled in real-time!
Download:
Streaming MPEG-1/3 Sample (updated, 43.2KB)
posted @
2008-02-01 07:49 neoragex2002 阅读(281) |
评论 (1) |
编辑
光枪其实是个接收机,其枪口处有个光电检测管(PD,photodiode),外加聚焦透镜,用来接收来自屏幕上某点处的光线。当光枪的扳机被按下时,光电检测管将检测接收到的光强,当光强超过一定阈值时,其输出1至游戏机,否则输出0。有两种方法可用来判断扳机触发时是否命中屏幕上的目标:
A.
逻辑判断:即闪烁屏幕。在扣下扳机的一瞬间,先涂黑整个屏幕,同时将所有目标绘制成白色,然后打开PD,此时,如果PD输出1,则目标命中。这种方法的优点在于足够简单,而缺陷在于:如果屏幕有多个目标,无法区分命中的究竟是哪一个目标(对光枪里面的PD别心存太多期望,它只是个廉价设备,无法用来判别颜色的)
B. 精确定时:即光栅计数器+微秒级定时器+闪烁屏幕。时序及说明如下:
- 扣下扳机的同时,开始涂黑整个屏幕
- 检测到第1个VBlank,此时屏幕已经全黑了
- 紧接着画下一帧,开始涂白整个屏幕,光枪PD打开,开始检测光输入
- PD输出一直为0,此间对HBlank个数进行计数,且每当发生了一个HBlank时,ms级定时器重新计时
- PD终于检测到了第一次光输入,且得到了此时的HBlank计数n和计时值t
- 接收到第2个VBlank,此时屏幕全白,光枪PD关闭
- 根据得到的n和计时值t,便可以知道扣动扳机时光枪所指向的究竟是屏幕上的哪个像素了:前者即为屏幕y坐标,而后者除以HBlank时间间隔再乘上光栅像素宽度即为屏幕x坐标,然后判断一下是否为目标,over
-
上述方法有两个前提:首先,需要2帧来完成判断,你的手抖动频率最好表超过30hz,否则瞄不准...其二,需要HBlank和VBlank计数,所以用CRT最简单,如果是投影和LCD的话,恐怕就得换换思路了
一点思考:
- 现在总算知道为什么有些模拟器(尤其是Console,比方说变态的bsnes)需要达到光栅级以上的模拟精度了吧?
- hmmm...就模拟器而言,如果想用真实的光枪,不管是那种显示设备,方法1都完全适用。而对于方法2,只要达到了光栅级渲染精度,HBlank/VBlank的获得便不是问题;稍微麻烦点的在于方法2中第5步,单从硬件原理考虑,如果用户使用的是CRT,那么还好办,主要是一些数值校正方面的工作(也就是说,CRT+光栅级精度的模拟器,完全有可能直接使用真实光枪来玩,哈哈)
- 对于方法2,如果用的是LCD的话,想要用真实光枪,最简单的方法莫过于直接使用像素级渲染精度的模拟器(逐像素绘制,每画一个像素模拟定时同步一次),遗憾的是,现有的模拟器没哪个能达到这种精度(bsnes应该是这方面最为接近的尝试)...这样模拟效率实在太低,因此此路不通。其实可以变通一下,仍使用光栅级模拟精度,一次计算一根扫描线,然后将其像素从左至右地“逐点”绘制出来,以供光枪检测,即,模拟仍然是精确到光栅的,但绘制定时却是精确到像素的,如果定时把握得好,用LCD也能实现与CRT+光枪同样的效果,哈哈~但不知道时间同步粒度太小,对rom逻辑本身是否有影响
- 这里需要澄清一下:常见街机光枪游戏其实分2类(这里不讨论IR Camera定位),一类是枪下面有底座的,如野狼突击队,根据其底座机械运动本身便能将枪口所指向的位置坐标实时计算出来,因此这类光枪游戏根本无需使用上述光线检测法,在MAME中,这类游戏的输入是用鼠标来模拟的;屏幕上一般都实时显示出了枪口当前所指向的位置,这是其特征所在。而另一类是枪下面只有线缆、没有底座的,如死亡之屋等***游戏,由于用的是光线检测法,因此其屏幕上并不会实时显示枪口瞄准镜,值得注意的是,这类游戏在移植到PC上时把光枪支持全砍了,而使用了鼠标模拟+显示瞄准镜的方式来替代,导致临场感大减
posted @
2008-01-01 07:51 neoragex2002 阅读(487) |
评论 (1) |
编辑
哈哈,从M$ Visual C++ Team的
Andy Rich那里又偷学到一招:VC8的隐含编译项
/d1reportSingleClassLayout和
/d1reportAllClassLayout 。看个复杂的例子吧(如下),现在假设我们想知道Derived类的对象布局,怎么办? 在Project Properties->C++->Command Line->Additional Options里面加上
/d1reportSingleClassLayoutDerived吧!
class CommonBase
{
int co;
};
class Base1: virtual public CommonBase
{
public:
virtual void print1() {}
virtual void print2() {}
private:
int b1;
};
class Base2: virtual public CommonBase
{
public:
virtual void dump1() {}
virtual void dump2() {}
private:
int b2;
};
class Derived: public Base1, public Base2
{
public:
void print2() {}
void dump2() {}
private:
int d;
};
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
F5编译之,你会惊奇地发现,Output里面有如下字样:
1 class Derived size(32):
2 +---
3 | +--- (base class Base1)
4 0 | | {vfptr}
5 4 | | {vbptr}
6 8 | | b1
7 | +---
8 | +--- (base class Base2)
9 12 | | {vfptr}
10 16 | | {vbptr}
11 20 | | b2
12 | +---
13 24 | d
14 +---
15 +--- (virtual base CommonBase)
16 28 | co
17 +---
18
19 Derived::$vftable@Base1@:
20 0 | &Base1::print1
21 1 | &Derived::print2
22
23 Derived::$vftable@Base2@:
24 0 | &Base2::dump1
25 1 | &Derived::dump2
26
27 Derived::$vbtable@Base1@:
28 0 | -4
29 1 | 24 (Derivedd(Base1+4)CommonBase)
30
31 Derived::$vbtable@Base2@:
32 0 | -4
33 1 | 12 (Derivedd(Base2+4)CommonBase)
34
35 Derived::print2 this adjustor: 0
36 Derived::dump2 this adjustor: 12
看到了吗? VC8居然输出了Derived对象的完整布局! 我们终于可以不必两眼一抹黑般的去peek/poke了....第1行表明,Derived对象总占用了32字节;其由三部分组成,分别是行3-行7、行8-行12、行13、行28;其中前二者分别是基类Base1、Base2的布局,最后的行28为虚拟基类Common的布局。
以基类Base1部分为例,可发现其由一个虚函数表指针vftable和虚基表指针vbtable构成,先看Base1部分的vftable所指向的虚表$vftable@Base1(行19),不难发现,其中的表项2已经被Derived::print2给override了;再来看Base2部分的vftable所指向的虚表$vftable@Base2(行23),可发现,同样的,Base2::dump2被Derived::dump2给override了。这不明摆着就是虚函数机制嘛,heh~
值得注意的是,这个例子同时说明,多继承场合下,其实在单一对象中是存在多个this指针的....行35-36给出了如何将Derived的this指针校正为其基类子对象this指针的偏移量,也就是说,根据行36,假设有个Derived d,那么d.dump1()实际上应该理解成通过虚表$vftable@Base2对((Base2*)(((char*)&d)+12))->dump1()的调用....即传递给所有Base2成员函数的this指针应该是(Base2*)((char*)(&d)+12),这里可能我写得恐怖了点,意思到了就成....这不,普通继承、多继承、对象Slicing的语义都在这个布局里面了,看仔细了哈~
OK,多继承看完了,继续看虚拟基类是如何布局的。虚基Common在Derived的布局中,位于Derived本身数据成员之后的位置。Base1、Base2中均保存了一个vbtable指针,其分别指向各自所使用的虚基表$vbtable@Base1和$vbtable@Base2,为什么要指向一个虚基表? 很简单,因为Base1、Base2有可能会同时继承多个不同的虚拟基类.....这充分体现了C++对象布局的复杂性....在每个虚基表中,保存了所继承的虚拟基类部分相对于子类部分vbtable指针的偏移值,以Base2为例,我们知道Base2的vbtable在Derived中的偏移值为16(行10),则根据$vbtable@Base2,虚基Common部分距离Base2 vbtable指针的偏移值为12,则有虚基Common在Derived中的总偏移值为16+12。与普通多继承同理,我们在调用非虚拟的虚基成员函数时,必须将Derived的this指针调整为指向虚基部分的this指针,只有这样才能成功地访问虚基自身的数据成员和虚基的虚拟函数(通过虚基自己的vftable,为简单起见,上例中我就没弄那么复杂了,大家可以自己玩玩,明白如何举一反三即可)
看完了上述解释,是不是感觉比啃
Inside C++ Object Model来得更快更直观啊?heh
posted @
2007-11-01 07:37 neoragex2002 阅读(840) |
评论 (11) |
编辑
蝴蝶效应: MAME 0.120u1中的一个小动向,也许就是一场大规模技术变动的前奏。经历了相当长久的视频系统改进铺垫之后,看来提高3D视频模拟效率这一议题总算被提上日程了。在最新的Mame0.120u1中,一系列3D基板的模拟均不同程度地得到了改善,而其中最令人关注的莫过于Aaron所写的那个新模块了( polynew.c),看上去就是一个通用的多边形视频驱动模块,其目标直指当前模拟效率极低的多边形光栅化过程(still software rendering...not shader),而且不断扩充的趋势非常明显。目前已经有Namco System 22、Voodoo等4个3D基板的驱动使用了这一模块。
MAME中的3D风暴即将来临,Are you ready?
posted @
2007-10-25 16:32 neoragex2002 阅读(316) |
评论 (5) |
编辑