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

推荐订阅源

GbyAI
GbyAI
J
Java Code Geeks
雷峰网
雷峰网
WordPress大学
WordPress大学
宝玉的分享
宝玉的分享
云风的 BLOG
云风的 BLOG
V
Visual Studio Blog
V
Vulnerabilities – Threatpost
S
Securelist
The Hacker News
The Hacker News
The Register - Security
The Register - Security
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Help Net Security
Help Net Security
G
Google Developers Blog
Hugging Face - Blog
Hugging Face - Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
M
MIT News - Artificial intelligence
AI
AI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
The GitHub Blog
The GitHub Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Schneier on Security
Schneier on Security
N
Netflix TechBlog - Medium
T
The Blog of Author Tim Ferriss
Google DeepMind News
Google DeepMind News
Hacker News - Newest:
Hacker News - Newest: "LLM"
H
Hacker News: Front Page
博客园 - 司徒正美
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
B
Blog
Microsoft Azure Blog
Microsoft Azure Blog
大猫的无限游戏
大猫的无限游戏
Security Latest
Security Latest
Engineering at Meta
Engineering at Meta
N
News and Events Feed by Topic
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
酷 壳 – CoolShell
酷 壳 – CoolShell
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
Threat Research - Cisco Blogs
U
Unit 42
V
V2EX
V2EX - 技术
V2EX - 技术
L
LINUX DO - 最新话题
aimingoo的专栏
aimingoo的专栏
Microsoft Security Blog
Microsoft Security Blog
Recorded Future
Recorded Future
P
Privacy & Cybersecurity Law Blog
美团技术团队
小众软件
小众软件
F
Fortinet All Blogs

博客园 - linyizsh

t&h MTE Best fit gbuffer normal Mipmap不连续问题。 MLAA(Morphological Antialiasing) Volumetric Obscurance ao propagation volume... lpv CheckPoint 修改crysis支持nvperfhud volume light/light shaft/god ray 小更新下,加了DOF DeferShading + VSM + HDR + SSAO CheckPoint d3d10 放几张美图 4.1 Atmospheric Scattering prt ZT
说下pack/unpack normal的问题
linyizsh · 2009-05-30 · via 博客园 - linyizsh

  现在很多延迟光照算法,都有保存normal的pass,为了节约资源,很多有把normal三个分量pack为两个分量的算法,以d3d的左手坐标为例,normal在camera空间。
  最开始有:
    pack:xy = norm.xy;
    unpack:norm.xy = xy;
               norm.z = -sqrt(1 - x^2 - y^2);
  这个方法开始用的很广泛,但它是错的,因为由于透视投影的关系,有些面并不朝向眼睛方向,但仍然能被渲染进buffer里,所以z的符号不能确定。
  stalker对它做了一个非常直接的改进:
      pack:xy = norm.xy * 0.5 + 0.5;
              x *= norm.z>0?1:-1;
      unpack:norm.xy = abs(xy) * 2.0 - 1.0;
                 norm.z = (x > 0?1:-1) * sqrt(1 - x^2 - y^2);
  简而言之就是把z的符号存到pack后的x里,因为pack后x一定是正数,从算法上来讲这是正确的,但在实际使用中,通常用来保存normal的texture每个分量不会超过16 bit,则在x和y接近1的时候,会有比较大的误差,这个时候z接近0,如果是一个大的平面,x的符号会在1和-1之间抖动,表现在图像上主要是灰白相间的条纹。
  cryengine3的present的也有一个pack的方法:
      pack:xy = normalize(norm.xy) * sqrt(norm.z * 0.5 + 0.5);
      unpack:norm.z = length(xy)^2 * 2 - 1;
                 norm.xy = normalize(xy) * sqrt(1 - norm.z * norm.z);
  意思是将z的值作为xy向量的长度。unpack的时候先由长度得到z,然后由于xy比例一致,解norm.xy/sqrt(1-norm.z*norm.z)=norm.xy/sqrt(norm.x*norm.x+norm.y*norm.y)=xy/sqrt(x*x+y*y)即可得到xy,光从算法上看这也是正确的,但实际上用起来也是有的问题的,一个是除0的问题,因为有normalize操作,在z接近1或-1的时候,unpack xy会得一个误差比较大的结果,光照效果会有跳跃,不过并不明显。另外一个是这个算法计算量比较多,导致本身的误差积累比较大,同一个平面,相机在不同角度会有不同亮度,这个有些情况下很明显。

  后面的两个方法,实际上在没有比较大的平面的情况下,问题有时候不太明显,而且在增加bit数之后问题会有改善,但既然增加了bit数,不如干脆存三个分量来的直接,而且不需要pack/unpack指令。到现在为止我仍然没有找到一个算法有非常满意的结果,仍然直接存三个分量是最满意的。

  嗯,刚发完,托小Q的福,看了http://developer.nvidia.com/object/real-time-normal-map-dxt-compression.html这个文章,压缩dxt5和3dc normalmap的方法,不过也同样适用在这里:

    pack:pX = X / ( 1 + Z )
            pY = Y / ( 1 + Z )

    unpack:denom = 2 / ( 1 + pX * pX + pY * pY )
               X = pX * denom
               Y = pY * denom
               Z = denom - 1

  目前看来这是个比较不错的办法,虽然稍微慢些,但没有边界值和数值精度的问题。比较稳定。