听枫阁 - 叶枫影
type: channel
link: https://leafvmaple.com/index.php/author/1/
description: 叶枫影
items: 逸剑风云诀-初出茅庐篇
items: 逸剑风云诀-传功弟子篇
items: 逸剑风云诀-精英弟子篇
items: Lua与C++交互之Luna
items: 目标文件概述
items: x86调用约定
items: Nintend Switch开发之一 大气层
items: [译]即时辐射度算法
items: 次时代游戏制作的CG技术发展趋势
items: [译]QSplat:大型网格的多分辨率点渲染系统

逸剑风云诀-初出茅庐篇
type: item
date: 2025-08-21T15:16:41+08:00
description: 初出茅庐篇【葬龙谷】【主线】葬龙谷之变对话三个NPC 熟悉操作 靠近马车。第一个选项 走为上策 和 出言相劝 都不影响后续。【梧桐村】经脉：前期主 任、冲（快速提升战力）前期瑜伽经心法需3000+气血50身法，战斗技巧：尽量不要被包围，攻击背面和侧面伤害更高，背击+命中。优先获取和请教心法 属性经脉丹优先给主角，主角战力傲视群雄以后再培养队友。【主线】初入梧桐村[江小彤]好感+30（30）拿江宅内 右侧 宝箱。出门左侧宝箱 【一周年礼包】打开获得【小熊猫坐骑】【宗师书札】【金元宝】【五转洗髓丹】【五品宁神丹】【逸剑风云决】把【宗师手札】【五转洗髓丹】吃了，【逸剑风云决】穿上。按J打开经脉图，选择任、冲脉点满前三个黄点，冲脉第三个暂时点不满。按B打开背包点击左下角坐骑切换到【DLC海豹坐骑】先不去找[小彤]往右走，按E消耗精力（左上角绿条是精力值）采集路过的所有资源（红蓝荧光点靠近可采集）。左下[樵夫]棚屋内宝箱。【支线】北望对话[赵启志]选择 肯定能，北方已经不打仗了。钓鱼点钓五条草鱼也可以去清河村找渔夫购买左侧[赵氏]货摊上方隐藏宝箱对话[赵氏]【支线】百晓生-无妄之灾对话[百晓生]选择 如何化解 付钱。【支线】铁匠的烦心事对话[铁匠] 选择 行吧，旁边的宝箱开了，前往钓鱼点对话李寡妇，在回复铁匠。郎中家左下棚屋宝箱左侧宝箱。继续往左走遇到[小彤]，打开背包把刚获得的装备穿上，切磋[小彤]装备金钱镖，走到左侧猴子处战斗帮小彤抢回木剑回到江吟风宅，获得【基础心法秘籍】，点满【基础心法】继续点经脉 把其他脉络前三个先点满，再点任脉和冲脉【主线】解毒之物-药材找[孙郎中]取药材，采集五份半边莲回复[孙郎中]【支线】枯藤老树昏鸦继续与[孙郎中]交谈 选择 趁着还硬朗，回去看看吧有后续获得【辛金丸】【乙木丹】，直接吃了【支线】慈母手中线对话[裁缝] 接取任务【支线】无妄蛇灾李村长 选择 义不容辞【支线】樵夫的斧子【支线】村民的困惑对话张樵夫 选择 好，我这就去找铁匠对话后再回复樵夫 选择 重新锻造一番吧，好吧再找铁匠，交谈两次 选择樵夫或许有办法回复樵夫，交谈两次。再去找郎中，去刚才抢木剑的地方。选项任意，下不下猴子都死再回复郎中完成任务。接着前往江宅右侧回复江吟风【主线】解毒之物-高粱酒前往客栈触发剧情，再去村口找卫霍,送礼到20选择切磋。邀请[卫霍]入队。解锁成就：招募卫霍[卫霍]好感+40（60）【支线】卫霍的承诺【支线】山猪为患送礼[卫霍]加好感（＞60），选择 帮他 。切磋[卫霍]【蟠龙棍法秘籍】，菜谱功法全部学习。【主线】最后一样解毒之物回江宅找江吟风。请教卫霍钓鱼、制衣以及 【江湖心法】【镇山心法】精力不够直接在床上休息，升满心法，继续点前三个经脉黄点。到桌边喝药。【存档30】根据获取江吟风教的不同武学到碗子山头领宝箱获不同取功法秘籍【霹雳霸刀】【化功绵掌】【惊雷剑法】只能获得其中一本所以需要读档收集后山山洞前找江吟风，选择 明白了 剑系武器装备纯钢剑 武学笔记吃了，靠近木桩，这场输赢无所谓。升满刚才学会的剑法，进入山洞。右侧宝箱【一转气血丹】，深处还有一个宝箱。吃【一转气血丹】，给卫霍换品级低品质好的装备。第一场战斗：有镇山用镇山，先杀小怪再杀BOSS。第二场战斗：直接往后稍稍让江吟风打就行。【主线】山洞大战战斗胜利后江吟风加入队伍。把江吟风身上除武器外所有装备换下来自己穿上。自身除周年饰品其他都换六品装备。前往洞口，开战选择回合敌人各自为战我们只需逐个击破即可由于没有额外击杀经验所以直接让江吟风打行了，我们在旁边喊加油。战胜后获得 【基础轻功秘籍】、【碧水剑法秘籍】、【五虎断门刀秘籍】、【幻阴掌秘籍】【支线】无妄蛇灾对话村长把任务交了前往后山山洞旁祭拜牢江。【主线】洛村寻人菜谱、武学全部学习，轻功升满，卫霍升级【镇山心法】，卫霍经脉也是先点3个黄点。出村前往洛村（M查看地点名字）【洛村】【支线】养生秘术对话魏老 把任务接了【支线】农忙对话杨婶 收割麦子回复杨婶。【支线】野猪进村对话柳氏柳氏旁边宝箱开了，对话野猪战斗后回复柳氏。【二转气血丹】* 2解锁成就：宝箱达人【支线】百晓生-桃花劫对话百晓生 选择 信他 付钱王大嘴后面的宝箱开了。进客栈对话掌柜，二楼逗猫 解锁成就：大橘为重王石头旁边宝箱开了交易王石头购买 【基础拳掌秘籍】、【基础刀法秘籍】、【基础剑法秘籍】【支线】蜃楼幻境左侧出村 前往平康城，路过驿站顺便开一下（后续可以和其他驿站互相传送）。一周目玩家无法触发蜃楼幻境。【平康城】【支线】千金难求醉仙楼 成生 选择 买客栈里右侧宝箱开了。【支线】同情心出门右下角小雨 选择 帮她先进武馆 右上宝箱开了进入药铺内左侧位置触发钱袋回去找小雨发现不见了，选择 还是算了（有后续）。【支线】化缘对话空闻 选择 给他水囊 赞同…

