package com.af.experiments.FxCameraApp.shaders;
import com.af.experiments.FxCameraApp.renderer.GLES20FramebufferObject;
import static android.opengl.GLES20.*;
public class GlPerlinNoiseShader extends GlShader {
private static final String FRAGMENT_SHADER =
"precision highp float;" + // 演算精度を指定します。
"varying highp vec2 vTextureCoord;" +
"uniform float scale;" +
"uniform vec4 colorStart;" +
"uniform vec4 colorFinish;" +
// Description : Array and textureless GLSL 2D/3D/4D simplex noise functions.
// Author : Ian McEwan, Ashima Arts.
// Maintainer : ijm
// Lastmod : 20110822 (ijm)
// License : Copyright (C) 2011 Ashima Arts. All rights reserved.
// Distributed under the MIT License. See LICENSE file.
// https://github.com/ashima/webgl-noise
"vec4 mod289(vec4 x) {" +
"return x - floor(x * (1.0 / 289.0)) * 289.0;" +
"}" +
"vec4 permute(vec4 x) {" +
"return mod289(((x * 34.0) + 1.0) * x);" +
"}" +
"vec4 taylorInvSqrt(vec4 r) {" +
"return 1.79284291400159 - 0.85373472095314 * r;" +
"}" +
"vec2 fade(vec2 t) {" +
"return t*t*t*(t*(t*6.0-15.0)+10.0);" +
"}" +
// Classic Perlin noise
"float cnoise(vec2 P) {" +
"vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0);" +
"vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0);" +
"Pi = mod289(Pi);" + // To avoid truncation effects in permutation
"vec4 ix = Pi.xzxz;" +
"vec4 iy = Pi.yyww;" +
"vec4 fx = Pf.xzxz;" +
"vec4 fy = Pf.yyww;" +
"vec4 i = permute(permute(ix) + iy);" +
"vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0 ;" +
"vec4 gy = abs(gx) - 0.5;" +
"vec4 tx = floor(gx + 0.5);" +
"gx = gx - tx;" +
"vec2 g00 = vec2(gx.x,gy.x);" +
"vec2 g10 = vec2(gx.y,gy.y);" +
"vec2 g01 = vec2(gx.z,gy.z);" +
"vec2 g11 = vec2(gx.w,gy.w);" +
"vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)));" +
"g00 *= norm.x;" +
"g01 *= norm.y;" +
"g10 *= norm.z;" +
"g11 *= norm.w;" +
"float n00 = dot(g00, vec2(fx.x, fy.x));" +
"float n10 = dot(g10, vec2(fx.y, fy.y));" +
"float n01 = dot(g01, vec2(fx.z, fy.z));" +
"float n11 = dot(g11, vec2(fx.w, fy.w));" +
"vec2 fade_xy = fade(Pf.xy);" +
"vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x);" +
"float n_xy = mix(n_x.x, n_x.y, fade_xy.y);" +
"return 2.3 * n_xy;" +
"}" +
"void main() {" +
"float n1 = (cnoise(vTextureCoord * scale) + 1.0) / 2.0;" +
"vec4 colorDiff = colorFinish - colorStart;" +
"vec4 color = colorStart + colorDiff * n1;" +
"gl_FragColor = color;" +
"}";
private float mScale = 8.0f;
private float[] mColorStart = new float[]{ 0.0f, 0.0f, 0.0f, 1.0f };
private float[] mColorFinish = new float[]{ 1.0f, 1.0f, 1.0f, 1.0f };
public GlPerlinNoiseShader() {
super(DEFAULT_VERTEX_SHADER, FRAGMENT_SHADER);
}
@Override
public void draw(final int texName, final GLES20FramebufferObject fbo) {
useProgram();
glBindBuffer(GL_ARRAY_BUFFER, getVertexBufferName());
glEnableVertexAttribArray(getHandle(DEFAULT_ATTRIB_POSITION));
glVertexAttribPointer(getHandle(DEFAULT_ATTRIB_POSITION), VERTICES_DATA_POS_SIZE, GL_FLOAT, false, VERTICES_DATA_STRIDE_BYTES, VERTICES_DATA_POS_OFFSET);
glEnableVertexAttribArray(getHandle(DEFAULT_ATTRIB_TEXTURE_COORDINATE));
glVertexAttribPointer(getHandle(DEFAULT_ATTRIB_TEXTURE_COORDINATE), VERTICES_DATA_UV_SIZE, GL_FLOAT, false, VERTICES_DATA_STRIDE_BYTES, VERTICES_DATA_UV_OFFSET);
glUniform1f(getHandle("scale"), mScale);
glUniform4fv(getHandle("colorStart"), 0, mColorStart, 0);
glUniform4fv(getHandle("colorFinish"), 0, mColorFinish, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableVertexAttribArray(getHandle(DEFAULT_ATTRIB_POSITION));
glDisableVertexAttribArray(getHandle(DEFAULT_ATTRIB_TEXTURE_COORDINATE));
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}