Рекурсивное изображение - пример html js css



Книга Рекурсивное изображение

Рекурсивное изображение (HTML код)


<div class="container">
</div>
<script type="text/fragment" id="fragShader">
  precision highp float;

  uniform vec2 u_resolution;
  uniform float u_time;
  uniform vec4 u_mouse;
  uniform float u_iMouselength;
  uniform sampler2D s_noise;

  uniform sampler2D b_noise;
  uniform sampler2D b_render;

  varying vec2 v_uv;
  
  const float layers = 10.;
  float depth = 20.;
  float t;
  
  #define PI 3.14159265359
  #define TAU PI * 2.

  vec2 getScreenSpace() {
    vec2 uv = (gl_FragCoord.xy - 0.5 * u_resolution.xy) / min(u_resolution.y, u_resolution.x);

    return uv;
  }
  vec2 rot(vec2 p, float a) {
    float c = cos(a);
    float s = sin(a);
    return p * mat2(c, -s, s, c);
  }
  float ngon(vec2 uv, float sides) {
    float split = TAU / sides;
    vec2 polar = vec2( length(uv), atan(uv.y, uv.x) / split );
    
    return polar.x * cos(fract(polar.y) * split - split * .5);
  }
  
  vec3 pal( in float t, in vec3 a, in vec3 b, in vec3 c, in vec3 d ) {
      return a + b*cos( 6.28318*(c*t+d) );
  }
  void main() {
    vec2 uv = getScreenSpace();
    
    uv *= 2.;
    
    float t = u_time - 171.25;
    
    vec2 rotuv = rot(uv, t*10.) * vec2(1.7, 1.);
    
    float field = ngon(rotuv, 4.);
    float field2 = ngon(rotuv + vec2(0., .1), 4.);
    // field = field2;
    float m = smoothstep(0.003, 0., field-.13) - smoothstep(0.003, 0., field2-.13); // Outer
    float i = smoothstep(0.003, 0., field-.06); // Inner
    float pa = clamp(m + i, 0., 1.);

    vec2 suv = gl_FragCoord.xy / u_resolution - .5;
    suv *= 1.01;
    suv.y = abs(suv.y) - sin(t*5.) * .02;
    suv.x = abs(suv.x) - cos(t*5.) * .05;
    suv = rot(suv, -t*2.);
    suv += .5;
    float offsfield = step(suv.x, 1.) * step(suv.y, 1.) * step(0., suv.x) * step(0., suv.y);
    vec4 tex = texture2D( b_render, suv );
    
    tex.x = tex.x - max(cos((1./tex.a)), 0.);
    tex.y = tex.y - max(sin(1./tex.a*5.) * .5, 0.);
    tex.z = tex.z - max(cos(1./tex.a*5.) * .5, 0.);
    tex *= .98;
    
    vec3 c = vec3(smoothstep( 0., .003, abs(field)-.12 ),  i, i + smoothstep( 0., .003, abs(field-.2)-.15 )) * (1. - smoothstep( 0., .003, abs(field-.19)-.15 ));
    
    float a = clamp(tex.w + m + i, 0., 1.);
    
    gl_FragColor = vec4(mix(tex.rgb, c, pa), a);
    
  }
</script>
<script type="text/fragment" id="renderShader">
  precision highp float;

  uniform vec2 u_resolution;
  uniform float u_time;
  uniform vec4 u_mouse;
  uniform float u_iMouselength;
  uniform sampler2D s_noise;

  uniform sampler2D b_render;

  varying vec2 v_uv;
  
  void main() {
    vec4 tex = texture2D(b_render, gl_FragCoord.xy / u_resolution );
    vec3 colour = mix(vec3(0), vec3(.2, .5, .8), tex.r);
    colour = mix(colour, vec3(.4, .2, .2), tex.g);
    colour = mix(colour, vec3(.2, .5, .3), tex.b);
    gl_FragColor = vec4(colour, 1.);
  }
</script>

Рекурсивное изображение (CSS код)



body {
  background: #333;
  color: #fff;
  font-family: sans-serif;
}
body,
html {
  margin: 0;
  overflow: hidden;
  padding: 0;
}
body {
  display: grid;
  place-items: center;
  height: 100vh;
}
.container {
}
canvas{
  max-width:1024px;
  max-height:1024px;
  height: 100vh;
  width: 100%;
  object-fit: contain;
}


