我尝试优化一个有效的计算着色器。其目的是创建图像:找到良好的颜色(使用一个小的调色板),然后调用imageStore(image, ivec2, vec4)
。
代码在这里:
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));
}
我想进行一些清理/优化,因为这种颜色转换在着色器中看起来很糟糕/没用(应该预先计算)。我的问题是:
vec4(r, g, b, 0.0)
?答案 0 :(得分:4)
是否可以直接这样做?不。
但是GLSL确实有许多用于打包/解包标准化值的功能。在您的情况下,您可以将值作为单个uint
uniform
传递,然后使用unpackUnorm4x8
将其转换为vec4
。因此您的代码变为:
vec4 color = unpackUnorm4x8(material.rgb);
这当然是内存与性能的折衷。因此,如果内存不是问题,则应该直接传递vec4
(never use vec3
)。
答案 1 :(得分:0)
是否可以使用4个字节(如R8G8B8A8)将vec4(r,g,b,0.0)直接打包在UBO中?
无法将其直接表示为4个单字节值。着色器中没有合适的数据类型,您无法将其声明为字节类型。
但是,为什么您认为需要这样做?只需将其上传为4个浮动元素-这是一个统一的样式,因此就好像您没有将其复制数千次一样,因此在实践中增加大小不会成为问题。