逸剑风云诀-传功弟子篇
type: item
date: 2025-08-20T17:45:00+08:00
description: 传功弟子篇【蔓阴林】左侧双生荼蘼触发剧情【莲花掌秘籍】回复玉伯，前往天鸣村。【天鸣村】【主线】筹备寿礼对话村长。【支线】丐帮之法对话刘玄。右下前往紫竹林。【紫竹林】【支线】玉容皓皓竹林右下侧拿到凤冠霞披。【支线】丐帮之法左上山坡 触发剧情。【主线】筹备寿礼刷完10个玄火力士回复 村长【支线】丐帮之法对话刘玄。前往南渝村【南渝村】【支线】玉容皓皓回复玉伯。荀杳杳好感+20（当前30）查看未署名的信。对话玉伯。前往名剑山庄。【名剑山庄】【支线】净衣派对话[欧阳献公]。【存档24】【支线】绝响难求前往莫邪阁 选择 找到琴谱，再来探望欧阳雪。前往姑苏客栈对话[掌柜]。姑苏城东找姑[苏小贩]。前往素节林【素节林】黑蛇王旁边宝箱，瀑布右边密道宝箱【巨木丹】【支线】绝响难求前往右下瀑布【龙泣剑法秘籍】欧阳雪好感+20（80）前往谭城【谭城】斗笠客战斗胜利获得【缠丝擒拿手秘籍】【支线】丐帮之法回复龚进。回复左江龙。【支线】净衣派回复乌天瘤【二转洗髓丹】【支线】拨云见日对话李元兴。前往谭城客栈。前往青萝山。【青萝山】【支线】拨云见日山顶遇到李元兴。对话荀杳杳把信给她荀杳杳好感+10（当前40）对话李元兴 选择 做出决定。回到丐帮【丐帮】【支线】丐帮大战对话[李元兴] 选择 做好准备。战斗后获得【神龙掌法秘籍】、【五罗青烟秘籍】、【擒龙功秘籍】传送到天鸣村。【天鸣村】【支线】丐帮大战先往下走找[荀杳杳][荀杳杳]好感+10（50）对话 [燕未还] 选择 已做好准备，击败黑白无常获得【丧哭棒】* 2[李元兴]好感+10（20）[荀杳杳]好感+0（50）[燕未还]好感+5（30）回丐帮对话[李元兴]【睡梦罗汉棍秘籍】，【青玉令（李元兴专属）】[李元兴]好感+10（当前30）送礼[李元兴]好感度（>=80）邀请[李元兴]切磋[李元兴]【一转气血丹】出谭城【三转洗髓丹】，【骸骨钉秘籍】、【腐尸毒秘籍】前往幽云泽渡口。