Рекурсивное изображение (JS код)



function _defineProperty(obj, key, value) {if (key in obj) {Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true });} else {obj[key] = value;}return obj;}function _classPrivateFieldGet(receiver, privateMap) {var descriptor = privateMap.get(receiver);if (!descriptor) {throw new TypeError("attempted to get private field on non-instance");}if (descriptor.get) {return descriptor.get.call(receiver);}return descriptor.value;}function _classPrivateFieldSet(receiver, privateMap, value) {var descriptor = privateMap.get(receiver);if (!descriptor) {throw new TypeError("attempted to set private field on non-instance");}if (descriptor.set) {descriptor.set.call(receiver, value);} else {if (!descriptor.writable) {throw new TypeError("attempted to set read only private field");}descriptor.value = value;}return value;}import { Vec2, Vec3, Vec4, Mat2, Mat3, Mat4, Quat } from 'https://cdn.skypack.dev/wtc-math';
import { Camera, Renderer, Mesh, Program, Geometry, Triangle, FragmentShader, Uniform, Texture, RenderTarget } from 'https://cdn.skypack.dev/wtc-gl';

console.clear();var _readFB = new WeakMap();var _writeFB = new WeakMap();var _name = new WeakMap();var _width = new WeakMap();var _height = new WeakMap();var _pxRatio = new WeakMap();var _tiling = new WeakMap();var _texdepth = new WeakMap();var _data = new WeakMap();

class Framebuffer {

















  constructor(gl, {
    name = 'FBO',
    width = 2048,
    height = 2048,
    dpr = Math.min(window.devicePixelRatio, 2),
    tiling = Texture.IMAGETYPE_REGULAR,
    texdepth = Framebuffer.TEXTYPE_UNSIGNED_BYTE,
    data = null } =
  {}) {_readFB.set(this, { writable: true, value: void 0 });_writeFB.set(this, { writable: true, value: void 0 });_name.set(this, { writable: true, value: void 0 });_width.set(this, { writable: true, value: void 0 });_height.set(this, { writable: true, value: void 0 });_pxRatio.set(this, { writable: true, value: void 0 });_tiling.set(this, { writable: true, value: Framebuffer.IMAGETYPE_REGULAR });_texdepth.set(this, { writable: true, value: Framebuffer.TEXTYPE_UNSIGNED_BYTE });_data.set(this, { writable: true, value: void 0 });
    this.gl = gl;

    this.name = name;
    this.height = height;
    this.dpr = dpr;
    _classPrivateFieldSet(this, _tiling, tiling);
    _classPrivateFieldSet(this, _texdepth, texdepth);

    this.resize(width, height);
  }
  resize(width, height) {
    this.width = width;
    this.height = height;
    _classPrivateFieldSet(this, _readFB, this.createFrameBuffer());
    _classPrivateFieldSet(this, _writeFB, this.createFrameBuffer());
  }
  createFrameBuffer() {

    const t = this.type;
    console.log(this.gl.REPEAT);
    console.log(this.wrap);

    let internalFormat = this.gl.RGBA;

    if (t === this.gl.FLOAT) {
      internalFormat = this.gl.RGBA32F;
    }

    const FB = new RenderTarget(this.gl, {
      width: this.width * this.dpr,
      height: this.height * this.dpr,
      wrapS: this.wrap,
      wrapT: this.wrap,
      type: this.type,
      internalFormat: internalFormat });

    return FB;
  }
  swap() {
    const temp = _classPrivateFieldGet(this, _readFB);
    _classPrivateFieldSet(this, _readFB, _classPrivateFieldGet(this, _writeFB));
    _classPrivateFieldSet(this, _writeFB, temp);
  }
  render(renderer, {
    scene,
    camera,
    update = true,
    clear })
  {
    renderer.render({ scene, camera, target: _classPrivateFieldGet(this, _writeFB), update, clear });
    this.swap();
  }

