当前位置: 首页 > news >正文

[cg][ds] 八面体映射编码Normal

UE 中的Normal 是通过UnitVectorToOctahedron将xyz,编码进二维xy中的,代码如下

OutGBufferA.rg = UnitVectorToOctahedron( normalize(GBuffer.WorldNormal) ) * 0.5f + 0.5f;float2 UnitVectorToOctahedron( float3 N )
{N.xy /= dot( 1, abs(N) );if( N.z <= 0 ){N.xy = ( 1 - abs(N.yx) ) * select( N.xy >= 0, float2(1,1), float2(-1,-1) );}return N.xy;
}

函数 float2 UnitVectorToOctahedron(float3 N) 的几何意义是将 单位球面(unit sphere)上的向量 映射到 二维平面上的八面体贴图(octahedral mapping)坐标。这种映射通常用于环境贴图(如天空盒)或压缩单位向量到 2D。


一、背景与动机

单位向量(即 ∥ N ∥ = 1 \|N\| = 1 N=1)表示球面上的一点。为了节省空间(比如存储在纹理中),我们希望将这个三维方向压缩成二维表示。Octahedral Mapping 是一种将单位球面映射到二维平面的一种高效方法,相较于球坐标和立方体贴图更均匀、无死角。


二、函数逐步解析

float2 UnitVectorToOctahedron(float3 N)
{N.xy /= dot(1, abs(N));
  • 将向量 N N N 的 xy 分量进行归一化,使得 ∣ N . x ∣ + ∣ N . y ∣ + ∣ N . z ∣ = 1 |N.x| + |N.y| + |N.z| = 1 N.x+N.y+N.z=1,这是八面体映射的核心。
  • dot(1, abs(N)) 表示 ∣ N . x ∣ + ∣ N . y ∣ + ∣ N . z ∣ |N.x| + |N.y| + |N.z| N.x+N.y+N.z
  • 得到的 N.xy 是初步映射到 2D 的坐标。
    if (N.z <= 0){N.xy = (1 - abs(N.yx)) * select(N.xy >= 0, float2(1,1), float2(-1,-1));}
  • 八面体映射将下半球( N . z ≤ 0 N.z \leq 0 N.z0)翻折映射到上半球的对应区域,以实现无缝 2D 映射。

  • N.yxN.xy 的交换,用于镜像处理。

  • select 是条件选择器(伪代码风格),表示:

    • 如果 N.xy >= 0,则使用 float2(1, 1)
    • 否则使用 float2(-1, -1)
  • 这样可以确保下半球的方向也能映射到 2D 空间中。

    return N.xy;
}

三、几何意义总结

  • 输入:单位向量 N ⃗ ∈ S 2 \vec{N} \in S^2 N S2(球面上的一点)

  • 输出:2D 平面坐标 v ⃗ ∈ [ − 1 , 1 ] 2 \vec{v} \in [-1,1]^2 v [1,1]2,表示该方向在八面体展开中的位置

  • 映射结构

    • 单位球体 → 八面体 → 展开成正方形平面
    • 映射是连续且几乎均匀的(适合 GPU 中的纹理存储)

四、可视化帮助

想象一个单位球体被一个八面体包住,然后将八面体沿其边缘展平在二维平面中。这个函数就是计算球面上任意一点在展开后的平面图中的位置。


相关文章:

  • 61、【OS】【Nuttx】编码规范解读(九)
  • SpringBoot 自动装配原理深度解析:从源码到实践
  • Bootstrap法进行随机模拟
  • 班翎流程平台 | 流程变量赋值事件,简化流程配置,灵活构建流程
  • micromamba安装 配置 pythonocc安装
  • LMEval ,谷歌开源的统一评估多模态AI模型框架
  • 树莓派设置静态ip 永久有效 我的需要设置三个 一个摄像头的 两个设备的
  • FastAPI 依赖注入
  • web-css
  • 2.2 C++之循环结构
  • arcgis js 4.x 的geometryEngine计算距离、面积、缓冲区等报错、失败
  • 整合Jdk17+Spring Boot3.2+Elasticsearch9.0+mybatis3.5.12的简单用法
  • OpenHarmony定制系统组合按键(二)
  • Linux线程入门
  • 麻省理工新突破:家庭场景下机器人实现精准控制,real-to-sim-to-real学习助力
  • Linux上给SD卡创建分区
  • Linux下挂载目录如何进行操作
  • 华为OD机试真题——最小矩阵宽度(宽度最小的子矩阵)(2025A卷:200分)Java/python/JavaScript/C/C++/GO最佳实现
  • 【异常解决】一招解决Navicat连接线上数据库时,隔一段时间不操作出现的卡顿问题
  • 【JavaEE】Spring事务
  • 专业的集团网站设计网络/我的百度购物订单
  • 一级造价工程师准考证打印时间/seo诊断a5
  • app网站制作美国传销/上海牛巨微seo
  • wordpress 站内搜索 慢/搜索引擎优化效果
  • 网站建设毕业设计综述/阿里指数查询入口
  • 淄博做网站的/百度网址大全官方网站