计算片段着色器中一行的平均值 (OpenGL ES 2.0)
Calculate mean of a row in the fragment shader (OpenGL ES 2.0)
我目前正在编写图像处理应用程序。为了达到所需的性能,我必须使用 GPU 来计算相机输入,更具体地说是使用 OpenGL ES 2.0。
在这个项目 (https://github.com/yulu/ShaderCam) 的帮助下,我实现了将图像传递到管道并使用片段着色器进行简单操作(如反转颜色等)。
我对 GLSL、片段着色器和顶点着色器的了解相当有限,但我知道管线约束以及这两个着色器在管线中的作用。
所以 - 制定问题 - 我想计算我收到的图像中一行的平均颜色,并 return 它(每行)到我的应用程序。
我在这里读到 这通常是可能的,但是我似乎无法找出以下内容:
1 (编辑:通过简单地将纹理的 w 和 h 传递给顶点和片段着色器解决):
知道行的结束位置(并将该信息保存在片段着色器中)。为此,我假设我必须将图片的宽度传递给顶点着色器,然后从那里传递给片段着色器,对吗?
2.: 如何计算片段着色器中每一行的颜色值的平均值,然后将它们传递给应用程序。如果我理解正确 - 片段着色器只执行每个像素的代码,所以我不确定如何实现这一点。
这是两个非常基本的着色器
顶点着色器:
uniform mat4 uTransformM;
uniform mat4 uOrientationM;
uniform vec2 ratios;
attribute vec2 aPosition;
varying vec2 vTextureCoord;
void main(){
gl_Position = vec4(aPosition, 0.0, 1.0);
vTextureCoord = (uTransformM * ((uOrientationM * gl_Position + 1.0)*0.5)).xy;
gl_Position.xy *= ratios;
}
片段着色器:
#extension GL_OES_EGL_image_external : require
precision mediump float;
uniform samplerExternalOES sTexture;
varying vec2 vTextureCoord;
void main(){
gl_FragColor = texture2D(sTexture, vTextureCoord);
//calc mean per row and pass it back
}
非常感谢您提供的每一个建议或帮助。
我找到了一种适合我的方法。这个想法是只计算一行像素的平均值,然后在应用程序中用
获得这一行
glReadPixels( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid * data);
这是我的片段着色器(注意表面的宽度也是必需的):
#extension GL_OES_EGL_image_external : require
precision mediump float;
uniform samplerExternalOES sTexture;
varying float width;
varying vec2 vTextureCoord;
void main(){
vec4 accumulatedRGB = texture2D(sTexture, vec2(0,vTextureCoord.y));
if(vTextureCoord.x < 0.50 && vTextureCoord.x > 0.499){ //small enough to only cover one line
for(float i=1.0;i<=width;++i)
{
float xPosOnTexture = i/width;
vec4 current = texture2D(sTexture, vec2(xPosOnTexture,vTextureCoord.y));
accumulatedRGB += current;
}
vec4 mean = accumulatedRGB/width;
gl_FragColor = vec4(mean.rgb , mean.a);//avg color for one line
}
else{
gl_FragColor = vec4(0.0,0.0,0.0,0.0);//rest of the screen
}
}
我目前正在编写图像处理应用程序。为了达到所需的性能,我必须使用 GPU 来计算相机输入,更具体地说是使用 OpenGL ES 2.0。 在这个项目 (https://github.com/yulu/ShaderCam) 的帮助下,我实现了将图像传递到管道并使用片段着色器进行简单操作(如反转颜色等)。
我对 GLSL、片段着色器和顶点着色器的了解相当有限,但我知道管线约束以及这两个着色器在管线中的作用。 所以 - 制定问题 - 我想计算我收到的图像中一行的平均颜色,并 return 它(每行)到我的应用程序。 我在这里读到 这通常是可能的,但是我似乎无法找出以下内容:
1 (编辑:通过简单地将纹理的 w 和 h 传递给顶点和片段着色器解决): 知道行的结束位置(并将该信息保存在片段着色器中)。为此,我假设我必须将图片的宽度传递给顶点着色器,然后从那里传递给片段着色器,对吗?
2.: 如何计算片段着色器中每一行的颜色值的平均值,然后将它们传递给应用程序。如果我理解正确 - 片段着色器只执行每个像素的代码,所以我不确定如何实现这一点。
这是两个非常基本的着色器 顶点着色器:
uniform mat4 uTransformM;
uniform mat4 uOrientationM;
uniform vec2 ratios;
attribute vec2 aPosition;
varying vec2 vTextureCoord;
void main(){
gl_Position = vec4(aPosition, 0.0, 1.0);
vTextureCoord = (uTransformM * ((uOrientationM * gl_Position + 1.0)*0.5)).xy;
gl_Position.xy *= ratios;
}
片段着色器:
#extension GL_OES_EGL_image_external : require
precision mediump float;
uniform samplerExternalOES sTexture;
varying vec2 vTextureCoord;
void main(){
gl_FragColor = texture2D(sTexture, vTextureCoord);
//calc mean per row and pass it back
}
非常感谢您提供的每一个建议或帮助。
我找到了一种适合我的方法。这个想法是只计算一行像素的平均值,然后在应用程序中用
获得这一行glReadPixels( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid * data);
这是我的片段着色器(注意表面的宽度也是必需的):
#extension GL_OES_EGL_image_external : require
precision mediump float;
uniform samplerExternalOES sTexture;
varying float width;
varying vec2 vTextureCoord;
void main(){
vec4 accumulatedRGB = texture2D(sTexture, vec2(0,vTextureCoord.y));
if(vTextureCoord.x < 0.50 && vTextureCoord.x > 0.499){ //small enough to only cover one line
for(float i=1.0;i<=width;++i)
{
float xPosOnTexture = i/width;
vec4 current = texture2D(sTexture, vec2(xPosOnTexture,vTextureCoord.y));
accumulatedRGB += current;
}
vec4 mean = accumulatedRGB/width;
gl_FragColor = vec4(mean.rgb , mean.a);//avg color for one line
}
else{
gl_FragColor = vec4(0.0,0.0,0.0,0.0);//rest of the screen
}
}