Created
April 24, 2015 10:41
-
-
Save hdf/916f19395a19ce48339e to your computer and use it in GitHub Desktop.
Mandelbrot with GLSL (http://codepen.io/anon/pen/JdPJrx?editors=100)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Mandelbrot with GLSL</title> | |
<style> | |
html, body {margin: 0; padding: 0;} | |
canvas {position: absolute; width: 100%; height: 100%;} | |
</style> | |
</head> | |
<body> | |
<canvas id="mandel"></canvas> | |
<script id="vertexShader" type="x-shader/x-vertex"> | |
attribute vec2 vertexPos; | |
uniform float aspectRatio; | |
varying vec2 pixelPos; | |
uniform float zoom; | |
uniform float movx; | |
uniform float movy; | |
void main() { | |
pixelPos = vec2(vertexPos.x / zoom + movx - 0.5, vertexPos.y / aspectRatio / zoom - movy); | |
gl_Position = vec4(vertexPos, 0.0, 1.0); | |
} | |
</script> | |
<script id="fragmentShader" type="x-shader/x-fragment"> | |
precision highp float; | |
varying vec2 pixelPos; | |
uniform int iter; | |
void main() { | |
vec2 z = pixelPos; | |
for (int i = 0; i < 1024; i++) { | |
z = pixelPos + vec2( | |
z.x*z.x - z.y*z.y, | |
2.0*z.x*z.y | |
); | |
//gl_FragColor = vec4(0.0, 0.0, 0.0, 0.3); | |
//if (length(z) > 1.5) { | |
gl_FragColor = vec4(z, 1.0/abs(length(z)+0.5), 0.7); | |
//} | |
if (i >= iter) break; | |
} | |
} | |
</script> | |
<script> | |
var width = window.innerWidth - window.pageXOffset; | |
var height = window.innerHeight - window.pageYOffset; | |
var zoom = 0.3, movx = 0.275, movy = 0.005, iter = 128; | |
// Coloring: | |
// http://nuclear.mutantstargoat.com/articles/sdr_fract/ | |
var canvas = document.getElementById('mandel'); | |
canvas.width = width; | |
canvas.height = height; | |
var gl = canvas.getContext('webgl'); | |
//gl.viewportWidth = canvas.width; | |
//gl.viewportHeight = canvas.height; | |
//gl.viewport(0, 0, canvas.width, canvas.height); | |
//gl.clearColor(0.0, 0.0, 0.0, 1.0); | |
//gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT); | |
var vertexShader_src = document.getElementById('vertexShader').firstChild.textContent.trim(); | |
var fragmentShader_src = document.getElementById('fragmentShader').firstChild.textContent.trim(); | |
var vertexShader = gl.createShader(gl.VERTEX_SHADER); | |
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); | |
gl.shaderSource(vertexShader, vertexShader_src); | |
gl.shaderSource(fragmentShader, fragmentShader_src); | |
gl.compileShader(vertexShader); | |
gl.compileShader(fragmentShader); | |
var program = gl.createProgram(); | |
gl.attachShader(program, vertexShader); | |
gl.attachShader(program, fragmentShader); | |
gl.linkProgram(program); | |
gl.useProgram(program); | |
function setShaderValues() { | |
gl.uniform1f(gl.getUniformLocation(program, 'aspectRatio'), canvas.clientWidth / canvas.clientHeight); | |
gl.uniform1f(gl.getUniformLocation(program, 'zoom'), zoom); | |
gl.uniform1i(gl.getUniformLocation(program, 'iter'), iter); | |
gl.uniform1f(gl.getUniformLocation(program, 'movx'), movx); | |
gl.uniform1f(gl.getUniformLocation(program, 'movy'), movy); | |
} | |
setShaderValues(); | |
var vertexPositionBuffer = gl.createBuffer(); | |
gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer); | |
var vertices = [ | |
1.0, 1.0, | |
-1.0, 1.0, | |
1.0, -1.0, | |
-1.0, -1.0 | |
]; | |
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); | |
var vertPos = gl.getAttribLocation(program, "vertexPos"); | |
gl.enableVertexAttribArray(vertPos); | |
gl.vertexAttribPointer(vertPos, 2, gl.FLOAT, false, 0, 0); | |
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); | |
canvas.onwheel = function(e) { | |
if (e.deltaY > 0) | |
zoom -= zoom / 2; | |
else { | |
movx += ((1 / this.clientWidth) * (e.clientX) - 0.5) / zoom; | |
if (movx > 3.5) movx = 3.5; | |
if (movx < -3) movx = -3; | |
movy += ((1 / this.clientHeight) * (e.clientY) - 0.5) / zoom; | |
if (movy > 1.25) movy = 1.25; | |
if (movy < -1.25) movy = -1.25; | |
zoom += zoom; | |
} | |
if (zoom < 0.3) zoom = 0.3; | |
//var tmp = Math.ceil(Math.log2(zoom))*5; | |
//iter = (tmp > 1)?(tmp+20):20; | |
} | |
</script> | |
<script type="text/javascript" src="https://raw.githubusercontent.com/mrdoob/stats.js/master/build/stats.min.js"></script> | |
<script> | |
var stats = new Stats(); | |
stats.setMode(0); // 0: fps, 1: ms | |
stats.domElement.style.position = 'absolute'; | |
stats.domElement.style.right = '0px'; | |
stats.domElement.style.top = '0px'; | |
document.body.appendChild( stats.domElement ); | |
var update = function(delta) { | |
stats.begin(); | |
setShaderValues(); | |
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); | |
stats.end(); | |
requestAnimationFrame(update); | |
}; | |
requestAnimationFrame(update); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment