Created
June 8, 2016 20:17
-
-
Save AVGP/b091f23baf6399ffc388015b3d57cc71 to your computer and use it in GitHub Desktop.
Comparison: Repeat & scale image -- Canvas 2D vs. WebGL
This file contains 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> | |
<head> | |
</head> | |
<body> | |
<canvas width="1920" height="1080"></canvas> | |
<script> | |
var frameCount = 0, fps = 0, tStart = 0 | |
var ctx = document.querySelector('canvas').getContext('2d') | |
var img = new Image() | |
img.src = 'logo.png' | |
img.onload = function() { | |
runTest() | |
} | |
function runTest() { | |
renderWithFPS() | |
} | |
function renderWithFPS() { | |
for(var i=0; i<1000; i++) { | |
var x = Math.random() * 1920, y = Math.random() * 1080, size = Math.random() * 512 | |
ctx.drawImage(img, x - 90, y - 90, size, size) // draw & scale | |
} | |
if(Date.now() - tStart >= 1000) { | |
fps = frameCount | |
console.log(fps) | |
frameCount = 0 | |
tStart = Date.now() | |
} | |
frameCount++ | |
requestAnimationFrame(renderWithFPS) | |
} | |
</script> | |
</body> | |
</html> |
This file contains 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> | |
<head> | |
<title>Shaderpad</title> | |
<style> | |
body { | |
width: 100%; | |
} | |
</style> | |
</head> | |
<body> | |
<canvas width="1920" height="1080"></canvas> | |
<div class="column" style="display: none"> | |
<textarea id="vs" rows="50" cols="120"> | |
attribute vec2 aVertexPosition; | |
attribute vec2 aTextureCoord; | |
uniform float uXOffset; | |
uniform float uYOffset; | |
uniform float uScale; | |
varying highp vec2 vTextureCoord; | |
void main(void) { | |
vTextureCoord = aTextureCoord; | |
vec2 scaledPos = (aVertexPosition + vec2(uXOffset, uYOffset)) * uScale; | |
gl_Position = vec4(scaledPos, 0.0, 1.0); | |
} | |
</textarea> | |
<textarea id="fs" rows="50" cols="120"> | |
precision highp float; | |
varying highp vec2 vTextureCoord; | |
uniform sampler2D uSampler; | |
void main(void) { | |
gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)); | |
} | |
</textarea> | |
</div> | |
<script> | |
var frameCount = 0, fps = 0, tStart = 0 | |
// WebGL related code | |
var canvas = document.querySelector('canvas'); | |
var gl = canvas.getContext('webgl'); | |
var texture = gl.createTexture() | |
var vertices = [ | |
0.1, 0.1, | |
-0.1, 0.1, | |
0.1, -0.1, | |
-0.1, -0.1 | |
] | |
var texCoordinates = [ | |
1.0, 0.0, | |
0.0, 0.0, | |
1.0, 1.0, | |
0.0, 1.0 | |
] | |
var vertexPosBuffer = gl.createBuffer(); | |
var texCoordBuffer = gl.createBuffer() | |
// Setup | |
gl.clearColor(0.0, 0.0, 0.0, 1.0); | |
gl.clear(gl.COLOR_BUFFER_BIT); | |
gl.viewport(0, 0, canvas.width, canvas.height); | |
// filling in the vertices | |
gl.bindBuffer(gl.ARRAY_BUFFER, vertexPosBuffer); | |
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); | |
vertexPosBuffer.itemSize = 2; | |
vertexPosBuffer.numItems = 4; | |
var vertexShaderSrc = document.getElementById("vs").value; | |
var fragmentShaderSrc = document.getElementById("fs").value; | |
var shaderProgram = gl.createProgram(); | |
var vs = gl.createShader(gl.VERTEX_SHADER); | |
var fs = gl.createShader(gl.FRAGMENT_SHADER); | |
gl.shaderSource(vs, vertexShaderSrc); | |
gl.compileShader(vs); | |
if(!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) { | |
alert('Vertex shader failed compilation:\n' + gl.getShaderInfoLog(vs)) | |
console.log(gl.getShaderInfoLog(shaderProgram)) | |
} | |
gl.shaderSource(fs, fragmentShaderSrc); | |
gl.compileShader(fs); | |
if(!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) { | |
alert('Fragment shader failed compilation:\n' + gl.getShaderInfoLog(fs)) | |
console.log(gl.getShaderInfoLog(shaderProgram)) | |
} | |
gl.attachShader(shaderProgram, vs); | |
gl.attachShader(shaderProgram, fs); | |
gl.linkProgram(shaderProgram); | |
if(!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { | |
alert("Could not initialise shaders"); | |
} | |
gl.useProgram(shaderProgram); | |
// compiling, attaching, linking the shaders | |
function renderWithFPS() { | |
gl.clear(gl.COLOR_BUFFER_BIT); | |
// bind the uniforms | |
gl.uniform1f(gl.getUniformLocation(shaderProgram, "uXOffset"), 0); | |
gl.uniform1f(gl.getUniformLocation(shaderProgram, "uYOffset"), 0); | |
gl.uniform1f(gl.getUniformLocation(shaderProgram, "uScale"), 1); | |
// Texture coordinate attribute | |
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer); | |
shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord"); | |
gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute); | |
gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0); | |
// Vertex position attribute | |
gl.bindBuffer(gl.ARRAY_BUFFER, vertexPosBuffer); | |
shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); | |
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); | |
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, vertexPosBuffer.itemSize, gl.FLOAT, false, 0, 0); | |
gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertexPosBuffer.numItems); | |
for(var i=0; i<1000; i++) { | |
gl.uniform1f(gl.getUniformLocation(shaderProgram, "uXOffset"), Math.random() * 2 - 1); | |
gl.uniform1f(gl.getUniformLocation(shaderProgram, "uYOffset"), Math.random() * 2 - 1); | |
gl.uniform1f(gl.getUniformLocation(shaderProgram, "uScale"), Math.random() * 2); | |
gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertexPosBuffer.numItems); | |
} | |
if(Date.now() - tStart >= 1000) { | |
fps = frameCount | |
console.log(fps) | |
frameCount = 0 | |
tStart = Date.now() | |
} | |
frameCount++ | |
requestAnimationFrame(renderWithFPS) | |
} | |
function runTest() { | |
var img = new Image() | |
img.onload = function() { | |
gl.bindTexture(gl.TEXTURE_2D, texture); | |
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img); | |
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); | |
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST); | |
gl.generateMipmap(gl.TEXTURE_2D); | |
gl.bindTexture(gl.TEXTURE_2D, null); | |
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer); | |
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texCoordinates), gl.STATIC_DRAW); | |
gl.activeTexture(gl.TEXTURE0); | |
gl.bindTexture(gl.TEXTURE_2D, texture); | |
gl.uniform1i(gl.getUniformLocation(shaderProgram, "uSampler"), 0); | |
renderWithFPS() | |
} | |
img.src = 'logo.png' | |
} | |
runTest() | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment