惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

人人都是产品经理
人人都是产品经理
MyScale Blog
MyScale Blog
Y
Y Combinator Blog
罗磊的独立博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
P
Proofpoint News Feed
Google DeepMind News
Google DeepMind News
V
Vulnerabilities – Threatpost
T
The Blog of Author Tim Ferriss
云风的 BLOG
云风的 BLOG
Recorded Future
Recorded Future
N
News and Events Feed by Topic
B
Blog RSS Feed
阮一峰的网络日志
阮一峰的网络日志
博客园_首页
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园 - 【当耐特】
N
Netflix TechBlog - Medium
博客园 - 叶小钗
B
Blog
Vercel News
Vercel News
T
Tenable Blog
T
The Exploit Database - CXSecurity.com
Spread Privacy
Spread Privacy
T
Threat Research - Cisco Blogs
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Last Week in AI
Last Week in AI
F
Fortinet All Blogs
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Microsoft Security Blog
Microsoft Security Blog
S
Securelist
Microsoft Azure Blog
Microsoft Azure Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Palo Alto Networks Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
D
DataBreaches.Net
Cyberwarzone
Cyberwarzone
Engineering at Meta
Engineering at Meta
Martin Fowler
Martin Fowler
G
GRAHAM CLULEY
Project Zero
Project Zero
Cisco Talos Blog
Cisco Talos Blog
A
Arctic Wolf
C
CERT Recently Published Vulnerability Notes
L
LangChain Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
C
Check Point Blog
A
About on SuperTechFans
W
WeLiveSecurity
The GitHub Blog
The GitHub Blog

机核

