Reputation: 377
Is there any way to do simple aggregated calculations over intermediate results in an OpenGL ES 2.0 shader?
For example, I have a vertex shader:
precision highp float;
attribute vec2 vTexPosition;
attribute vec3 vPosition;
varying vec2 fTexPosition;
void main() {
fTexPosition = vTexPosition;
gl_Position = vec4(vPosition, 1);
}
And a fragment shader:
precision highp float;
uniform float maxSomeHardToCalculateValue;
varying vec2 fTexPosition;
void main() {
float someHardToCalculateValue = someHeavyFunction(fTexPosition);
gl_FragColor = vec4(hsl2rgb(0, 0.6, someHardToCalculateValue / maxSomeHardToCalculateValue), 1);
}
I'm calling them from Android with something like this:
private void draw(float maxValue) {
int maxValueLocation = GLES20.glGetUniformLocation(programId, "maxSomeHardToCalculateValue");
GLES20.glUniform1f(maxValueLocation, maxValue);
int positionHandle = GLES20.glGetAttribLocation(programId, "vPosition");
int texPositionHandle = GLES20.glGetAttribLocation(programId, "vTexPosition");
GLES20.glEnableVertexAttribArray(positionHandle);
GLES20.glEnableVertexAttribArray(texPositionHandle);
GLES20.glVertexAttribPointer(positionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, COORDS_PER_VERTEX * 4, vertexBuffer);
GLES20.glVertexAttribPointer(texPositionHandle, TEX_COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, TEX_COORDS_PER_VERTEX * 4, textureBuffer);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, orderBuffer.capacity(), GLES20.GL_UNSIGNED_SHORT, orderBuffer);
GLES20.glDisableVertexAttribArray(texPositionHandle);
GLES20.glDisableVertexAttribArray(positionHandle);
}
And then
setupProgram();
setupFramebuffer();
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, framebufferId);
draw(1f);
float maxValue = getMaxValueSomehow();
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
draw(maxValue);
In this example, I need a way to extract the max of the calculated someHardToCalculateValue
. I'm currently getting pixel info from the framebuffer with GLES20.glReadPixels
and calculating the max, but it's giving me 8-bit precission, which is not enough.
I've thought of accessing some kind of writable atomic uniform
directly from the shader and put the max there too, but after reading the Internet and do some tests with atomic counters I'm beginning to think it's not possible, at least in Android.
Upvotes: 0
Views: 40