如何有效地计算在整个像素着色器阶段中使用颜色的次数
How to efficiently count the times that a color was used during whole Pixel Shader Stage?
我正在考虑在像素着色器中实现它。这是我的部分代码:
首先,我创建了一个Texture1D作为颜色表
D3D11_TEXTURE1D_DESC t1d;
t1d.Width = ModelInfo::ColorCount;
t1d.ArraySize = 1;
t1d.MipLevels = 1;
t1d.CPUAccessFlags = 0;
t1d.MiscFlags = 0;
t1d.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
t1d.Usage = D3D11_USAGE_DEFAULT;
t1d.BindFlags = D3D11_BIND_SHADER_RESOURCE;
ZeroMemory(&InitData, sizeof(InitData));
InitData.pSysMem = ModelInfo::Colors;
hr = m_D3DDevice->CreateTexture1D(&t1d, &InitData, &m_ColorTable);
if (FAILED(hr))
return hr;
D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
viewDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
viewDesc.Texture1D.MostDetailedMip = 0;
viewDesc.Texture1D.MipLevels = 1;
hr = m_D3DDevice->CreateShaderResourceView(m_ColorTable, &viewDesc, &m_ColorResView);
if (FAILED(hr))
return hr;
然后我把它传给像素着色器
m_ImmediateContext->PSSetShaderResources(0, 1, &m_ColorResView);
在像素着色器中,我使用这样的颜色表:
Texture1D RandomTex : register(t0);
float4 PS(VS_OUTPUT Input, uint Primitive : SV_PrimitiveID) : SV_Target
{
uint Index = Primitive % ColorCount.x;
return RandomTex[Index];
}
我想使用这个颜色表中每种颜色的alpha通道来计算在整个像素着色器阶段中使用的颜色的次数。。。
我想修改像素着色器中的颜色表,就像下面的代码一样。但这似乎是不可行的。
RandomTex[Index].a = RandomTex[Index].a + 1;
我一直在寻找一种方法来有效地计算颜色,而不是在纹理上渲染,并使用c++在cpu上计算。
我想的所有方法都必须在cpu上做一些额外的计数工作,因为我发现很难做像x++这样的操作(可能是gpu上的一些并行问题),此外,我认为需要渲染纹理两次的方法可能比在cpu上直接计数要慢。
我已经研究了很长时间了。但没有用。请帮助或尝试给出一些如何实现这一目标的想法。
您可以将一个小的写入缓冲区附加到像素着色器(使用无序视图),并在像素着色器中使用原子操作。
这是修改后的HLSL代码
Texture1D RandomTex : register(t0);
RWStructuredBuffer<uint> RWColorCountData : register(u1);
float4 PS(VS_OUTPUT Input, uint Primitive : SV_PrimitiveID) : SV_Target
{
uint Index = Primitive % ColorCount.x;
InterlockedAdd(RWColorCountData[Index], 1);
return RandomTex[Index];
}
这里我使用StructuredBuffer,但如果您愿意,也可以使用ByteAddressBuffer。还要注意,资源附加到寄存器u1,因为第一个插槽仍然由渲染目标占用。
写入缓冲区应具有与1d纹理相同的元素计数,并且需要连接到管道(在渲染目标的顶部),使用OMSetRenderTargetsAndUnorderedAccessViews
每帧,您还需要将缓冲区清除回0(如果需要),否则,值将随着时间的推移而增加,为此您可以使用ClearUnorderedAccessViewUint
请注意,在您的情况下,由于您使用的是uint缓冲区,并且函数需要uint Values[4],因此只有Values[0]将用作清除值。
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 是否可以在C++中使变量真正只读
- 如何从C++代码中检索 QML 的文本字段中的文本?
- 在C++中使用线程查找友好号码比单个线程花费更多时间
- QDateTime::toString() 在退出处理程序中使用时失败
- Qt::D irectConnection在多线程环境中使用时如何工作?
- 实例化时结构字段中的默认值
- C++,在多行代码段中注释
- G++ 在生成文件中使用时停止工作
- 如何使用连接器 c++ 在 mySQL 表二进制(16) 字段中存储 c++ 字节数组?
- 在C++中使虚拟函数私有化
- 从OpenGL应用程序中提取颜色/深度缓冲区
- 为什么"non-standard syntax; use '&' to create a pointer to member"在 CTOR 中使用线程?
- PyFunctionObject 在 Py_Finalize 中使程序崩溃,如果它在 PyTuple 中被设置了项目
- 当在循环中使用时,std::shared_ptr 对该循环的矢量化有任何影响吗?
- 在缓冲区/数组中使用颜色结构
- 如何检查字段中输入的数字是否重复
- QTranslator 在 if 语句中使用时不起作用
- 隐藏复合数据类型的某些字段,使其不被写入(或从hdf5文件中读取)
- 在实例变量中定义字段会使所有实例字段相同