Glsl 我可以将R8G8B8A8放入UBO中,并将其用作vec4吗?

Glsl 我可以将R8G8B8A8放入UBO中,并将其用作vec4吗?,glsl,vulkan,compute-shader,Glsl,Vulkan,Compute Shader,我尝试优化一个工作的计算着色器。它的目的是创建一个图像:使用一个小调色板找到好的颜色,并调用imageStoreimage、ivec2、vec4 颜色在UNIFORMBUFER中以uint数组进行索引。 此UBO中的一种颜色打包在一个uint中,如{0-255,0-255,0-255,0-255}。 代码如下: struct Entry { *some other data* uint rgb; }; layout(binding = 0) uniform SConfigura

我尝试优化一个工作的计算着色器。它的目的是创建一个图像:使用一个小调色板找到好的颜色,并调用imageStoreimage、ivec2、vec4

颜色在UNIFORMBUFER中以uint数组进行索引。 此UBO中的一种颜色打包在一个uint中,如{0-255,0-255,0-255,0-255}。 代码如下:

struct Entry
{
    *some other data*
    uint rgb;
};

layout(binding = 0) uniform SConfiguration
{
    Entry materials[MATERIAL_COUNT];
} configuration;

void main()
{
    Entry material = configuration.materials[currentMaterialId];

    float r = (material.rgb >> 16) / 255.;
    float g = ((material.rgb & G_MASK) >> 8) / 255.;
    float b = (material.rgb & B_MASK) / 255.;

    imageStore(outImage, ivec2(gl_GlobalInvocationID.xy), vec4(r, g, b, 0.0));
}
我想清理/优化一点,因为这种颜色转换在着色器中看起来很糟糕/无用,应该预先计算。我的问题是:

是否可以使用像R8G8B8A8那样的4个字节,在UBO中直接打包vec4r、g、b、0.0? 是否可以使用像R8G8B8A8那样的4个字节,在UBO中直接打包vec4r、g、b、0.0

无法将其直接表示为4个单字节值;着色器中没有适当的数据类型允许您将其声明为字节类型

然而,你为什么认为你需要这样做?只需将其上传为4个浮点数——这是一个统一的浮点数,因此您不会将其复制数千次,因此在实践中,额外的大小不太可能是一个问题

是否可以使用像R8G8B8A8那样的4个字节,在UBO中直接打包vec4r、g、b、0.0

无法将其直接表示为4个单字节值;着色器中没有适当的数据类型允许您将其声明为字节类型


然而,你为什么认为你需要这样做?只需将其上传为4个浮点数-这是一个统一的浮点数,因此您不会将其复制数千次,因此在实践中,额外的大小不太可能是一个问题。

可以直接进行吗?没有

但是GLSL确实有许多用于打包/解包规范化值的函数。在您的情况下,可以将该值作为单个uint统一传递,然后使用Unpunorm4x8将其转换为vec4。因此,您的代码变成:

    vec4 color = unpackUnorm4x8(material.rgb);

当然,这是内存与性能的折衷。因此,如果内存不是问题,您应该直接传递vec4。

可以直接传递吗?没有

但是GLSL确实有许多用于打包/解包规范化值的函数。在您的情况下,可以将该值作为单个uint统一传递,然后使用Unpunorm4x8将其转换为vec4。因此,您的代码变成:

    vec4 color = unpackUnorm4x8(material.rgb);

当然,这是内存与性能的折衷。因此,如果内存不是问题,您可能应该直接传递vec4。

与原始问题无关,但为什么需要在此处使用imageStore?它通常比仅从片段着色器中写入像素更慢、更高的功耗,并且通常会禁用优化,例如帧缓冲区压缩。除非你真的需要,否则不要使用它;对于像这样的简单情况,片段着色器几乎总是一个更好的解决方案。我不为主板使用任何顶点/片段/光栅化,只为UI使用。这里有一些照片:。所以我认为imageStore对我来说是最好的选择,但是我愿意接受更多的意见,因为我在渲染领域还是个新手。你认为它是imageStore的一个好用例吗?与最初的问题无关,但是为什么你需要在这里使用imageStore呢?它通常比仅从片段着色器中写入像素更慢、更高的功耗,并且通常会禁用优化,例如帧缓冲区压缩。除非你真的需要,否则不要使用它;对于像这样的简单情况,片段着色器几乎总是一个更好的解决方案。我不为主板使用任何顶点/片段/光栅化,只为UI使用。这里有一些照片:。所以我认为imageStore对我来说是最好的选择,但是我愿意接受更多的意见,因为我在渲染领域还是个新手。你认为它是imageStore的一个很好的用例吗?事实上,在写这个问题时,我也这么认为。我没有太多的材料,所以空间不是问题,这个缓冲区永远不会更新。谢谢你的回答。澄清的答案只是为了消除术语包使用的任何歧义,因为你可以按照上面的@Nicol Bolas答案使用unpack。事实上,在写问题时,我也这么想。我没有太多的材料,所以空间不是问题,这个缓冲区永远不会更新。谢谢你的回答。澄清答案只是为了消除术语包使用的任何歧义,因为你可以按照上面的@Nicol Bolas答案使用unpack。unpack并不总是免费的,所以除非你真的需要节省空间,否则上传4个浮动。unpack并不总是免费的,除非你真的需要节省空间,上传4个浮动。