游戏性能旗舰最强之选,一加 Ace 6 至尊版国补到手价2999元起 6元钱自己更换电动车刹车线 《生化危机9:安魂曲》编剧Haris Orkin专访 摸金游戏?音乐游戏!暗区新赛季这把能弹的琴有何来历? 好评国产武侠SRPG《息风谷战略》免费DLC现已推出 | 机核 GCORES 碎片 《生化危机:安魂曲》将于5月实装首个免费更新内容 | 机核 GCORES 新锐东方游戏,谱写世界新章! 沉浸式恋爱视觉小说游戏《心象演算》免费试玩版现已正式上线 | 机核 GCORES 互动影游《代号三国:龙起》上线!穿越三国与曹操并肩、与佳人同行、与权谋博弈! 《老头收集梦想生活》,游戏酒桌会6,录音笔VOL.689 | 机核 GCORES 破界·共生——《白日梦:无限世界》五大核心游戏特点解析 价格已到史低,锐龙5 9600X/锐龙7 9700X正适合抄底 时间循环之旅即刻启程!《归环》一周目测试今日开启 热门在线韩游变魂游,洛奇衍生作能否打破“花瓶”魔咒? LG UltraGear evo 全新高端显示器系列:当“5K”遇见“AI”,不止强大,更懂热爱 反套路三国互动影游《代号三国:龙起》今日上线! 愿望单登记人数突破10万!备受瞩目的“女儿养成游戏” 《梦幻魔法公主》今日于Steam平台上线!限时八折优惠中 《黑神话:悟空》全球音乐会2026巡演将于4月29日12时开票 | 机核 GCORES “Snowguelike”生存肉鸽挖矿新作《蛙穿雪境》公布发售日期,5月7日正式上线 | 机核 GCORES 重塑移动办公、AI创作新境!全新华硕灵耀Air系列、ProArt 骁龙版震撼首发,创芯未来 均分88:《Saros》媒体评分汇总 | 机核 GCORES 上海烛龙公布合作遗迹探险游戏《吉时已到》首支预告片 | 机核 GCORES 首个独立游戏《萝薇日记》已上线Steam! 烛龙新IP《吉时已到》首曝,打造国内首款中式合作遗迹探险游戏 喜加一:《暗黑破坏神Ⅳ》国服现已开启限时免费领取本体活动 | 机核 GCORES 新版《生化危机》电影定于9月18日上映,官方网站现已上线 | 机核 GCORES 《冲就完事模拟器2》“星球大战”联动DLC正式宣布 | 机核 GCORES SteamController将于5月4日发售,售价99美元 | 机核 GCORES 事已至此,内存这么用也算省钱了,“2+1”非对称双通道应用实测 505游戏母公司现已收购《明末:渊虚之羽》IP | 机核 GCORES 基石 手动杂谈12|格斗游戏也能讲好故事 | 机核 GCORES I Love You Mr Snowball 我的向日葵小姐 会比GTA6先发售吗?最硬核的生存游戏《DAYZ》要推新DLC了 周记02:在2026遇到新怪谈 什么硬件,能让游戏Loading界面快速消失? | 机核 GCORES GadioSpec《百年风云世界杯》免费试听集 | 机核 GCORES 百年风云世界杯Vol.1丨足球崛起 | 机核 GCORES 100年前,一群人提前替我们经历了AI恐惧 | 机核 GCORES 《呼啸山庄》2026 ——一辆当代艺术的大卡车冲撞了我的大脑 手游《天穗之咲稻姬:日之香巡灵传》宣布将于7月27日停服 | 机核 GCORES 集结梦之队,征战世界杯,《最佳球会ONLINE》上线Steam 山水绝景随心拼 休闲建造游戏《千里山河录》Steam商店页公开 巫师帽、法袍、魔杖,为什么它们是影视、游戏里的法师必备三件套? 《无鞘信使》-第一章 复古风自动战斗肉鸽《终结之终结》Steam商店页面现已上线 电脑里有一款不破不立的MMO,录音笔VOL.688 | 机核 GCORES 《生化危机》30周年纪念周边发售,这次是真的“保护伞” 可靠耐用+AI全能,惠普战66 2025锐龙版深度体验 《时之书:无尽终章》关卡“大航海时代”全球首次公开 经典名作《乌龙派出所》改编经营模拟游戏《乌龙派出所~阿两的商店街物语~》正式宣布支持简体中文 明日开冲,解锁反套路三国互动影游《代号三国:龙起》即将上线 独立游戏《这是我的宝藏!》已发售~ 降低难度不是唯一解,无压力死亡也是好体验 Netflix官宣新片《普通人》:讲述韩国现代史上的权力风暴 《生化危机:安魂曲》全球销量现已突破700万份 《绝地鸭卫》PC版5月15日正式发售 亡妻回忆录?女性向情感叙事游戏《S-mail》现已正式发售 全新酷黑风格,酷睿Ultra 200S PLUS的高性价比搭档!七彩虹BATTLE-AX B860M-PLUS S WIFI7 V20 超级黑刃主板测评 胖狗 索尼发布了港台地区PS5产品价格调整公告,将于5月1日起实施 二次元怪猎+性感美女!《碧蓝幻想:无尽黄昏》开启Beta公测 这款怪谈类型中式恐怖游戏居然更新了?! 《百日战纪 -最终防卫学园-》改编漫画将于今年冬季开启连载 《如被附身,请致电我们》:匈牙利黑色幽默恐怖小说 《竹屿山房杂部卷五》(译文) 大树 超越引擎 摄影分享丨四月 碎片杂记vol.72 当老式FPS与老式动画技术碰撞出新时代的火花—《神探杰克鼠》 想做独游,如何避免首个项目就褒姒? 在线多人动作游戏《OCTOPinbs》将于5月12日上线Steam! 《酒鬼女神的酒诡》确定将于2026年登陆Steam 《CRYMELIGHT》将于11月5日(周四)正式发售!4月25日开始预购! 钢铁国度MKI部落Evolution,蛮兵部分 【钢铁国度】部落-Primal MK I,蛮兵部分 这是一个高中生用ai跑出来的作品,我自称他为物理神话 钢铁国度MKI部落Metamorphosis,蛮兵部分上 钢铁国度MKI部落Metamorphosis,蛮兵部分下 INDIE Live Expo于4月25日举办:首发9款新作,超200款独立游戏亮相 暗黑卡牌策略新作《魔忌:穷鼠啮狸》发布全新中文试玩版和发售预告片,4月30日正式上线在即 战锤40K长篇小说:变节者・苦难主宰(三)(全书完) 战锤40K长篇小说:变节者・苦难主宰(二) 战锤40K长篇小说:变节者・苦难主宰(一) 英语语言学习丨短语专题1:短语的特点 唯一的EVE战争 【少前同人】【M200】战术人形会梦见音乐会吗 【昏迷3】即将发售,前作主角悉数到场!“恶灵”宋老师化身可操控角色 业内人士:游戏公司“十有八九”使用生成式AI,包括卡普空 欢庆一周年:《光与影:33号远征队》全新纪念艺术图、超值折扣与免费更新同步上线 才刚刚开始呢 【抽奖】《星际卡车司机》推出免费大型更新,四折平史低折扣进行中 四人合作FPS游戏《佣兵猎手》抢先体验重大更新 1 现已上线 Raw Fury新作《深馅地牢 Deep Dish Dungeon》将于今秋加入 XGP 塔防幸存者游戏《魔怪来袭》推出首个 DLC 《饿狼传说:群狼之城》1周年纪念!新DLC“沃尔夫冈·克劳萨”今日参战 猫狗相伴 欢乐闯关 双人合作平台跳跃游戏《猫狗同行》上线Steam商店页 《同行:月球逃脱》(Together: Moon Escape)上线将于明日上线Steam
SIGGRAPH 粗读丨看看《地平线:西之绝境》燃烧海岸DLC中的云层渲染(中)
Hakumen · 2024-12-27 · via 机核