  get wrap() {
    switch (_classPrivateFieldGet(this, _tiling)) {
      case Framebuffer.IMAGETYPE_REGULAR:
        return this.gl.CLAMP_TO_EDGE;
        break;
      case Framebuffer.IMAGETYPE_TILING:
        return this.gl.REPEAT;
        break;
      case Framebuffer.IMAGETYPE_MIRROR:
        return this.gl.MIRRORED_REPEAT;
        break;}

  }
  get type() {
    switch (_classPrivateFieldGet(this, _texdepth)) {
      case Framebuffer.TEXTYPE_FLOAT:
        return this.gl.FLOAT;
        break;
      case Framebuffer.TEXTYPE_UNSIGNED_BYTE:
        return this.gl.UNSIGNED_BYTE;
        break;
      case Framebuffer.TEXTYPE_HALF_FLOAT_OES:
        const e = this.gl.getExtension('OES_texture_half_float');
        // console.log(e.HALF_FLOAT_OES)
        if (this.gl.renderer.isWebgl2) {
        }
        // t = this.renderer.isWebgl2 ? this.ctx.HALF_FLOAT : e.HALF_FLOAT_OES;
        return (e === null || e === void 0 ? void 0 : e.HALF_FLOAT_OES) || this.gl.HALF_FLOAT;
        break;}

  }

  get read() {
    return _classPrivateFieldGet(this, _readFB);
  }
  get write() {
    return _classPrivateFieldGet(this, _writeFB);
  }

  set data(value) {
    if (value instanceof Float32Array) _classPrivateFieldSet(this, _data, value);
  }
  get data() {
    return _classPrivateFieldGet(this, _data) || null;
  }
  set width(value) {
    if (value > 0) _classPrivateFieldSet(this, _width, value);
  }
  get width() {
    return _classPrivateFieldGet(this, _width) || 1;
  }
  set height(value) {
    if (value > 0) _classPrivateFieldSet(this, _height, value);
  }
  get height() {
    return _classPrivateFieldGet(this, _height) || 1;
  }
  set pxRatio(value) {
    if (value > 0) _classPrivateFieldSet(this, _pxRatio, value);
  }
  get pxRatio() {
    return _classPrivateFieldGet(this, _pxRatio) || 1;
  }
  set tiling(value) {
    if ([Texture.IMAGETYPE_REGULAR, Texture.IMAGETYPE_TILE, Texture.IMAGETYPE_MIRROR].indexOf(value) > -1) _classPrivateFieldSet(this, _tiling, value);
  }
  get tiling() {
    return _classPrivateFieldGet(this, _tiling);
  }
  set texdepth(value) {
    if ([Framebuffer.TEXTYPE_FLOAT, Framebuffer.TEXTYPE_UNSIGNED_BYTE, Framebuffer.TEXTYPE_HALF_FLOAT_OES].indexOf(value) > -1) _classPrivateFieldSet(this, _texdepth, value);
  }
  get texdepth() {
    return _classPrivateFieldGet(this, _texdepth);
  }}_defineProperty(Framebuffer, "TEXTYPE_FLOAT", 0);_defineProperty(Framebuffer, "TEXTYPE_UNSIGNED_BYTE", 1);_defineProperty(Framebuffer, "TEXTYPE_HALF_FLOAT_OES", 2);_defineProperty(Framebuffer, "IMAGETYPE_REGULAR", 0);_defineProperty(Framebuffer, "IMAGETYPE_TILING", 1);_defineProperty(Framebuffer, "IMAGETYPE_MIRROR", 2);


const defaultShaderV = `
attribute vec3 position;
attribute vec2 uv;
varying vec2 v_uv;
void main() {
gl_Position = vec4(position, 1.0);
v_uv = uv;
}
`;

