Opengl 我需要我的GLSL片段着色器返回距离计算

Opengl 我需要我的GLSL片段着色器返回距离计算,opengl,glsl,fragment-shader,Opengl,Glsl,Fragment Shader,我正在使用一些标准的GLSL(版本120)顶点和片段着色器来模拟激光雷达。换句话说,它应该返回颜色和距离,而不是在每个x,y位置(每个像素,通过片段着色器)返回颜色 我想我实际上并不需要所有的颜色,因为我只需要强度;例如,我可以将距离存储在gl\u FragColor.b中,并使用.rg作为强度。但是,我不完全清楚我是如何再次得到这个值的 有没有一种简单的方法可以从片段着色器返回值?我尝试了改变,但似乎片段着色器除了gl\u FragColor之外无法写入其他变量 我知道有些人使用GLSL管道进

我正在使用一些标准的GLSL(版本120)顶点和片段着色器来模拟激光雷达。换句话说,它应该返回颜色和距离,而不是在每个x,y位置(每个像素,通过片段着色器)返回颜色

我想我实际上并不需要所有的颜色,因为我只需要强度;例如,我可以将距离存储在
gl\u FragColor.b
中,并使用
.rg
作为强度。但是,我不完全清楚我是如何再次得到这个值的

有没有一种简单的方法可以从片段着色器返回值?我尝试了
改变
,但似乎片段着色器除了
gl\u FragColor
之外无法写入其他变量


我知道有些人使用GLSL管道进行通用(非图形)GPU处理,这可能是一种选择-除非我仍然希望正常渲染对象。

片段着色器输出到渲染缓冲区。如果您想使用GPU进行计算并将数据回迁到主机内存中,您有几个选项

  • 创建帧缓冲区并向其附加纹理以保存数据。渲染图像后,可以将纹理中的信息读回宿主内存
  • 使用或将内存写入任意绑定的缓冲区,并读回缓冲区内容

OpenGL已经通过深度缓冲区返回了这个“距离计算”,尽管它不是线性的。您可以简单地创建一个帧缓冲区对象(FBO),附加颜色和深度缓冲区,对其进行渲染,然后将结果放在深度缓冲区中(尽管您必须撤消深度变换)。如果您熟悉深度计算,这是编程的最简单选项

正如您所建议的,另一种方法是将值存储在颜色缓冲区中。您不必使用主颜色缓冲区,因为这样会丢失颜色或必须渲染两次。相反,将第二个渲染目标(纹理)附加到FBO(
GL\u COLOR\u ATTACHMENT1
),并使用
GL\u FragData[0]
作为普通颜色,使用
GL\u FragData[1]
作为距离(对于较新的GL版本,应在片段着色器中声明
out
变量)。这取决于所需的精度,但您可能希望使距离纹理32位浮动(
GL_R32F
并写入
GL_FragData[1].r
)。
-这是一个不错的起点:

是的,GLSL可用于计算目的。特别是ARB_图像_加载_存储和nvidia的无绑定图形。您甚至可以通过计算着色器访问共享内存(尽管我从来没有一个计算着色器的速度比它慢5倍)。正如@Jherico所说,片段着色器通常输出到帧缓冲区附件/渲染目标中的单个位置,最近的功能(如图像单元(ARB_image_load_store))允许您从着色器写入任意位置。这可能是过度的和缓慢的,但你也可以写你的距离到一个缓冲区通过图像单位


最后,如果要将数据返回到主机(CPU可访问)端,请将
glGetTexImage
与距离纹理一起使用(或者
glMapBuffer
如果决定使用图像单位)。

要将片段着色器输出返回到什么位置?主机内存?纹理?我想是宿主记忆吧。我不太清楚如何回答这个问题。我想,我只希望能够从缓冲区中获取值。我越想这个问题,就越觉得将其存储在颜色通道中是有意义的。但是,有没有办法不干扰颜色存储?你能添加一个链接或类似的东西来解释如何做到这一点吗?我以前听过这些答案,但找不到好的参考资料。我添加了一些相关文本的链接。我希望我能多次投票支持这个答案。谢谢,谢谢。