xxxxxxxxxx
202
const colorBox = ["#01204E","#028391","#F6DCAC","#FEAE6F"];
let pg;
function setup() {
createCanvas(800, 800, WEBGL);
//strokeWeight(0.3);
noStroke();
pg = createGraphics(width, height);
}
function draw() {
background(220);
translate(-width/2, -height/2);
let count = 0;
for(let i=0;i<height+100;i+=50){
pg.push();
pg.translate(0,i);
pg.fill(random(colorBox));
sinWave(pg);
pg.pop();
count++;
}
// シェーダーの設定
const theShader1 = createShader(shader1.vs, shader1.fs);
shader(theShader1);
theShader1.setUniform(`u_tex`, pg);
theShader1.setUniform(`u_time`, frameCount / 50);
theShader1.setUniform('u_resolution', [pg.width, pg.height]);
image(pg,0,0);
noLoop();
}
keyPressed = () => {
if (key === 's') {
saveCanvas(canvas, 'image', 'png');
//saveGif('canvas', 4);
}
};
function sinWave(pg) {
const r = 50;
for(let i = -10;i<pg.width;i+=10){
const x = i;
const y = r*sin(radians(i));
const tx = i+10;
const ty = r*sin(radians(i+10));
//point(x,y);
pg.push();
heartDraw(x,y,tx,ty,pg);
pg.pop();
}
}
// 実装参考:
// https://editor.p5js.org/makio135/sketches/AUy_cG-d4
// https://qiita.com/QUANON/items/672588719b178291f351
// http://blog.livedoor.jp/reona396/archives/54891368.html
const heartDraw = (sx,sy,tx,ty,pg) => {
const R = 7;
let n = 700;
let startX = sx;
let startY = sy;
// ベクトルの終点
let endX = tx;
let endY = ty;
// ベクトルの成分を求める
let dx = endX - startX;
let dy = endY - startY;
// ベクトルの角度を求める
let angle = atan2(dy, dx);
pg.push();
pg.translate(tx, ty);
pg.rotate(-PI/2);
pg.rotate(angle);
pg.beginShape();
for (let i = 0; i < n; i++) {
let x = xHeart(TAU * i / n,R);
let y = yHeart(TAU * i / n,R);
pg.vertex(x, y);
}
pg.endShape(CLOSE);
pg.pop();
}
const xHeart = (angle, radius) => {
const x = radius / 15.0 * 16 * Math.pow(Math.sin(angle), 3);
return x;
}
const yHeart = (p, radius) => {
const y = radius / 15.0 * (-13 * Math.cos(p) + 5 * Math.cos(2 * p) + 2 * Math.cos(3 * p) + Math.cos(4 * p));
return y;
}
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;
float map(float value, float min1, float max1, float min2, float max2) {
return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
}
float random2(float x) {
return fract(sin(x)*1e4);
}
// Based on Morgan McGuire @morgan3d
// https://www.shadertoy.com/view/4dS3Wd
// https://thebookofshaders.com/edit.php#11/3d-noise.frag
float noise (vec3 p) {
const vec3 step = vec3(110.0, 241.0, 171.0);
vec3 i = floor(p);
vec3 f = fract(p);
// For performance, compute the base input to a
// 1D random from the integer part of the
// argument and the incremental change to the
// 1D based on the 3D -> 1D wrapping
float n = dot(i, step);
vec3 u = f * f * (3.0 - 2.0 * f);
return mix( mix(mix(random2(n + dot(step, vec3(0,0,0))),
random2(n + dot(step, vec3(1,0,0))),
u.x),
mix(random2(n + dot(step, vec3(0,1,0))),
random2(n + dot(step, vec3(1,1,0))),
u.x),
u.y),
mix(mix(random2(n + dot(step, vec3(0,0,1))),
random2(n + dot(step, vec3(1,0,1))),
u.x),
mix(random2(n + dot(step, vec3(0,1,1))),
random2(n + dot(step, vec3(1,1,1))),
u.x),
u.y),
u.z);
}
float rand(vec2 co){
float a=fract(dot(co,vec2(2.067390879775102,12.451168662908249)))-.5;
float s=a*(6.182785114200511+a*a*(-38.026512460676566+a*a*53.392573080032137));
float t=fract(s*43758.5453);
return t;
}
void main(){
vec2 uv=vTexCoord;
vec3 pos = vec3(uv*1.0, u_time*0.5); // uv*1.0で拡大・縮になる(1.0で等倍)
float noises = noise(pos);
float noises_jagi = noise(vec3(uv*100.0, 10.0)); // ジャギらせ用ノイズ UVとは別で用意した
// ノイズの濃いところをジャギらせる
float radius = map(noises_jagi, 0.0, 1.0, 0.001, 0.01);
uv.x = uv.x + rand(uv)*radius;
uv.y = uv.y + rand(uv)*radius;
// fractでリピートできる
// uv*0.5 = 0.5倍することで拡大される
// noises*x = xでノイズの影響を強める
vec4 tex=texture2D(u_tex,fract((uv*1.0 + (noises*0.7))));
gl_FragColor = tex + random2(uv.y+u_time)*0.3;
}
`,
};