读取和写入片段着色器中的缓冲区
Read and write to a buffer in a fragment shader
我正在尝试在片段中使用缓冲区,例如追加缓冲区:对于片段着色器的每次执行,我都会获取缓冲区的偏移量,添加数据并增加偏移量。
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(location = 0) in vec2 inPosition;
layout(location = 0) out vec4 outColor;
layout(std140, binding = 0) buffer CommandDraw {
uint indexCount;
uint instanceCount;
uint firstIndex;
int vertexOffset;
uint firstInstance;
};
layout(std430, binding = 1) buffer SSBO {
float data[];
};
void addVertex(vec4 pos, vec4 color)
{
uint id = indexCount++;
uint offset = id * 8;
data[offset] = pos.x;
data[offset + 1] = pos.y;
data[offset + 2] = pos.z;
data[offset + 3] = pos.w;
data[offset + 4] = color.x;
data[offset + 5] = color.y;
data[offset + 6] = color.z;
data[offset + 7] = color.w;
}
void main()
{
vec3 color = vec3(0.0);
addVertex(vec4(inPosition, 0.0, 1.0), vec4(1.0, 0.0, 0.0, 1.0));
outColor = vec4(inPosition / 2.0 + vec2(0.5), 0.0, 1.0);
}
我用全屏四边形执行片段着色器。
问题是最终偏移量(此处为 indexCount
)太低:它应该等于 width * height
,但该值较低(大约 60
,范围等于 1280 * 720
).
我认为问题是由于片段着色器的并行执行造成的:某些片段可能同时使用相同的缓冲区。
我的问题是:是否可以像使用 std::mutex
一样 "lock" 资源来避免片段同时使用相同的资源?
不需要互斥;只需使用 atomic increment of the index value:
uint id = atomicAdd(indexCount, 1);
所有这些原子函数 return 以前的值。所以你的代码应该没问题。
如果您根本不打算压缩数据(也就是说,如果您只是编写浮点数),那么制作输出 SSBO 真的毫无意义。最好让它反映您正在编写的变量类型:
struct Vertex
{
vec4 pos;
vec4 color;
};
layout(std430, binding = 1) writeonly restrict buffer SSBO {
Vertex vertices[];
};
我正在尝试在片段中使用缓冲区,例如追加缓冲区:对于片段着色器的每次执行,我都会获取缓冲区的偏移量,添加数据并增加偏移量。
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(location = 0) in vec2 inPosition;
layout(location = 0) out vec4 outColor;
layout(std140, binding = 0) buffer CommandDraw {
uint indexCount;
uint instanceCount;
uint firstIndex;
int vertexOffset;
uint firstInstance;
};
layout(std430, binding = 1) buffer SSBO {
float data[];
};
void addVertex(vec4 pos, vec4 color)
{
uint id = indexCount++;
uint offset = id * 8;
data[offset] = pos.x;
data[offset + 1] = pos.y;
data[offset + 2] = pos.z;
data[offset + 3] = pos.w;
data[offset + 4] = color.x;
data[offset + 5] = color.y;
data[offset + 6] = color.z;
data[offset + 7] = color.w;
}
void main()
{
vec3 color = vec3(0.0);
addVertex(vec4(inPosition, 0.0, 1.0), vec4(1.0, 0.0, 0.0, 1.0));
outColor = vec4(inPosition / 2.0 + vec2(0.5), 0.0, 1.0);
}
我用全屏四边形执行片段着色器。
问题是最终偏移量(此处为 indexCount
)太低:它应该等于 width * height
,但该值较低(大约 60
,范围等于 1280 * 720
).
我认为问题是由于片段着色器的并行执行造成的:某些片段可能同时使用相同的缓冲区。
我的问题是:是否可以像使用 std::mutex
一样 "lock" 资源来避免片段同时使用相同的资源?
不需要互斥;只需使用 atomic increment of the index value:
uint id = atomicAdd(indexCount, 1);
所有这些原子函数 return 以前的值。所以你的代码应该没问题。
如果您根本不打算压缩数据(也就是说,如果您只是编写浮点数),那么制作输出 SSBO 真的毫无意义。最好让它反映您正在编写的变量类型:
struct Vertex
{
vec4 pos;
vec4 color;
};
layout(std430, binding = 1) writeonly restrict buffer SSBO {
Vertex vertices[];
};