GDC2013 Relighting Forge in Halo 4 Just-In-Time LightingofUserGeneratedContent

# brief
- 要解决的问题是给User Generated Content实现说得过去的光照效果
- 首先probe完全用离线烘焙的,问题完全没解决
- 会在加载前烘焙forge object的lightmap(应该是直接光+AO*环境光)、还有给背景场景(空场景)加上shadow

# Forge
- editor, debuted in halo3.可以用各种建筑碎片、甚至vehicle啥的来拼个地图然后上传,然后可以进去玩
- 光照有问题,因为没了lightmap,所以建筑例外一个样的光照显得亮,另外也没shadow
- boss跑过来跟程序员说:we got this amazing lightmapper, let's port it to xbox, let's do it.(想再xbox上bake)

# offline
- atlasing:展lightmapuv,不需要考虑filtering或者compression,但是要考虑哪里应该有更多的面积
- rasterization:每个lightmap像素会对应到scene的surface上, packing的时候需要注意用了bilinear filtering(需要啊add padding pixels)
- packing:这里要开始考虑compression了,compression用的是block algorithm,所以如果你把很多相差很大的像素放到一个block里,就一定会因为压缩而有artifact
- direct lighting: 用shader直接渲染。这样得到的就是运行时结果的高精度版本
- indirect lighting: 用hemi-cube render。当然很慢。然后存SH
- linear SH on surface geometry,(5 terms).
- Quadric SH in air probe(used to render dynamic objects)(9 terms)

# runtime
- 用convolve BRDF with baked SH data(具体怎么做没说)
- probe for dynamic, lightmap for static
- dynamic lighting
- dynamic lights: expensive, for cinematics
- dynamic drop shadows, 基本上是给multiplayer用(好像就是planar shadow)
- directional lights的cascaded shadow(并不敢全屏都用,所以远处还是fallback成staticly baked term)
- no occlusion for dynamic objects

# User Generated Contente problem
- more dynamic objects than normal
- mutual occlusion becomes important
- can not generate dynamic shadows for all objects
- but placed objects are not really dynamic

# just in time lighing
- 在载入场景时的一段时间能完全使用cpu和gpu来生成lighting数据
- memory情况不好,因为场景得加载好
- performance constraint也不小,不能等太久
- somethings impossible
- high quality surface reflection
- raytracing data structure
- uncompressed UV space RT

# makding JIT tracing
- do as much as possible offline
- burn background environment, airprobes(done even in halo3)
- make atlas for forge objects: 可以用上pc上的lightmapper的pack lightmap的代码
- don't regenerate SH and color from scratch
- 直接用airprobe的,这个完全不考虑新增加的东西造成的间接光照啊。。。
- only encode occlusion,因为比color简单
- 如果事light的话需要quantize different light at different intensity into 0-1024 color space(10,10,10 true texture)
- 但是只有occlusion也有问题,direction信息没有,如果有一个绿光、一个红光同时找到一个表面上(各一半)就没法搞。不过halo都是outdoor,所以没问题
- do regenerate static sun channels from scratch
- 说是这个简单多了

# 对比有和没有JIT lighting
- 没有肯定不行,环境光一样导致很怪
- 有JIT lighting时,由于主要时occlusion,所以不仅让人疑问是不是只要把AO bake了就行
- 不能用baked AO,因为东西互相之间遮蔽

# offline atlasing and packing
- 一个物体的UV是一个mini atlas。一般用32x32

# runtime packing
- 需要把mini atlas拼到一个mega atlas上,典型的CS的box packing problem
- 需要处理不同大小的mini atlas
- 主要时运算时间不能太长,所以效率不高

# xbox packing
- typical forge user用不完这个mega atlas的budget
- upscale objects with the biggest worldspace size(前提是budget有剩余。。。)

# occlusion baking
- render shadow spot lights around object(我的理解就是模拟半球面上的raytracing)
- sum by cosine weighted contribution
- fade to grey instead of black(应该就是个保底的ambient值,防止完全黑, hide artifact)

