xxxxxxxxxx
218
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 + .5,1.) ;
//texture
//vec4 smpColor0 = texture2D(u_tex, var_vertTexCoord);
float noise1 = noise((st-centerPos)*500.);
float noise2 = noise((st-centerPos)*1000.);
float tone = step(noise1,dot);
vec3 col = u_col * tone + (u_col-0.2) * (1.-tone);
col += noise2*.25;
gl_FragColor = vec4(col.rgb,1.);
}
`;
const CYCLE = 120;
function setup() {
createCanvas(windowWidth, windowHeight,WEBGL);
//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", [0.4,0.8,-0.8]);
noStroke();
}
function draw() {
background(40);
orbitControl();
rotateX(-PI/5);
const radius = min(width,height)*(0.2+0.03*ease());
setCol("#943A9B");
ball(radius,30,30);
setCol("#FF8888");
push();
const radius2 = min(width,height)*0.05;
const y2 = map(ease2(),0,1,-min(width,height)*0.7,-radius2*1.5);
translate(0,y2,0);
sphere(radius2);
pop();
}
function ball(radius, detailX, detailY,id = 0)
{
const gId = `ball|${radius}|${id}`;
//update geom every frame
//if (!this._renderer.geometryInHash(gId)) {}
const ball = function(){
for(let yi = 0; yi <= detailY; yi ++)
{
const yRadian = map(yi,0,detailY,PI/2,-PI/2);
const y = sin(yRadian)*radius;
const radiusXZ = cos(yRadian)*radius;
let offsetRatio = map(yi,0,detailY,-1,1);
offsetRatio = pow(offsetRatio,4)*(offsetRatio/abs(offsetRatio));
const yOffset = offsetRatio*radius*ease();
for(let xi = 0; xi <= detailX; xi++)
{
const r = xi* TWO_PI/detailX;
const x = cos(r)*radiusXZ;
const z = sin(r)*radiusXZ;
this.vertices[xi + (detailX+1)*yi] = new p5.Vector(x,y+yOffset,z);
this.uvs[xi + (detailX+1)*yi] = [0,0];//※uvがないと表示されない
}
}
};
const geometry = new p5.Geometry(detailX,detailY,ball);
geometry.computeFaces().computeNormals().averageNormals();
geometry._makeTriangleEdges()._edgesToVertices();//make stroke vert
this._renderer.createBuffers(gId, geometry);
this._renderer.drawBuffers(gId);
//this._renderer.drawBuffersScaled(gId,1,1,1);
return this;
}
function ease() {
const currentRatio = (frameCount % CYCLE)/CYCLE;
const cycleRatio = currentRatio < 0.5 ? currentRatio*2 : (1-(currentRatio))*2;
const currentCicleQuartEaseOutRatio = -pow(cycleRatio - 1, 2) + 1;
return currentCicleQuartEaseOutRatio;
}
function ease2 () {
const currentRatio = (frameCount % CYCLE)/CYCLE;
return pow(currentRatio-1,7) + 1;
}
//_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);
}