2013-02-03 63 views
1

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

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绑定?

+0

如何在'INT []'存储在所述浮子作为整数(使用相同的位模式,即,不截断),在该数组上执行'createBitmap'并将其上传为RGBA纹理?或者你可以使用'glUniform1fv'。 – Michael

回答

1

简短的回答是“这是不可能通过OpenGL着色器直接完成,但有可能通过的renderScript” 更多细节关于“着色器”的方法: 片段着色器的代码是波纹管。注意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; 
} 

java代码:

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