前言

上一篇中,作者以相对简短(其实也挺充实)的方式带我们回顾了Nubis体积云系统的前置技术路线,及其优缺点。

简单概括来说,本身对于远处观看的和近处观看的体积云,渲染上自然有着不同的设计——在上篇中分别翻译为垂直轮廓法封包法的两种建模方式,其数据源格式、采样方式、是否支持光照、是否支持演进(可以理解为通过数学推算的动画,例如随风移动)等维度上都有区别。而且旧的两种云建模方式在制作上都是相对不友好的,不容易直接在制作阶段预览到结果。

这次的内容就会正式展开Nubis3系统中的体积云系统,或者说是体素云系统——上一篇中作者提到了,这一技术在最终要在成品游戏的DLC中交付给玩家是有一定挑战的,这次让我们一起看看这个方案落地的设计和实现。

文章还是以翻译原文的讲稿为主,并且由于原文的篇幅很多地方较长,会进行适当的精简和概括。由于图文内容量都很大,这次分为了上中下三篇——这是其中的中篇;打星号的部分则是我个人的补充说明。

1 体素云建模——Voxel Clouds Modeling

经历了短短几个月的快节奏开发后,我们得以圆满完成了这一任务——没有计划上的延误。

这里开始介绍我们为沉浸式(immersive)的实时体积云准备的解决方案。

回顾一下我们的光线步进(ray-march)的过程:

  • 我们在(从摄像机)开始追踪时并不确定具体云的位置。

  • 当命中云层时我们开始采样云的密度。

  • 直接光能量计算——需要一个(让人懊恼的,annoyingly)昂贵的第二条ray-march射线朝向光源。

  • 之后计算环境光的能量(*基于概率估算)。

  • 最终需要累加次一级的光源的能量(*基于概率估算)。

  • 之后我们对于每一个单位步长中都重复这一步骤,直到密度达到不透明(或出了云层)才停止march过程。

None of these operations are terribly efficient or were designed to work efficiently with voxels, but our approach to voxel cloud rendering replaces and optimizes almost every one of them with faster better voxel–based methodologies. Let’s start this overhaul at the beginning.

这些步骤都不是特别高性能、或是面向高效采样体素而设计,但我们的体积云渲染方案替换和优化了其中几乎每个步骤,使之变成更快的基于体素的方法。让我们从头开始介绍这次大型的改造。

开发一个高效的渲染与光照解决方案离不开稳固的建模方法,因为3A级实时图形技术中,你需要做(很多)“如何做”以及“消耗多少内存”的决策,(这些决策)可能会提升性能也可能影响性能。

回顾我们的2.5D云方案的密度采样,其中从2D建模数据中构建了3D云的体积——在提高其分辨率之前。

