parent
569e57eac8
commit
8875c7bff3
@ -0,0 +1,14 @@ |
||||
package com.otaliastudios.cameraview.filter; |
||||
|
||||
import android.content.Context; |
||||
|
||||
public interface ContextParameterFilter { |
||||
/** |
||||
* Sets the parameter. |
||||
* The value should always be between 0 and 1. |
||||
* |
||||
* @param value parameter |
||||
*/ |
||||
void setContext(Context value); |
||||
|
||||
} |
@ -0,0 +1,140 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import android.opengl.GLES20; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
import com.otaliastudios.cameraview.size.Size; |
||||
import com.otaliastudios.opengl.core.Egloo; |
||||
|
||||
import java.nio.FloatBuffer; |
||||
|
||||
public class AirsolidGlitchFilter extends BaseFilter { |
||||
private static final String FRAGMENT_SHADER = |
||||
"#extension GL_OES_EGL_image_external : require\n" + |
||||
"precision highp float;\n" + |
||||
"\n" + |
||||
"uniform vec3 iResolution;\n" + |
||||
"uniform float iTime;\n" + |
||||
"uniform samplerExternalOES iChannel0;\n" + |
||||
"varying vec2 " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + ";\n" + |
||||
"float rand(vec2 p)\n" + |
||||
"{\n" + |
||||
" float t = floor(iTime * 50.) / 10.; //speed \n" + |
||||
" return fract(sin(dot(p, vec2(t * 12.9898, t * 78.233))) * 43758.5453);\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"float noise(vec2 uv, float blockiness)\n" + |
||||
"{ \n" + |
||||
" vec2 lv = fract(uv);\n" + |
||||
" vec2 id = floor(uv);\n" + |
||||
" \n" + |
||||
" float n1 = rand(id);\n" + |
||||
" float n2 = rand(id+vec2(1,0));\n" + |
||||
" float n3 = rand(id+vec2(0,1));\n" + |
||||
" float n4 = rand(id+vec2(1,1));\n" + |
||||
" \n" + |
||||
" vec2 u = smoothstep(0.0, 1.0 + blockiness, lv);\n" + |
||||
"\n" + |
||||
" return mix(mix(n1, n2, u.x), mix(n3, n4, u.x), u.y);\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"float fbm(vec2 uv, int count, float blockiness, float complexity)\n" + |
||||
"{\n" + |
||||
" float val = 0.0;\n" + |
||||
" float amp = 0.5;\n" + |
||||
" \n" + |
||||
" while(count != 0)\n" + |
||||
" {\n" + |
||||
" \tval += amp * noise(uv, blockiness);\n" + |
||||
" amp *= 0.5;\n" + |
||||
" uv *= complexity; \n" + |
||||
" count--;\n" + |
||||
" }\n" + |
||||
" \n" + |
||||
" return val;\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"const float glitchAmplitude = 0.9; // increase this\n" + |
||||
"const float glitchNarrowness = 400.0;\n" + |
||||
"const float glitchBlockiness = 10000.0;\n" + |
||||
"const float glitchMinimizer = 10.0; // decrease this\n" + |
||||
"\n" + |
||||
"void mainImage( out vec4 fragColor, in vec2 fragCoord )\n" + |
||||
"{\n" + |
||||
" // Normalized pixel coordinates (from 0 to 1)\n" + |
||||
" vec2 uv = fragCoord/iResolution.xy;\n" + |
||||
" vec2 a = vec2(uv.x * (iResolution.x / iResolution.y), uv.y);\n" + |
||||
" vec2 uv2 = vec2(a.x / iResolution.x, exp(a.y));\n" + |
||||
"\tvec2 id = floor(uv * 20.0); // size noise\n" + |
||||
" //id.x /= floor(texture(iChannel0, vec2(id / 8.0)).r * 8.0);\n" + |
||||
"\n" + |
||||
" // Generate shift amplitude\n" + |
||||
" float shift = glitchAmplitude * pow(fbm(uv2, int(rand(id) * 6.), glitchBlockiness, glitchNarrowness), glitchMinimizer);\n" + |
||||
" \n" + |
||||
" // Create a scanline effect\n" + |
||||
" float scanline = abs(cos(uv.y * 400.)); //scanline intensite\n" + |
||||
" scanline = smoothstep(0.0, 2.0, scanline);\n" + |
||||
" shift = smoothstep(0.00001, 0.2, shift);\n" + |
||||
" \n" + |
||||
" // Apply glitch and RGB shift\n" + |
||||
" float colR = texture2D(iChannel0, vec2(uv.x + shift, uv.y)).r * (1. - shift) ;\n" + |
||||
" float colG = texture2D(iChannel0, vec2(uv.x - shift, uv.y)).g * (1. - shift) + rand(id) * shift;\n" + |
||||
" float colB = texture2D(iChannel0, vec2(uv.x - shift, uv.y)).b * (1. - shift);\n" + |
||||
" // Mix with the scanline effect\n" + |
||||
" vec3 f = vec3(colR, colG, colB) - (0.1 * scanline); //scanline intensite\n" + |
||||
" \n" + |
||||
" // Output to screen\n" + |
||||
" fragColor = vec4(f, 1.0);\n" + |
||||
"}" + |
||||
"\nvoid main() {\n" + |
||||
"\tmainImage(gl_FragColor, " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + " * iResolution.xy);\n" + |
||||
"}"; |
||||
|
||||
long START_TIME = System.currentTimeMillis(); |
||||
private int iGlobalTimeLocation = -1; |
||||
private int iResolutionLocation = -1; |
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return FRAGMENT_SHADER; |
||||
} |
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
iResolutionLocation = -1; |
||||
iGlobalTimeLocation = -1; |
||||
START_TIME = System.currentTimeMillis(); |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(int programHandle) { |
||||
super.onCreate(programHandle); |
||||
iResolutionLocation = GLES20.glGetUniformLocation(programHandle, "iResolution"); |
||||
Egloo.checkGlProgramLocation(iResolutionLocation, "iResolution"); |
||||
|
||||
|
||||
iGlobalTimeLocation = GLES20.glGetUniformLocation(programHandle, "iTime"); |
||||
Egloo.checkGlProgramLocation(iGlobalTimeLocation, "iTime"); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPreDraw(long timestampUs, @NonNull float[] transformMatrix) { |
||||
super.onPreDraw(timestampUs, transformMatrix); |
||||
|
||||
Size size = getSize(); |
||||
if (size != null) { |
||||
GLES20.glUniform3fv(iResolutionLocation, 1, |
||||
FloatBuffer.wrap(new float[]{(float) size.getWidth(), (float) size.getHeight(), 1.0f})); |
||||
Egloo.checkGlError("glUniform3fv"); |
||||
} |
||||
|
||||
|
||||
float time = (((float) (System.currentTimeMillis() - START_TIME)) / 1000.0f) + 1; |
||||
GLES20.glUniform1f(iGlobalTimeLocation, time); |
||||
Egloo.checkGlError("glUniform1f"); |
||||
} |
||||
} |
@ -0,0 +1,81 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import android.opengl.GLES20; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
import com.otaliastudios.cameraview.size.Size; |
||||
import com.otaliastudios.opengl.core.Egloo; |
||||
|
||||
import java.nio.FloatBuffer; |
||||
|
||||
public class AnaglyphFilter extends BaseFilter { |
||||
private static final String FRAGMENT_SHADER = |
||||
"#extension GL_OES_EGL_image_external : require\n" + |
||||
"precision highp float;\n" + |
||||
"\n" + |
||||
"uniform vec3 iResolution;\n" + |
||||
"uniform float iTime;\n" + |
||||
"uniform samplerExternalOES iChannel0;\n" + |
||||
"varying vec2 " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + ";\n" + |
||||
"void mainImage( out vec4 fragColor, in vec2 fragCoord )\n" + |
||||
"{\n" + |
||||
"\tvec2 uv = fragCoord.xy / iResolution.xy;\n" + |
||||
" \n" + |
||||
" vec4 left = texture2D(iChannel0, uv);\n" + |
||||
" vec4 right = texture2D(iChannel0, uv + vec2(0.015, 0.0));\n" + |
||||
"\t\n" + |
||||
" vec3 color = vec3(left.r, right.gb);\n" + |
||||
" color = clamp(color, 0.0, 1.0);\n" + |
||||
" fragColor = vec4(color, 1.0);\n" + |
||||
"}\n" + |
||||
"void main() {\n" + |
||||
"\tmainImage(gl_FragColor, " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + " * iResolution.xy);\n" + |
||||
"}"; |
||||
|
||||
|
||||
long START_TIME = System.currentTimeMillis(); |
||||
private int iGlobalTimeLocation = -1; |
||||
private int iResolutionLocation = -1; |
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return FRAGMENT_SHADER; |
||||
} |
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
iResolutionLocation = -1; |
||||
iGlobalTimeLocation = -1; |
||||
START_TIME = System.currentTimeMillis(); |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(int programHandle) { |
||||
super.onCreate(programHandle); |
||||
iResolutionLocation = GLES20.glGetUniformLocation(programHandle, "iResolution"); |
||||
Egloo.checkGlProgramLocation(iResolutionLocation, "iResolution"); |
||||
|
||||
iGlobalTimeLocation = GLES20.glGetUniformLocation(programHandle, "iTime"); |
||||
// Egloo.checkGlProgramLocation(iGlobalTimeLocation, "iTime");
|
||||
} |
||||
|
||||
@Override |
||||
protected void onPreDraw(long timestampUs, @NonNull float[] transformMatrix) { |
||||
super.onPreDraw(timestampUs, transformMatrix); |
||||
|
||||
Size size = getSize(); |
||||
if (size != null) { |
||||
GLES20.glUniform3fv(iResolutionLocation, 1, |
||||
FloatBuffer.wrap(new float[]{(float) size.getWidth(), (float) size.getHeight(), 1.0f})); |
||||
Egloo.checkGlError("glUniform3fv"); |
||||
} |
||||
|
||||
float time = ((float) (System.currentTimeMillis() - START_TIME)) / 1000.0f; |
||||
GLES20.glUniform1f(iGlobalTimeLocation, time); |
||||
Egloo.checkGlError("glUniform1f"); |
||||
} |
||||
} |
@ -0,0 +1,93 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import android.opengl.GLES20; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
import com.otaliastudios.cameraview.size.Size; |
||||
import com.otaliastudios.opengl.core.Egloo; |
||||
|
||||
import java.nio.FloatBuffer; |
||||
|
||||
public class AsciiFilter extends BaseFilter { |
||||
private static final String FRAGMENT_SHADER = |
||||
"#extension GL_OES_EGL_image_external : require\n" + |
||||
"precision highp float;\n" + |
||||
"\n" + |
||||
"uniform vec3 iResolution;\n" + |
||||
"uniform samplerExternalOES iChannel0;\n" + |
||||
"varying vec2 " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + ";\n" + |
||||
"float character(int n, vec2 p)\n" + |
||||
"{\n" + |
||||
"\tp = floor(p*vec2(4.0, -4.0) + 2.5);\n" + |
||||
" if (clamp(p.x, 0.0, 4.0) == p.x)\n" + |
||||
"\t{\n" + |
||||
" if (clamp(p.y, 0.0, 4.0) == p.y)\t\n" + |
||||
"\t\t{\n" + |
||||
" \tint a = int(round(p.x) + 5.0 * round(p.y));\n" + |
||||
"\t\t\tif (((n >> a) & 1) == 1) return 1.0;\n" + |
||||
"\t\t}\t\n" + |
||||
" }\n" + |
||||
"\treturn 0.0;\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"void mainImage( out vec4 fragColor, in vec2 fragCoord )\n" + |
||||
"{\n" + |
||||
"\tvec2 pix = fragCoord.xy;\n" + |
||||
"\tvec3 col = texture2D(iChannel0, floor(pix/8.0)*8.0/iResolution.xy).rgb;\t\n" + |
||||
"\t\n" + |
||||
"\tfloat gray = 0.3 * col.r + 0.59 * col.g + 0.11 * col.b;\n" + |
||||
"\t\n" + |
||||
"\tint n = 4096; // .\n" + |
||||
"\tif (gray > 0.2) n = 65600; // :\n" + |
||||
"\tif (gray > 0.3) n = 332772; // *\n" + |
||||
"\tif (gray > 0.4) n = 15255086; // o \n" + |
||||
"\tif (gray > 0.5) n = 23385164; // &\n" + |
||||
"\tif (gray > 0.6) n = 15252014; // 8\n" + |
||||
"\tif (gray > 0.7) n = 13199452; // @\n" + |
||||
"\tif (gray > 0.8) n = 11512810; // #\n" + |
||||
"\t\n" + |
||||
"\tvec2 p = mod(pix/4.0, 2.0) - vec2(1.0);\n" + |
||||
" \n" + |
||||
"\tif (iMouse.z > 0.5)\tcol = gray*vec3(character(n, p));\n" + |
||||
"\telse col = col*character(n, p);\n" + |
||||
"\t\n" + |
||||
"\tfragColor = vec4(col, 1.0);\n" + |
||||
"}" + |
||||
"\nvoid main() {\n" + |
||||
"\tmainImage(gl_FragColor, " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + " * iResolution.xy);\n" + |
||||
"}"; |
||||
private int iResolutionLocation = -1; |
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return FRAGMENT_SHADER; |
||||
} |
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
iResolutionLocation = -1; |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(int programHandle) { |
||||
super.onCreate(programHandle); |
||||
iResolutionLocation = GLES20.glGetUniformLocation(programHandle, "iResolution"); |
||||
Egloo.checkGlProgramLocation(iResolutionLocation, "iResolution"); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPreDraw(long timestampUs, @NonNull float[] transformMatrix) { |
||||
super.onPreDraw(timestampUs, transformMatrix); |
||||
|
||||
Size size = getSize(); |
||||
if (size != null) { |
||||
GLES20.glUniform3fv(iResolutionLocation, 1, |
||||
FloatBuffer.wrap(new float[]{(float) size.getWidth(), (float) size.getHeight(), 1.0f})); |
||||
Egloo.checkGlError("glUniform3fv"); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,79 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import android.opengl.GLES20; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
import com.otaliastudios.opengl.core.Egloo; |
||||
|
||||
public class ChromaticAberrationFilter extends BaseFilter { |
||||
private static final String FRAGMENT_SHADER = |
||||
"#extension GL_OES_EGL_image_external : require\n" + |
||||
"precision mediump float;\n" + |
||||
"\n" + |
||||
"uniform vec3 iResolution;\n" + |
||||
"uniform float iGlobalTime;\n" + |
||||
"uniform samplerExternalOES iChannel0;\n" + |
||||
"varying vec2 "+DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME+";\n" + |
||||
"\n" + |
||||
"void mainImage( out vec4 fragColor, in vec2 fragCoord )\n" + |
||||
"{\n" + |
||||
" vec2 uv = fragCoord.xy;\n" + |
||||
"\n" + |
||||
"\tfloat amount = 0.0;\n" + |
||||
"\t\n" + |
||||
"\tamount = (1.0 + sin(iGlobalTime*6.0)) * 0.5;\n" + |
||||
"\tamount *= 1.0 + sin(iGlobalTime*16.0) * 0.5;\n" + |
||||
"\tamount *= 1.0 + sin(iGlobalTime*19.0) * 0.5;\n" + |
||||
"\tamount *= 1.0 + sin(iGlobalTime*27.0) * 0.5;\n" + |
||||
"\tamount = pow(amount, 3.0);\n" + |
||||
"\n" + |
||||
"\tamount *= 0.05;\n" + |
||||
"\t\n" + |
||||
" vec3 col;\n" + |
||||
" col.r = texture2D( iChannel0, vec2(uv.x+amount,uv.y) ).r;\n" + |
||||
" col.g = texture2D( iChannel0, uv ).g;\n" + |
||||
" col.b = texture2D( iChannel0, vec2(uv.x-amount,uv.y) ).b;\n" + |
||||
"\n" + |
||||
"\tcol *= (1.0 - amount * 0.5);\n" + |
||||
"\t\n" + |
||||
" fragColor = vec4(col,1.0);\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"\n" + |
||||
"void main() {\n" + |
||||
" \tmainImage(gl_FragColor, "+DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME+");\n" + |
||||
"}"; |
||||
|
||||
long START_TIME = System.currentTimeMillis(); |
||||
private int iGlobalTimeLocation = -1; |
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return FRAGMENT_SHADER; |
||||
} |
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
iGlobalTimeLocation = -1; |
||||
START_TIME = System.currentTimeMillis(); |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(int programHandle) { |
||||
super.onCreate(programHandle); |
||||
iGlobalTimeLocation = GLES20.glGetUniformLocation(programHandle, "iGlobalTime"); |
||||
Egloo.checkGlProgramLocation(iGlobalTimeLocation, "iGlobalTime"); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPreDraw(long timestampUs, @NonNull float[] transformMatrix) { |
||||
super.onPreDraw(timestampUs, transformMatrix); |
||||
float time = ((float) (System.currentTimeMillis() - START_TIME)) / 1000.0f; |
||||
GLES20.glUniform1f(iGlobalTimeLocation, time); |
||||
Egloo.checkGlError("glUniform1f"); |
||||
} |
||||
} |
@ -0,0 +1,56 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
import com.otaliastudios.cameraview.filter.OneParameterFilter; |
||||
|
||||
public class ColorspaceFilter extends BaseFilter { |
||||
private static final String FRAGMENT_SHADER = "#extension GL_OES_EGL_image_external : require\n" + |
||||
"precision mediump float;\n" + |
||||
|
||||
"varying vec2 vTextureCoord;" + |
||||
"uniform samplerExternalOES sTexture;" + |
||||
|
||||
"void main() {" + |
||||
"highp vec2 sampleDivisor = vec2(1.0 / 200.0, 1.0 / 320.0);" + |
||||
|
||||
"highp vec2 samplePos = vTextureCoord - mod(vTextureCoord, sampleDivisor);" + |
||||
"highp vec4 color = texture2D(sTexture, samplePos);" + |
||||
|
||||
"mediump vec4 colorCyan = vec4(85.0 / 255.0, 1.0, 1.0, 1.0);" + |
||||
"mediump vec4 colorMagenta = vec4(1.0, 85.0 / 255.0, 1.0, 1.0);" + |
||||
"mediump vec4 colorWhite = vec4(1.0, 1.0, 1.0, 1.0);" + |
||||
"mediump vec4 colorBlack = vec4(0.0, 0.0, 0.0, 1.0);" + |
||||
|
||||
"mediump vec4 endColor;" + |
||||
"highp float blackDistance = distance(color, colorBlack);" + |
||||
"highp float whiteDistance = distance(color, colorWhite);" + |
||||
"highp float magentaDistance = distance(color, colorMagenta);" + |
||||
"highp float cyanDistance = distance(color, colorCyan);" + |
||||
|
||||
"mediump vec4 finalColor;" + |
||||
|
||||
"highp float colorDistance = min(magentaDistance, cyanDistance);" + |
||||
"colorDistance = min(colorDistance, whiteDistance);" + |
||||
"colorDistance = min(colorDistance, blackDistance);" + |
||||
|
||||
"if (colorDistance == blackDistance) {" + |
||||
"finalColor = colorBlack;" + |
||||
"} else if (colorDistance == whiteDistance) {" + |
||||
"finalColor = colorWhite;" + |
||||
"} else if (colorDistance == cyanDistance) {" + |
||||
"finalColor = colorCyan;" + |
||||
"} else {" + |
||||
"finalColor = colorMagenta;" + |
||||
"}" + |
||||
|
||||
"gl_FragColor = finalColor;" + |
||||
"}"; |
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return FRAGMENT_SHADER; |
||||
} |
||||
} |
@ -0,0 +1,109 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import android.opengl.GLES20; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
import com.otaliastudios.cameraview.size.Size; |
||||
import com.otaliastudios.opengl.core.Egloo; |
||||
|
||||
import java.nio.FloatBuffer; |
||||
|
||||
public class CrackedFilter extends BaseFilter { |
||||
private static final String FRAGMENT_SHADER = |
||||
"#extension GL_OES_EGL_image_external : require\n" + |
||||
"#extension GL_OES_standard_derivatives : enable\n" + |
||||
"precision highp float;\n" + |
||||
"\n" + |
||||
"uniform vec3 iResolution;\n" + |
||||
// "uniform float iGlobalTime;\n" +
|
||||
"uniform samplerExternalOES iChannel0;\n" + |
||||
"varying vec2 " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + ";\n" + |
||||
"\n" + |
||||
"float rnd(vec2 s)\n" + |
||||
"{\n" + |
||||
" return 1.-2.*fract(sin(s.x*253.13+s.y*341.41)*589.19);\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"void mainImage( out vec4 fragColor, in vec2 fragCoord )\n" + |
||||
"{\n" + |
||||
"\tvec2 p=(fragCoord.xy*2.-iResolution.xy)/iResolution.x;\n" + |
||||
"\n" + |
||||
" vec2 v=vec2(1E3);\n" + |
||||
" vec2 v2=vec2(1E4);\n" + |
||||
" vec2 center=vec2(.1,-.5);\n" + |
||||
" for(int c=0;c<30;c++)\n" + |
||||
" {\n" + |
||||
" float angle=floor(rnd(vec2(float(c),387.44))*16.)*3.1415*.4-.5;\n" + |
||||
" float dist=pow(rnd(vec2(float(c),78.21)),2.)*.5;\n" + |
||||
" vec2 vc=vec2(center.x+cos(angle)*dist+rnd(vec2(float(c),349.3))*7E-3,\n" + |
||||
" center.y+sin(angle)*dist+rnd(vec2(float(c),912.7))*7E-3);\n" + |
||||
" if(length(vc-p)<length(v-p))\n" + |
||||
" {\n" + |
||||
"\t v2=v;\n" + |
||||
"\t v=vc;\n" + |
||||
" }\n" + |
||||
" else if(length(vc-p)<length(v2-p))\n" + |
||||
" {\n" + |
||||
" v2=vc;\n" + |
||||
" }\n" + |
||||
" }\n" + |
||||
"\n" + |
||||
" float col=abs(length(dot(p-v,normalize(v-v2)))-length(dot(p-v2,normalize(v-v2))))+.002*length(p-center);\n" + |
||||
" col=7E-4/col;\n" + |
||||
" if(length(v-v2)<4E-3)col=0.;\n" + |
||||
"// if(length(v-p)<4E-3)col=1E-6;\n" + |
||||
" if(col<.3)col=0.;\n" + |
||||
" vec4 tex=texture2D(iChannel0,(fragCoord.xy)/iResolution.xy+rnd(v)*.02);\n" + |
||||
" fragColor=col*vec4(vec3(1.-tex.xyz),1.)+(1.-col)*tex;\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"void main() {\n" + |
||||
"\tmainImage(gl_FragColor, " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + " * iResolution.xy);\n" + |
||||
"}"; |
||||
|
||||
|
||||
long START_TIME = System.currentTimeMillis(); |
||||
// private int iGlobalTimeLocation = -1;
|
||||
private int iResolutionLocation = -1; |
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return FRAGMENT_SHADER; |
||||
} |
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
// iGlobalTimeLocation = -1;
|
||||
// START_TIME = System.currentTimeMillis();
|
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(int programHandle) { |
||||
super.onCreate(programHandle); |
||||
iResolutionLocation = GLES20.glGetUniformLocation(programHandle, "iResolution"); |
||||
Egloo.checkGlProgramLocation(iResolutionLocation, "iResolution"); |
||||
|
||||
// iGlobalTimeLocation = GLES20.glGetUniformLocation(programHandle, "iGlobalTime");
|
||||
// Egloo.checkGlProgramLocation(iGlobalTimeLocation, "iGlobalTime");
|
||||
} |
||||
|
||||
@Override |
||||
protected void onPreDraw(long timestampUs, @NonNull float[] transformMatrix) { |
||||
super.onPreDraw(timestampUs, transformMatrix); |
||||
|
||||
Size size = getSize(); |
||||
if (size != null) { |
||||
GLES20.glUniform3fv(iResolutionLocation, 1, |
||||
FloatBuffer.wrap(new float[]{(float) size.getWidth(), (float) size.getHeight(), 1.0f})); |
||||
Egloo.checkGlError("glUniform3fv"); |
||||
} |
||||
|
||||
float time = ((float) (System.currentTimeMillis() - START_TIME)) / 1000.0f; |
||||
// GLES20.glUniform1f(iGlobalTimeLocation, time);
|
||||
Egloo.checkGlError("glUniform1f"); |
||||
} |
||||
} |
@ -0,0 +1,128 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import android.opengl.GLES20; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
import com.otaliastudios.cameraview.filter.TwoParameterFilter; |
||||
import com.otaliastudios.opengl.core.Egloo; |
||||
|
||||
public class CrosshatchFilter extends BaseFilter implements TwoParameterFilter { |
||||
private static final String CROSSHATCH_FRAGMENT_SHADER = "#extension GL_OES_EGL_image_external : require\n" + |
||||
"precision mediump float;" + |
||||
"varying vec2 vTextureCoord;\n" + |
||||
" uniform samplerExternalOES sTexture;\n" + |
||||
"uniform highp float crossHatchSpacing;\n" + |
||||
"uniform highp float lineWidth;\n" + |
||||
"const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);\n" + |
||||
"void main()\n" + |
||||
"{\n" + |
||||
"highp float luminance = dot(texture2D(sTexture, vTextureCoord).rgb, W);\n" + |
||||
"lowp vec4 colorToDisplay = vec4(1.0, 1.0, 1.0, 1.0);\n" + |
||||
"if (luminance < 1.00)\n" + |
||||
"{\n" + |
||||
"if (mod(vTextureCoord.x + vTextureCoord.y, crossHatchSpacing) <= lineWidth)\n" + |
||||
"{\n" + |
||||
"colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0);\n" + |
||||
"}\n" + |
||||
"}\n" + |
||||
"if (luminance < 0.75)\n" + |
||||
"{\n" + |
||||
"if (mod(vTextureCoord.x - vTextureCoord.y, crossHatchSpacing) <= lineWidth)\n" + |
||||
"{\n" + |
||||
"colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0);\n" + |
||||
"}\n" + |
||||
"}\n" + |
||||
"if (luminance < 0.50)\n" + |
||||
"{\n" + |
||||
"if (mod(vTextureCoord.x + vTextureCoord.y - (crossHatchSpacing / 2.0), crossHatchSpacing) <= lineWidth)\n" + |
||||
"{\n" + |
||||
"colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0);\n" + |
||||
"}\n" + |
||||
"}\n" + |
||||
"if (luminance < 0.3)\n" + |
||||
"{\n" + |
||||
"if (mod(vTextureCoord.x - vTextureCoord.y - (crossHatchSpacing / 2.0), crossHatchSpacing) <= lineWidth)\n" + |
||||
"{\n" + |
||||
"colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0);\n" + |
||||
"}\n" + |
||||
"}\n" + |
||||
"gl_FragColor = colorToDisplay;\n" + |
||||
"}\n"; |
||||
|
||||
private float crossHatchSpacing = 0.03f; |
||||
private int crossHatchSpacingLocation = -1; |
||||
|
||||
private float lineWidth = 0.003f; |
||||
private int lineWidthLocation = -1; |
||||
|
||||
@Override |
||||
public void onCreate(int programHandle) { |
||||
super.onCreate(programHandle); |
||||
crossHatchSpacingLocation = GLES20.glGetUniformLocation(programHandle, "crossHatchSpacing"); |
||||
Egloo.checkGlProgramLocation(crossHatchSpacingLocation, "crossHatchSpacing"); |
||||
|
||||
lineWidthLocation = GLES20.glGetUniformLocation(programHandle, "lineWidth"); |
||||
Egloo.checkGlProgramLocation(lineWidthLocation, "lineWidth"); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPreDraw(long timestampUs, @NonNull float[] transformMatrix) { |
||||
super.onPreDraw(timestampUs, transformMatrix); |
||||
GLES20.glUniform1f(crossHatchSpacingLocation, crossHatchSpacing); |
||||
GLES20.glUniform1f(lineWidthLocation, lineWidth); |
||||
Egloo.checkGlError("glUniform1f"); |
||||
} |
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
crossHatchSpacing = 0.03f; |
||||
crossHatchSpacingLocation = -1; |
||||
lineWidth = 0.003f; |
||||
lineWidthLocation = -1; |
||||
} |
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return CROSSHATCH_FRAGMENT_SHADER; |
||||
} |
||||
|
||||
@Override |
||||
public void setParameter1(float value) { |
||||
setCrossHatchSpacing(value); |
||||
} |
||||
|
||||
@Override |
||||
public float getParameter1() { |
||||
return getCrossHatchSpacing(); |
||||
} |
||||
|
||||
@Override |
||||
public void setParameter2(float value) { |
||||
setLineWidth(value); |
||||
} |
||||
|
||||
@Override |
||||
public float getParameter2() { |
||||
return getLineWidth(); |
||||
} |
||||
|
||||
public float getLineWidth() { |
||||
return lineWidth; |
||||
} |
||||
|
||||
public void setLineWidth(float lineWidth) { |
||||
this.lineWidth = lineWidth; |
||||
} |
||||
|
||||
public float getCrossHatchSpacing() { |
||||
return crossHatchSpacing; |
||||
} |
||||
|
||||
public void setCrossHatchSpacing(float crossHatchSpacing) { |
||||
this.crossHatchSpacing = crossHatchSpacing; |
||||
} |
||||
} |
@ -0,0 +1,134 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import android.opengl.GLES20; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
import com.otaliastudios.cameraview.size.Size; |
||||
import com.otaliastudios.opengl.core.Egloo; |
||||
|
||||
import java.nio.FloatBuffer; |
||||
|
||||
public class Day41GlitchFilter extends BaseFilter { |
||||
private static final String FRAGMENT_SHADER = |
||||
"#extension GL_OES_EGL_image_external : require\n" + |
||||
"precision highp float;\n" + |
||||
"\n" + |
||||
"uniform vec3 iResolution;\n" + |
||||
"uniform float iTime;\n" + |
||||
"uniform samplerExternalOES iChannel0;\n" + |
||||
"varying vec2 " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + ";\n" + |
||||
"float rand(vec2 p)\n" + |
||||
"{\n" + |
||||
" float t = floor(iTime * 20.) / 10.;\n" + |
||||
" return fract(sin(dot(p, vec2(t * 12.9898, t * 78.233))) * 43758.5453);\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"float noise(vec2 uv, float blockiness)\n" + |
||||
"{ \n" + |
||||
" vec2 lv = fract(uv);\n" + |
||||
" vec2 id = floor(uv);\n" + |
||||
" \n" + |
||||
" float n1 = rand(id);\n" + |
||||
" float n2 = rand(id+vec2(1,0));\n" + |
||||
" float n3 = rand(id+vec2(0,1));\n" + |
||||
" float n4 = rand(id+vec2(1,1));\n" + |
||||
" \n" + |
||||
" vec2 u = smoothstep(0.0, 1.0 + blockiness, lv);\n" + |
||||
"\n" + |
||||
" return mix(mix(n1, n2, u.x), mix(n3, n4, u.x), u.y);\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"float fbm(vec2 uv, int count, float blockiness, float complexity)\n" + |
||||
"{\n" + |
||||
" float val = 0.0;\n" + |
||||
" float amp = 0.5;\n" + |
||||
" \n" + |
||||
" while(count != 0)\n" + |
||||
" {\n" + |
||||
" \tval += amp * noise(uv, blockiness);\n" + |
||||
" amp *= 0.5;\n" + |
||||
" uv *= complexity; \n" + |
||||
" count--;\n" + |
||||
" }\n" + |
||||
" \n" + |
||||
" return val;\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"const float glitchAmplitude = 0.2; // increase this\n" + |
||||
"const float glitchNarrowness = 4.0;\n" + |
||||
"const float glitchBlockiness = 2.0;\n" + |
||||
"const float glitchMinimizer = 8.0; // decrease this\n" + |
||||
"\n" + |
||||
"void mainImage( out vec4 fragColor, in vec2 fragCoord )\n" + |
||||
"{\n" + |
||||
" \n" + |
||||
" vec2 uv = fragCoord/iResolution.xy;\n" + |
||||
" float aspect = iResolution.x / iResolution.y;\n" + |
||||
" vec2 a = vec2(uv.x * aspect , uv.y);\n" + |
||||
" vec2 uv2 = vec2(a.x / iResolution.x, exp(a.y));\n" + |
||||
"\n" + |
||||
" \n" + |
||||
" float shift = glitchAmplitude * pow(fbm(uv2, 4, glitchBlockiness, glitchNarrowness), glitchMinimizer);\n" + |
||||
" \n" + |
||||
" float colR = texture2D(iChannel0, vec2(uv.x + shift, uv.y)).r * (1. - shift);\n" + |
||||
" float colG = texture2D(iChannel0, vec2(uv.x - shift, uv.y)).g * (1. - shift);\n" + |
||||
" float colB = texture2D(iChannel0, vec2(uv.x - shift, uv.y)).b * (1. - shift);\n" + |
||||
" \n" + |
||||
" // Mix with the scanline effect\n" + |
||||
" vec3 f = vec3(colR, colG, colB);\n" + |
||||
"\n" + |
||||
" \n" + |
||||
" fragColor = vec4(f, 1.);\n" + |
||||
"}" + |
||||
"\nvoid main() {\n" + |
||||
"\tmainImage(gl_FragColor, " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + " * iResolution.xy);\n" + |
||||
"}"; |
||||
|
||||
long START_TIME = System.currentTimeMillis(); |
||||
private int iGlobalTimeLocation = -1; |
||||
private int iResolutionLocation = -1; |
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return FRAGMENT_SHADER; |
||||
} |
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
iResolutionLocation = -1; |
||||
iGlobalTimeLocation = -1; |
||||
START_TIME = System.currentTimeMillis(); |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(int programHandle) { |
||||
super.onCreate(programHandle); |
||||
iResolutionLocation = GLES20.glGetUniformLocation(programHandle, "iResolution"); |
||||
Egloo.checkGlProgramLocation(iResolutionLocation, "iResolution"); |
||||
|
||||
|
||||
iGlobalTimeLocation = GLES20.glGetUniformLocation(programHandle, "iTime"); |
||||
Egloo.checkGlProgramLocation(iGlobalTimeLocation, "iTime"); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPreDraw(long timestampUs, @NonNull float[] transformMatrix) { |
||||
super.onPreDraw(timestampUs, transformMatrix); |
||||
|
||||
Size size = getSize(); |
||||
if (size != null) { |
||||
GLES20.glUniform3fv(iResolutionLocation, 1, |
||||
FloatBuffer.wrap(new float[]{(float) size.getWidth(), (float) size.getHeight(), 1.0f})); |
||||
Egloo.checkGlError("glUniform3fv"); |
||||
} |
||||
|
||||
|
||||
float time = (((float) (System.currentTimeMillis() - START_TIME)) / 1000.0f) + 1; |
||||
GLES20.glUniform1f(iGlobalTimeLocation, time); |
||||
Egloo.checkGlError("glUniform1f"); |
||||
} |
||||
} |
@ -0,0 +1,108 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import android.opengl.GLES20; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
import com.otaliastudios.cameraview.size.Size; |
||||
import com.otaliastudios.opengl.core.Egloo; |
||||
|
||||
import java.nio.FloatBuffer; |
||||
|
||||
public class DrunkDialFilter extends BaseFilter { |
||||
private static final String FRAGMENT_SHADER = |
||||
"#extension GL_OES_EGL_image_external : require\n" + |
||||
"precision highp float;\n" + |
||||
"\n" + |
||||
"uniform vec3 iResolution;\n" + |
||||
"uniform float iTime;\n" + |
||||
"uniform samplerExternalOES iChannel0;\n" + |
||||
"varying vec2 " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + ";\n" + |
||||
"void mainImage( out vec4 fragColor, in vec2 fragCoord )\n" + |
||||
"{\n" + |
||||
"\t// Just playing around with shaders for my first time.\n" + |
||||
"\t// Pardon the unoptimized mess.\n" + |
||||
"\t// -Dan\n" + |
||||
"\tfloat drunk = sin(iTime*2.0)*6.0;\n" + |
||||
"\tfloat unitDrunk1 = (sin(iTime*1.2)+1.0)/2.0;\n" + |
||||
"\tfloat unitDrunk2 = (sin(iTime*1.8)+1.0)/2.0;\n" + |
||||
"\n" + |
||||
"\tvec2 normalizedCoord = mod((fragCoord.xy + vec2(0, drunk)) / iResolution.xy, 1.0);\n" + |
||||
"\tnormalizedCoord.x = pow(normalizedCoord.x, mix(1.25, 0.85, unitDrunk1));\n" + |
||||
"\tnormalizedCoord.y = pow(normalizedCoord.y, mix(0.85, 1.25, unitDrunk2));\n" + |
||||
"\n" + |
||||
"\tvec2 normalizedCoord2 = mod((fragCoord.xy + vec2(drunk, 0)) / iResolution.xy, 1.0);\t\n" + |
||||
"\tnormalizedCoord2.x = pow(normalizedCoord2.x, mix(0.95, 1.1, unitDrunk2));\n" + |
||||
"\tnormalizedCoord2.y = pow(normalizedCoord2.y, mix(1.1, 0.95, unitDrunk1));\n" + |
||||
"\n" + |
||||
"\tvec2 normalizedCoord3 = fragCoord.xy/iResolution.xy;\n" + |
||||
"\t\n" + |
||||
"\tvec4 color = texture2D(iChannel0, normalizedCoord);\t\n" + |
||||
"\tvec4 color2 = texture2D(iChannel0, normalizedCoord2);\n" + |
||||
"\tvec4 color3 = texture2D(iChannel0, normalizedCoord3);\n" + |
||||
"\n" + |
||||
"\t// Mess with colors and test swizzling\n" + |
||||
"\tcolor.x = sqrt(color2.x);\n" + |
||||
"\tcolor2.x = sqrt(color2.x);\n" + |
||||
"\t\n" + |
||||
"\tvec4 finalColor = mix( mix(color, color2, mix(0.4, 0.6, unitDrunk1)), color3, 0.4);\n" + |
||||
"\t\n" + |
||||
"\t// \n" + |
||||
"\tif (length(finalColor) > 1.4)\n" + |
||||
"\t\tfinalColor.xy = mix(finalColor.xy, normalizedCoord3, 0.5);\n" + |
||||
"\telse if (length(finalColor) < 0.4)\n" + |
||||
"\t\tfinalColor.yz = mix(finalColor.yz, normalizedCoord3, 0.5);\n" + |
||||
"\t\t\n" + |
||||
"\tfragColor = finalColor;\t\t\n" + |
||||
"}\n"+ |
||||
"\nvoid main() {\n" + |
||||
"\tmainImage(gl_FragColor, " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + " * iResolution.xy);\n" + |
||||
"}"; |
||||
|
||||
long START_TIME = System.currentTimeMillis(); |
||||
private int iGlobalTimeLocation = -1; |
||||
private int iResolutionLocation = -1; |
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return FRAGMENT_SHADER; |
||||
} |
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
iResolutionLocation = -1; |
||||
iGlobalTimeLocation = -1; |
||||
START_TIME = System.currentTimeMillis(); |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(int programHandle) { |
||||
super.onCreate(programHandle); |
||||
iResolutionLocation = GLES20.glGetUniformLocation(programHandle, "iResolution"); |
||||
Egloo.checkGlProgramLocation(iResolutionLocation, "iResolution"); |
||||
|
||||
|
||||
iGlobalTimeLocation = GLES20.glGetUniformLocation(programHandle, "iTime"); |
||||
Egloo.checkGlProgramLocation(iGlobalTimeLocation, "iTime"); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPreDraw(long timestampUs, @NonNull float[] transformMatrix) { |
||||
super.onPreDraw(timestampUs, transformMatrix); |
||||
|
||||
Size size = getSize(); |
||||
if (size != null) { |
||||
GLES20.glUniform3fv(iResolutionLocation, 1, |
||||
FloatBuffer.wrap(new float[]{(float) size.getWidth(), (float) size.getHeight(), 1.0f})); |
||||
Egloo.checkGlError("glUniform3fv"); |
||||
} |
||||
|
||||
|
||||
float time = (((float) (System.currentTimeMillis() - START_TIME)) / 1000.0f) + 1; |
||||
GLES20.glUniform1f(iGlobalTimeLocation, time); |
||||
Egloo.checkGlError("glUniform1f"); |
||||
} |
||||
} |
@ -0,0 +1,83 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import android.opengl.GLES20; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
import com.otaliastudios.opengl.core.Egloo; |
||||
|
||||
import java.nio.FloatBuffer; |
||||
|
||||
public class EMInterferenceFilter extends BaseFilter { |
||||
private static final String FRAGMENT_SHADER = |
||||
"#extension GL_OES_EGL_image_external : require\n" + |
||||
"precision highp float;\n" + |
||||
"\n" + |
||||
"uniform float iGlobalTime;\n" + |
||||
"uniform samplerExternalOES iChannel0;\n" + |
||||
"varying vec2 " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + ";\n" + |
||||
"\n" + |
||||
"float rng2(vec2 seed)\n" + |
||||
"{\n" + |
||||
" return fract(sin(dot(seed * floor(iGlobalTime * 12.), vec2(127.1,311.7))) * 43758.5453123);\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"float rng(float seed)\n" + |
||||
"{\n" + |
||||
" return rng2(vec2(seed, 1.0));\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"void mainImage( out vec4 fragColor, in vec2 fragCoord )\n" + |
||||
"{\n" + |
||||
"\tvec2 uv = fragCoord.xy;\n" + |
||||
" vec2 blockS = floor(uv * vec2(24., 9.));\n" + |
||||
" vec2 blockL = floor(uv * vec2(8., 4.));\n" + |
||||
"\n" + |
||||
" float r = rng2(uv);\n" + |
||||
" vec3 noise = (vec3(r, 1. - r, r / 2. + 0.5) * 1.0 - 2.0) * 0.08;\n" + |
||||
"\n" + |
||||
" float lineNoise = pow(rng2(blockS), 8.0) * pow(rng2(blockL), 3.0) - pow(rng(7.2341), 17.0) * 2.;\n" + |
||||
"\n" + |
||||
" vec4 col1 = texture2D(iChannel0, uv);\n" + |
||||
" vec4 col2 = texture2D(iChannel0, uv + vec2(lineNoise * 0.05 * rng(5.0), 0));\n" + |
||||
" vec4 col3 = texture2D(iChannel0, uv - vec2(lineNoise * 0.05 * rng(31.0), 0));\n" + |
||||
"\n" + |
||||
"\tfragColor = vec4(vec3(col1.x, col2.y, col3.z) + noise, 1.0);\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"void main() {\n" + |
||||
"\tmainImage(gl_FragColor, " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + ");\n" + |
||||
"}"; |
||||
|
||||
long START_TIME = System.currentTimeMillis(); |
||||
private int iGlobalTimeLocation = -1; |
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return FRAGMENT_SHADER; |
||||
} |
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
iGlobalTimeLocation = -1; |
||||
START_TIME = System.currentTimeMillis(); |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(int programHandle) { |
||||
super.onCreate(programHandle); |
||||
iGlobalTimeLocation = GLES20.glGetUniformLocation(programHandle, "iGlobalTime"); |
||||
Egloo.checkGlProgramLocation(iGlobalTimeLocation, "iGlobalTime"); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPreDraw(long timestampUs, @NonNull float[] transformMatrix) { |
||||
super.onPreDraw(timestampUs, transformMatrix); |
||||
float time = ((float) (System.currentTimeMillis() - START_TIME)) / 1000.0f; |
||||
GLES20.glUniform1f(iGlobalTimeLocation, time); |
||||
Egloo.checkGlError("glUniform1f"); |
||||
} |
||||
} |
@ -0,0 +1,106 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import android.content.Context; |
||||
import android.opengl.GLES20; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.R; |
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
import com.otaliastudios.cameraview.filter.ContextParameterFilter; |
||||
import com.otaliastudios.cameraview.size.Size; |
||||
import com.otaliastudios.opengl.core.Egloo; |
||||
|
||||
import java.nio.FloatBuffer; |
||||
|
||||
public class EarlybirdFilter extends BaseFilter implements ContextParameterFilter { |
||||
|
||||
|
||||
private static final String FRAGMENT_SHADER = |
||||
"#extension GL_OES_EGL_image_external : require\n" + |
||||
"precision mediump float; \n" + |
||||
"uniform samplerExternalOES sTexture; \n" + |
||||
"varying vec2 " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + "; \n" + |
||||
"const vec3 W = vec3(0.2125, 0.7154, 0.0721);\n" + |
||||
"\n" + |
||||
"vec3 BrightnessContrastSaturation(vec3 color, float brt, float con, float sat)\n" + |
||||
"{\n" + |
||||
"\tvec3 black = vec3(0., 0., 0.);\n" + |
||||
"\tvec3 middle = vec3(0.5, 0.5, 0.5);\n" + |
||||
"\tfloat luminance = dot(color, W);\n" + |
||||
"\tvec3 gray = vec3(luminance, luminance, luminance);\n" + |
||||
"\t\n" + |
||||
"\tvec3 brtColor = mix(black, color, brt);\n" + |
||||
"\tvec3 conColor = mix(middle, brtColor, con);\n" + |
||||
"\tvec3 satColor = mix(gray, conColor, sat);\n" + |
||||
"\treturn satColor;\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"vec3 ovelayBlender(vec3 Color, vec3 filter){\n" + |
||||
"\tvec3 filter_result;\n" + |
||||
"\tfloat luminance = dot(filter, W);\n" + |
||||
"\t\n" + |
||||
"\tif(luminance < 0.5)\n" + |
||||
"\t\tfilter_result = 2. * filter * Color;\n" + |
||||
"\telse\n" + |
||||
"\t\tfilter_result = 1. - (1. - (2. *(filter - 0.5)))*(1. - Color);\n" + |
||||
"\t\t\n" + |
||||
"\treturn filter_result;\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"vec3 multiplyBlender(vec3 Color, vec3 filter){\n" + |
||||
"\tvec3 filter_result;\n" + |
||||
"\tfloat luminance = dot(filter, W);\n" + |
||||
"\t\n" + |
||||
"\tif(luminance < 0.5)\n" + |
||||
"\t\tfilter_result = 2. * filter * Color;\n" + |
||||
"\telse\n" + |
||||
"\t\tfilter_result = Color;\n" + |
||||
"\t\t\t\n" + |
||||
"\treturn filter_result;\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"void main()\n" + |
||||
"{\n" + |
||||
"\t //get the pixel\n" + |
||||
" vec2 st = " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + ".st;\n" + |
||||
" vec3 irgb = texture2D(sTexture, st).rgb;\n" + |
||||
" \n" + |
||||
" //adjust the brightness/contrast/saturation\n" + |
||||
" float T_bright = 1.2;\n" + |
||||
" float T_contrast = 1.1;\n" + |
||||
" float T_saturation = 1.2;\n" + |
||||
" vec3 bcs_result = BrightnessContrastSaturation(irgb, T_bright, T_contrast, T_saturation);\n" + |
||||
" \n" + |
||||
" //more red, less blue\n" + |
||||
" vec3 rb_result = vec3(bcs_result.r*1.1, bcs_result.g, bcs_result.b*0.9);\n" + |
||||
" \n" + |
||||
" gl_FragColor = vec4(rb_result, 1.);\n" + |
||||
"}"; |
||||
|
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return FRAGMENT_SHADER; |
||||
} |
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(int programHandle) { |
||||
super.onCreate(programHandle); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPreDraw(long timestampUs, @NonNull float[] transformMatrix) { |
||||
super.onPreDraw(timestampUs, transformMatrix); |
||||
} |
||||
|
||||
@Override |
||||
public void setContext(Context value) { |
||||
} |
||||
} |
@ -0,0 +1,48 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
|
||||
public class EdgeDetectionFilter extends BaseFilter { |
||||
private static final String FRAGMENT_SHADER = |
||||
"#extension GL_OES_EGL_image_external : require\n" + |
||||
"#extension GL_OES_standard_derivatives : enable\n" + |
||||
"precision highp float;\n" + |
||||
"\n" + |
||||
"uniform samplerExternalOES iChannel0;\n" + |
||||
"varying vec2 " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + ";\n" + |
||||
"\n" + |
||||
"void mainImage( out vec4 fragColor, in vec2 fragCoord )\n" + |
||||
"{\n" + |
||||
" vec2 uv = fragCoord.xy;\n" + |
||||
" vec4 color = texture2D(iChannel0, fragCoord);\n" + |
||||
" float gray = length(color.rgb);\n" + |
||||
" fragColor = vec4(vec3(step(0.06, length(vec2(dFdx(gray), dFdy(gray))))), 1.0);\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"void main() {\n" + |
||||
" mainImage(gl_FragColor, " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + ");\n" + |
||||
"}"; |
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return FRAGMENT_SHADER; |
||||
} |
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(int programHandle) { |
||||
super.onCreate(programHandle); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPreDraw(long timestampUs, @NonNull float[] transformMatrix) { |
||||
super.onPreDraw(timestampUs, transformMatrix); |
||||
} |
||||
} |
@ -0,0 +1,143 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import android.opengl.GLES20; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
import com.otaliastudios.cameraview.size.Size; |
||||
import com.otaliastudios.opengl.core.Egloo; |
||||
|
||||
import java.nio.FloatBuffer; |
||||
|
||||
public class EdgeGlowFilter extends BaseFilter { |
||||
private static final String FRAGMENT_SHADER = |
||||
"#extension GL_OES_EGL_image_external : require\n" + |
||||
"precision highp float;\n" + |
||||
"\n" + |
||||
"uniform vec3 iResolution;\n" + |
||||
"uniform float iTime;\n" + |
||||
"uniform samplerExternalOES iChannel0;\n" + |
||||
"varying vec2 " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + ";\n" + |
||||
"\n" + |
||||
"/* Returns rgb vec from input 0-1 */\n" + |
||||
"vec3 getRainbowColor(in float val) {\n" + |
||||
" /*convert to rainbow RGB*/\n" + |
||||
" float a = (1.0 - val) * 6.0;\n" + |
||||
" int X = int(floor(a));\n" + |
||||
" float Y = a - float(X);\n" + |
||||
" float r = 0.;\n" + |
||||
" float g = 0.;\n" + |
||||
" float b = 0.;\n" + |
||||
" if (X == 0) {\n" + |
||||
" r = 1.; g = Y; b = 0.;\n" + |
||||
" } else if (X == 1) {\n" + |
||||
" r = 1. - Y; g = 1.; b = 0.;\n" + |
||||
" } else if (X == 2) {\n" + |
||||
" r = 0.; g = 1.; b = Y;\n" + |
||||
" } else if (X == 3) {\n" + |
||||
" r = 0.; g = 1. - Y; b = 1.;\n" + |
||||
" } else if (X == 4) {\n" + |
||||
" r = Y; g = 0.; b = 1.;\n" + |
||||
" } else if (X == 5) {\n" + |
||||
" r = 1.; g = 0.; b = 1. - Y;\n" + |
||||
" } else {\n" + |
||||
" r = 0.; g = 0.; b = 0.;\n" + |
||||
" }\n" + |
||||
" return vec3(r, g, b);\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"float d;\n" + |
||||
"\n" + |
||||
"float lookup(vec2 p, float dx, float dy, float edgeIntensity)\n" + |
||||
"{\n" + |
||||
" vec2 uv = (p.xy + vec2(dx * edgeIntensity, dy * edgeIntensity)) / iResolution.xy;\n" + |
||||
" vec4 c = texture2D(iChannel0, uv.xy);\n" + |
||||
"\t\n" + |
||||
"\t// return as luma\n" + |
||||
" return 0.2126*c.r + 0.7152*c.g + 0.0722*c.b;\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"void mainImage( out vec4 fragColor, in vec2 fragCoord )\n" + |
||||
"{\n" + |
||||
" float timeNorm = mod(iTime, 5.) / 5.;\n" + |
||||
" vec3 glowCol = getRainbowColor(timeNorm);\n" + |
||||
" float edgeIntensity = 1.;\n" + |
||||
" if (timeNorm < .5) { edgeIntensity += (4. * timeNorm);}\n" + |
||||
" else { edgeIntensity += -4. * (timeNorm - 1.); }\n" + |
||||
" vec2 p = fragCoord.xy;\n" + |
||||
" \n" + |
||||
"\t// simple sobel edge detection\n" + |
||||
" float gx = 0.0;\n" + |
||||
" gx += -1.0 * lookup(p, -1.0, -1.0, edgeIntensity);\n" + |
||||
" gx += -2.0 * lookup(p, -1.0, 0.0, edgeIntensity);\n" + |
||||
" gx += -1.0 * lookup(p, -1.0, 1.0, edgeIntensity);\n" + |
||||
" gx += 1.0 * lookup(p, 1.0, -1.0, edgeIntensity);\n" + |
||||
" gx += 2.0 * lookup(p, 1.0, 0.0, edgeIntensity);\n" + |
||||
" gx += 1.0 * lookup(p, 1.0, 1.0, edgeIntensity);\n" + |
||||
" \n" + |
||||
" float gy = 0.0;\n" + |
||||
" gy += -1.0 * lookup(p, -1.0, -1.0, edgeIntensity);\n" + |
||||
" gy += -2.0 * lookup(p, 0.0, -1.0, edgeIntensity);\n" + |
||||
" gy += -1.0 * lookup(p, 1.0, -1.0, edgeIntensity);\n" + |
||||
" gy += 1.0 * lookup(p, -1.0, 1.0, edgeIntensity);\n" + |
||||
" gy += 2.0 * lookup(p, 0.0, 1.0, edgeIntensity);\n" + |
||||
" gy += 1.0 * lookup(p, 1.0, 1.0, edgeIntensity);\n" + |
||||
" \n" + |
||||
"\t// hack: use g^2 to conceal noise in the video\n" + |
||||
" float g = gx*gx + gy*gy;\n" + |
||||
" \n" + |
||||
" vec4 col = texture2D(iChannel0, p / iResolution.xy);\n" + |
||||
" col += vec4(g * glowCol, 1.0);\n" + |
||||
" \n" + |
||||
" fragColor = col;\n" + |
||||
"}" + |
||||
"\n" + |
||||
"void main() {\n" + |
||||
"\tmainImage(gl_FragColor, " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + " * iResolution.xy);\n" + |
||||
"}"; |
||||
|
||||
|
||||
long START_TIME = System.currentTimeMillis(); |
||||
private int iGlobalTimeLocation = -1; |
||||
private int iResolutionLocation = -1; |
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return FRAGMENT_SHADER; |
||||
} |
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
iGlobalTimeLocation = -1; |
||||
START_TIME = System.currentTimeMillis(); |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(int programHandle) { |
||||
super.onCreate(programHandle); |
||||
iResolutionLocation = GLES20.glGetUniformLocation(programHandle, "iResolution"); |
||||
Egloo.checkGlProgramLocation(iResolutionLocation, "iResolution"); |
||||
|
||||
iGlobalTimeLocation = GLES20.glGetUniformLocation(programHandle, "iTime"); |
||||
Egloo.checkGlProgramLocation(iGlobalTimeLocation, "iTime"); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPreDraw(long timestampUs, @NonNull float[] transformMatrix) { |
||||
super.onPreDraw(timestampUs, transformMatrix); |
||||
|
||||
Size size = getSize(); |
||||
if (size != null) { |
||||
GLES20.glUniform3fv(iResolutionLocation, 1, |
||||
FloatBuffer.wrap(new float[]{(float) size.getWidth(), (float) size.getHeight(), 1.0f})); |
||||
Egloo.checkGlError("glUniform3fv"); |
||||
} |
||||
|
||||
float time = ((float) (System.currentTimeMillis() - START_TIME)) / 1000.0f; |
||||
GLES20.glUniform1f(iGlobalTimeLocation, time); |
||||
Egloo.checkGlError("glUniform1f"); |
||||
} |
||||
} |
@ -0,0 +1,77 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import android.opengl.GLES20; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
import com.otaliastudios.cameraview.filter.OneParameterFilter; |
||||
import com.otaliastudios.cameraview.filter.TwoParameterFilter; |
||||
import com.otaliastudios.opengl.core.Egloo; |
||||
|
||||
/** |
||||
* exposure: The adjusted exposure (-1 - 0 - 1 as the default) |
||||
*/ |
||||
public class ExposureFilter extends BaseFilter implements OneParameterFilter { |
||||
private static final String EXPOSURE_FRAGMENT_SHADER = "#extension GL_OES_EGL_image_external : require\n" + |
||||
"precision mediump float;\n" + |
||||
"uniform samplerExternalOES sTexture;\n" + |
||||
"uniform float exposure;\n" + |
||||
"varying vec2 "+DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME+";\n" + |
||||
"void main()\n" + |
||||
"{\n" + |
||||
" vec4 textureColor = texture2D(sTexture, "+DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME+");\n" + |
||||
" gl_FragColor = vec4(textureColor.rgb * pow(2.0, exposure), textureColor.w);\n" + |
||||
"}"; |
||||
|
||||
private float exposure = 1f; |
||||
private int exposureLocation = -1; |
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return EXPOSURE_FRAGMENT_SHADER; |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(int programHandle) { |
||||
super.onCreate(programHandle); |
||||
exposureLocation = GLES20.glGetUniformLocation(programHandle, "exposure"); |
||||
Egloo.checkGlProgramLocation(exposureLocation, "exposure"); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPreDraw(long timestampUs, @NonNull float[] transformMatrix) { |
||||
super.onPreDraw(timestampUs, transformMatrix); |
||||
GLES20.glUniform1f(exposureLocation, exposure); |
||||
Egloo.checkGlError("glUniform1f"); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
exposure = 1f; |
||||
exposureLocation = -1; |
||||
} |
||||
|
||||
@Override |
||||
public void setParameter1(float value) { |
||||
setExposure(value); |
||||
} |
||||
|
||||
@Override |
||||
public float getParameter1() { |
||||
return getExposure(); |
||||
} |
||||
|
||||
public float getExposure() { |
||||
return exposure; |
||||
} |
||||
/** |
||||
* exposure: The adjusted exposure (-10.0 - 10.0, with 0.0 as the default) |
||||
*/ |
||||
public void setExposure(float exposure) { |
||||
this.exposure = exposure; |
||||
} |
||||
} |
@ -0,0 +1,115 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import android.opengl.GLES20; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
import com.otaliastudios.cameraview.filter.OneParameterFilter; |
||||
import com.otaliastudios.cameraview.filter.TwoParameterFilter; |
||||
import com.otaliastudios.opengl.core.Egloo; |
||||
|
||||
/** |
||||
* exposure: The adjusted exposure (-10.0 - 10.0, with 0.0 as the default) |
||||
*/ |
||||
public class HalftoneFilter extends BaseFilter implements TwoParameterFilter { |
||||
private static final String EXPOSURE_FRAGMENT_SHADER = "#extension GL_OES_EGL_image_external : require\n" + |
||||
"precision mediump float;" + |
||||
"varying vec2 vTextureCoord;\n" + |
||||
|
||||
"uniform samplerExternalOES sTexture;\n" + |
||||
|
||||
"uniform highp float fractionalWidthOfPixel;\n" + |
||||
"uniform highp float aspectRatio;\n" + |
||||
|
||||
"const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);\n" + |
||||
|
||||
"void main()\n" + |
||||
"{\n" + |
||||
" highp vec2 sampleDivisor = vec2(fractionalWidthOfPixel, fractionalWidthOfPixel / aspectRatio);\n" + |
||||
" highp vec2 samplePos = vTextureCoord - mod(vTextureCoord, sampleDivisor) + 0.5 * sampleDivisor;\n" + |
||||
" highp vec2 textureCoordinateToUse = vec2(vTextureCoord.x, (vTextureCoord.y * aspectRatio + 0.5 - 0.5 * aspectRatio));\n" + |
||||
" highp vec2 adjustedSamplePos = vec2(samplePos.x, (samplePos.y * aspectRatio + 0.5 - 0.5 * aspectRatio));\n" + |
||||
" highp float distanceFromSamplePoint = distance(adjustedSamplePos, textureCoordinateToUse);\n" + |
||||
" lowp vec3 sampledColor = texture2D(sTexture, samplePos).rgb;\n" + |
||||
" highp float dotScaling = 1.0 - dot(sampledColor, W);\n" + |
||||
" lowp float checkForPresenceWithinDot = 1.0 - step(distanceFromSamplePoint, (fractionalWidthOfPixel * 0.5) * dotScaling);\n" + |
||||
" gl_FragColor = vec4(vec3(checkForPresenceWithinDot), 1.0);\n" + |
||||
"}"; |
||||
|
||||
private float fractionalWidthOfPixel = 0.01f; |
||||
private int fractionalWidthOfPixelLocation = -1; |
||||
private float aspectRatio = 1f; |
||||
private int aspectRatioLocation = -1; |
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return EXPOSURE_FRAGMENT_SHADER; |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(int programHandle) { |
||||
super.onCreate(programHandle); |
||||
|
||||
fractionalWidthOfPixelLocation = GLES20.glGetUniformLocation(programHandle, "fractionalWidthOfPixel"); |
||||
Egloo.checkGlProgramLocation(fractionalWidthOfPixelLocation, "fractionalWidthOfPixel"); |
||||
|
||||
aspectRatioLocation = GLES20.glGetUniformLocation(programHandle, "aspectRatio"); |
||||
Egloo.checkGlProgramLocation(aspectRatioLocation, "aspectRatio"); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPreDraw(long timestampUs, @NonNull float[] transformMatrix) { |
||||
super.onPreDraw(timestampUs, transformMatrix); |
||||
GLES20.glUniform1f(fractionalWidthOfPixelLocation, fractionalWidthOfPixel); |
||||
GLES20.glUniform1f(aspectRatioLocation, aspectRatio); |
||||
Egloo.checkGlError("glUniform1f"); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
fractionalWidthOfPixel = 0.01f; |
||||
fractionalWidthOfPixelLocation = -1; |
||||
aspectRatio = 1f; |
||||
aspectRatioLocation = -1; |
||||
} |
||||
|
||||
@Override |
||||
public void setParameter1(float value) { |
||||
setFractionalWidthOfPixel(value); |
||||
} |
||||
|
||||
@Override |
||||
public float getParameter1() { |
||||
return getFractionalWidthOfPixel(); |
||||
} |
||||
|
||||
@Override |
||||
public void setParameter2(float value) { |
||||
setAspectRatio(value); |
||||
} |
||||
|
||||
@Override |
||||
public float getParameter2() { |
||||
return getAspectRatio(); |
||||
} |
||||
|
||||
public float getFractionalWidthOfPixel() { |
||||
return fractionalWidthOfPixel; |
||||
} |
||||
|
||||
public void setFractionalWidthOfPixel(float fractionalWidthOfPixel) { |
||||
this.fractionalWidthOfPixel = fractionalWidthOfPixel; |
||||
} |
||||
|
||||
public float getAspectRatio() { |
||||
return aspectRatio; |
||||
} |
||||
|
||||
public void setAspectRatio(float aspectRatio) { |
||||
this.aspectRatio = aspectRatio; |
||||
} |
||||
} |
@ -0,0 +1,141 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import android.opengl.GLES20; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
import com.otaliastudios.cameraview.size.Size; |
||||
import com.otaliastudios.opengl.core.Egloo; |
||||
|
||||
import java.nio.FloatBuffer; |
||||
|
||||
public class HighEdgeGlowFilter extends BaseFilter { |
||||
private static final String FRAGMENT_SHADER = |
||||
"#extension GL_OES_EGL_image_external : require\n" + |
||||
"precision highp float;\n" + |
||||
"\n" + |
||||
"uniform vec3 iResolution;\n" + |
||||
"uniform float iTime;\n" + |
||||
"uniform samplerExternalOES iChannel0;\n" + |
||||
"varying vec2 " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + ";\n" + |
||||
"\n" + |
||||
"/* Returns rgb vec from input 0-1 */\n" + |
||||
"vec3 getRainbowColor(in float val) {\n" + |
||||
" /*convert to rainbow RGB*/\n" + |
||||
" float a = (1.0 - val) * 6.0;\n" + |
||||
" int X = int(floor(a));\n" + |
||||
" float Y = a - float(X);\n" + |
||||
" float r = 0.;\n" + |
||||
" float g = 0.;\n" + |
||||
" float b = 0.;\n" + |
||||
" if (X == 0) {\n" + |
||||
" r = 1.; g = Y; b = 0.;\n" + |
||||
" } else if (X == 1) {\n" + |
||||
" r = 1. - Y; g = 1.; b = 0.;\n" + |
||||
" } else if (X == 2) {\n" + |
||||
" r = 0.; g = 1.; b = Y;\n" + |
||||
" } else if (X == 3) {\n" + |
||||
" r = 0.; g = 1. - Y; b = 1.;\n" + |
||||
" } else if (X == 4) {\n" + |
||||
" r = Y; g = 0.; b = 1.;\n" + |
||||
" } else if (X == 5) {\n" + |
||||
" r = 1.; g = 0.; b = 1. - Y;\n" + |
||||
" } else {\n" + |
||||
" r = 0.; g = 0.; b = 0.;\n" + |
||||
" }\n" + |
||||
" return vec3(r, g, b);\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"float d;\n" + |
||||
"\n" + |
||||
"float lookup(vec2 p, float dx, float dy, float edgeIntensity)\n" + |
||||
"{\n" + |
||||
" vec2 uv = (p.xy + vec2(dx * edgeIntensity, dy * edgeIntensity)) / iResolution.xy;\n" + |
||||
" vec4 c = texture2D(iChannel0, uv.xy);\n" + |
||||
"\t\n" + |
||||
"\t// return as luma\n" + |
||||
" return 0.2126*c.r + 0.7152*c.g + 0.0722*c.b;\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"void mainImage( out vec4 fragColor, in vec2 fragCoord )\n" + |
||||
"{\n" + |
||||
" float timeNorm = mod(iTime, 5.) / 5.;\n" + |
||||
" vec3 glowCol = getRainbowColor(timeNorm);\n" + |
||||
" float edgeIntensity = 10.;\n" + |
||||
" vec2 p = fragCoord.xy;\n" + |
||||
" \n" + |
||||
"\t// simple sobel edge detection\n" + |
||||
" float gx = 0.0;\n" + |
||||
" gx += -1.0 * lookup(p, -1.0, -1.0, edgeIntensity);\n" + |
||||
" gx += -2.0 * lookup(p, -1.0, 0.0, edgeIntensity);\n" + |
||||
" gx += -1.0 * lookup(p, -1.0, 1.0, edgeIntensity);\n" + |
||||
" gx += 1.0 * lookup(p, 1.0, -1.0, edgeIntensity);\n" + |
||||
" gx += 2.0 * lookup(p, 1.0, 0.0, edgeIntensity);\n" + |
||||
" gx += 1.0 * lookup(p, 1.0, 1.0, edgeIntensity);\n" + |
||||
" \n" + |
||||
" float gy = 0.0;\n" + |
||||
" gy += -1.0 * lookup(p, -1.0, -1.0, edgeIntensity);\n" + |
||||
" gy += -2.0 * lookup(p, 0.0, -1.0, edgeIntensity);\n" + |
||||
" gy += -1.0 * lookup(p, 1.0, -1.0, edgeIntensity);\n" + |
||||
" gy += 1.0 * lookup(p, -1.0, 1.0, edgeIntensity);\n" + |
||||
" gy += 2.0 * lookup(p, 0.0, 1.0, edgeIntensity);\n" + |
||||
" gy += 1.0 * lookup(p, 1.0, 1.0, edgeIntensity);\n" + |
||||
" \n" + |
||||
"\t// hack: use g^2 to conceal noise in the video\n" + |
||||
" float g = gx*gx + gy*gy;\n" + |
||||
" \n" + |
||||
" vec4 col = texture2D(iChannel0, p / iResolution.xy);\n" + |
||||
" col += vec4(g * glowCol, 1.0);\n" + |
||||
" \n" + |
||||
" fragColor = col;\n" + |
||||
"}" + |
||||
"\n" + |
||||
"void main() {\n" + |
||||
"\tmainImage(gl_FragColor, " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + " * iResolution.xy);\n" + |
||||
"}"; |
||||
|
||||
|
||||
long START_TIME = System.currentTimeMillis(); |
||||
private int iGlobalTimeLocation = -1; |
||||
private int iResolutionLocation = -1; |
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return FRAGMENT_SHADER; |
||||
} |
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
iGlobalTimeLocation = -1; |
||||
START_TIME = System.currentTimeMillis(); |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(int programHandle) { |
||||
super.onCreate(programHandle); |
||||
iResolutionLocation = GLES20.glGetUniformLocation(programHandle, "iResolution"); |
||||
Egloo.checkGlProgramLocation(iResolutionLocation, "iResolution"); |
||||
|
||||
iGlobalTimeLocation = GLES20.glGetUniformLocation(programHandle, "iTime"); |
||||
Egloo.checkGlProgramLocation(iGlobalTimeLocation, "iTime"); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPreDraw(long timestampUs, @NonNull float[] transformMatrix) { |
||||
super.onPreDraw(timestampUs, transformMatrix); |
||||
|
||||
Size size = getSize(); |
||||
if (size != null) { |
||||
GLES20.glUniform3fv(iResolutionLocation, 1, |
||||
FloatBuffer.wrap(new float[]{(float) size.getWidth(), (float) size.getHeight(), 1.0f})); |
||||
Egloo.checkGlError("glUniform3fv"); |
||||
} |
||||
|
||||
float time = ((float) (System.currentTimeMillis() - START_TIME)) / 1000.0f; |
||||
GLES20.glUniform1f(iGlobalTimeLocation, time); |
||||
Egloo.checkGlError("glUniform1f"); |
||||
} |
||||
} |
@ -0,0 +1,112 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import android.opengl.GLES20; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
import com.otaliastudios.cameraview.filter.TwoParameterFilter; |
||||
import com.otaliastudios.opengl.core.Egloo; |
||||
|
||||
/** |
||||
* between 0.0 to 1.0 |
||||
*/ |
||||
public class HighlightShadowFilter extends BaseFilter implements TwoParameterFilter { |
||||
private static final String EXPOSURE_FRAGMENT_SHADER = "#extension GL_OES_EGL_image_external : require\n" + |
||||
"precision mediump float;" + |
||||
" uniform samplerExternalOES sTexture;\n" + |
||||
" uniform float shadows;\n" + |
||||
" uniform float highlights;\n" + |
||||
" varying vec2 vTextureCoord;\n" + |
||||
" \n" + |
||||
" const mediump vec3 luminanceWeighting = vec3(0.3, 0.3, 0.3);\n" + |
||||
" \n" + |
||||
" void main()\n" + |
||||
" {\n" + |
||||
" vec4 source = texture2D(sTexture, vTextureCoord);\n" + |
||||
" mediump float luminance = dot(source.rgb, luminanceWeighting);\n" + |
||||
" \n" + |
||||
" mediump float shadow = clamp((pow(luminance, 1.0/(shadows+1.0)) + (-0.76)*pow(luminance, 2.0/(shadows+1.0))) - luminance, 0.0, 1.0);\n" + |
||||
" mediump float highlight = clamp((1.0 - (pow(1.0-luminance, 1.0/(2.0-highlights)) + (-0.8)*pow(1.0-luminance, 2.0/(2.0-highlights)))) - luminance, -1.0, 0.0);\n" + |
||||
" lowp vec3 result = vec3(0.0, 0.0, 0.0) + ((luminance + shadow + highlight) - 0.0) * ((source.rgb - vec3(0.0, 0.0, 0.0))/(luminance - 0.0));\n" + |
||||
" \n" + |
||||
" gl_FragColor = vec4(result.rgb, source.a);\n" + |
||||
" }"; |
||||
|
||||
private float shadows = 1f; |
||||
private int shadowsLocation = -1; |
||||
|
||||
private float highlights = 0f; |
||||
private int highlightsLocation = -1; |
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return EXPOSURE_FRAGMENT_SHADER; |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(int programHandle) { |
||||
super.onCreate(programHandle); |
||||
|
||||
shadowsLocation = GLES20.glGetUniformLocation(programHandle, "shadows"); |
||||
Egloo.checkGlProgramLocation(shadowsLocation, "shadows"); |
||||
|
||||
highlightsLocation = GLES20.glGetUniformLocation(programHandle, "highlights"); |
||||
Egloo.checkGlProgramLocation(highlightsLocation, "highlights"); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPreDraw(long timestampUs, @NonNull float[] transformMatrix) { |
||||
super.onPreDraw(timestampUs, transformMatrix); |
||||
GLES20.glUniform1f(shadowsLocation, shadows); |
||||
GLES20.glUniform1f(highlightsLocation, highlights); |
||||
Egloo.checkGlError("glUniform1f"); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
shadows = 1f; |
||||
shadowsLocation = -1; |
||||
highlights = 0f; |
||||
highlightsLocation = -1; |
||||
} |
||||
|
||||
@Override |
||||
public void setParameter1(float value) { |
||||
setShadows(value); |
||||
} |
||||
|
||||
@Override |
||||
public float getParameter1() { |
||||
return getShadows(); |
||||
} |
||||
|
||||
@Override |
||||
public void setParameter2(float value) { |
||||
setHighlights(value); |
||||
} |
||||
|
||||
@Override |
||||
public float getParameter2() { |
||||
return getHighlights(); |
||||
} |
||||
|
||||
public float getShadows() { |
||||
return shadows; |
||||
} |
||||
|
||||
public void setShadows(float shadows) { |
||||
this.shadows = shadows; |
||||
} |
||||
|
||||
public float getHighlights() { |
||||
return highlights; |
||||
} |
||||
|
||||
public void setHighlights(float highlights) { |
||||
this.highlights = highlights; |
||||
} |
||||
} |
@ -0,0 +1,82 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import android.opengl.GLES20; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
import com.otaliastudios.cameraview.filter.OneParameterFilter; |
||||
import com.otaliastudios.opengl.core.Egloo; |
||||
|
||||
/** |
||||
* exposure: The adjusted exposure (-10.0 - 10.0, with 0.0 as the default) |
||||
*/ |
||||
public class LuminanceThresholdFilter extends BaseFilter implements OneParameterFilter { |
||||
private static final String EXPOSURE_FRAGMENT_SHADER = "#extension GL_OES_EGL_image_external : require\n" + |
||||
"precision mediump float;" + |
||||
"varying highp vec2 vTextureCoord;\n" + |
||||
"\n" + |
||||
"uniform samplerExternalOES sTexture;\n" + |
||||
"uniform highp float threshold;\n" + |
||||
"\n" + |
||||
"const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);\n" + |
||||
"\n" + |
||||
"void main()\n" + |
||||
"{\n" + |
||||
" highp vec4 textureColor = texture2D(sTexture, vTextureCoord);\n" + |
||||
" highp float luminance = dot(textureColor.rgb, W);\n" + |
||||
" highp float thresholdResult = step(threshold, luminance);\n" + |
||||
" \n" + |
||||
" gl_FragColor = vec4(vec3(thresholdResult), textureColor.w);\n" + |
||||
"}"; |
||||
|
||||
|
||||
private float threshold = 0.5f; |
||||
private int thresholdLocation = -1; |
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return EXPOSURE_FRAGMENT_SHADER; |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(int programHandle) { |
||||
super.onCreate(programHandle); |
||||
thresholdLocation = GLES20.glGetUniformLocation(programHandle, "threshold"); |
||||
Egloo.checkGlProgramLocation(thresholdLocation, "threshold"); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPreDraw(long timestampUs, @NonNull float[] transformMatrix) { |
||||
super.onPreDraw(timestampUs, transformMatrix); |
||||
GLES20.glUniform1f(thresholdLocation, threshold); |
||||
Egloo.checkGlError("glUniform1f"); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
threshold = 0.5f; |
||||
thresholdLocation = -1; |
||||
} |
||||
|
||||
@Override |
||||
public void setParameter1(float value) { |
||||
setThreshold(value); |
||||
} |
||||
|
||||
@Override |
||||
public float getParameter1() { |
||||
return getThreshold(); |
||||
} |
||||
|
||||
public float getThreshold() { |
||||
return threshold; |
||||
} |
||||
|
||||
public void setThreshold(float threshold) { |
||||
this.threshold = threshold; |
||||
} |
||||
} |
@ -0,0 +1,49 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
|
||||
public class MirrorFilter extends BaseFilter { |
||||
private static final String FRAGMENT_SHADER = |
||||
"#extension GL_OES_EGL_image_external : require\n" + |
||||
"precision highp float;\n" + |
||||
"\n" + |
||||
"uniform samplerExternalOES iChannel0;\n" + |
||||
"varying vec2 " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + ";\n" + |
||||
"\n" + |
||||
"void mainImage( out vec4 fragColor, in vec2 fragCoord )\n" + |
||||
" {\n" + |
||||
" vec2 flipCoord = vec2(1.0-fragCoord.x, fragCoord.y);\n" + |
||||
" if(flipCoord.x >= 0.5){\n" + |
||||
" \tfragColor = texture2D(iChannel0, vec2( flipCoord.x - 0.5, flipCoord.y ));\n" + |
||||
" } else {\n" + |
||||
" \tfragColor = texture2D(iChannel0, vec2( 0.5 - flipCoord.x,flipCoord.y ));\n" + |
||||
" }\n" + |
||||
" }\n" + |
||||
"\n" + |
||||
"void main() {\n" + |
||||
" \tmainImage(gl_FragColor, " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + ");\n" + |
||||
" }"; |
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return FRAGMENT_SHADER; |
||||
} |
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(int programHandle) { |
||||
super.onCreate(programHandle); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPreDraw(long timestampUs, @NonNull float[] transformMatrix) { |
||||
super.onPreDraw(timestampUs, transformMatrix); |
||||
} |
||||
} |
@ -0,0 +1,143 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import android.opengl.GLES20; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
import com.otaliastudios.cameraview.size.Size; |
||||
import com.otaliastudios.opengl.core.Egloo; |
||||
|
||||
import java.nio.FloatBuffer; |
||||
|
||||
public class NeonEdgeGlowFilter extends BaseFilter { |
||||
private static final String FRAGMENT_SHADER = |
||||
"#extension GL_OES_EGL_image_external : require\n" + |
||||
"precision highp float;\n" + |
||||
"\n" + |
||||
"uniform vec3 iResolution;\n" + |
||||
"uniform float iTime;\n" + |
||||
"uniform samplerExternalOES iChannel0;\n" + |
||||
"varying vec2 " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + ";\n" + |
||||
"\n" + |
||||
"/* Returns rgb vec from input 0-1 */\n" + |
||||
"vec3 getRainbowColor(in float val) {\n" + |
||||
" /*convert to rainbow RGB*/\n" + |
||||
" float a = (1.0 - val) * 6.0;\n" + |
||||
" int X = int(floor(a));\n" + |
||||
" float Y = a - float(X);\n" + |
||||
" float r = 0.;\n" + |
||||
" float g = 0.;\n" + |
||||
" float b = 0.;\n" + |
||||
" if (X == 0) {\n" + |
||||
" r = 1.; g = Y; b = 0.;\n" + |
||||
" } else if (X == 1) {\n" + |
||||
" r = 1. - Y; g = 1.; b = 0.;\n" + |
||||
" } else if (X == 2) {\n" + |
||||
" r = 0.; g = 1.; b = Y;\n" + |
||||
" } else if (X == 3) {\n" + |
||||
" r = 0.; g = 1. - Y; b = 1.;\n" + |
||||
" } else if (X == 4) {\n" + |
||||
" r = Y; g = 0.; b = 1.;\n" + |
||||
" } else if (X == 5) {\n" + |
||||
" r = 1.; g = 0.; b = 1. - Y;\n" + |
||||
" } else {\n" + |
||||
" r = 0.; g = 0.; b = 0.;\n" + |
||||
" }\n" + |
||||
" return vec3(57,255,20);\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"float d;\n" + |
||||
"\n" + |
||||
"float lookup(vec2 p, float dx, float dy, float edgeIntensity)\n" + |
||||
"{\n" + |
||||
" vec2 uv = (p.xy + vec2(dx * edgeIntensity, dy * edgeIntensity)) / iResolution.xy;\n" + |
||||
" vec4 c = texture2D(iChannel0, uv.xy);\n" + |
||||
"\t\n" + |
||||
"\t// return as luma\n" + |
||||
" return 0.2126*c.r + 0.7152*c.g + 0.0722*c.b;\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"void mainImage( out vec4 fragColor, in vec2 fragCoord )\n" + |
||||
"{\n" + |
||||
" float timeNorm = mod(iTime, 5.) / 5.;\n" + |
||||
" vec3 glowCol = getRainbowColor(timeNorm);\n" + |
||||
" float edgeIntensity = 1.;\n" + |
||||
" if (timeNorm < .5) { edgeIntensity += (4. * timeNorm);}\n" + |
||||
" else { edgeIntensity += -4. * (timeNorm - 1.); }\n" + |
||||
" vec2 p = fragCoord.xy;\n" + |
||||
" \n" + |
||||
"\t// simple sobel edge detection\n" + |
||||
" float gx = 0.0;\n" + |
||||
" gx += -1.0 * lookup(p, -1.0, -1.0, edgeIntensity);\n" + |
||||
" gx += -2.0 * lookup(p, -1.0, 0.0, edgeIntensity);\n" + |
||||
" gx += -1.0 * lookup(p, -1.0, 1.0, edgeIntensity);\n" + |
||||
" gx += 1.0 * lookup(p, 1.0, -1.0, edgeIntensity);\n" + |
||||
" gx += 2.0 * lookup(p, 1.0, 0.0, edgeIntensity);\n" + |
||||
" gx += 1.0 * lookup(p, 1.0, 1.0, edgeIntensity);\n" + |
||||
" \n" + |
||||
" float gy = 0.0;\n" + |
||||
" gy += -1.0 * lookup(p, -1.0, -1.0, edgeIntensity);\n" + |
||||
" gy += -2.0 * lookup(p, 0.0, -1.0, edgeIntensity);\n" + |
||||
" gy += -1.0 * lookup(p, 1.0, -1.0, edgeIntensity);\n" + |
||||
" gy += 1.0 * lookup(p, -1.0, 1.0, edgeIntensity);\n" + |
||||
" gy += 2.0 * lookup(p, 0.0, 1.0, edgeIntensity);\n" + |
||||
" gy += 1.0 * lookup(p, 1.0, 1.0, edgeIntensity);\n" + |
||||
" \n" + |
||||
"\t// hack: use g^2 to conceal noise in the video\n" + |
||||
" float g = gx*gx + gy*gy;\n" + |
||||
" \n" + |
||||
" vec4 col = texture2D(iChannel0, p / iResolution.xy);\n" + |
||||
" col += vec4(g * glowCol, 1.0);\n" + |
||||
" \n" + |
||||
" fragColor = col;\n" + |
||||
"}" + |
||||
"\n" + |
||||
"void main() {\n" + |
||||
"\tmainImage(gl_FragColor, " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + " * iResolution.xy);\n" + |
||||
"}"; |
||||
|
||||
|
||||
long START_TIME = System.currentTimeMillis(); |
||||
private int iGlobalTimeLocation = -1; |
||||
private int iResolutionLocation = -1; |
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return FRAGMENT_SHADER; |
||||
} |
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
iGlobalTimeLocation = -1; |
||||
START_TIME = System.currentTimeMillis(); |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(int programHandle) { |
||||
super.onCreate(programHandle); |
||||
iResolutionLocation = GLES20.glGetUniformLocation(programHandle, "iResolution"); |
||||
Egloo.checkGlProgramLocation(iResolutionLocation, "iResolution"); |
||||
|
||||
iGlobalTimeLocation = GLES20.glGetUniformLocation(programHandle, "iTime"); |
||||
Egloo.checkGlProgramLocation(iGlobalTimeLocation, "iTime"); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPreDraw(long timestampUs, @NonNull float[] transformMatrix) { |
||||
super.onPreDraw(timestampUs, transformMatrix); |
||||
|
||||
Size size = getSize(); |
||||
if (size != null) { |
||||
GLES20.glUniform3fv(iResolutionLocation, 1, |
||||
FloatBuffer.wrap(new float[]{(float) size.getWidth(), (float) size.getHeight(), 1.0f})); |
||||
Egloo.checkGlError("glUniform3fv"); |
||||
} |
||||
|
||||
float time = (((float) (System.currentTimeMillis() - START_TIME)) / 1000.0f) + 1; |
||||
GLES20.glUniform1f(iGlobalTimeLocation, time); |
||||
Egloo.checkGlError("glUniform1f"); |
||||
} |
||||
} |
@ -0,0 +1,88 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import android.opengl.GLES20; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
import com.otaliastudios.cameraview.size.Size; |
||||
import com.otaliastudios.opengl.core.Egloo; |
||||
|
||||
import java.nio.FloatBuffer; |
||||
|
||||
public class RainbowFilter extends BaseFilter { |
||||
private static final String FRAGMENT_SHADER = |
||||
"#extension GL_OES_EGL_image_external : require\n" + |
||||
"precision highp float;\n" + |
||||
"\n" + |
||||
"uniform vec3 iResolution;\n" + |
||||
"uniform samplerExternalOES iChannel0;\n" + |
||||
"uniform float iTime;\n" + |
||||
"varying vec2 " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + ";\n" + |
||||
"\n" + |
||||
"vec2 size = vec2(50.0, 50.0);\n" + |
||||
"vec2 distortion = vec2(20.0, 20.0);\n" + |
||||
"float speed = 0.75;" + |
||||
"\n" + |
||||
"void mainImage( out vec4 fragColor, in vec2 fragCoord )\n" + |
||||
"{\n" + |
||||
" vec2 transformed = vec2(\n" + |
||||
" fragCoord.x + sin(fragCoord.y / size.x + iTime * speed) * distortion.x,\n" + |
||||
" fragCoord.y + cos(fragCoord.x / size.y + iTime * speed) * distortion.y\n" + |
||||
" );\n" + |
||||
" vec2 relCoord = fragCoord.xy / iResolution.xy;\n" + |
||||
" fragColor = texture2D(iChannel0, fragCoord/iResolution.xy) + vec4(\n" + |
||||
" (cos(relCoord.x + iTime * speed * 4.0) + 1.0) / 2.0,\n" + |
||||
" (relCoord.x + relCoord.y) / 2.0,\n" + |
||||
" (sin(relCoord.y + iTime * speed) + 1.0) / 2.0,\n" + |
||||
" 0\n" + |
||||
" );\n" + |
||||
"}\n" + |
||||
"void main() {\n" + |
||||
" mainImage(gl_FragColor, " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + ");\n" + |
||||
"}"; |
||||
|
||||
|
||||
long START_TIME = System.currentTimeMillis(); |
||||
private int iGlobalTimeLocation = -1; |
||||
private int iResolutionLocation = -1; |
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return FRAGMENT_SHADER; |
||||
} |
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
iGlobalTimeLocation = -1; |
||||
START_TIME = System.currentTimeMillis(); |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(int programHandle) { |
||||
super.onCreate(programHandle); |
||||
iResolutionLocation = GLES20.glGetUniformLocation(programHandle, "iResolution"); |
||||
Egloo.checkGlProgramLocation(iResolutionLocation, "iResolution"); |
||||
|
||||
iGlobalTimeLocation = GLES20.glGetUniformLocation(programHandle, "iTime"); |
||||
Egloo.checkGlProgramLocation(iGlobalTimeLocation, "iTime"); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPreDraw(long timestampUs, @NonNull float[] transformMatrix) { |
||||
super.onPreDraw(timestampUs, transformMatrix); |
||||
|
||||
Size size = getSize(); |
||||
if (size != null) { |
||||
GLES20.glUniform3fv(iResolutionLocation, 1, |
||||
FloatBuffer.wrap(new float[]{(float) size.getWidth(), (float) size.getHeight(), 1.0f})); |
||||
Egloo.checkGlError("glUniform3fv"); |
||||
} |
||||
|
||||
float time = ((float) (System.currentTimeMillis() - START_TIME)) / 1000.0f; |
||||
GLES20.glUniform1f(iGlobalTimeLocation, time); |
||||
Egloo.checkGlError("glUniform1f"); |
||||
} |
||||
} |
@ -0,0 +1,46 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import android.content.Context; |
||||
import android.content.res.Resources; |
||||
import android.graphics.Bitmap; |
||||
import android.graphics.BitmapFactory; |
||||
import android.opengl.GLES20; |
||||
import android.opengl.GLUtils; |
||||
|
||||
public class TextureHelper { |
||||
public static int loadTexture(final Context context, final int resourceId) |
||||
{ |
||||
final int[] textureHandle = new int[1]; |
||||
|
||||
GLES20.glGenTextures(1, textureHandle, 0); |
||||
|
||||
if (textureHandle[0] != 0) |
||||
{ |
||||
final BitmapFactory.Options options = new BitmapFactory.Options(); |
||||
options.inScaled = false; // No pre-scaling
|
||||
|
||||
// Read in the resource
|
||||
final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId, options); |
||||
|
||||
// Bind to the texture in OpenGL
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]); |
||||
|
||||
// Set filtering
|
||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); |
||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST); |
||||
|
||||
// Load the bitmap into the bound texture.
|
||||
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); |
||||
|
||||
// Recycle the bitmap, since its data has been loaded into OpenGL.
|
||||
bitmap.recycle(); |
||||
} |
||||
|
||||
if (textureHandle[0] == 0) |
||||
{ |
||||
throw new RuntimeException("Error loading texture."); |
||||
} |
||||
|
||||
return textureHandle[0]; |
||||
} |
||||
} |
@ -0,0 +1,90 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import android.opengl.GLES20; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
import com.otaliastudios.cameraview.size.Size; |
||||
import com.otaliastudios.opengl.core.Egloo; |
||||
|
||||
import java.nio.FloatBuffer; |
||||
|
||||
public class ToasterFilter extends BaseFilter { |
||||
private static final String FRAGMENT_SHADER = |
||||
"#extension GL_OES_EGL_image_external : require\n" + |
||||
"precision mediump float; \n" + |
||||
"uniform samplerExternalOES u_Texture0; \n" + |
||||
// "uniform sampler2D u_Texture4;\n" +
|
||||
"varying vec2 " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + "; \n" + |
||||
"const vec3 W = vec3(0.2125, 0.7154, 0.0721);\n" + |
||||
"\n" + |
||||
"vec3 BrightnessContrastSaturation(vec3 color, float brt, float con, float sat)\n" + |
||||
"{\n" + |
||||
"\tvec3 black = vec3(0., 0., 0.);\n" + |
||||
"\tvec3 middle = vec3(0.5, 0.5, 0.5);\n" + |
||||
"\tfloat luminance = dot(color, W);\n" + |
||||
"\tvec3 gray = vec3(luminance, luminance, luminance);\n" + |
||||
"\t\n" + |
||||
"\tvec3 brtColor = mix(black, color, brt);\n" + |
||||
"\tvec3 conColor = mix(middle, brtColor, con);\n" + |
||||
"\tvec3 satColor = mix(gray, conColor, sat);\n" + |
||||
"\treturn satColor;\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"vec3 ovelayBlender(vec3 Color, vec3 filter){\n" + |
||||
"\tvec3 filter_result;\n" + |
||||
"\t\n" + |
||||
"\t//if(luminance < 0.5)\n" + |
||||
"\t//\tfilter_result = 2. * trans_filter * Color;\n" + |
||||
"\t//else\n" + |
||||
"\t\tfilter_result = 1. - (1. - (2. *(filter - 0.5)))*(1. - Color);\n" + |
||||
"\t\t\n" + |
||||
"\treturn filter_result;\n" + |
||||
"}\n" + |
||||
"\n" + |
||||
"void main()\n" + |
||||
"{\n" + |
||||
"\t //get the pixel\n" + |
||||
" vec2 st = " + DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME + ".st;\n" + |
||||
" vec3 irgb = texture2D(u_Texture0, st).rgb;\n" + |
||||
// " vec3 filter = texture2D(u_Texture4, st).rgb;\n" +
|
||||
" \n" + |
||||
" //adjust the brightness/contrast/saturation\n" + |
||||
" float T_bright = 1.0;\n" + |
||||
" float T_contrast = 1.0;\n" + |
||||
" float T_saturation = 1.0;\n" + |
||||
" vec3 bcs_result = BrightnessContrastSaturation(irgb, T_bright, T_contrast, T_saturation);\n" + |
||||
" \n" + |
||||
" //more red\n" + |
||||
" vec3 rb_result = vec3(bcs_result.r*1.3, bcs_result.g, bcs_result.b*0.9);\n" + |
||||
" \n" + |
||||
// " //add filter (overlay blending)\n" +
|
||||
// " vec3 after_filter = mix(bcs_result, ovelayBlender(bcs_result, filter), 0.55);\n" +
|
||||
" \t\n" + |
||||
" gl_FragColor = vec4(rb_result, 1.);\n" + |
||||
"}"; |
||||
|
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return FRAGMENT_SHADER; |
||||
} |
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(int programHandle) { |
||||
super.onCreate(programHandle); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPreDraw(long timestampUs, @NonNull float[] transformMatrix) { |
||||
super.onPreDraw(timestampUs, transformMatrix); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,38 @@ |
||||
package com.otaliastudios.cameraview.filters; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import com.otaliastudios.cameraview.filter.BaseFilter; |
||||
|
||||
public class WavesReflectionFilter extends BaseFilter { |
||||
private static final String FRAGMENT_SHADER = |
||||
"#extension GL_OES_EGL_image_external : require\n" + |
||||
"precision highp float;\n" + |
||||
"\n" + |
||||
"uniform vec3 iResolution;\n" + |
||||
"uniform samplerExternalOES iChannel0;\n" + |
||||
"varying vec2 "+DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME+";\n" + |
||||
"\n" + |
||||
"float waterLevel = 0.5;\n" + |
||||
"float waveAmplitude = 0.01;\n" + |
||||
"\n" + |
||||
"void mainImage( out vec4 fragColor, in vec2 fragCoord )\n" + |
||||
" {\n" + |
||||
" if(fragCoord.y >= waterLevel){\n" + |
||||
" fragColor = texture2D(iChannel0, fragCoord);\n" + |
||||
" }else{\n" + |
||||
" fragColor = texture2D(iChannel0,vec2(fragCoord.x + fract(sin(dot(fragCoord.xy ,vec2(12.9898,78.233))) * 43758.5453) * waveAmplitude,\n" + |
||||
" \t\t\t\t2.0 * waterLevel - fragCoord.y));\n" + |
||||
" }\n" + |
||||
" }\n" + |
||||
"\n" + |
||||
"void main() {\n" + |
||||
" \tmainImage(gl_FragColor, "+DEFAULT_FRAGMENT_TEXTURE_COORDINATE_NAME+");\n" + |
||||
" }"; |
||||
|
||||
@NonNull |
||||
@Override |
||||
public String getFragmentShader() { |
||||
return FRAGMENT_SHADER; |
||||
} |
||||
} |
After Width: | Height: | Size: 519 KiB |
Loading…
Reference in new issue