-
Notifications
You must be signed in to change notification settings - Fork 89
/
GrainEffect.java
108 lines (96 loc) · 4.34 KB
/
GrainEffect.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package com.sherazkhilji.videffects;
import android.opengl.GLSurfaceView;
import com.sherazkhilji.videffects.interfaces.ShaderInterface;
import java.util.Date;
import java.util.Random;
/**
* Applies film grain effect to video.
*
* @author sheraz.khilji
*/
public class GrainEffect implements ShaderInterface {
private int mWidth;
private int mHeight;
private float strength;
private Random mRandom;
/**
* Initialize Effect
*
* @param strength Float, between 0 and 1. Zero means no distortion, while 1
* indicates the maximum amount of adjustment.
*/
public GrainEffect(float strength) {
if (strength < 0.0f)
strength = 0.0f;
if (strength > 1.0f)
strength = 1.0f;
this.strength = strength;
}
public void setStrength(float strength) {
this.strength = strength;
}
/**
* Init all values that will be used by this shader.
*
* @param mGlSurfaceView which is responsible for displaying your video
*/
private void initValues(GLSurfaceView mGlSurfaceView) {
mWidth = mGlSurfaceView.getWidth();
mHeight = mGlSurfaceView.getHeight();
mRandom = new Random(new Date().getTime());
}
@Override
public String getShader(GLSurfaceView mGlSurfaceView) {
initValues(mGlSurfaceView);
float[] seed = {mRandom.nextFloat(), mRandom.nextFloat()};
String scaleString = "scale = " + strength + ";\n";
String[] seedString = new String[2];
seedString[0] = "seed[0] = " + seed[0] + ";\n";
seedString[1] = "seed[1] = " + seed[1] + ";\n";
String stepX = "stepX = " + 0.5f / mWidth + ";\n";
String stepY = "stepY = " + 0.5f / mHeight + ";\n";
// locString[1] = "loc[1] = loc[1]+" + seedString[1] + ";\n";
return "#extension GL_OES_EGL_image_external : require\n"
+ "precision mediump float;\n"
+ " vec2 seed;\n"
+ "varying vec2 vTextureCoord;\n"
+ "uniform samplerExternalOES tex_sampler_0;\n"
+ "uniform samplerExternalOES tex_sampler_1;\n"
+ "float scale;\n"
+ " float stepX;\n"
+ " float stepY;\n"
+ "float rand(vec2 loc) {\n"
+ " float theta1 = dot(loc, vec2(0.9898, 0.233));\n"
+ " float theta2 = dot(loc, vec2(12.0, 78.0));\n"
+ " float value = cos(theta1) * sin(theta2) + sin(theta1) * cos(theta2);\n"
+
// keep value of part1 in range: (2^-14 to 2^14).
" float temp = mod(197.0 * value, 1.0) + value;\n"
+ " float part1 = mod(220.0 * temp, 1.0) + temp;\n"
+ " float part2 = value * 0.5453;\n"
+ " float part3 = cos(theta1 + theta2) * 0.43758;\n"
+ " float sum = (part1 + part2 + part3);\n"
+ " return fract(sum)*scale;\n"
+ "}\n"
+ "void main() {\n"
// Parameters that were created above
+ seedString[0]
+ seedString[1]
+ scaleString
+ stepX
+ stepY
+ " float noise = texture2D(tex_sampler_1, vTextureCoord + vec2(-stepX, -stepY)).r * 0.224;\n"
+ " noise += texture2D(tex_sampler_1, vTextureCoord + vec2(-stepX, stepY)).r * 0.224;\n"
+ " noise += texture2D(tex_sampler_1, vTextureCoord + vec2(stepX, -stepY)).r * 0.224;\n"
+ " noise += texture2D(tex_sampler_1, vTextureCoord + vec2(stepX, stepY)).r * 0.224;\n"
+ " noise += 0.4448;\n"
+ " noise *= scale;\n"
+ " vec4 color = texture2D(tex_sampler_0, vTextureCoord);\n"
+ " float energy = 0.33333 * color.r + 0.33333 * color.g + 0.33333 * color.b;\n"
+ " float mask = (1.0 - sqrt(energy));\n"
+ " float weight = 1.0 - 1.333 * mask * noise;\n"
+ " gl_FragColor = vec4(color.rgb * weight, color.a);\n"
+ " gl_FragColor = gl_FragColor+vec4(rand(vTextureCoord + seed), rand(vTextureCoord + seed),rand(vTextureCoord + seed),1);\n"
+ "}\n";
}
}