干擾(noise)

干擾(noise)


更多有趣示例 盡在小紅磚社區

示例

在這裏插入圖片描述

HTML

  return x - floor(x * (1.0 / 289.0)) * 289.0;
}

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;
}

float snoise(vec3 v) {

  const vec2  C = vec2(1.0/6.0, 1.0/3.0) ;
  const vec4  D = vec4(0.0, 0.5, 1.0, 2.0);

  // First corner
  vec3 i  = floor(v + dot(v, C.yyy) );
  vec3 x0 =   v - i + dot(i, C.xxx) ;

  // Other corners
  vec3 g = step(x0.yzx, x0.xyz);
  vec3 l = 1.0 - g;
  vec3 i1 = min( g.xyz, l.zxy );
  vec3 i2 = max( g.xyz, l.zxy );

  //   x0 = x0 - 0.0 + 0.0 * C.xxx;
  //   x1 = x0 - i1  + 1.0 * C.xxx;
  //   x2 = x0 - i2  + 2.0 * C.xxx;
  //   x3 = x0 - 1.0 + 3.0 * C.xxx;
  vec3 x1 = x0 - i1 + C.xxx;
  vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
  vec3 x3 = x0 - D.yyy;      // -1.0+3.0*C.x = -0.5 = -D.y

  // Permutations
  i = mod289(i);
  vec4 p = permute( permute( permute(
      i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
    + i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
    + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));

  // Gradients: 7x7 points over a square, mapped onto an octahedron.
  // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
  float n_ = 0.142857142857; // 1.0/7.0
  vec3  ns = n_ * D.wyz - D.xzx;

  vec4 j = p - 49.0 * floor(p * ns.z * ns.z);  //  mod(p,7*7)

  vec4 x_ = floor(j * ns.z);
  vec4 y_ = floor(j - 7.0 * x_ );    // mod(j,N)

  vec4 x = x_ *ns.x + ns.yyyy;
  vec4 y = y_ *ns.x + ns.yyyy;
  vec4 h = 1.0 - abs(x) - abs(y);

  vec4 b0 = vec4( x.xy, y.xy );
  vec4 b1 = vec4( x.zw, y.zw );

  //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
  //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
  vec4 s0 = floor(b0)*2.0 + 1.0;
  vec4 s1 = floor(b1)*2.0 + 1.0;
  vec4 sh = -step(h, vec4(0.0));

  vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
  vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;

  vec3 p0 = vec3(a0.xy,h.x);
  vec3 p1 = vec3(a0.zw,h.y);
  vec3 p2 = vec3(a1.xy,h.z);
  vec3 p3 = vec3(a1.zw,h.w);

  //Normalise gradients
  vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
  p0 *= norm.x;
  p1 *= norm.y;
  p2 *= norm.z;
  p3 *= norm.w;

  // Mix final noise value
  vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
  m = m * m;
  return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3) ) );

}
  
</script>

CSS

body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background-color: #0000FF;
}

.stats {
  position: absolute;
  top: 5px;
  left: 5px;
}

JS

// Original here https://twitter.com/etiennejcb/status/1092882184321548289
// Original Code: https://gist.github.com/Bleuje/094d45a8cb11d16ce002d014ba761559
class ThreeBasic {
  useControls = false;
  renderer = null;
  camera = null;
  scene = null;
  controls = null;
  constructor(withControls = false){
    this.hasControls = withControls;
  }
  init(){
    const VIEW_ANGLE = 45,
    ASPECT = window.innerWidth / window.innerHeight,
    NEAR = 0.1,
    FAR = 10000;
    const camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
    camera.position.z = 30;
    
    
    const scene = new THREE.Scene();
    
    const renderer = new THREE.WebGLRenderer({ alpha: true,  antialias: true});
    if(this.hasControls){
      this.controls = new THREE.OrbitControls(camera, renderer.domElement);
    }
    document.body.appendChild(renderer.domElement);
    
    
    this.camera = camera;
    this.scene = scene;
    this.renderer = renderer;
    this.onResize();
  }
  add(mesh){
    this.scene.add(mesh);
  }
onResize(){
  
  this.renderer.setSize(window.innerWidth, window.innerHeight);
  // uniforms.u_res.value.x = renderer.domElement.width;
  // uniforms.u_res.value.y = renderer.domElement.height;
  this.camera.aspect = window.innerWidth / window.innerHeight;
}
  render(){
	  this.renderer.render( this.scene, this.camera );
  }
}
const App = new ThreeBasic(true);
App.init();