在一个基于体素的方法中,整个昂贵的操作可以被移到shader外,但这意味着需要能开发一种建模云的方式——存储并高效地通过采样器来访问它们。

There are many tedious and unrealistic ways to model voxel clouds by hand but the most promising approach that I found the most success with in the past was using fluid simulation to “grow” clouds.

尽管也有许多乏味而不现实的手工(建模体积云)的方式,但以过去的经验我探索出的最靠谱的方式是——通过流体模拟器来“生成”云。

在我们2014年未最终使用(un-shelving)的流体模拟实验的基础上进行“人造云层”,似乎会是一个不错的开始,但我们需要一种能将流体模拟数据导入体积云的方法。(*原文用了一个生造词,“frankenclouding”)

We developed a set of authoring tools in Houdini, that we call Atlas. At its heart, Atlas is a compositing pipeline for voxel data with various ways to generate or source and manipulate the data.

我们在Houdini中开发了一组资源加工工具——它被我们称为Atlas。在其内核中,Atlas是一组能将体素数据以多种方式进行生成、存储(作为来源)及操作的工具链组合。

例如,我们的一个大气环境艺术家Bryan Adams,从游戏中的长颈兽模型建立了一个体积云(如图)。

One of the things we learned early on was that multiple voxel grid boxes bounded us both figuratively and literally. Keeping them in memory and switching between them in the inner loop of a ray-march was not ideal and lead to slow performance.

其中我们很快总结出的一件经验就是——多重体素格对我们来说是一种限制(无论从比喻意义上还是字面意思上)。将其保留在内存中并在一次ray-march过程中(在其中)切换,本身就是不理想并会导致低性能的。

*这里作者又用了bounded这个词来做了一次双关,感觉又是一种特有的冷笑话了(上篇里也有过)。而且这个限制并不是被体积边界限制了,更多还是(同一空间里)多重体积这个数据设计导致的。

因此,下一步的思路就是当整个云的形体被构造后,我们将每立方米(every cubic meter)的云的密度信息写入一个密度体素栅格(dense voxel grid)中。

这将解决建模云过程的第一个挑战,并将2.5D的云采样中相对开销大的部分替换掉——如果不是引入了使人崩溃的几个问题的话...

第一个问题是我们要面对的是天量的体素栅格,这肯定会有内存瓶颈。

游戏的DLC区域面积有4平方公里,而我们需要大约500米垂直高度的空间来放置云层——从地面到空中。由于玩家可能飞跃云层,因此我们也需要足够的体素栅格的精度以保存细节信息。

即使放低期望并进行估算,也需要2048x2048x256尺寸的体素栅格以保证每2平方米的精度——玩家的飞行坐骑的翼展就有大约2米,因此这已经是比较极限的数据估计了。

这个密度的栅格需要很多内存,并且会因此导致更长的ray-march时间——因为潜在需要消耗更大的内存带宽。之前的经验告诉我们这样不可行。

也有一些稀疏的体素格式,能仅在有物体的区域内存储一些(相对)更高精度的数据,但需要一些间接定位(indirection)的步骤,这会增大每次采样的开销。对于已经有相当大开销的ray-march来说这是很致命的——并且由于时间也很有限,我们决定搁置这种方案。

我们决定从BC4压缩格式,8米的精度开始。(*就是暂时不考虑稀疏体素这个方式了,另外这里8米应该是长宽,高度应该还是1米)

让我们来总结一下体积云建模的技术路径:

  • 我们通过Houdini中一款称为Aero云解算模拟器来生成云。

  • 之后我们修改并将其整合到我们的“人造云层”中。

Then store them in obscenely low resolution voxel grids to be sampled at render time. It sounds like its hardly a solution to our goals, but…

  • 最终我们可耻地将密度数据以较低分辨率存储在体素栅格中,并在渲染时对其进行采样。听起来这差不多也算是一种解决方案,然而...

*最后一句作者用了很多作为技术分享不太常见的语气词,比如obscenely和sounds like、hardly,可见到这一步勉强实现的效果确实不太让人满意。obscenely这个词直译比“可耻”可能还严重一点,也比较奇怪,原意我这里就不写了,感兴趣可以去查一下。

