Opengl 在片段着色器中读取自定义纹理格式
我正在创建一个NES模拟器,我正在试验将功能(在适当的情况下)卸载到GPU的想法。我想到的一个想法是以自定义格式将屏幕像素输出到缓冲区,对每个像素的属性进行编码,以便着色器可以确定如何显示它们。这将从emulator中最热门的函数之一中卸载相当多的逻辑/分支 以下是单个像素的编码示例,每个像素使用2个字节: 字节1(调色板索引):Opengl 在片段着色器中读取自定义纹理格式,opengl,shader,vulkan,Opengl,Shader,Vulkan,我正在创建一个NES模拟器,我正在试验将功能(在适当的情况下)卸载到GPU的想法。我想到的一个想法是以自定义格式将屏幕像素输出到缓冲区,对每个像素的属性进行编码,以便着色器可以确定如何显示它们。这将从emulator中最热门的函数之一中卸载相当多的逻辑/分支 以下是单个像素的编码示例,每个像素使用2个字节: 字节1(调色板索引):bbbb-ssss b:背景像素调色板索引 s:精灵像素调色板索引 字节2(像素属性):bbs rgbp b:2位背景像素值 s:2位精灵像素值 r:强调红色 g
bbbb-ssss
:背景像素调色板索引b
:精灵像素调色板索引s
bbs rgbp
:2位背景像素值b
:2位精灵像素值s
:强调红色r
:强调绿色g
:强调蓝色b
:精灵像素优先级p
我对编写着色器比较陌生,所以我的第一个问题是:这可能吗?在我所做的研究中,似乎纹理需要采用特定的格式,以便在每个像素处从纹理中读取颜色信息,而我自定义的2字节“颜色”格式本身甚至不表示颜色。如果可能,可以采取什么高级别方法来实现这一点?我计划使用vulkan,但任何更普遍的方法(因为它与着色器相关)都是受欢迎的。图形自2000年以来发生了变化。着色器(大部分)是计算值的任意程序。这些值有时可能被解释为颜色是不相关的。着色器是程序;他们做你想让他们做的事 类似地,纹理不包含颜色,除非着色器选择将其解释为颜色。纹理只不过是值的查找表。同样,这些值可能是颜色,但可能不是。这完全取决于着色器如何使用这些值 可以创建使用整数格式(与规格化整数相反)的纹理。然后,您可以在着色器中执行任何您喜欢的位操纵。对于着色器来说,上面描述的任何操作都不会特别困难 在您的例子中,纹理可能是2通道格式,每个通道8位,使用无符号整数值。在OpenGL中,此格式将拼写为
GL\u RG8UI
:红色/绿色(两个通道的名称)、每个通道8位和无符号整数值。OpenGL可能会将这些通道称为“红色”和“绿色”,但重要的是着色器如何处理它们,而不是它们的名称
在Vulkan中,此格式的拼写为VK_format\u R8G8_UINT
:两个8位无符号整数值通道
您将遇到的主要问题不是图像格式或着色器。它以一种高效的方式将数据传输到GPU
在OpenGL中,您别无选择,只能不断地将数据从CPU可访问的内存DMA到GPU可访问的纹理。在Vulkan,您可能不必这样做
Vulkan实现可以说线性纹理可以存储在CPU和GPU都可访问的内存中。他们不需要提供这些,但很多人可以这样做。在这种实现中,不需要DMA;GPU可以直接读取CPU所写的内容。您仍然需要加倍缓冲这样的图像(以最小化GPU/CPU同步。当GPU读取前一帧的数据时,您正在写入一个图像),但这应该会提高DMA版本的性能
当然,对于无法实现的实现,您仍然需要一个代码路径。图形自2000年以来发生了变化。着色器(大部分)是计算值的任意程序。这些值有时可能被解释为颜色是不相关的。着色器是程序;他们做你想让他们做的事 类似地,纹理不包含颜色,除非着色器选择将其解释为颜色。纹理只不过是值的查找表。同样,这些值可能是颜色,但可能不是。这完全取决于着色器如何使用这些值 可以创建使用整数格式(与规格化整数相反)的纹理。然后,您可以在着色器中执行任何您喜欢的位操纵。对于着色器来说,上面描述的任何操作都不会特别困难 在您的例子中,纹理可能是2通道格式,每个通道8位,使用无符号整数值。在OpenGL中,此格式将拼写为
GL\u RG8UI
:红色/绿色(两个通道的名称)、每个通道8位和无符号整数值。OpenGL可能会将这些通道称为“红色”和“绿色”,但重要的是着色器如何处理它们,而不是它们的名称
在Vulkan中,此格式的拼写为VK_format\u R8G8_UINT
:两个8位无符号整数值通道
您将遇到的主要问题不是图像格式或着色器。它以一种高效的方式将数据传输到GPU
在OpenGL中,您别无选择,只能不断地将数据从CPU可访问的内存DMA到GPU可访问的纹理。在Vulkan,您可能不必这样做
Vulkan实现可以说线性纹理可以存储在CPU和GPU都可访问的内存中。他们不需要提供这些,但很多人可以这样做。在这种实现中,不需要DMA;GPU可以直接读取CPU所写的内容。您仍然需要加倍缓冲这样的图像(以最小化GPU/CPU同步。当GPU读取前一帧的数据时,您正在写入一个图像),但这应该会提高DMA版本的性能
当然,对于不可能实现的实现,您仍然需要一个代码路径