|
| 1 | +/** |
| 2 | + * @author wysaid |
| 3 | + |
| 4 | + * |
| 5 | +*/ |
| 6 | + |
| 7 | +package jp.co.cyberagent.android.gpuimage; |
| 8 | + |
| 9 | +import android.opengl.GLES20; |
| 10 | + |
| 11 | + |
| 12 | +public class GPUImageBilateralFilter extends GPUImageFilter { |
| 13 | + public static final String BILATERAL_VERTEX_SHADER = "" + |
| 14 | + "attribute vec4 position;\n" + |
| 15 | + "attribute vec4 inputTextureCoordinate;\n" + |
| 16 | + |
| 17 | + "const int GAUSSIAN_SAMPLES = 9;\n" + |
| 18 | + |
| 19 | + "uniform vec2 singleStepOffset;\n" + |
| 20 | + |
| 21 | + "varying vec2 textureCoordinate;\n" + |
| 22 | + "varying vec2 blurCoordinates[GAUSSIAN_SAMPLES];\n" + |
| 23 | + |
| 24 | + "void main()\n" + |
| 25 | + "{\n" + |
| 26 | + " gl_Position = position;\n" + |
| 27 | + " textureCoordinate = inputTextureCoordinate.xy;\n" + |
| 28 | + |
| 29 | + " int multiplier = 0;\n" + |
| 30 | + " vec2 blurStep;\n" + |
| 31 | + |
| 32 | + " for (int i = 0; i < GAUSSIAN_SAMPLES; i++)\n" + |
| 33 | + " {\n" + |
| 34 | + " multiplier = (i - ((GAUSSIAN_SAMPLES - 1) / 2));\n" + |
| 35 | + |
| 36 | + " blurStep = float(multiplier) * singleStepOffset;\n" + |
| 37 | + " blurCoordinates[i] = inputTextureCoordinate.xy + blurStep;\n" + |
| 38 | + " }\n" + |
| 39 | + "}"; |
| 40 | + |
| 41 | + public static final String BILATERAL_FRAGMENT_SHADER = "" + |
| 42 | + "uniform sampler2D inputImageTexture;\n" + |
| 43 | + |
| 44 | + " const lowp int GAUSSIAN_SAMPLES = 9;\n" + |
| 45 | + |
| 46 | + " varying highp vec2 textureCoordinate;\n" + |
| 47 | + " varying highp vec2 blurCoordinates[GAUSSIAN_SAMPLES];\n" + |
| 48 | + |
| 49 | + " uniform mediump float distanceNormalizationFactor;\n" + |
| 50 | + |
| 51 | + " void main()\n" + |
| 52 | + " {\n" + |
| 53 | + " lowp vec4 centralColor;\n" + |
| 54 | + " lowp float gaussianWeightTotal;\n" + |
| 55 | + " lowp vec4 sum;\n" + |
| 56 | + " lowp vec4 sampleColor;\n" + |
| 57 | + " lowp float distanceFromCentralColor;\n" + |
| 58 | + " lowp float gaussianWeight;\n" + |
| 59 | + " \n" + |
| 60 | + " centralColor = texture2D(inputImageTexture, blurCoordinates[4]);\n" + |
| 61 | + " gaussianWeightTotal = 0.18;\n" + |
| 62 | + " sum = centralColor * 0.18;\n" + |
| 63 | + " \n" + |
| 64 | + " sampleColor = texture2D(inputImageTexture, blurCoordinates[0]);\n" + |
| 65 | + " distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n" + |
| 66 | + " gaussianWeight = 0.05 * (1.0 - distanceFromCentralColor);\n" + |
| 67 | + " gaussianWeightTotal += gaussianWeight;\n" + |
| 68 | + " sum += sampleColor * gaussianWeight;\n" + |
| 69 | + |
| 70 | + " sampleColor = texture2D(inputImageTexture, blurCoordinates[1]);\n" + |
| 71 | + " distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n" + |
| 72 | + " gaussianWeight = 0.09 * (1.0 - distanceFromCentralColor);\n" + |
| 73 | + " gaussianWeightTotal += gaussianWeight;\n" + |
| 74 | + " sum += sampleColor * gaussianWeight;\n" + |
| 75 | + |
| 76 | + " sampleColor = texture2D(inputImageTexture, blurCoordinates[2]);\n" + |
| 77 | + " distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n" + |
| 78 | + " gaussianWeight = 0.12 * (1.0 - distanceFromCentralColor);\n" + |
| 79 | + " gaussianWeightTotal += gaussianWeight;\n" + |
| 80 | + " sum += sampleColor * gaussianWeight;\n" + |
| 81 | + |
| 82 | + " sampleColor = texture2D(inputImageTexture, blurCoordinates[3]);\n" + |
| 83 | + " distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n" + |
| 84 | + " gaussianWeight = 0.15 * (1.0 - distanceFromCentralColor);\n" + |
| 85 | + " gaussianWeightTotal += gaussianWeight;\n" + |
| 86 | + " sum += sampleColor * gaussianWeight;\n" + |
| 87 | + |
| 88 | + " sampleColor = texture2D(inputImageTexture, blurCoordinates[5]);\n" + |
| 89 | + " distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n" + |
| 90 | + " gaussianWeight = 0.15 * (1.0 - distanceFromCentralColor);\n" + |
| 91 | + " gaussianWeightTotal += gaussianWeight;\n" + |
| 92 | + " sum += sampleColor * gaussianWeight;\n" + |
| 93 | + |
| 94 | + " sampleColor = texture2D(inputImageTexture, blurCoordinates[6]);\n" + |
| 95 | + " distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n" + |
| 96 | + " gaussianWeight = 0.12 * (1.0 - distanceFromCentralColor);\n" + |
| 97 | + " gaussianWeightTotal += gaussianWeight;\n" + |
| 98 | + " sum += sampleColor * gaussianWeight;\n" + |
| 99 | + |
| 100 | + " sampleColor = texture2D(inputImageTexture, blurCoordinates[7]);\n" + |
| 101 | + " distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n" + |
| 102 | + " gaussianWeight = 0.09 * (1.0 - distanceFromCentralColor);\n" + |
| 103 | + " gaussianWeightTotal += gaussianWeight;\n" + |
| 104 | + " sum += sampleColor * gaussianWeight;\n" + |
| 105 | + |
| 106 | + " sampleColor = texture2D(inputImageTexture, blurCoordinates[8]);\n" + |
| 107 | + " distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);\n" + |
| 108 | + " gaussianWeight = 0.05 * (1.0 - distanceFromCentralColor);\n" + |
| 109 | + " gaussianWeightTotal += gaussianWeight;\n" + |
| 110 | + " sum += sampleColor * gaussianWeight;\n" + |
| 111 | + " gl_FragColor = sum / gaussianWeightTotal;\n" + |
| 112 | +// " gl_FragColor.r = distanceNormalizationFactor / 20.0;" + |
| 113 | + " }"; |
| 114 | + |
| 115 | + private float mDistanceNormalizationFactor; |
| 116 | + private int mDisFactorLocation; |
| 117 | + private int mSingleStepOffsetLocation; |
| 118 | + |
| 119 | + public GPUImageBilateralFilter() { |
| 120 | + this(8.0f); |
| 121 | + } |
| 122 | + |
| 123 | + public GPUImageBilateralFilter(final float distanceNormalizationFactor) { |
| 124 | + super(BILATERAL_VERTEX_SHADER, BILATERAL_FRAGMENT_SHADER); |
| 125 | + mDistanceNormalizationFactor = distanceNormalizationFactor; |
| 126 | + } |
| 127 | + |
| 128 | + @Override |
| 129 | + public void onInit() { |
| 130 | + super.onInit(); |
| 131 | + mDisFactorLocation = GLES20.glGetUniformLocation(getProgram(), "distanceNormalizationFactor"); |
| 132 | + mSingleStepOffsetLocation = GLES20.glGetUniformLocation(getProgram(), "singleStepOffset"); |
| 133 | + } |
| 134 | + |
| 135 | + @Override |
| 136 | + public void onInitialized() { |
| 137 | + super.onInitialized(); |
| 138 | + setDistanceNormalizationFactor(mDistanceNormalizationFactor); |
| 139 | + } |
| 140 | + |
| 141 | + public void setDistanceNormalizationFactor(final float newValue) { |
| 142 | + mDistanceNormalizationFactor = newValue; |
| 143 | + setFloat(mDisFactorLocation, newValue); |
| 144 | + } |
| 145 | + |
| 146 | + private void setTexelSize(final float w, final float h) { |
| 147 | + setFloatVec2(mSingleStepOffsetLocation, new float[] {1.0f / w, 1.0f / h}); |
| 148 | + } |
| 149 | + |
| 150 | + @Override |
| 151 | + public void onOutputSizeChanged(final int width, final int height) { |
| 152 | + super.onOutputSizeChanged(width, height); |
| 153 | + setTexelSize(width, height); |
| 154 | + } |
| 155 | +} |
0 commit comments