欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

干扰(noise)

程序员文章站 2022-07-01 13:54:32
...

干扰(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();