let lastTime = 0;
class ParticleShader extends FragmentShader {
  constructor({
    fragment,
    fragment2,
    dimensions = new Vec2(window.innerWidth, window.innerHeight),
    container = document.body,
    autoResize = true,
    uniforms = {},
    onBeforeRender = t => {},
    onAfterRender = t => {} } =
  {}) {
    super({
      fragment, dimensions, container, autoResize, uniforms, onBeforeRender, onAfterRender });


    const geometry = new Triangle(this.gl);
    this.mainProgram = new Program(this.gl, {
      vertex: defaultShaderV,
      fragment: fragment2,
      uniforms: this.uniforms });

    this.mainMesh = new Mesh(this.gl, { geometry, program: this.mainProgram });
    this.mainFBO = new Framebuffer(this.gl, {
      name: 'render',
      width: this.dimensions.width,
      height: this.dimensions.height,
      texdepth: Framebuffer.TEXTYPE_FLOAT,
      tiling: Framebuffer.IMAGETYPE_TILING });
  }
  resize() {
    this.dimensions = new Vec2(window.innerWidth, window.innerHeight);
    if (this.mainFBO) this.mainFBO.resize(window.innerWidth, window.innerHeight);
    this.u_resolution.value = this.dimensions.scaleNew(this.renderer.dpr).array;

    this.renderer.dimensions = this.dimensions;
  }
  render(t) {
    this.onBeforeRender(t);

    const diff = t - lastTime;
    lastTime = t;


    if (this.playing) {
      requestAnimationFrame(this.render);
    }

    const v = this.u_time.value;
    this.u_time.value = v + diff * 0.00005;

    this.mainMesh.program.uniforms[`b_${this.mainFBO.name}`] = new Uniform({
      name: this.mainFBO.name,
      value: this.mainFBO.read.texture,
      kind: 'texture' });


    this.mainFBO.render(this.renderer, { scene: this.mainMesh });

    this.mesh.program.uniforms['u_resolution'] = new Uniform({ name: 'res', value: this.dimensions.scaleNew(this.renderer.dpr).array, kind: 'vec2' });

    this.renderer.render({ scene: this.mesh, target: null });

    this.onAfterRender(t);
  }}


// Create the fragment shader wrapper
const FSWrapper = new ParticleShader({
  container: document.querySelector('.container'),
  autoResize: false,
  dimensions: new Vec2(1024, 1024),
  fragment2: document.querySelector('#fragShader').innerText,
  fragment: document.querySelector('#renderShader').innerText });


const { gl, uniforms, renderer } = FSWrapper;
const px = renderer.dpr;

// Set up mouse uniforms
(function () {
  const tarmouse = new Vec4(0, 0, 0, 0);
  const curmouse = tarmouse.clone();
  let pointerdown = false;
  uniforms.u_mouse = new Uniform({
    name: 'mouse',
    value: tarmouse.array,
    kind: 'float_vec4' });

  uniforms.u_iMouselength = new Uniform({
    name: 'iMouselength',
    value: 0,
    kind: 'float' });

  document.body.addEventListener('pointermove', e => {
    tarmouse.x = e.x * px;
    tarmouse.y = (window.innerHeight - e.y) * px;
    if (pointerdown) {
      tarmouse.z = e.x * px;
      tarmouse.w = (window.innerHeight - e.y) * px;
    }
  });
  document.body.addEventListener('pointerdown', e => {
    pointerdown = true;
    tarmouse.z = e.x * px;
    tarmouse.w = (window.innerHeight - e.y) * px;
  });
  document.body.addEventListener('pointerup', e => {
    pointerdown = false;
  });
  let oldTime;
  const animouse = d => {
    const factor = d - oldTime;
    oldTime = d;
    const diff = tarmouse.xy.subtractNew(curmouse.xy);
    uniforms.u_iMouselength.value = diff.length;
    curmouse.add(diff.scale(1. / factor * .05));
    uniforms.u_mouse.value = curmouse.array;
    requestAnimationFrame(animouse);
  };
  requestAnimationFrame(animouse);
})();

// Set up textures
(function () {
  // Create the texture
  const texture = new Texture(gl, {
    wrapS: gl.REPEAT,
    wrapT: gl.REPEAT });

  // Load the image into the uniform
  const img = new Image();
  img.crossOrigin = "anonymous";
  img.src = "https://assets.codepen.io/982762/noise.png";
  img.onload = () => texture.image = img;

  uniforms.s_noise = new Uniform({
    name: "noise",
    value: texture,
    kind: "texture" });

})();
//# sourceURL=pen.js
    

Рекурсивное изображение (Результат кода)

85   0  
    Ничего не найдено.

Добавить ответ:
Отменить.