*体素阶段精度的不足,后续作者团队通过利用节省出的性能空间进行了视觉效果精度上的弥补。

2 采样密度——Sampling Density

Past experience had taught us that balancing work between memory accessing and instructions in the compute shader can yield better performance on the GPU, so we chose to solve this in the density sampler itself as we have done in the past.

过去的经验教育了我们,在compute shader中平衡内存的使用和指令的调用能获得GPU端更更好的性能表现,因此我们在解决这个采样密度的问题时也参照了这一思路。

回顾一下之前(非体积采样)的方案:

  • 将2D的NDF模型数据解压成空间轮廓。

  • 之后“超精度”这一空间轮廓——通过以高频噪声侵蚀的方式。

问题是——当采样体素数据时,这一超精度方法还能生效么?答案是肯定的。

比起明确定义出每个体素的(高分辨率的)密度,我们的方法是从一个低清晰度的基于体素的空间轮廓进行“超精度”——使用一个新的细节噪声。

这使我们得以规避内存瓶颈——通过分流了一部分工作至超精度指令的方式,正如之前在2.5D云中做的那样。

*这里还没有具体描述细节噪声的结构,但给出了体素块的尺寸和形状。

这里用对比图简单做一个预览:上方的图是初始的空间轮廓渲染后的形态,下方的图是超精度之后的结果。

The Dimensional Profile is generated from a signed-distance field of the cloud to ensure that we get a gradient from outside to inside.

空间轮廓生成自一个有向距离场(缩写成SDF),以确保能得到一个从外到内的梯度。

我们的Atlas工具允许用户建模(被称为)Nubis体素数据场的数据,缩写成NVDF。作为对空间轮廓数据的补充,制作者能建立额外的NVDF,例如:

  • 细节类型(Detail Type),用来混合从纤细到波浪状的噪声细节。

  • 密度缩放(Density Scale),在噪声应用于超精度时适当降低密度。

这些数据使用BC6格式压缩(*之前的文章介绍过),支持3个通道——每个纹素(texel)占用1字节。

下面让我们看看体素云采样函数在超精度过程中的具体实现,以及新的3D噪声的一些特色。

我们的密度采样器中的第一步是:采样空间轮廓NVDF数据。

之所以第一步执行它,因为如果结果为0,则可以跳过后续关于云采样的步骤;如果空间轮廓是非0值,则我们将云模型数据传入超精度函数。

在深入超精度函数前,我们需要先来看看新的3D云细节噪声。

让我们看看这组实景定时拍摄(*原文中是较长一段视频)——虽然当时如果用了三脚架(Tripod)会使拍摄更稳定,不过目前也足以展示重点了。大家都看过类似的镜头,然而为了更好理解流体的特性,最好从不同的视角来观察它。

尤其是上下颠倒(观察)时,它看起来更像泼入水中的牛奶。从这个视角更容易想象水蒸气(water vapor)所受的压力和云整体受的挤压。这一点是我们建模细节噪声时所重视的细节。

*这里作者采用流体类比的思路来观察,让人觉得既吃惊又合理。

回顾一下,我们将云的细节分类为了波浪状的和纤细的。

当水蒸气进入一个冷空气区域时,它会更容易(原文是effectively)地向外被挤出。

The billows that we see are the result of some of that expanding vapor punching through weak spots in this squeezing force.

我们看到的波浪状效果是一些扩散的蒸气,在这类挤压力下穿透稀薄的部分后的结果。

现在,在脑中倒装这一过程,就能得到一个更纤细的荷叶边(scalloped)的形体。

这一过程发生在水蒸气蒸发,同时周围的空气挤压蒸气时。

这里展示了另一组延时拍摄——云稀薄得就像网一样(*原视频后面云逐步消散了)。

此时,空气的扰动就起到了更决定性的作用,为云的形体带来了额外的扭曲。

小结一下:

  • 在密度降低处,表现为多层的纤细细节和卷曲(curly)的扰动。

  • 在密度增加处,表现为多层波浪状的视觉。

在之前的方法中,我们使用反相的Worley噪声来生成波浪状的细节,但我们不得不重复采样很多层以获得类似云的效果——而不是堆叠的球体。

