我正在尝试使用JOGL在Java和GLSL之间进行接口以并行处理数组。我对在屏幕上绘制任何内容都不感兴趣。我希望能够使用一对float数组,将它们传递给着色器程序,使用GPU处理它们,然后将值返回给Java代码。
例如,我有浮点数组
float[] array1 = {...};
float[] array2 = {...};
然后我有一个包含该行的着色器程序
float resultArray = sin(array2)*array1; // Just a random function of the two arrays
然后将'resultArray'作为浮点数组返回给我的Java程序以用于其他目的。
我当前的代码是
int v = gl.glCreateShader(GL.GL_VERTEX_SHADER);
int f = gl.glCreateShader(GL.GL_FRAGMENT_SHADER);
String vertShader =
"
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
}
";
gl.glShaderSource(v, 1, vertShader, (int[])null);
gl.glCompileShader(v);
String fragShader =
"
out float resultArray;
varying float array1;
varying float array2;
void main( void )
{
// Assuming this code should go in the fragment shader
float resultArray = sin(array2)*array1;
}
";
gl.glShaderSource(f, 1, fragShader, (int[])null);
gl.glCompileShader(f);
int shaderprogram = gl.glCreateProgram();
gl.glAttachShader(shaderprogram, v);
gl.glAttachShader(shaderprogram, f);
gl.glLinkProgram(shaderprogram);
gl.glValidateProgram(shaderprogram);
gl.glUseProgram(shaderprogram);
float[] resultArray = gl.callSomeMethodThatDoesntExist(shaderprogram, array1, array2);
但是我不确定如何将float数组传递到着色器中,也不确定如何处理后的结果。
有人能指出我正确的方向吗?
答案 0 :(得分:2)
嘿@Daniel,您可以使用制服将数组传递到着色器中。我喜欢将制服看作是着色器的参数或输入。
来自https://www.khronos.org/opengl/wiki/Uniform_(GLSL):
这些[制服]充当着色器程序的用户可以传递给该程序的参数。
struct Thingy
{
vec4 an_array[3];
int foo;
};
layout(location = 2) uniform Thingy some_thingies[6];
有些人喜欢将数组作为纹理传递,其中r,g,b值表示您在着色器中需要的一些值。
uniform sampler2D myTexture;
用于恢复您的输出;通常,您的着色器将输出到默认的帧缓冲区。
默认帧缓冲区是用于创建OpenGL的帧缓冲区。它与OpenGL上下文一起创建。像帧缓冲对象一样,默认的帧缓冲是一系列图像。与FBO不同,这些图像之一通常代表您实际在屏幕的某个部分看到的图像。 默认的帧缓冲区是在构造OpenGL上下文时创建的。
据我所知,片段着色器只能输出到帧缓冲区,因此,如果您需要取回某种数组,则需要输出到帧缓冲区,然后从帧缓冲区中提取数据
片段着色器的用户定义输出表示一系列 “颜色”。这些颜色值被定向到基于 在glDrawBuffers状态上。不过,这些被称为“片段颜色” 您可以将它们视为任意数据。
您还可以根据设置帧缓冲区的方式输出到多个缓冲区,请参见:https://www.khronos.org/opengl/wiki/Fragment_Shader#Output_buffers
片段颜色和帧缓冲区中的实际缓冲区之间的映射由glDrawBuffers定义,它是帧缓冲区状态的一部分。 例如,如果我们这样设置绘制缓冲区:
const GLenum缓冲区[] = {GL_COLOR_ATTACHMENT4,GL_COLOR_ATTACHMENT2, GL_NONE,GL_COLOR_ATTACHMENT0}; glDrawBuffers(4,buffers);
不幸的是,虽然片段着色器仅在每个像素可用的数据上操作,并且您无法控制哪个像素。为了解决这个问题,人们经常使用一种称为延迟着色的技术,该技术将有关像素所需的信息作为片段着色器的纹理输入(通常用于后期处理)传递。
希望这个答案不会太冗长和复杂,不幸的是,使用着色器返回数组比您预期的要复杂一些。
或者,OpenCL可能更适合您尝试做的事情,尽管我对此没有经验。