# occlusion bakding implementation details
- 把scene分成若干bucket
- 分bucket算lighting
- 如何避免boudary的情况:把物体的bound扩大一些,保证物体在边界时会被加到多个bound里,这样烘焙bound的时候,边缘物体不会丢失,他们对别的物体的遮蔽也有效
- 对每一组bucket,从周围的sphere上渲染shadow directional light,进行累加,这样一组一组地进行,效率的确高。approximate integrated visibility
- 90 directions
- using 10:10:10:2 format(还是32bit哦)。only 1024 possible values,要保证累加的light不超precision,light多的话每个的intensity都很小

# rasterization
- 在vs里很简单地控制一下,让直接输出到megatexture的atlas上去
- some texels are missed:解释的原因是GPU rasterization is different from bilinear aware rasterization
- rasterize 3 times
- fill
- point(之所以要有这个是因为packer可能把好几个triangle(都是1个像素)合并成1个像素。这种情况三角形被认为是degenerated
- wireframe
- 这样可以expand surface area,cost acceptable,用blend mode保证no pixel drawn twice,说是不然又bleeding(我想是指边界上的黑?)
- blur
- 因为又artifact,要blur,但是至应该在minichart里blend,不能越过边界
- 3x3 box filter
- not to blend garbage boarder pixels(mark pixels actually drawn to with alpha)
- avoid blur between large delta(和当前点光照差得大的不参加blur)
- fill missing texels(在这步,如果这个texel还是没被draw to,就用周围的值)
- texture compression
- DXT。solved, there's sample code, can be done on gpu

# Sunlight on objects
- 不能分bucket了,得一下子搞出整个场景的 shadowmap

# sunlight on environment(the ground)
- modify existing sun channel(感觉应该是带在游戏asset里的)
- 现在这一步已经有了空场景的lightmap,要把可能受到forge object影响的物体重新烘焙lightmap,说是其实只是把shadow加上
- 用min blend mode to add shadow
- easy to add shadow, hard to remove them
- 说是如果物体在bake过shadow后有移动了,很难把刚才加上的shadow去掉
- option1:quickly relight environment sun lightmap
- option2: reload original sun texture and rebake shadow
- 最终用option1,因为halo不支持游戏过程中加载,日了狗了(可是最刚开始的过程就是option2吧?)

# sunlight in environment
- relight shrubbery(草、石头啥的) with downward raycast, 就是用raycast找下面又lightmap的物体,然后采那里的lightmap

# memory and speed limitation
- limited graphics memory(10MB EDRAM on XBox)
- PC用1792x1792的texture,已经是12.75MB了
- 而且不能用非32bit的rendertarget
- 降低RT尺寸,red存left half, green存right half,blue和alpha用来存marker(blur用)
- combined opposite-facing lights into one draw during occlusion pass
- 90个dir,其实是45对方向
- 一个surface一定被某一个2个相对方向的某一个lit,我的问题是:不考虑遮挡吗?的确有可能完全不被任何一个lit啊?

# tying down to GPU
- 不能完全不管别的事情,不然好像看门狗会直接启动
- need to present every 66ms
- xbox360 will clear gpu memory after present, need to save working state
- display update spinner(hack)

# Results
- allow 651 objects
- 1408x1408 occlusion + sun map = 3.78M

# potential improvement
- user-placed spotlight
- gaussian blur other than box filter
- 不要给lightmap上的每个texel一个position和normal
- 在gpu上可以triangle和baycentric coordinate
- 在cpu上可以直接从vertex stream上得到
- darken probe(他们的实现了probe是完全不会改变的,暗的屋里还是亮的probe)
- GI
- imperfect shadow map
- heightmap global illumination

# QA
- 如果真的要在JIT lighting里实现spotlight,大概是什么peformance:大概还好,不需要改太多,因为烘焙时也和实时渲染差不多
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值