c++ - 读取和写入片段着色器中的缓冲区
问题描述
我正在尝试在片段中使用缓冲区,例如附加缓冲区:对于片段着色器的每次执行,我都会获取缓冲区的偏移量,添加数据并增加偏移量。
#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
)。
我认为问题在于片段着色器的并行执行:某些片段可能同时使用相同的缓冲区。
我的问题是:是否可以像使用 a 一样“锁定”资源std::mutex
以避免片段同时使用相同的资源?
解决方案
不需要互斥锁;只需使用索引值的原子增量:
uint id = atomicAdd(indexCount, 1);
所有这些原子函数都返回先前的值。所以你的代码应该没问题。
如果您根本不打算压缩数据(也就是说,如果您只是编写浮点数),那么制作输出 SSBO 真的没有意义。最好让它反映您正在编写的变量类型:
struct Vertex
{
vec4 pos;
vec4 color;
};
layout(std430, binding = 1) writeonly restrict buffer SSBO {
Vertex vertices[];
};
推荐阅读
- dicom - DICOM 文件元信息版本用零填充
- android - Android Beacon 在应用程序关闭后停止扫描(在最近的应用程序列表中将其刷掉)
- ios - 如何在 Swift 中修改 UISearchBar 的宽高?
- angular - 如何检查 angular5 中的所有 mat-checkbox?
- amazon-web-services - mkdir() 在本地 POXIS 文件系统上是否具有 AWS Elastic Block Storage 的原子性?
- laravel - 在 laravel 5.7 中安装 MDBootstrap(Vue 版本)
- apache-spark - spark SQL 线程被阻塞并永远运行
- php - 使用 php 将秒数转换为用户友好的格式
- c++ - C++ 重载 == 比较来自不同类的对象
- java - 如何防止 XMLStreamWriter writeCharacter 方法将 \r 转换为