xxxxxxxxxx
294
let canvas;
let pg;
let colors1 = ['#2C7865', '#90D26D'];
let colors2 = ['#DD5746', '#4793AF'];
let theShader1;
function setup(){
const p_init = () => {
canvas = createCanvas(700,700, WEBGL);
imageMode(CENTER);
textureMode(NORMAL);
frameRate(24);
noStroke();
};
p_init();
pg = createGraphics(width, height);
image_init(pg);
theShader1 = createShader(shader1.vs, shader1.fs);
}
function draw(){
background(220);
push();
translate(-width/2,-height/2);
pg.push();
const rand = random(1);
if (rand < 0.5) {
grid(parseInt(random(3, 10)), pg, colors1);
} else {
grid(parseInt(random(3, 10)), pg, colors2);
}
pg.pop();
shader(theShader1);
theShader1.setUniform(`u_tex`, pg);
theShader1.setUniform('u_resolution', [pg.width, pg.height]);
theShader1.setUniform(`u_time`, -frameCount / 35);
// image(pg, 0, 0);
rect(0,0,width,height);
pop();
noLoop();
}
function keyPressed(){
if (key === 's') {
saveCanvas(canvas, 'p5js_rect-wave2', 'png');
//p.saveGif('p5js_rect-wave2', 4);
}
}
/** pgの初期化関数
* @function image_init
* @param {p5.Graphics} pg - p5.Graphics
*/
const image_init = (pg) => {
pg.rectMode(CENTER);
//pg.background(220);
pg.fill(255);
pg.noStroke();
};
/** num個で分割したグリッドを画面いっぱいに生成する
* @method grid
* @param {Number} num - 画面の分割数
* @param {p5.Graphics} pg - p5.Graphics
* @param {Array} colors - 色の配列
*/
const grid = (num, pg, colors) => {
const w = width / num;
const wHarf = w / 2;
for (let i = 0; i < num * 2; i++) {
for (let j = 0; j < num * 2; j++) {
pg.push();
if ((i % 2 === 0 && j % 2 === 0) || (i % 2 === 1 && j % 2 === 1)) {
pg.fill(colors[0]);
hisi(pg, w, i * w + wHarf, j * w + wHarf);
} else {
pg.fill(colors[1]);
hisi(pg, w, i * w + wHarf, j * w + wHarf);
}
pg.pop();
}
}
};
/** ひし形
* @method grid
* @param {Number} r - 半径
* @param {Number} w - 中点のx座標
* @param {Number} h - 中点のy座標
*/
const hisi = (pg, r, w, h) => {
const n = 4;
const angle = 360 / n;
pg.beginShape();
for (let i = 0; i < n; i++) {
pg.push();
const x = r * Math.cos(radians(45 + angle * i));
const y = r * Math.sin(radians(45 + angle * i));
const afin = afin_shear(x + w, y + h, w, h, 0.2, 0.2);
pg.vertex(afin[0], afin[1]);
pg.pop();
}
pg.endShape(CLOSE);
};
//行列計算
function afin(a, b) {
let x;
let y;
for (let k = 0; k < 3; k++) {
let a0 = a[k][0] * b[0];
let a1 = a[k][1] * b[1];
let a2 = a[k][2] * b[2];
if (k == 0) {
x = a0 + a1 + a2;
} else if (k == 1) {
y = a0 + a1 + a2;
}
}
return [x, y];
}
//平行移動
function afin_translate(x, y, tx, ty) {
let a = [
[1, 0, tx],
[0, 1, ty],
[0, 0, 1],
];
let b = [x, y, 1];
return afin(a, b);
}
//回転
function afin_rotate(shita, x, y, tx, ty) {
let a = [
[Math.cos(shita), -Math.sin(shita), tx - tx * Math.cos(shita) + ty * Math.sin(shita)],
[Math.sin(shita), Math.cos(shita), ty - tx * Math.sin(shita) - ty * Math.cos(shita)],
[0, 0, 1],
];
let b = [x, y, 1];
return afin(a, b);
}
//拡大縮小
function afin_scale(x, y, tx, ty, sx, sy) {
let a = [
[sx, 0, tx - tx * sx],
[0, sy, ty - ty * sy],
[0, 0, 1],
];
let b = [x, y, 1];
return afin(a, b);
}
//せん断
// 参考:https://imagingsolution.net/imaging/affine-transformation/
function afin_shear(x, y, tx, ty, shx, shy) {
let a = [
[1, shx, -shx * ty],
[shy, 1, -shy * tx],
[0, 0, 1],
];
let b = [x, y, 1];
return afin(a, b);
}
const shader1 = {
vs: `
precision highp float;
precision highp int;
attribute vec3 aPosition;
attribute vec2 aTexCoord;
varying vec2 vTexCoord;
uniform mat4 uProjectionMatrix;
uniform mat4 uModelViewMatrix;
void main() {
vec4 positionVec4 = vec4(aPosition, 1.0);
gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;
vTexCoord = aTexCoord;
}
`,
fs: `
precision highp float;
precision highp int;
varying vec2 vTexCoord;
uniform sampler2D u_tex;
uniform float u_time;
uniform vec2 u_resolution;
float pi=3.14159265358979;
// ボロノイ図をUVの値につかう
float rand(vec2 x){
return fract(cos(mod(dot(x,vec2(13.9898,8.141)),3.14))*43758.5453);
}
vec2 rand2(vec2 x){
return fract(cos(mod(vec2(dot(x,vec2(13.9898,8.141)),
dot(x,vec2(3.4562,17.398))),vec2(3.14)))*43758.5453);
}
// Based on https://www.shadertoy.com/view/ldl3W8
// The MIT License
// Copyright © 2013 Inigo Quilez
vec3 iq_voronoi(vec2 x,vec2 size,vec2 stretch,float randomness,vec2 seed){
vec2 n=floor(x);
vec2 f=fract(x);
vec2 mg,mr,mc;
float md=8.;
for(int j=-1;j<=1;j++)
for(int i=-1;i<=1;i++){
vec2 g=vec2(float(i),float(j));
vec2 o=randomness*rand2(seed+mod(n+g+size,size));
vec2 c=g+o;
vec2 r=c-f;
vec2 rr=r*stretch;
float d=dot(rr,rr);
if(d<md){
mc=c;
md=d;
mr=r;
mg=g;
}
}
md=8.;
for(int j=-2;j<=2;j++)
for(int i=-2;i<=2;i++){
vec2 g=mg+vec2(float(i),float(j));
vec2 o=randomness*rand2(seed+mod(n+g+size,size));
vec2 r=g+o-f;
vec2 rr=(mr-r)*stretch;
if(dot(rr,rr)>.00001)
md=min(md,dot(.5*(mr+r)*stretch,normalize((r-mr)*stretch)));
}
return vec3(md,mc+n);
}
vec4 voronoi(vec2 uv,vec2 size,vec2 stretch,float intensity,float randomness,float seed){
uv*=size;
vec3 v=iq_voronoi(uv,size,stretch,randomness,rand2(vec2(seed,1.-seed)));
return vec4(v.yz,intensity*length((uv-v.yz)*stretch),v.x);
}
const float scale_x=10.;
const float scale_y=10.;
const float stretch_x=1.62;
const float stretch_y=1.;
const float intensity=1.;
const float randomness=.85;
float random(vec2 c){
return fract(sin(dot(c.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
void main(){
vec2 uv=vTexCoord;
float minSize=min(u_resolution.x,u_resolution.y);
vec4 voronoiColor=voronoi((uv),vec2(scale_x,scale_y),vec2(stretch_y,stretch_x),intensity,randomness,0.);
float celler=voronoiColor.z;
// fractでリピートできる
vec4 tex=texture2D(u_tex,fract((uv+(celler*0.08))));
// white noise用
float interval = 3.0;
float strength = smoothstep(interval * 0.5, interval, interval - mod(u_time, interval));
float whiteNoise = (random(uv + mod(u_time, 10.0)) * 2.0 - 1.0) * (0.15 + strength * 0.15);
//vec4 tex = texture2D(u_tex, uv);
gl_FragColor = tex + whiteNoise;
//gl_FragColor = vec4(0.58, 0.64, 0.95, 1.00);
}
`,
};