逸剑风云诀-精英弟子篇
type: item
date: 2025-08-20T15:03:00+08:00
description: 精英弟子篇【武当】【主线】武当大比找[清虚]获得【流云剑法秘籍】对话[元启]。回弟子房休息。武当大比获胜后【三转气血丹】、【三转洗髓丹】习得【太极神功】【主线】祭拜故人[元鸣]、[莫弃]、[莫问]加入队伍。切磋[元鸣]【一转洗髓丹】请教[莫问]【真武剑气】现在开始先不做主线，前往天剑宗。【天剑宗】切磋[肖剑声]【剑心诀秘籍】、【乙木丹】前往蔓阴林。【蔓阴林】【支线】飞蝎使中路往下直走触发[褚无救]剧情战斗。第一场优先击杀[褚无救]。【三转洗髓丹】、【辛金丸】第二场还是先解决[褚无救]。【瘟疱掌秘籍】打完返回大地图。[娜乌]好感+20（20）自动传送到北山村。【北山村】对话[顾思归] 选择 学习。【白鹤归】[顾思归]好感+20（20）前往少林寺。【少林寺】对话[涤罪僧]，离开少林。【存档27】【支线】韶华轻掷韶华轻掷分支：救[孔亮]：[孔亮]入队成就，请教【天罡刀法】。不救[孔亮]：等到支线甘泉苦水完成后去神鹰门可以获得【漫天花雨秘籍】救不救不影响后续主线，漫天花雨可以继承。对话[涤罪僧]选择 帮助孔亮，战斗后获得 【血河神鉴秘籍】、【神鹰指法秘籍】、【黄龙刀法秘籍】[涤罪僧]好感+10（10）若不帮助[孔亮]则[冷鹰]好感+10前往谭城。【谭城】切磋[张判龙]【锐金丹】客栈切磋[哑头陀]【参茸养身汤菜谱】【支线】酒鬼乞丐对话[小狗儿]选择 帮助对话[龚进] 【莲花棒法秘籍】晋庸右上角邀请[孔亮]请教[孔亮] 【天罡刀法】前往丐帮。【丐帮】切磋[侯九]【佛跳墙菜谱】前往雷家村。【雷家村】切磋[冷无情]【二转气血丹】【支线】雷家村对话[冷无情]选择 前来相助 略有耳闻。询问所有村民。回报[冷无情]选择 准备好了。【连鼓山】走至中央触发剧情，打完回雷家村找[冷无情]。【雷家村】两场战斗，第一场较难，先杀[覆海蛟]，再打[叶飞] 【天龙斩秘籍】。【桃花林】【支线】反攻前奏对话[冷无情]选择 休整充沛。前往雷家村调查，再回桃花林对话。前往双河村铲除暗探[简希]、[郝任]、[陆虢]。前往连鼓山。【连鼓山】支援[仇无道]、[斩无刑]、[冷无情]【乌角巾精良图纸】【乌角巾】是目前最好的装备前往山顶，战斗后获得【玄鸟剑势秘籍】，【极品混元丹】、【极品烈阳丹】【三转洗髓丹】，返回雷家村。前往莲心湖。【莲心湖】【支线】娄赴召的归宿走至湖中心，战斗后获得【刀山火海势秘籍】、【玄火掌法秘籍】邀请[叶飞]切磋[叶飞]【雁行功秘籍】前往武当。【武当】请教[道玄]【炼丹】，【四象无极功】切磋[道玄]【极品血灵丹】、【九炼熊蛇丸】、【三转洗髓丹】、【三转气血丹】、【极品纯阳丹丹方】切磋[道通]【癸水丹】切磋[道微]【二转洗髓丹】、【没药】送礼[道微]好感度(>=80)后续拿【归元刀法秘籍】前往姑苏。【姑苏城】提升司马铃练度：刀法：恶鬼刀法 | 狂风刀法 | 刀山火海势 | 霹雳霸刀轻功：雁行功 | 轻身术 | 武当轻功心法：叶家心法 | 吐纳法 | 瑜伽经 | 四关十二元经经脉：阴点出神藏>阳点满>任点满【支线】姑苏曼舞送礼[司马铃]好感度(>=80)前往客栈。二连战后获得【太华十二剑】、【追命三仙剑秘籍】[司马铃] 力道+15 根骨+5 身法+10 内力+5[司马铃]习得【白帝剑器·灵】请教[司马铃]【白帝剑器·灵】前往梧桐村。【梧桐村】对话[村长] 询问小彤去向祭拜[江吟风]。【主线】姑苏雨夜前往姑苏城。【姑苏城】前往渡口触发剧情，再前往客栈。雨夜渡口右侧宝箱，武馆宝箱，侯九宝箱。过桥 战斗胜利获得【恶鬼心法秘籍】传送至名剑山庄。【名剑山庄】早晨【主线】品剑大会客房出来右侧假山宝箱，莫邪阁宝箱，东边假山宝箱，[欧阳小武]下方宝箱【流水丹】名剑山庄钓点【鳜鱼 鲤鱼 海参 鲍鱼 冰鲤】请教[欧阳剑英]【锻造】，【飘雪穿云剑】、【鲸息功】、【混元神剑功】切磋[欧阳剑英]【天羽奇剑秘籍】对话 [莫问]、[莫弃]、[元鸣]。三场战斗获胜【武岳枪法秘籍】、【玄焰身法秘籍】傍晚客房出来右侧假山宝箱【名剑心法秘籍】，剑心亭右侧宝箱。前往剑心亭 选择 有点压抑欧阳雪好感+10（10）询问琴曲【五灵心经·残】提升至6级夜晚欧阳雪入队，他的武器【素弦】卸下来开一下图鉴莫邪阁前方石桌宝箱【中品纯阳丹】，客房出来右侧假山宝箱【名剑剑法秘籍】元鸣左侧宝箱前往渡口划船至姑苏。【姑苏城】[花灯小贩]背后宝箱【心火丹】、【上品纯阳丹丹方】说书的右侧宝箱[穷书生]右上栏杆内角隐藏宝箱【辛金丸】对话[花灯小贩] 选择 【华 灯 映 雪】[欧阳雪]好感+10（20）【姑苏灯会】百味馄饨对话[萧大爷]吃馄饨 选择安慰【萧家食录】（不要用掉后续有任务）、【二十四气馄饨】【姑苏灯会】街头卖艺对话[江飞鱼]选择 江飞鱼。【姑苏灯会】茶摊说书可以都听一遍（真假参半）。【姑苏灯会】霓裳羽衣最后对话[穷书生]…

