android GPUImage シェーダ文字列を別ファイルにするには

cyberagent製のGPUImageFilterのシェーダは、java/kotlinの文字列で定義されています。

次は、GPUImageContrastFilter.java の CONTRAST_FRAGMENT_SHADERです。

public static final String CONTRAST_FRAGMENT_SHADER = "" + "varying highp vec2 textureCoordinate;\n" + " \n" + " uniform sampler2D inputImageTexture;\n" + " uniform lowp float contrast;\n" + " \n" + " void main()\n" + " {\n" + " lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + " \n" + " gl_FragColor = vec4(((textureColor.rgb - vec3(0.5)) * contrast + vec3(0.5)), textureColor.w);\n" + " }";

文字列のまま編集するのは、面倒なんですね。行ごとに、ダブルクォートで囲んで、行末に「+」をつける必要があります。

別ファイルにしたいなと思って探したら、GPUImageFilterにloadShaderメソッドとconvertStreamToStringメソッドがありました。

(1)loadShaderメソッド

loadShaderメソッドは、assetsから読み込みます。次のように使います。

GPUImageGrayscaleFilterを機能はそのままで、シェーダー文字列をassetsに出して、MyGPUImageGrayscaleFilterを作ってみます。

まず、assets/gpuimage/my_grayscale.c を新規作成します。

precision highp float; varying vec2 textureCoordinate; uniform sampler2D inputImageTexture; const highp vec3 W = vec3(0.2125, 0.7154, 0.0721); void main() { lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); float luminance = dot(textureColor.rgb, W); gl_FragColor = vec4(vec3(luminance), textureColor.a); }

次に、MyGPUImageGrayscaleFilter.javaを作ります。

public class MyGPUImageGrayscaleFilter extends GPUImageFilter { public static MyGPUImageGrayscaleFilter create(Context context) { String fragmentShader = GPUImageFilter.loadShader("gpuimage/my_grayscale.c", context); return new MyGPUImageGrayscaleFilter(fragmentShader); } public MyGPUImageGrayscaleFilter(String fragmentShader) { super(NO_FILTER_VERTEX_SHADER, fragmentShader); } }

GPUImageFilterのインスタンスを作る箇所では、上で用意したcreateメソッドを使います。

GPUImageGrayscaleFilter filter = new GPUImageGrayscaleFilter(); ↓ MyGPUImageGrayscaleFilter filter = MyGPUImageGrayscaleFilter.create(context);

または、次のように MyGPUImageGrayscaleFilter.javaを作っておき、

public class MyGPUImageGrayscaleFilter extends GPUImageFilter { public MyGPUImageGrayscaleFilter(String fragmentShader) { super(NO_FILTER_VERTEX_SHADER, fragmentShader); } }

インスタンスを作る側で、assetsから読み込んでもいいと思います。

String fragmentShader = GPUImageFilter.loadShader("gpuimage/my_grayscale.c", context); MyGPUImageGrayscaleFilter filter = new MyGPUImageGrayscaleFilter(fragmentShader);

(2) convertStreamToStringメソッド

convertStreamToStringメソッドは、RAWリソースのファイルから読み込みます。

res/raw/my_grayscale.txt を新規作成します。内容はさきほどの assets/gpuimage/my_grayscale.c と同じ内容です。

public class MyGPUImageGrayscaleFilter extends GPUImageFilter { public static MyGPUImageGrayscaleFilter create(Context context) { String fragmentShader = GPUImageFilter.convertStreamToString(context.getResources().openRawResource(R.raw.my_grayscale)); return new MyGPUImageGrayscaleFilter(fragmentShader); } public MyGPUImageGrayscaleFilter(String fragmentShader) { super(NO_FILTER_VERTEX_SHADER, fragmentShader); } }

GPUImageFilterのインスタンスを作る箇所では、上で用意したcreateメソッドを使います。

GPUImageGrayscaleFilter filter = new GPUImageGrayscaleFilter(); ↓ MyGPUImageGrayscaleFilter filter = MyGPUImageGrayscaleFilter.create(context);

または、次のように MyGPUImageGrayscaleFilter.javaを作っておき、

public class MyGPUImageGrayscaleFilter extends GPUImageFilter { public MyGPUImageGrayscaleFilter(String fragmentShader) { super(NO_FILTER_VERTEX_SHADER, fragmentShader); } }

インスタンスを作る側で、R.rawから読み込んでもいいと思います。

String fragmentShader = GPUImageFilter.convertStreamToString(context.getResources().openRawResource(R.raw.my_grayscale)); MyGPUImageGrayscaleFilter filter = new MyGPUImageGrayscaleFilter(fragmentShader);
タイトルとURLをコピーしました