Fractal WebGL
by Vladimir
HTML
<canvas width="600" height="600" id="canvas"/>
<script type="glsl/vertex">
attribute vec2 coords;
void main(void) {
gl_Position = vec4(coords.xy, 0.0, 1.0);
}
</script>
<script type="glsl/fragment">
precision highp float;
uniform vec2 mouse;
uniform vec2 resolution;
void main(void) {
vec2 m = mouse/resolution;
vec2 p = gl_FragCoord.xy;
// вот собственно сама формула реализована в этих 3 строчках
vec2 q = (p + p - resolution) / resolution.y;
for(int i = 0; i < 10; i++)
q = abs(q)/dot(q,q) - m;
gl_FragColor = vec4(q, q.x/q.y, 1.0);
}
</script>
JavaScript
let gl = canvas.getContext('webgl');
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, 3, -1, -1, 3, -1]), gl.STATIC_DRAW);
let pid = gl.createProgram();
shader('vertex', gl.VERTEX_SHADER);
shader('fragment', gl.FRAGMENT_SHADER);
gl.linkProgram(pid);
gl.useProgram(pid);
let coords = gl.getAttribLocation(pid, "coords");
gl.vertexAttribPointer(coords, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(coords);
let mouse = gl.getUniformLocation(pid, 'mouse');
let resolution = gl.getUniformLocation(pid, 'resolution');
gl.uniform2f(resolution, gl.drawingBufferWidth, gl.drawingBufferHeight);
let changeCenter = e => {
e = e.touches ? e.touches[0] : e;
gl.uniform2f(mouse, e.pageX - canvas.offsetLeft, e.pageY - canvas.offsetTop);
draw();
}
window.addEventListener('mousemove', changeCenter);
window.addEventListener('touchmove', changeCenter);
draw();
function draw() {
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.clearColor(0, 0, 0, 0);
gl.drawArrays(gl.TRIANGLES, 0, 3);
}
function shader(src, type) {
let sid = gl.createShader(type);
gl.shaderSource(sid, document.querySelector(`script[type="glsl/${src}"]`).textContent);
gl.compileShader(sid);
var message = gl.getShaderInfoLog(sid);
gl.attachShader(pid, sid);
if (message.length > 0) {
console.log(src.split('\n').map(function (str, i) {
return ("" + (1 + i)).padStart(4, "0") + ": " + str
}).join('\n'));
throw message;
}
}