Lua与C++交互之Luna
type: item
date: 2020-10-24T22:05:00+08:00
description: Luna作为一套比较出名的Lua与C++绑定的框架，以其简洁的代码且贴近面向对象的书写方式，与游戏脚本的需求重合性较高，因此被广泛应用在游戏行业中。然而比较有趣的是，虽然该框架用途广泛，但是很少人知道这套框架的作者，甚至不知道框架的名字。2003年，Lenny Palozzi在Lua社区中发表了名为：《A template class for binding C++ to Lua》的文章。文章中，作者介绍了一种C++与Lua绑定的新框架，并将这个框架命名为Luna。文中提出了几个思路：将构造函数以className为key存到全局表中，当用户调用className()时，也就会显式调用C++的构造函数在构造函数中，为用户生成一个userdata，将类对象指针存入其中，同时将类的函数指针以函数名为key也存入其中，返回该userdata给用户在lua中使用，作为Lua曾的类对象。当用户以面向对象的方式，对该类对象执行.操作时，会触发C++中的函数，C++会从table取出类指针以及函数指针，以正确的执行类成员函数。这些也就是Luna的核心思维，后来很多人尝试对Luna框架进行了优化（包括之后会提到的Lunar），但是最终都没有完全脱离这套模式。《A template class for binding C++ to Lua》一文虽然已经写得足够详细，但是涉及的Lua版本过低，且其代码泛化不足。Lua5作为用途最广泛的版本，大部分人自然更需要以Lua5版本的Luna。5年后的2008年，《Simpler Cpp Binding》这篇文章应运而生。算法本文主要以《Simpler Cpp Binding》作为分析的参考。定义定义类名类名之后需要注册到全局表中，让Lua使用者能调用到构造函数static const char className[]; const char Account::className[] = "Account";定义需要导出的函数为了安全性与实用性，并不需要把所有C++函数都导出给Lua使用者使用#define method(class, name) {#name, &class::name} Luna<Account>::RegType Account::methods[] = { method(Account, deposit), method(Account, withdraw), method(Account, balance), {0,0} };RegType是一个结构体数组，以{函数名，函数指针}的形式保存所有需要导出的函数。注册面向对象的类，实际上是一组数据（变量）和定义在这种数据上的操作方法（函数）组成的。Luna也是参照这一理念涉及的，它将函数放在全局对象上，而数据放在一个table中交给用户使用。注册Lua类对象（数据）luaL_newmetatable(L, T::className); lua_pushliteral(L, "__metatable"); lua_pushvalue(L, methods); lua_settable(L, metatable); // hide metatable from Lua getmetatable() lua_pushliteral(L, "__index"); lua_pushvalue(L, methods); lua_settable(L, metatable); lua_pushliteral(L, "__tostring"); lua_pushcfunction(L, tostring_T); lua_settable(L, metatable); lua_pushliteral(L, "__gc"); lua_pushcfunction(L, gc_T); lua_settable(L, metatable);metatable重定向了table中一些重要的元操作，将会作为Lua类对象（实际上是一个userdata）的主元表，其具体结构如下：$\text{metatable} \begin{cases} \text{__metatable = method} \\ \text{__index = method} \\ \text{__tostring = tostring_T} \\ \text{__gc = gc_T} \end{cases}$注册全局对象（函数）lua_newtable(L); int methods = lua_gettop(L); lua_pushstring(L, T::className); lua_pushvalue(L, methods); lua_settable(L, LUA_GLOBALSIND…

