gpt4 book ai didi

c++ - 如何有效地计算整个像素着色器阶段使用颜色的次数?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:42:27 26 4
gpt4 key购买 nike

我正在考虑在像素着色器中实现它。这是我的部分代码:

首先,我创建一个 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 channel 来计算在整个像素着色器阶段使用了多少次颜色...

我想像下面的代码一样修改像素着色器中的颜色表。但它似乎不可行。

RandomTex[Index].a = RandomTex[Index].a + 1;

我一直在寻找一种有效计算颜色的方法,而不是使用 C++ 在纹理上渲染颜色并在 CPU 上计算。

我认为所有方法都必须在 cpu 上做一些额外的计数工作,因为我发现很难像 x++ 那样进行操作(可能是 gpu 上的一些并行问题),除了那些我认为需要渲染纹理两次的方法这可能比直接在 cpu 上计算要慢。

我研究了很长时间。但没有用。请帮助或尝试提供一些想法如何实现这一目标。

最佳答案

您可以将一个小的写入缓冲区附加到您的像素着色器(具有无序 View ),并在像素着色器中使用原子操作。

这里是修改后的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,因为第一个插槽仍由您的渲染目标占用。

您的写入缓冲区应该与您的一维纹理具有相同的元素计数,并且需要附加到管道(在渲染目标之上),带有OMSetRenderTargetsAndUnorderedAccessViews

每一帧,您还需要将缓冲区清除回 0(如果需要),否则值会随着时间增加,为此您可以使用 ClearUnorderedAccessViewUint

请注意,在您的情况下,由于您使用的是 uint 缓冲区并且该函数需要 UINT 值 [4],因此只有值 [0] 将用作清除值。

关于c++ - 如何有效地计算整个像素着色器阶段使用颜色的次数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46998180/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com