这次我们决定使用Houdini中的Alligator噪声(如图),既有着和之前的噪声相似的结构,又有着更像云的不均匀的空隙(lacunarity)。

对于纤细的细节,之前我们使用了Perlin-Worley混合噪声——不过,这对于超精度生成的过程来说还不够细致。

作为替代,我们从一个反相的alligator噪声开始,并使用一个卷曲噪声将其扭曲成需要的形态——这被我们称为Curly-Alligator噪声。(*Alligator直译是短吻鳄,这里属于专有指代)

我们生成的这些3D纹理是4通道128x128x128的体素。

前两个通道分别存储低频和高频的Curly-Alligator噪声,而后两个通道则是低频和高频的Alligator噪声——讲座的最后会介绍一些辅助产生这些3D噪声的工具。

我也乐于分享一个生成Alligator噪声的工具的源码(*图中链接),它是由SideFX Software提供的。

了解了这些3D噪声的具体格式后,我们可以回到超精度部分的具体实现了。

第一步是(类似2.5D云中一样)使我们的细节噪声卷动——我们通过添加一个“风偏移量”来改变采样位置,以实现这一效果。(*类似UV动画,只不过是三维的)

下一步我们依据MIP级别(根据摄像机距离计算)来采样3D噪声。这能提升大约15%的性能,并且一个合适的MIP级别并不会导致结果上可察觉的影响。

由于采样器会被频繁调用,因此能省一点是一点(原文是every little bit helps)。

下面让我们看看如何定义纤细和波浪状的细节噪声(在超精度函数内部)。

首先,让我们看看纤细云的照片。

注意在密度没那么高的部分,有一些非常高频的细节;而在更致密的区域有着低频的纤细结构。我们想要在超精度的过程中模仿这种关系。

回顾我们的空间轮廓NVDF,可以看到它已经提供了一个从外到内的梯度。

*虽然箭头是向外的,但原文描述的方向确实是from the outside to the inside;箭头更多可能是表达受挤压扩散的方向。

为了模仿这一点,我们可以简单地基于空间轮廓来对低频和高频纤细噪声做混合。

*lerp函数就是线性插值,看多了的应该都不陌生。

*三张图依次是:只有高频、只有低频、混合噪声的结果。

下面来看一些波浪状云层的照片。

注意到在靠近内核的部分有着低频的波浪状形体,而靠近表面则有着高频的波浪状形体。

对于波浪状形体,我们希望在边缘(相对核心)采样更多的球状结构。同样的我们也是基于空间轮廓来混合低频和高频的噪声。

*同样,三张图依次是:只有高频、只有低频、混合噪声的结果。

之后我们基于类型数据(type data),在采样位置对两种噪声(的混合结果)再做混合。

*三张图从上到下依次是:只有纤细噪声、只有波浪噪声、两者基于类型数据混合。

这在远距离时运作良好,但仍然无法符合我们想要飞跃云层的目标——在近处仍相当缺乏细节。因此,我们开发了一种重用高频噪声的方式,以在必要时添加一些更高频的噪声,同时不再进行额外的高开销的噪声采样。

我们创建了一种被称为双折叠噪声的算法,以获得两种类型各自对应的更高频噪声。

*具体公式如图,基础思想就是展开到-1和1的范围后,又通过取绝对值abs“折叠”,之后pow取多次方。

之后我们基于细节类型数据对两种类型的更高频噪声进行混合,最后再基于到摄像机的距离和之前(远距离情况下)的噪声云层进行混合。

*上面两张图展示了:未增加细节和增加了细节后的不同结果。

这里展示了飞跃云层的过程中这些细节噪声是如何生效的——并且可以看出这一效果是无缝切换的。(*因为都是连续插值的)

现在我们明白了噪声的混合及运作过程,让我们将其整合到函数中:

  • 首先,我们使用一个重映射(remap)函数来侵蚀云的空间轮廓。

  • 之后我们将超精度密度(up-rezed density)乘上密度缩放。

  • 最后有一个使结果显得更锐利的方式是通过pow函数——更多地在低密度区域进行这项处理能使这部分提高清晰度。

  • 之后我们将其作为超精度的结果返回。

