6

我正在寻找一种在鼠标点读取像素颜色的方法。在 OpenGL 中,它是通过在绘制场景(或部分场景)后调用函数“glReadPixels”来完成的。我想在背景中做一个简单的颜色选择例程,用于识别 3D 空间中的形状/线条。

那么,在 SharpDX (DirectX10 / DirectX11) 中是否有任何等效的方法/功能/建议可以做同样的事情?

4

3 回答 3

8

Direct3D11 完全可以做到这一点:只需按照以下步骤操作:

  • 使用DeviceContext.CopySubResourceRegion将部分从源纹理复制到暂存纹理(要回读的像素区域的大小,格式相同,但使用 ResourceUsage.Staging)
  • 使用 Device.Map/UnMap 从这个暂存纹理​​中检索像素。

网上有很多关于这个话题的讨论(例如:“在DX11中从纹理读取一个像素到CPU ”)

于 2012-11-12T15:06:44.720 回答
2

另一种选择是使用小型计算着色器,例如:

Texture2D<float4> TextureInput: register(t0);
StructuredBuffer<float2> UVBuffer: register(t1);
RWStructuredBuffer<float4> RWColorBuffer : register(u0);

SamplerState Sampler : register( s0 );

[numthreads(1, 1, 1)]
void CSGetPixels( uint3 DTid : SV_DispatchThreadID )
{ 
float4 c = TextureInput.SampleLevel(Sampler , UVBuffer[DTid.x].xy, 0);
RWColorBuffer [DTid.x] = c;
}

它为您提供了更多“格式不可知论”的优势。

过程就是这样。

  • 为 UV (float2) 创建一个小的结构化缓冲区(像素位置/纹理大小,当然不要忘记翻转 Y 轴)。将要采样的像素位置复制到此缓冲区中。
  • 创建一个可写缓冲区和一个暂存缓冲区 (float4)。需要与您的 uv 缓冲区相同的元素计数。
  • 全部绑定并调度
  • 将可写缓冲区复制到暂存缓冲区。
  • 在 cpu 中映射和读取 float4 数据

请注意,为简单起见,我省略了计算着色器中的线程组优化/检查。

于 2012-11-13T06:42:18.170 回答
1

由于您使用的是 C#,我的建议是使用 GDI+,因为 DX 中没有像“glReadPixels”这样的功能。GDI+ 提供了非常简单的方法来读取鼠标指针处的像素颜色。请参阅stackoverflow.com/questions/1483928

如果 GDI+ 不行,因为它不是很快,你不能坚持使用“Ray”来拾取通常的对象吗?您想识别(我想是 3 维的)形状/线条,这很容易使用射线(并检查交叉点)来挑选它们。

于 2012-11-12T12:36:38.510 回答