GPU PRO 5 - 1.2 Reducing Texture Memory Usage by 2-Channel Color Encoding 笔记

本笔记仅为个人的理解,如果有误欢迎指出。

Reducing Texture Memory Usageby 2-Channel Color Encoding

使用双通道颜色编码改善纹理内存

一般纹理上一个像素的颜色信息是存在RGB三个通道里,本篇文章将纹理通过一些前置条件把三个通道的信息有损压缩到两个通道上。

RGB颜色空间可以表示为一个三维表示的立方体,一张纹理的所有颜色都分布在这个立方体之内,但是普通的纹理他所有像素在这个立方体中存在一定的空间关联性,具体来说在三维空间中可以找到一个平面,他与这张纹理的所有像素点都相对较近。这个技术的实现的核心就是如何找到这个平面,并将这个平面用一个维度去表示。

文章将RGB颜色信息拆成了两个部分,一个是亮度信息,一个是色调/饱和度信息。这两个信息被两个通道所存储,通过这两个通道的信息最终得到一个在该平面上的颜色。

首先是如何计算出这个颜色平面。

第一步:将原始的RGB信息通过权重计算转换到一个新的RGB值。

这一步主要是为了调整各颜色在最终颜色平面的的影响,在文章中权重RGB的权重选择了1/2,1/4,1/2。γ表示从输入颜色空间转换到线性空间的 gamma 值

第二步:计算转换后的RGB到颜色平面的误差。

因为规定了平面是经过原点(0,0,0),所以颜色平面可以用一个法向量表示。转换后的点到平面的距离可以表示为点到法向量的点积

所以在这一步的目标是找到一个法向量使得各RGB点到该法向量的距离平方和最小,也就是:

而法向量如何选择文章中并没有给出详细说明,文章中说穷举候选法向量的方式来比较每个法向量的err,再选出误差最小的那个。但具体候选的法向量怎么来的:

第三步:将第一步的权重转换转换回来,这里直接用一个逆转置矩阵进行变换。

这个颜色平面在RGB颜色空间中与边界交叉可以获得几个顶点,一个顶点是(0,0,0),与顶点相邻的两个顶点(bc1,bc2)则定义为该颜色平面的基色。也就是平面的两个基向量。

平面上的所有颜色都位于原点和这两个基色点所构成的夹角范围内,而夹角则是最后所需要存储的数据。

夹角计算步骤如下:

1,将线RGB空间中的颜色点投影到该颜色平面上。

2,计算该点在平面上的二维坐标。

3,找到一条从原点开始经过该点的二维直线。

4,计算这条直线与两个基色之间的二维线段的交点比例,即得到基色的混合系数。

这个步骤将夹角映射到bc1 到 bc2 的线段上,用线段的比例表示这个夹角。

两个通道,一个通道存储基色的混合系数,表示色调。另一个通道存储亮度。

亮度由一个固定的公式从RGB信息计算得到:

颜色还原代码如下:


文章主要的思想其实还是如何用一个颜色平面拟合一张在RGB空间下的纹理,这个平面才是能够双通道存储的核心,这里用的是最小二乘法进行的拟合。

而每个颜色在映射到平面上后,已经可以用一个二维坐标表示,这个时候其实已经是实现了双通道存储数据的基础。但文章将xy坐标这个二维信息转换为了亮度和色调这两个信息,这应该是为了抽出亮度这个信息,方便在实际应用中调整图片效果。毕竟调整通道中xy的值会导致颜色失准,而调整亮度值并不会。

文章中的压缩示例:

参考链接:

GPU Pro5 渲染篇

相关推荐
一个人旅程~3 小时前
关于imac27inch因改短用户名导致混合硬盘和系统崩溃的问题分析与故障解决
经验分享·笔记·macos·新浪微博
心祭丫丫3 小时前
【每天一个 Python 小案例17】Python 实现通讯录
开发语言·人工智能·笔记·python·学习
派大猩猩_5 小时前
Obsidian 笔记怎么同步多端:Nutstore Sync 大笔记库同步测评
笔记·obsidian·obsidian插件·obsidian同步
叼烟扛炮9 小时前
Linux 学习笔记(五十):网络层——IP 协议、子网划分与 NAT 魔法
linux·笔记·学习
叼烟扛炮9 小时前
Linux 学习笔记(六十):单线程的逆袭——epoll 高并发服务器实战
linux·服务器·网络·笔记·学习·算法
Rabitebla11 小时前
【Linux操作系统】进程篇(十一):进程程序替换——从底层原理到 exec 函数族
linux·服务器·c++·笔记·学习·算法
叼烟扛炮12 小时前
[LangChain] 学习笔记(03):打破失忆症——对话机制与上下文管理
java·前端·javascript·笔记·学习·langchain
景煜拾年12 小时前
InnoAI SQL 助手
运维·数据库·笔记·sql
旖旎夜光12 小时前
【C++ 基础入门】类和对象(下):初始化列表、static 成员、友元与内部类
c++·笔记·学习
LONGZHIQIN12 小时前
STM32学习笔记
笔记·stm32·学习·arm