xxxxxxxxxx
258
var vert = `
precision highp float;
// attributes, in
attribute vec3 aPosition;
attribute vec3 aNormal;
attribute vec2 aTexCoord;
// attributes, out
varying vec3 var_vertPos;
varying vec3 var_vertNormal;
varying vec2 var_vertTexCoord;
varying vec4 var_centerGlPosition;//原点
// matrices
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
uniform mat3 uNormalMatrix;
uniform float u_time;
void main() {
vec3 pos = aPosition;
vec4 posOut = uProjectionMatrix * uModelViewMatrix * vec4(pos, 1.0);
gl_Position = posOut;
// set out value
var_vertPos = pos;
var_vertNormal = aNormal;
var_vertTexCoord = aTexCoord;
var_centerGlPosition = uProjectionMatrix * uModelViewMatrix * vec4(0., 0., 0.,1.0);
}
`;
var frag = `
precision highp float;
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
uniform vec3 u_lightDir;
uniform vec3 u_col;
uniform mat3 uNormalMatrix;
uniform float u_pixelDensity;
uniform sampler2D u_tex;
//attributes, in
varying vec4 var_centerGlPosition;
varying vec3 var_vertNormal;
varying vec2 var_vertTexCoord;
float random (in vec2 st) {
highp float a = 12.9898;
highp float b = 78.233;
highp float c = 43758.5453;
highp float dt= dot(st.xy ,vec2(a,b));
highp float sn= mod(dt,3.14);
return fract(sin(sn) * c);
}
float noise(vec2 st) {
vec2 i = vec2(0.);
i = floor(st);
vec2 f = vec2(0.);
f = fract(st);
vec2 u = vec2(0.);
u = f*f*(3.0-2.0*f);
return mix( mix( random( i + vec2(0.0,0.0) ),
random( i + vec2(1.0,0.0) ), u.x),
mix( random( i + vec2(0.0,1.0) ),
random( i + vec2(1.0,1.0) ), u.x), u.y);
}
float grid(vec2 uv){
uv *= 10.;
uv = fract(uv);
float v = uv.x >= 0. && uv.x < 0.1 || uv.y >= 0. && uv.y < 0.1 ? 1. : 0.;
return v;
}
float gridGra(in vec2 uv , float gridNum){
float scale = gridNum;
uv *= scale;
uv = fract(uv);
float o = abs(uv.y + -0.5)*2.;
o *= abs(uv.x + -0.5)*2.;
return o;
}
void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
st.x *= u_resolution.x/u_resolution.y;
vec2 centerPos = var_centerGlPosition.xy/var_centerGlPosition.w;//スクリーン変換
centerPos = (centerPos + 1.0)*.5*u_pixelDensity;//gl_FragCoordと座標を合わせる pixelDensityによって係数が変化する
centerPos.x *= u_resolution.x/u_resolution.y;//gl_FragCoordと座標を合わせる
vec3 vertNormal = normalize(uNormalMatrix * var_vertNormal);
float dot = dot(vertNormal,-normalize(u_lightDir));
dot = pow(dot *.5 + .7,1.) ;
float noise1 = noise((st-centerPos)*600.);
float noise2 = noise((st-centerPos)*1000.);
float tone = step(noise1,dot);
vec3 col = u_col * tone + (u_col-0.1) * (1.-tone);
col *= clamp(dot + 0.2,0.,1.);
//col += noise2*.1;
gl_FragColor = vec4(col.rgb,1.);
}
`;
const STACKCYCLE = 40;
let size;
const COL = createCols("https://coolors.co/01023b-eedd00-9e0059-ff0054-ff5400");
/* more cool color palettes:
1. https://coolors.co/d6ffde-ffadd3-ff5797-ff00ff-000000
2. https://coolors.co/ca61c3-ee85b5-ff958c-1b998b-eac435
3. https://coolors.co/01023b-eedd00-9e0059-ff0054-ff5400
4. https://coolors.co/bae1ff-baffc9-ffffba-ffdfba-ffb3ba
*/
let sh;
function setup() {
createCanvas(windowWidth, windowHeight,WEBGL);
let legoHeight = height/10;
size = lego(4,2,legoHeight);
//ortho
let dep = max(width,height);
ortho(-width / 2, width / 2, -height / 2, height / 2,-dep*3 , dep*3);
//shader
sh = createShader(vert,frag);
this.shader(sh);
sh.setUniform("u_resolution", [width,height]);
sh.setUniform("u_pixelDensity", pixelDensity());
sh.setUniform("u_lightDir", [1,1,-1]);
noStroke();
}
function draw() {
background(230);
const loopCycle = STACKCYCLE * COL.length;
const loopCountRatio = (frameCount%loopCycle)/loopCycle;
const stackCount = Math.floor(frameCount/STACKCYCLE);
const stackCountRatio = (frameCount%STACKCYCLE)/STACKCYCLE;
let blockId = 1000+stackCount*2;
rotateX(-PI/8);
rotateY(PI/5);
//rotateY(loopCountRatio*TAU);
push();
rotateY(stackCountRatio-1);
if((blockId/2)%2 == 0)rotateY(PI/2);
push();
translate(0,map(stackCountRatio,0,1,-height*0.5,0),0);
translate(0,0,size.baseD/2);
setCol(COL[blockId%COL.length]);
lego(4,2,size.baseH);
pop();
push();
translate(0,map(stackCountRatio,0,1,-height*0.8,0),0);
translate(0,0,-size.baseD/2);
setCol(COL[(blockId-1)%COL.length]);
lego(4,2,size.baseH);
pop();
pop();
blockId-=2;
const offsetY = size.baseH*stackCountRatio;
for(let y = 0; y <= height; y +=size.baseH)
{
push();
translate(0,y+offsetY,0);
if((blockId/2)%2 == 0)rotateY(PI/2);
push();
translate(0,0,size.baseD/2);
setCol(COL[blockId%COL.length]);
lego(4,2,size.baseH);
pop();
push();
translate(0,0,-size.baseD/2);
setCol(COL[(blockId-1)%COL.length]);
lego(4,2,size.baseH);
pop();
pop();
blockId-=2;
}
}
///////////////
function lego(xNum,zNum,hei = 9.6)
{
const sizeMult = hei/9.6;
const baseW = xNum*8*sizeMult;
const baseD = zNum * 8*sizeMult;
const baseH = 9.6*sizeMult;
const pinSpan = 8*sizeMult;
const pinH = 1.7*sizeMult;
const pinRadius = 2.5*sizeMult;
box(baseW,baseH,baseD);
for(let xi=0; xi <xNum; xi++)
{
for(let zi=0; zi <zNum; zi++)
{
const pinX = (xi+0.5)*pinSpan-baseW/2;
const pinZ = (zi+0.5)*pinSpan-baseD/2;
const pinY = -baseH/2 - pinH/2;
push();
translate(pinX,pinY,pinZ);
cylinder(pinRadius,pinH);
pop();
}
}
return {baseW:baseW,baseH:baseH,baseD:baseD,pinSpan:pinSpan,pinH:pinH,pinRadius:pinRadius};
}
/////////////////
function createCols(_url)
{
let slash_index = _url.lastIndexOf('/');
let pallate_str = _url.slice(slash_index + 1);
let arr = pallate_str.split('-');
for (let i = 0; i < arr.length; i++) {
arr[i] = '#' + arr[i];
}
return arr;
}
////////////////////
//_col color or number
function setCol(_col,_shader = sh,_uniformName = "u_col")
{
const col = typeof (_col) == "string" ? color(_col) : _col;
let colArray = col._array;
colArray.pop();
_shader.setUniform(_uniformName,colArray);
}