目标文件概述
type: item
date: 2020-10-24T00:11:00+08:00
description: 目标文件代码文件经过编译器编译、链接器链接后，将会生成目标文件。与认知不同的是，即使是用于执行的可执行目标文件，都并非单纯由指令序列组成。所有的目标必须包含一系列供操作系统加载器使用的结构信息，这个结构信息由操作系统进行约定，因此不同操作系统的结构信息各异。比较主流的目标文件格式如下表：操作系统文件格式MAGICLinuxELFELFWindowsPEMZMacMach-O0xfeedface/0xfeedfacfELFExecutable and linking formatELF是Linux系统下一种常见的目标文件，有三种主要类型可执行文件用于提供程序的进程映像，加载到内存执行可重定位文件用于与其他目标文件链接，一起创建可执行文件或共享目标文件共享目标文件用于与其他可重定位目标文件和共享文件链接成其他目标文件，或与可执行文件组合创建进程映像。在看文件结构的详细定义之前，我们先动手编译一个简单的目标文件，亲自察看其文件内容并配合结构定义能更方便的理解。为了更直观的理解，程序显然越简单越好。比如下面这个就很不错：int main() {}gcc编译得到.out文件后，我们使用readelf来实际查看其文件内容gcc -march=i686 -fno-builtin -fno-PIC -Wall -ggdb -m32 -gstabs -nostdinc a.cpp readelf -a a.outELF Header在文件开头描述了整个文件的组织，结构如下struct elfhdr { uint magic; // must equal ELF_MAGIC uchar elf[12]; ushort type; ushort machine; uint version; uint entry; // 程序入口的虚拟地址 uint phoff; // program header 表的位置偏移 uint shoff; uint flags; ushort ehsize; ushort phentsize; ushort phnum; //program header表中的入口数目 ushort shentsize; ushort shnum; ushort shstrndx; };而在我们的目标文件中，ELF Header长这个样子ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: DYN (Shared object file) Machine: Intel 80386 Version: 0x1 Entry point address: 0x1070 Start of program headers: 52 (bytes into file) Start of section headers: 16020 (bytes into file) Flags: 0x0 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 12 Size of section headers: 40 (bytes) Number of section headers: 33 Section header string table index: 32可以发现，ELF Header实际上是该文件的大体信息，包括Magic，文件类型，入口地址等等。如果是可执行文件，紧接着Header将会是Program Header数组，结构如下struct proghdr { uint type; // 段类型 uint offset; // 段相对文件头的偏移值 uint va; // 段的第一个字节将被放到内存中的虚拟地址 uint pa; uint filesz; uint memsz; // 段在内存映像中占用的字节数 uint flags; uint align; };每个程序结构描述了一个段或者系统准备执行所必需的其它信息。每个段包含一个或者多个 “节区”（section） ，也就是“段内容”（Segment Contents）我们的目标文件Program Headers如下Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align PH…

x86调用约定
type: item
date: 2020-10-22T23:39:00+08:00
description: 调用约定调用约定(Calling Conventions)指的是为了函数调用能顺利进行，被调用者与调用者达成的一系列包括参数传递与名字修饰在内的约定。总的来说有下面几种：参数传递约定极微参数或复杂参数独立部分的分配顺序参数是如何被传递的（放置在堆栈上，或是寄存器中，亦或两者混合）被调用者应保存调用者的哪个寄存器调用函数时如何为任务准备堆栈，以及任务完成如何恢复名字修饰约定x86架构微处理器有多种调用约定(Calling Conventions)，不同语言，甚至不同的编译器都有不同的编译选项以便开发者选择。出于方便，本文仅从GCC的角度进行分析。参数传递约定为了能更直观的观察各个不同调用约定产生的汇编代码的区别，需要关闭编译优化，同时也不需要去搜索标准系统目录，我们选择如下编译选项：gcc -march=i686 -fno-builtin -fno-PIC -Wall -ggdb -m32 -gstabs -nostdinccdelcallC声明调用cdel(C declaration)即C声明，是C语言实际上的默认标准。主要约定如下：函数实参从右至左依次压栈函数结果保存在EAX中（16位及8位程序分别为AX， AL）调用结束后，栈数据不会清理，调用者需按自己需要进行处理。所编译的代码:int __attribute__((__cdelcall__)) cdelfunc(int x, int y, int z) { return x + y + z; } int main() { cdelfunc(1, 2, 3); }经过objdump -S可以比较得到如下的汇编代码（无关代码已经忽略）000011ad <_Z8cdelfunciii>: int __attribute__((__cdelcall__)) cdelfunc(int x, int y, int z) { return x + y + z; } 11b1: 55 push %ebp 11b2: 89 e5 mov %esp,%ebp 11b4: 8b 55 08 mov 0x8(%ebp),%edx 11b7: 8b 45 0c mov 0xc(%ebp),%eax 11ba: 01 c2 add %eax,%edx 11bc: 8b 45 10 mov 0x10(%ebp),%eax 11bf: 01 d0 add %edx,%eax 11c1: 5d pop %ebp 11c2: c3 ret 000011c3 : 11c7: 55 push %ebp 11c8: 89 e5 mov %esp,%ebp 11ca: 83 ec 0c sub $0xc,%esp 11cd: c7 44 24 08 03 00 00 movl $0x3,0x8(%esp) 11d5: c7 44 24 04 02 00 00 movl $0x2,0x4(%esp) 11dd: c7 04 24 01 00 00 00 movl $0x1,(%esp) 11e4: e8 c4 ff ff ff call 11ad <_Z8cdelfunciii> 11e9: b8 00 00 00 00 mov $0x0,%eax该调用过程分为以下三步：先看调用者main函数，由于3个int长度为12字节，调用者在栈上开辟了12字节的空间（ESP - 0xC），然后依次存入3, 2, 1。接着调用_Z7stdfunciii。被调用者_Z7stdfunciii将调用者的EBP压栈，然后从栈上0x8, 0xC, 0x10分别取出参数，运算后存入EAX。第三步为隐藏操作，由于函数使用指令ret返回，CPU不会对栈进行任何处理，栈上依然保留着之前的参数，此时应由调用者进行手动处理。stdcall标准调用函数实参从右至左依次压栈函数结果保存在EAX中（16位及8位程序分别为AX， AL）调用结束后，栈数据将会由CPU进行清理。类似的，我们使用__stdcall__替换__cdelcall__，将会得到如下的汇编代码：000011ad <_Z7stdfunciii>: int __attribute__((__stdcall__)) stdfunc(int x, int y, int z) { return x + y + z; } 11ad: f3 0f 1e fb endbr32 11b1: 55 push %ebp 11b2: 89 e5 mov %esp,%ebp 11b4: 8b 55 08 mov 0x8(%ebp),%edx 11b7: 8b 45 0c mov 0xc(%ebp),%eax 11ba: 01 c2 add %eax,%edx 11bc: 8b 45 10 mov 0x10(%e…

Nintend Switch开发之一 大气层
type: item
date: 2019-04-26T01:03:00+08:00
description: Atmosphère是Nintendo Switch一款很有意思的定制固件，法语意为大气层。由Exosphère（散逸层）、Stratosphère（平流层）等等几个不同的组件组成，每个组件对应着大气层的组成部分，负责执行Nintendo Switch不同的系统功能。Atmosphère的组件包括：Fusée 一个自定义引导程序。Exosphère（散逸层） 功能齐全的定制安全监视器。Stratosphère（平流层） 一套定制系统模块。Thermosphère（热层） 一种基于管理程序的emuNAND实现。该组件尚未实装。Troposphère（对流层） Horizon OS的应用程序级补丁。该组件尚未实装。FuseeFusée（不要与FuséeGelée混淆）是启动Atmosphère并取代Nintendo的Package1loader/bootloader所需的自定义引导程序。它目前使用Tegra X1 RCM漏洞来运行。Fusée分为两个独立的部分：fusée-primary和fusée-secondary。这是由于RCM漏洞限制了发送到设备上的payload的文件大小。截至2018年6月，新发售的Switch系统使用了ipatched启动芯片而让Fusée（或任何需要FuséeGelée漏洞的有效载荷）无法工作。所有ipatched系统共享HAC-S-JXE-C3产品代码。虽然Fusée无法在这些ipatched设备上运行，但他们仍然使用固件4.1.0，这很容易受到即将推出的DéjaVu软件攻击。但请注意，如果您在其中任何一个ipatched设备上更新了高于4.1.0的固件，那么安装Atmosphère或运行任何自制程序的可能性几乎不存在。此外，据悉名为“Mariko”的Switch的硬件版本正在开发中。虽然目前仍未在商店中看到过这样的单元，但预计任天堂会默默地推出它们。Mariko单元很可能会修复目前用于访问CFW的FuséeGelée的启动芯片漏洞，并可能拥有自己的专有引导程序。Fusse-PrimaryFusée-primary是从外部设备发送到交换机的payload文件（fusee-primary.bin）。一旦发送，fusée-primary会在Switch的SD卡加载fusée-secondary之前进行初步准备。可以通过Switch SD卡上的BCT.ini文件配置Fusée-primary。Fusse-SecondaryFusée-secondary是一个payload文件，保留在Switch的SD卡（fusee-secondary.bin）的根目录下。它在fusée-primary完成后自动启动，并负责为将来运行的环境（如自制菜单）准备Switch的硬件。 Fusée-secondary还负责验证和启动Exosphère。Fusée-secondary包含各种.kip模块。这些模块可以修改操作系统中的现有功能，也可以添加新功能。Fusée还能够链接其他payload，例如Linux。ExosphèreExosphère是Arm的TrustZone（TZ）的重新实现，也称为安全监视器（Secure_Monitor.bin）。它具有Switch处理器上可用的最高权限模式，并且可以访问控制台上的所有内容。Exosphère可能会在Jamais Vu和DéjaVu即将推出的Switch软件漏洞中扮演重要角色，它允许用户在Fusée-Gélee补丁（ipatched）Switch控制台上启动Atmosphère，并且还可以直接启动来自Switch本身的CFW，而不使用任何类型的外部设备（例如计算机或RCM夹具），只要它们位于足够低的系统固件上。TrustZone/Secure MonitorTrustZone负责Switch上的所有加密操作。它运行方式背后的想法是所有密钥都保留在TrustZone中，而用户空间只能获得它们的“句柄”。这将确保keydata永远不会泄漏并保持安全。它还有一些更多的职责，例如电源管理，提供随机数源，以及提供对存储在熔丝中的各种信息的访问。扩展Exosphère目前只包含一个扩展，一个SMC允许自制软件查找当前运行的Atmosphère版本，以便找出哪些拓展是允许使用的。StratosphèreStratosphère允许自定义Horizon OS和Switch内核。它包括扩展内核并提供新功能的自定义系统模块。它还包括重新实现的加载器系统模块来Hook重要的系统操作。Stratosphère包含的系统模块包括：boot 该模块启动系统并初始化硬件。creport 重新实现任天堂的崩溃报告系统。将所有错误日志转储到SD卡，而不是将它们保存到NAND并将它们发送到Nintendo。fs…

[译]即时辐射度算法
type: item
date: 2018-06-16T11:03:00+08:00
description: 我们提供了从辐射度方程进行即时渲染的基本步骤。直接在纹理化场景描述上操作，非常高效且简单的算法可以生成照片级真实图像，而无需任何有限元核心或对基础积分方程进行离散化处理。通过利用图形硬件，利用用于解决全局光照问题的准随机游走确定性技术以及抖动低差异采样的新方法获得仅需数秒钟的渲染速率。分类和学科描述：I.3.3 [计算机图形学]：图片/图像生成 - 抗锯齿| 位图和帧缓冲操作| 显示算法| 查看算法;I.3.7 [计算机图形学]：三维图形和现实 - 动画|颜色，阴影，阴影和纹理|光能传递关键词：辐射方程，辐射率，阴影，蒙特卡罗积分，准蒙特卡罗积分，准随机游走，抖动低差异采样，硬件，累积缓冲区，实时渲染算法，照片写实。1 介绍提供一个写实场景描述，这个场景由辐射度积分方程[Kaj86]渲染而产生写实图像。在漫反射的前提下，得到弗雷德霍姆积分方程近似解的最常用方法是辐射度算法。 在经典算法[CW93]中，辐射度积分方程的核心是通过投影到某些有限基上，得到为场景元素数量的二次方的形状因子矩阵。 对于它的稀疏表示，已经引入了具有阶梯型基函数的阶梯型方法。 尽管如此，这些Galerkin算法需要存储积分方程的内核和离散解。除了用于高度复杂精确网格生成的阴影表示[LTG92]外，这样的投影还引入了离散化误差。在蒙特卡罗仿真领域中，不需要内核离散化的算法也是可行的，使用仅需要把解投影到有限基上的随机积分方案。与随机渐进法相似，在[Kerl96b]中，渐进性粒子仿真方案基于导入低差异采样。这个渐进性方案在略微优越的速率下平滑收敛，而且与随机算法相比没有变化。在双向路径追踪算法[LW93, VG94]中，尽管辐射度方程解的离散情况已经被避免，但其渲染时间远没有实时性。另外一个方面，图形学硬件能够实时通过扩展光源[HA 90, Hei 91, SKvW 92]照亮和遮蔽贴图场景。在我们新方法中，我们将光线确定性粒子仿真（即准随机游走原理）的优点与可用硬件功能结合，始终由辐射度方程进行渲染，既不使用核心也不使用积分方程解的中间解的投影，导致过程非常快速，健壮和直接。在介绍之后，论文的第二节中，我们简要的阐述全局光照问题的数学模型。第三节解释新的渲染过程及的准蒙特卡罗积分、准随机游走原理的基本技术。第四节，我们支持基本算法的一些扩展，包括基于抖动低差异采样的抗锯齿，镜面反射以及实时应用程序的改进，第五节讨论了该算法。最后一节得出结论，并指出未来研究的方向。2 全局光照我们的眼睛能感受到来自每单位角每单位面积功率的辐射。在真空中，辐射度$L$满足辐射方程[Kaj86]：$$L(y,\vec{w}_{r})=L_{e}(y,\vec{w}_{r})+\int_{\Omega}f_{r}(\vec{w}_{i},y, \vec{w}_{r})L(h(y,\vec{w}_{i}),-\vec{w}_{i})cos\theta_{i}dw_{i}\qquad$$其中$\Omega$是单位半球上垂直于$y$点表面的所有方向$\vec{w}=(\Omega,\phi)$的集合。$S$是作为边界表示而建模的场景表面。$h$函数返回当从$y$点出发向$\vec{\omega}_{i}$方向发射一条射线击中的第一个点。术语$cos\theta_{i}$表示将入射光线垂直投射到表面，$\theta_{i}$是$y$表面法线与入射光线$\vec{\omega}_{i}$之间的夹角。点$y$朝$\vec{w}_{r}$的辐射度$L$就是源辐射度$L_{e}$与反射辐射度之和。我们可以使用符号简写为：$$ L=L_{e}+T_{f_{r}}L $$双向反射分布函数$f_{r}$考虑了颜色和光泽度等表面特性。在一般设置中，这个函数取决于辐射的入射方向$\vec{w_{i}}$和反射方向$\vec{w_{r}}$以及基准点$y$。在辐射度设置中，$f_{r}=f_{d}(y):=\frac{\rho_{d}(y)}{\pi}$仅限于漫反射，然后辐射也会变得各向同性：$$L(y)=L_{\omega}(y)+\frac{\rho_{d}(y)}{\pi}\int_{\Omega}L(h(y,\vec{\omega}_{i})) cos\theta_{i}d\omega_{i}\qquad $$$\rho_{d}(y)$是漫反射贴图的反射性。给定一个四元组，全局光照问题由以下计算函数得到：$$<L,\Psi>:=\int_{S}\int_{\Omega}L(y,\vec{\omega})\Psi(y,\vec{\omega})cos\theta d\omega dy$$与辐射度设置相关，也与全辐射等式相关。检测器功能有多种选择，例如，在经典或分层辐射度方法[CW93]中使用的有限向量空…

次时代游戏制作的CG技术发展趋势
type: item
date: 2018-06-15T20:16:00+08:00
description: 1 游戏CG技术的挑战写实的CG影像表现对于增强模拟现实世界的游戏环境中的沉浸感是必不可少的。特别是在高品质游戏制作中，改进图形表现使之成为成为大吸引力点的机会很多，如何做出让玩家第一眼看到就惊讶无比的影像已经成为了一个重要的技术课题。图1 Agni's Philosophy例如，SQUARE ENIX在2012年举办的E3这个世界上最大的游戏展上，公开的《Agni's Philosophy》实时CG技术演示。如图1的截图所示，实时计算影像已经接近电影质量，各公司和各研究机构正在进行各种研究和开发，以进一步提高性能。在游戏中开发CG技术的困难在于，它必须在每个游戏场景中实现健壮的计算，同时确保有限的计算资源之间的响应。与电影等影视产品不同的是，在游戏中，不仅仅是角色操作和相机操作，包括故事的速度和顺序之类的掌控权通常都留在玩家手中。出于这个原因，无论玩家视角如何，无论玩家进行了什么操作，都必须要能立即显示高品质的图像。此外，游戏制作所需的金钱和时间成本随着每一代硬件产品而呈指数级增长，尤其是处理60fps全高清视频的高品质游戏时， 为了避免在屏幕上出现锯齿，必须要生成高精度的多边形模型，纹理，动画等，这是造成开发周期延长和成本增加的原因之一。减少数据制作所需成本是各公司的共同课题， 给予依赖于设计经验的传统工作流程以技术支持，或是能够全自动生成一些数据的系统也已经被开发出来。本文介绍了几种应用于游戏的CG技术。首先，我们描述被称为实时全局光照（Global Illumination）的渲染技术。接下来，我将从物理模拟开始到统计分析方法的引入为止，总结CG动画技术的最新发展趋势。最后，我们介绍一种称为程序技术（Procedural Technologies），可动态生成游戏实时处理的数据的最新技术，并总结今后的展望。2 写实渲染的挑战2.1 图形硬件的应用在当前的游戏图像表示中，通过利用称为GPU（图形处理单元）专用于3D图形处理的并行计算单元已经开发了用于实时可编程地渲染CG场景的技术。在传统的CG系统 ，CG是利用硬件固有机能计算出来的，但是在GPU中，开发人员可以自由地编程控制绘图功能。尤其3D对象的质感表现依靠着GPU的登场得到了飞速发展。例如，为了再现人体皮肤的纹理，也在使用诸如在皮肤内模拟漫反射光的技术。2.2 基于即时辐射度技术（Instant Radiosity）的实时全局光照在此之前的技术中，确定对象颜色的时候，只处理从光源直接入射的光线。即不考虑来自其它物体的反射光和物体内部的透射光的影响。而用于模拟这些对象之间的光的相互反射和传播的技术被称为全局光照（GI）。为了实现精确的GI，需要模拟光传播的各种路径，其计算量通常很大。例如，以追踪方法和光子映射方法为代表的典型算法，为了得到物理上精确的结果，渲染一张静态画需要几秒到几个小时的计算时间。因此，GI限于应用于诸如电影等视频作品。然而，在近年来的高品质游戏中，GI和类似技术的引入变得不可或缺。出于这个原因，适合于游戏机的有限计算资源，特别是GPU计算体系结构的近似算法的正在持续不断的开发。图3 使用立即辐射度的实时全局照明在这种情况下，即时辐射度技术作为一种可以在游戏中得到实际应用的技术而受到关注。在即时辐射度技术中，如图2所示，在场景中放置一个接近物体表面反射间接光的颜色和强度的虚拟点光源，并且在渲染计算时，除了实际光源以外，还需要来自所有虚拟点光源的直接入射光进行对象的颜色计算。例如，通过在红色物体附近放置发射红光的虚拟点光源，近似模拟来自对象的反射光。一旦确定了虚拟点光源的亮度，颜色和排列，剩下的渲染过程就可以在一般的GPU计算管线上执行，因此它与现有的硬件兼容。而且，通过调整虚拟点光源的数量，可以容易地权衡计算速度和质量进行优化。图3显示了基于立即辐射度技术在GPU中实装的实时GI渲染结果，这表明即使使用现有的硬件配置，也可以获得足够高质量的影像。如上所述，即时辐射度技术具有优良的特性，因此预计可应用于次时代游戏。3 动画技术的发展伴随着纹理表现对GPU的使用和GI技术的发展，背景影像和场景纹理变得难以与现实区分。但是，如果角色像机器人或玩偶一样移动，整个影像的质量反而会使游戏的世界观崩塌。因此近年来，游戏场景的构成对象，特别是模仿人类模型角色的动画控制技术成了瞩目的焦点。3.1 使用数据交换和转换的经典技术在游戏中的传统动画技术中，通过在短时间切换数据进行回放，生成对应玩家操作的一系列动画。在许多高品质游戏中，会通过动作捕捉设备进行三维测量，以创建高度逼真的动画数据。然而，在简单地再现记录数据的技术中，可以在游戏中呈现的动画变化是有限的。在游戏中，多次重复显示相同的动作，重复播放相同的动画，会降低玩家的兴致。此外，影像要展示足够的说服力，显示与地形和…

[译]QSplat:大型网格的多分辨率点渲染系统
type: item
date: 2018-06-11T07:08:00+08:00
description: 3D扫描技术的进步使数亿多边形网格的实际创建得以实现。用于显示、简化渐进式网格传输的传统算法对于这种尺寸的数据集而言是不切实际的。我们定义了一个用于表示和逐步显示这些网格的系统，这些网格将基于边界球体的多分辨率层次结构与基于点的渲染系统结合在一起。专门使用一个数据结构用于视锥截取，背面剔除，细节层次选择和渲染。这种表示方法非常紧凑，可以快速计算，适用于大型数据集。我们是为了用于大型3D数字化项目而编写的，它可以快速启动，保持用户可设置的交互式帧速率，而不管对象的复杂程度或相机位置如何，在运动过程中产生合理的图像质量，并在空闲时逐渐细化为高的最终图像质量。我们已经在包含数亿样本的扫描模型上演示了该系统。分类和学科描述：I.3.3 [计算机图形]：图片/图像生成 - 显示算法;I.3.5 [计算机图形]：计算几何和对象建模 - 曲线，曲面，实体和对象表示;I.3.6 [计算机图形]：方法和技术 - 图形数据结构和数据类型。关键词：渲染系统，空间数据结构，细节层次算法，压缩算法1 简介计算机图形学最近的一个重大趋势是在渲染过程中向着使用实时对象采样表现方式转变。这种趋势的一个例子是越来越多地使用三维扫描系统，它可以生成物理对象三维采样模型。然而，3D扫描仪的一个问题是如何处理他们生产的大量数据。在过去几年中，3D扫描系统的硬件和软件组件的改进已经将实际可获得的扫描网格大小增加到数亿个样本。当前工作站不能实时显示这种尺寸的网格，传统网格简化和逐步显示算法的运行时间和空间需求使得这些方法对于包含超过几百万个样本的扫描网格来说不切实际。而且，许多这样的技术着重于优化单个边和顶点的布局，每个顶点将会消耗大量精力。然而，扫描的数据通常具有大量的顶点，并且由于噪声的原因，它们的位置往往不够精确。这揭示存在一种替代方法，这种方法将个别点视为相对不重要，这样对原始网格而言实际上降低了消耗。最近采用这种范式的研究包括Krishnamurthy和Levoy的样条拟合系统[Krishnamurthy 96]，Curless和Levoy[的距离图像合并系统Curless 96]，以及基于八叉树粒子的Yemez和Schmitt渲染系统[Yemez 99]。这些算法不会精确处理范围数据，实际上也不会保留原始网格的任何样本的3D位置。遵循这种低基本成本算法的趋势，我们开发了一种用于大型网格交互式显示的新算法。这个被称为QSplat的算法是在一个大型3D数字化项目[Levoy 00]的过程中设计的。由于它使用基于遍历边界球体层次结构的简单渲染算法，因此适合浏览此项目中生成的模型，该模型包含1亿至10亿个样本。此外，QSplat不保持输入网格的连通性（在扫描固有数据时仅能用于解决深度不连续性而没有其他意义），而是依赖于基于点的表示和图示渲染(splat rendering)。因此，我们的系统比类似的基于多边形的系统具有更低的预处理和渲染成本。在本文中，我们将介绍QSplat数据结构和渲染算法，并讨论一些权衡和设计决策，以使其适用于大型网格。我们描述系统的渲染性能，并讨论它的预处理成本。最后，我们考虑它与以前用于显示大型网格的算法的关系，并描述用于渲染其他类型大型几何数据集的一些未来扩展。2 QSplat数据结构和算法QSplat使用层次结构的边界球体[Rubin 80，Arvo 89]进行可见性剔除，细节层次控制和渲染。树的每个节点都包含球体中心和半径，法线，普通锥体的宽度[Shirman 93]以及可选的颜色。可以从多边形，体素或点云中生成这样的边界球体层次结构，但对于我们的应用程序，我们只需要一种用于从三角形网格生成层次结构的算法。层次结构被进行预处理，然后写入磁盘。2.1 渲染算法一旦构建了层次结构，将使用以下算法进行显示：TraverseHierarchy(node) { if (node not visible) skip this branch of the tree else if (node is a leaf node) draw a splat else if (benefit of recursing further is too low) draw a splat else for each child in children(node) TraverseHierarchy(child) }我们现在详细研究这个基本算法的几个阶段。可见性剔除: 当我们递归边界球体层次时，我们剔除不可见的节点。通过测试每个球体相对视锥体的位面来进行视锥剔除。如果球体位于外部，则它和其子树将被丢弃并且不会被进一步处理。如果球体完全位于平截头体的内部，不会尝试对该节点的子节点进行进一步的视锥体剔除。我们还将在渲染过程中使用存储在每个节点的法线和法线锥来进行执行背面剔…