Рекурсивное изображение - пример 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


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


642   0  

Comments

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