1

我需要将 LUT 从 Android 应用程序传递到片段着色器以进行颜色校正。我发现了一些将 LUT 作为位图传递的示例

GLES20.glBindTexture(GLES20.GL_TEXTURE_CUBE_MAP, name);
...
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.raw.brick1);
GLUtils.texImage2D(GLES20.GL_TEXTURE_CUBE_MAP, 0, bitmap, 0);

但是,如果我的 LUT 不是 3D 图像文件并且不是使用一系列 texture2D 贴图构建的,该怎么办?我的 LUT 是一个float[]数组。如何在我的片段着色器中将它与统一的 samplerCube 绑定?

4

1 回答 1

1

简短的回答是“不可能直接通过 OpenGL 着色器,但可以通过渲染脚本”有关“着色器”方法的更多详细信息:片段着色器代码如下。注意必须定义1行才能使用texture3D

#extension GL_OES_texture_3D : enable 
precision mediump float;
uniform sampler2D u_texture0;
uniform vec4 uColor;
varying vec4 v_vertex;
uniform sampler3D u_lut;
void main() {
    vec2 texcoord0 = v_vertex.xy;
    vec4 rawColor=texture2D(u_texture0, texcoord0);
    vec4 outColor = texture3D(u_lut, rawColor.rgb);
    gl_FragColor = outColor; //rawColor;
}

爪哇代码:

FloatBuffer texBuffer = ByteBuffer.allocateDirect(array.length * Float.SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, iAxisSize, iAxisSize, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, texBuffer);

它可以在没有编译或运行时错误的情况下工作,但结果你会看到黑屏。当然你必须使用glTexImage3D函数而不是glTexImage2D,但是它没有在android SDK17中实现,你不能用它做任何事情。

好消息:在 Android SDK17 中实现了 ScriptIntrinsicLUT,可用于将 1D LUT 应用于源图像。Java代码如下:

private RenderScript mRS;
private Allocation mInAllocation;
private Allocation mOutAllocation;
private ScriptC_mono mScript;
private ScriptIntrinsicLUT mIntrinsic;
...
mRS = RenderScript.create(this);
mIntrinsic = ScriptIntrinsicLUT.create(mRS, Element.U8_4(mRS) );
createLUT();
mInAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
                                                Allocation.MipmapControl.MIPMAP_NONE,
                                                Allocation.USAGE_SCRIPT);
mOutAllocation = Allocation.createTyped(mRS, mInAllocation.getType());
mIntrinsic.forEach(mInAllocation, mOutAllocation);
mOutAllocation.copyTo(mBitmapOut);
...
private void createLUT() {
    for (int ct=0; ct < 256; ct++) {
        float f = ((float)ct) / 255.f;

        float r = f;
        if (r < 0.5f) {
            r = 4.0f * r * r * r;
        } else {
            r = 1.0f - r;
            r = 1.0f - (4.0f * r * r * r);
        }
        mIntrinsic.setRed(ct, (int)(r * 255.f + 0.5f));

        float g = f;
        if (g < 0.5f) {
            g = 2.0f * g * g;
        } else {
            g = 1.0f - g;
            g = 1.0f - (2.0f * g * g);
        }
        mIntrinsic.setGreen(ct, (int)(g * 255.f + 0.5f));

        float b = f * 0.5f + 0.25f;
        mIntrinsic.setBlue(ct, (int)(b * 255.f + 0.5f));
    }
}

更多详情:http: //developer.android.com/reference/android/renderscript/ScriptIntrinsicLUT.html http://my.fit.edu/~vkepuska/ece5570/adt-bundle-windows-x86_64/sdk/sources/ android-17/com/android/rs/image/CrossProcess.java

于 2013-02-11T15:56:58.737 回答