恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
方向一指,颜色即现:揭秘立方体贴图原理
首页
资讯中心
/
方向一指,颜色即现:揭秘立方体贴图原理
方向一指,颜色即现:揭秘立方体贴图原理
发布时间:2026/10/16 2:12:14
一句话答案拍贴图时就是按方向存的查的时候再按方向取回来。存和取用的是同一套规则所以一一对应。下面分步讲清楚。一、核心画面从盒子中心射出一条线还是那个比喻你站在正方体房间的正中心6 面墙贴着照片。现在你朝某个方向伸出一根激光笔┌─────────────────┐ │ │ │ ● │ ← 激光打到墙上的这个点 │ ╱ │ │ ╱ │ │ ◎ │ ← 你站在中心 │ │ └─────────────────┘关键事实从中心出发一个方向只会打到墙上唯一一个点。方向不同 → 打到的点不同方向相同 → 一定打到同一个点所以方向和墙上的点是一一对应的。墙上的点又对应照片上的某个像素于是方向 → 墙上的点 → 照片上的像素 → 颜色剩下的问题只是怎么算出激光打在哪面墙、哪个位置只需要三步。二、三步算出落点先约定房间中心在原点 (0,0,0)6 面墙分别在右墙 x 1 左墙 x -1 上墙 y 1 下墙 y -1 前墙 z 1 后墙 z -1举个例子方向是(0.4, 0.2, 0.8)意思是往右一点、往上一点点、主要往前。第 1 步选墙 —— 看哪个数最大激光同时往三个方向前进x 方向每走一步前进 0.4y 前进 0.2z 前进 0.8。谁前进得最快谁就最先撞到墙。z 方向走得最快0.8 最大→ 最先碰到 z 1 的墙 → 打在【前墙】规则就是看三个分量中绝对值最大的那个它决定撞哪面墙正负号决定是前还是后右还是左、上还是下。第 2 步算位置 —— 等比例放大让最大的那个变成 1前墙在 z 1 的位置。激光要走到 z 1需要把整个方向等比例放大0.8 要变成 1就要除以 0.8 (0.4, 0.2, 0.8) ÷ 0.8 (0.5, 0.25, 1)这就是激光撞墙时的真实坐标z 1 说明在前墙上而剩下的(0.5, 0.25)就是在这面墙上的位置——中心偏右 0.5偏上 0.25。前墙范围 -1 到 1 ┌──────────────────────┐ 1 │ │ │ ● │ ← (0.5, 0.25) │ ┼ │ ← 墙的中心 (0, 0) │ │ └──────────────────────┘ -1 -1 1第 3 步换算成图片坐标墙上坐标范围是 -1 到 1而图片坐标习惯用 0 到 1简单平移缩放一下图片坐标 (墙上坐标 1) ÷ 2 横向(0.5 1) ÷ 2 0.75 纵向(0.25 1) ÷ 2 0.625如果前墙这张图是 256×256那就是第192 列、160 行附近的像素。读出它的颜色完成三、为什么方向的长短无所谓试试把方向换成(4, 2, 8)它和 (0.4, 0.2, 0.8) 指向同一个方向只是长了 10 倍z 最大 → 前墙 (4, 2, 8) ÷ 8 (0.5, 0.25, 1) ← 和刚才完全一样因为第 2 步要除以最大的那个长度被自动消掉了。所以 Shader 里传方向时不用归一化只要方向对就行。同一条射线上的所有点查到的都是同一个颜色。四、最关键的为什么存的时候就是这么存的前面讲的是怎么取但为什么取出来的颜色刚好就是那个方向的景色看贴图是怎么做出来的在中心放一个相机视角 90°朝前、后、左、右、上、下各拍一张。相机拍照的本质就是照片上的每个像素记录的都是从相机位置朝某个方向看过去的颜色。拍的时候 方向 (0.4, 0.2, 0.8) 看到一棵树 → 存进前墙照片的 (0.75, 0.625) 取的时候 给出方向 (0.4, 0.2, 0.8) → 算出前墙照片的 (0.75, 0.625) → 取回那棵树存和取用的是同一套几何关系所以必然对得上。至于为什么是 90°6 个 90° 的视野刚好把周围一圈不重不漏地拼满没有缝隙也没有重叠。五、实际写代码时上面三步你完全不用自己写。Shader 里只需要一句float4 color texCUBE(_Cube, direction);显卡里有专门的硬件自动完成选墙 → 除以最大值 → 换算坐标 → 读像素。你真正要关心的只是传进去的方向从哪来用途传入的方向含义天空盒视线方向我往哪看就看到哪片天反射视线被表面反弹后的方向镜子里映出反弹方向上的东西环境光表面法线方向朝上的面接收天空的光朝下的接收地面的点光源阴影灯 → 被照点的方向灯往这个方向看最近的东西有多远一句话总结从盒子中心朝某个方向射一条线必定打在唯一一面墙的唯一一个点上。选墙看哪个分量最大定位置靠除以这个最大值。而贴图本来就是站在中心朝各个方向拍下来的所以按方向取正好取回那个方向的景色。