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" +
" }";
Code language: PHP (php)
文字列のまま編集するのは、面倒なんですね。行ごとに、ダブルクォートで囲んで、行末に「+」をつける必要があります。
別ファイルにしたいなと思って探したら、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);
}
Code language: JavaScript (javascript)
次に、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);
}
}
Code language: JavaScript (javascript)
GPUImageFilterのインスタンスを作る箇所では、上で用意したcreateメソッドを使います。
GPUImageGrayscaleFilter filter = new GPUImageGrayscaleFilter();
↓
MyGPUImageGrayscaleFilter filter = MyGPUImageGrayscaleFilter.create(context);
Code language: JavaScript (javascript)
または、次のように MyGPUImageGrayscaleFilter.javaを作っておき、
public class MyGPUImageGrayscaleFilter extends GPUImageFilter {
public MyGPUImageGrayscaleFilter(String fragmentShader) {
super(NO_FILTER_VERTEX_SHADER, fragmentShader);
}
}
Code language: JavaScript (javascript)
インスタンスを作る側で、assetsから読み込んでもいいと思います。
String fragmentShader = GPUImageFilter.loadShader("gpuimage/my_grayscale.c", context);
MyGPUImageGrayscaleFilter filter = new MyGPUImageGrayscaleFilter(fragmentShader);
Code language: JavaScript (javascript)
(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);
}
}
Code language: JavaScript (javascript)
GPUImageFilterのインスタンスを作る箇所では、上で用意したcreateメソッドを使います。
GPUImageGrayscaleFilter filter = new GPUImageGrayscaleFilter();
↓
MyGPUImageGrayscaleFilter filter = MyGPUImageGrayscaleFilter.create(context);
Code language: JavaScript (javascript)
または、次のように MyGPUImageGrayscaleFilter.javaを作っておき、
public class MyGPUImageGrayscaleFilter extends GPUImageFilter {
public MyGPUImageGrayscaleFilter(String fragmentShader) {
super(NO_FILTER_VERTEX_SHADER, fragmentShader);
}
}
Code language: JavaScript (javascript)
インスタンスを作る側で、R.rawから読み込んでもいいと思います。
String fragmentShader = GPUImageFilter.convertStreamToString(context.getResources().openRawResource(R.raw.my_grayscale));
MyGPUImageGrayscaleFilter filter = new MyGPUImageGrayscaleFilter(fragmentShader);
Code language: JavaScript (javascript)