写在前面
前两天学习并整理的大气散射基础知识:【Unity大气渲染】关于单次大气散射的理论知识,收获了很多,但不得不承认的是,这其实已经是最早的、90年代的非常古老的方法了,后来也出现了一些优化性的计算思路和方法。因此,我打算先不急着跟各种教程在Unity中实现大气散射,而是再花时间来看看最近的游戏是如何去实现大气渲染的:06.游戏中地形大气和云的渲染(下) | GAMES104-现代游戏引擎:从入门到实践
接下来就跟着GAMES104讲地形大气和云渲染的部分学习并做简单的记录,涉及到之前没提到的Mie散射也只选择直接截图PPT的方式记录啦!毕竟对于做作品来说,之后实现出来才是重要的~
当然,May佬的百人计划在今年8月份也有一期关于大气散射的讲解,这里也放上课程的链接以及对应的超长内容整理的知乎文章链接:
【百人计划】图形 4.6 雾之 大气散射_哔哩哔哩_bilibili
话不多说,开始今天的学习!
天空(球、离我们很远)与云(非常visible的、离我们很近)是两个最重要的元素。其实还有个东西Fog,但雾效并不只是大气,更多的是可控性的效果,所以这里把雾和天空/云分开来考虑。
3A的标准在手游实现将会非常坑爹hhh,另外我想实现的是风格化天空盒,会参考更多以精简计算。
太阳、大气中的气体分子与气溶胶分子,于是Rayleigh散射和Mie散射就被提出来了~Rayleigh散射波长越短散射的越厉害,而Mie散射对所有波长光一视同仁。
g=0的时候,跟Rayleigh散射差不多;但g>0的时候,下图右边所示就会会更加向前。


Mie散射就是一些日出日落halo。

真实世界的散射绝对不止一次散射,一定还有多次散射!听上去很麻烦,但实际上目前的3A游戏多需要考虑多次散射。如下图右侧考虑多次散射的才是符合真实大气的样子:


单次散射其实就是RayMarching(沿着视线不断向下积分,算是一种暴力解法吧),实际上计算所有的大气效果都是用Ray Marching这个思路。

大气中的光学现象其实就只有两个部分:Transmittance&Scattering,这俩分别对应着我上一篇文章中的衰减系数T项和散射系数S项,这里介绍了一种很机智的算法计算Transmiitance——Precomputed Atmosphere Scattering,预计算。
(插播一点,这里也可以看看游戏魔法编程:unity实现完整大气散射 - 知乎后面部分对LUT的介绍)
这里最重要的思想是参数化——对于海拔高度为h的点,用视线与天顶角度去计算T项,从这一点一路走到大气层边界,记录边界处的Transmittance值。
那我怎么去用这个LUT表?——去查!怎么查?如下左图,假设我们想知道Xm位置的山脉的Transmittance的值,查1(从人眼位置Xv出发到边界的值);查2(山脉Xm到边界的值),查1/查2就是当前Xv位置看Xm位置的Transmiitance的值了。

选择海拔为h的点,向大气层边界去看(打出一条射线),这个时候看向的方向到天顶的角度1,这个时候太阳到天顶的角度2,看向的方向和太阳之间的角度3,这三个角度其实就得到了一个立体角!那么,这三个角度组成的立体角其实就能表达当前海拔高度所有视线方向沿途的Transmittance值,再从不同海拔通过RayMarching的方法一下获取一堆数据,这样一来就足以在一个3D Texture中将单次散射所有的光(4D数据)全部存下来了。

我们用前两次的两个结果再做几次积分(其实3-4次已经够用了),就能得到多次散射的结果。

预计算很费计算,手游上不太星。
刚开始是蓝天白云->下雨的效果的过渡,这个过渡需要很流畅;同时我们的美术会需要调整一些参数,这中间由于有预计算,会很麻烦。

这里是课程最后提到的UE采用的方法,是在论文A Scalable and Production Ready Sky and Atmosphere Rendering Technique的基础上实现的,具体可以看看这篇文章:UE4新版大气实时渲染-论文导读 - 知乎 (zhihu.com)
仅作简单的记录:
对于一个分子,可以假设四面八方光是均匀的,那就算两次,知道一个差值,就知道后来所有的值的百分比了!

既然世界需要动态,那省事儿创造更流畅的画面才是关键,那假设人不变(干掉h),假设太阳不变(干掉太阳的那个角度),


我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
我有一大串格式化数据(例如JSON),我想使用Psychinruby同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解