const variants = ['z-noise','noise-zoom-in'];
const config = {
  timeSpeed: 0.005,
  variant: variants[0]
}

const src1 = 'https://images.pexels.com/photos/1930421/pexels-photo-1930421.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260';
const src2 = 'https://images.pexels.com/photos/1906819/pexels-photo-1906819.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260';
const t0 = new THREE.TextureLoader().load(src1);
const t1 = new THREE.TextureLoader().load(src2);
// CODE GOES HERE
const uniforms = {
   u_time: {type:'f', value: 0},
  u_freq: {type:'f', value: 10.},
  u_speed: {type:'f', value: 2.},
  t0: {type:'t', value: t0},
  t1: {type:'t', value:t1},
}
let segments = 128;
let geometry = new THREE.PlaneBufferGeometry(16,16,segments, segments);
const noise = document.getElementById('noise').textContent;
const getShaders = (name)=>{
  let vertex = document.getElementById(name+'-vertex') || document.getElementById('vertex');
  let fragment = document.getElementById(name+'-fragment') || document.getElementById('fragment');
  return {
    fragmentShader:  noise+fragment.textContent,
    vertexShader:  noise+vertex.textContent
  }
}

const material = new THREE.ShaderMaterial({
  uniforms,
  ...getShaders(config.variant),
  side: THREE.DoubleSide
});
const mesh = new THREE.Mesh(geometry, material);

// Adding materials 
  App.add(mesh);

//
let stats = new Stats();
stats.showPanel(0);
stats.domElement.className = "stats"
document.body.appendChild( stats.domElement );
/*
pow(
  (1 + noise.eval(
   4 * SEED + scl * pos.x/2,
   scl * pos.y / 2 + mr * cos(TWO_PI*t),
   scl * pos.z / 2 + mr * sin(TWO_PI*t))
  )/2,
  4.0);
*/
const gui = new dat.GUI()
gui.add(config,"timeSpeed", 0.005,0.04);
const gui_variant = gui.add(config, 'variant', variants);
gui_variant.onFinishChange((type)=>{
  const shaders = getShaders(type);
  material.vertexShader = shaders.vertexShader;
  material.fragmentShader = shaders.fragmentShader;
  material.needsUpdate = true;
});
const possibles = [];
const calcPosibleSpeeds = () => {
  while(possibles.length > 0){
    possibles.splice(0, 1);
  }
  for(var i = 1, max = uniforms.u_freq.value; i < max; i++) {
    if(max % i === 0) {
      possibles.push(i);
    }
  }
}

calcPosibleSpeeds();
console.log(possibles);

// const gui_speed = gui.add(uniforms.u_speed, "value", possibles );
const gui_freq = gui.add(uniforms.u_freq, "value", 2,15,1);
gui_freq.name("frequency");
gui_freq.onFinishChange((val)=>{
  
  // calcPosibleSpeeds();
  // gui_speed.options(possibles);
  // console.log(possibles)
  // uniforms.u_speed.value = possibles[0];
})
 // Gui controls go here
gui.close();
const update = ()=>{
  uniforms.u_time.value += config.timeSpeed;
  // squareMesh.rotation.y+=0.025;
}
function draw(){
  stats.begin();
  App.render();
  stats.end();
  update();
  
  requestAnimationFrame(draw)
}
function init(){
  requestAnimationFrame(draw)
}


window.addEventListener('resize', ()=>{
  App.onResize();
  
  
});
window.addEventListener('mousemove',(e)=>{
  // uniforms.u_mouse.value.x = e.clientX/window.innerWidth;
  // uniforms.u_mouse.value.y = e.clientY/window.innerHeight;
})

init();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章