*解说稿没有完全覆盖公式的每一步,但是参照各处的命名一致性应该比较清晰了。

总结一下:

从结果来说,这套实现是一种能从地面到空中近距离的无缝体积云渲染方案,它有着简化后的采样函数,既回避(sidesteps)了高内存使用同时又能提供足够高的细节度。

我们的空间轮廓能提供相对低精度的每8米一样本的精度,通过一些超精度方法能提升至(相当于)0.5米的精度。

解决方案的关键是平衡内存(从1米降至8米)和指令调用(引入一些噪声采样)来获得相对更好的性能。

不过我们还远没有结束这一改造(overhaul)过程,因为在最差的情况下,960x540像素的渲染会消耗10毫秒——而在地面观看时,我们需要和其它的一些资源一起分配性能预算。从影视特效或宣传动画的角度来说或许足够了,但作为一个实时渲染的游戏来说不能达到3A标准。

*最后一句及后面有一个bonus页,作者展示了一些在致密栅格采样(dense grid sampling)方面的探索。不过截至这一段落为止作者并没有明确后续是否要应用进一步提升精度的方案。

3 光照计算——Lighting

光照,让人哭笑不得的是(ironically)——它也是体积ray-march步骤中开销最重的部分之一。在它的面前我们的任务似乎是不可完成的:既需要节省大量的性能,又要提高质量以支持飞过云层时的效果。

回顾我们之前的介绍,我们把光照分解为直接散射(Direct Scattering)、环境散射(Ambient Scattering)和次级光源(Secondary Sources)三部分。

其中直接散射的计算开销非常大,因为需要向光源发射第二级的ray-march采样射线(*而且是逐采样点的)——我们也尝试了各种可能来加速或替换第二级的ray-march采样。

直到我们以体素的角度来考虑这一问题,之前有一个看起来比较高傲(loftier)的点子就显得有些合理了。

主程(Principal Tech Programmer)Nathan Vos一直想将光采样射线与视线采样射线中解耦,不过直到使用了体素方案后,改动的复杂度才降到了合适的范围。

在我们的新方案中:

  • 前2次采样的方法沿用之前的方案。

  • 但剩余的采样在一个单独的pass中被预计算,并存储于256x256x32尺寸的体素栅格中。

这有助于保持云的近处表面的细节,并提供一种更弥散(diffuse)的视觉效果。需要明确的是,预计算是发生在ray-march的步骤之外的。

Here is how it works: If a voxel has cloud in it, then a ray is marched between that voxel and the boundaries of the voxel grid and density is accumulated at each step.

这里展示了它(预计算的体素栅格)运作的方式:如果一个体素中有云的数据,则向光源发出一根射线,直到达到定义的边界,而过程中的每一步都对密度做累加。(*这里density因为是采样的光照,可以理解成通透程度。但后面还是简化翻译成密度。)

我们发现这大约减少了40%的渲染时间。这项操作自身消耗在0.1-0.2毫秒之间,取决于在一天里的时间以及射线到太阳的距离。这一开销是平摊到8帧之后的结果。

作为节省性能之后的补充,我们终于能渲染远距离云内阴影了。

这里(上面的图)是之前的方案中256米,10条光采样射线的结果。

下面的图则是基于体素的光照方案的结果。这是一次难得的场合,基于性能的优化得出了更好的效果。(*下面的图虽然看着更黑了,看似少了一些细节,但是明暗关系更“对”了一些)

切换到体素方案也为我们带来了一些自由,以固化(solidify)我们建模多重散射效果的方式——对应云的内发光到暗边缘的效果。让我们深入看看这一实现。

让我们看看休斯顿的Natural History博物馆展出的水晶样本。

It’s interesting because you can peer deeply into the core through the little gaps between each crystal. If you blur your eyes, you can almost see what looks like a lump of lighter material under the surface.

有趣的是你能从水晶针的微小缝隙中观察到其内核部分——如果你让视觉稍微模糊点,你就能把它近似看作(暗色)表面下的一小块发光材质。

很难不观察到其中的相似点。在云的表面边界处,有着更少的材质(*这里指实际的水蒸气、冰晶等)——使入射光线更容易散射到随机的方向,因而不容易进入人眼。

因而你能想象云内部有这样一个概率场——朝向观察者的内散射,随着深度越深就越是各向同性(isotropic)或全方向的(omnidirectional)。这种透射向表面的光照很像隔着一层厚棉花的闪光灯。

或是像水晶体结构由内而外发出的光。

从结果上观察这种散射的潜在规律,能更有助于我们建模实时散射效果。

*从自然界的实际效果观察,是这个作者很重要的一种思路。虽然实际上设计这种概率场是一种近似,但视觉上又很“真实”。

幸运的是,我们已经有了这种体积描述。让我们以图中的云为例。

下方的图展示了它的空间轮廓——让我们把这作为(散射)概率场的基础。

先让我们将这片云对齐到视线和太阳的中间。

然后取这个角度中心位置的一个切片作为样本。

这里是切片从初始角度进行观察的效果。

这里展示了我们使用空间轮廓作为散射参数的效果。为了模拟光散射被云体吸收的情况,我们额外应用了一个beer-lambert衰减曲线。(*上图是无衰减的,下图是模拟了衰减的)

这一曲线值在靠近太阳和云的内部的位置更大,以模拟前述的内部光散射效果。

让我们看看实际交付版的游戏中云光照的效果。

*上图是没考虑多重散射估计的,下图是应用了这一算法的。

*这是太阳在观察者背后的情况。上图是没有多重散射估计的,下图是应用了这一算法的。

就像在2.5D云中的那样,我们也使用空间轮廓作为估算环境光散射的概率场。

*上图是没有计算环境光贡献的,下图是计算了的。

由于我们(基于体素的)预计算光照采样的方案运转不错,我们终于考虑改进环境光照的计算方式,从概率估计变成采样累加。

当我们以射线采样预计算天空光照时,我们获得了能局部调整环境光强度的参数,使得天空被其它云遮挡的区域会计算更少的光强度。

在计算时,我们就直接乘上这一累加后的密度系数(*负值的exp,见图中公式)。

*上图展示了无方向性(旧算法)的环境散射效果,下图展示了基于体素光的方向性环境光散射。

而灯光之类的次级光源我们还是基于概率场来估算。

首先,我们定义了一个基于球体的潜在能量范围,并乘上一个模拟出的非均匀(non-homogeneous)密度系数。

这里展示了游戏中的一处效果。

由于这是一次大改造,因此确保云的渲染在一日循环中的始终有效是很重要的。这里让我们执行一个循环以进行观察。

那些远距离云上的阴影也极大提升了观感。

最后总结一下:

  • 我们解耦了光线的ray march过程,预计算并存储在一个体素栅格中的累加密度结果集合中。

  • 通过这一过程(相对原来)减少了每帧40%的开销,我们把这些性能空间用来添加远距离云的阴影。

  • 我们也使用这一方案来改进了环境光的效果。

  • 额外地,我们的一些光照估算方式被简化成直接查找(体素)空间轮廓。

有时就是这样,改良一项效果会开启其它解决方案的门。

结语

存储空间和指令调用(或算法复杂度)的平衡是作者提出的一项很有实践智慧的视角。在给定的需求——飞入云层作为大前提下,体素数据的使用就不可避免。在此基础上,云的建模从体素的结构和性能指标开始考虑,并在后续的密度采样和光照计算尽量发挥体素(对画面)带来的优势来改进渲染管线。

另一个很重要的视角就是——从物理光学中观察。毕竟这些方案无论显得如何“真”,其实中间不乏估算与trick;但很多时候,使用概率场或概率密度来计算光照或采样等,很类似数学拟合后的结果——其结果首先是要有合理的曲线,其次就是不会发生能量凭空增加的情况。只有做到了这一点,在实现全天候光照的时候才能有相对准确的结果。

这一篇读到的这三部分应该也算是Nubis3体积云系统的核心,下周更新的剩余的部分会包含一些系统整合方面的介绍。

最后是资料链接:

Nubis3: Methods (and madness) to model and render immersive real-time voxel-based cloud 1080P PPTX PDF