Created
May 8, 2024 13:55
-
-
Save davidsharp/f67d673a05cc4a5efdf66609644d0f33 to your computer and use it in GitHub Desktop.
pinched a webgl shader example and playing with shaders for use as a progress bar
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
<body bgcolor=black> | |
<canvas id='canvas1' width='1024' height='720'> | |
</canvas> | |
<button onclick="progress=Math.max(0.0,progress-0.1)"><</button> | |
<button onclick="progress=Math.min(1.0,progress+0.1)">></button> | |
</body> | |
<script id="vs" type="x-shader/x-vertex"> | |
attribute vec3 aPosition; | |
varying vec3 vPosition; | |
void main() { | |
gl_Position = vec4(aPosition, 1.0); | |
vPosition = aPosition; | |
} | |
</script> | |
<script id="fs" type="x-shader/x-fragment"> | |
precision mediump float; | |
uniform float uTime; | |
varying vec3 vPosition; | |
uniform float progress; | |
vec3 played = vec3(0.5,0.5,1.0); | |
void main() { | |
vec3 color = ((progress*2.0)-1.0)>vPosition.x?played:vec3(1.0,1.0,1.0); | |
gl_FragColor = vec4(color, 1.0); | |
} | |
</script> | |
<script> | |
var progress = 0.5; | |
/** | |
* Function that pulls out text content from a DOM element | |
* @param id - ID of the DOM element | |
* @returns {string} | |
*/ | |
function getStringFromDOMElement(id) { | |
var node = document.getElementById(id); | |
// Recurse and get all text in the node | |
var recurseThroughDOMNode = function recurseThroughDOMNode(childNode, textContext) { | |
if (childNode) { | |
if (childNode.nodeType === 3) { | |
textContext += childNode.textContent; | |
} | |
return recurseThroughDOMNode(childNode.nextSibling, textContext); | |
} else { | |
return textContext; | |
} | |
}; | |
return recurseThroughDOMNode(node.firstChild, ''); | |
} | |
/** | |
* Create and attach a shader to gl program | |
* @param gl | |
* @param program | |
* @param type | |
* @param src | |
*/ | |
function addshader(gl, program, type, src) { | |
var shader = gl.createShader(type); | |
gl.shaderSource(shader, src); | |
gl.compileShader(shader); | |
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { | |
throw "Cannot compile shader:\n\n" + gl.getShaderInfoLog(shader); | |
} | |
gl.attachShader(program, shader); | |
} | |
/** | |
* Function that creates and links the gl program with the | |
* application's vertex and fragment shader. | |
* @param gl | |
* @param vertexShader | |
* @param fragmentShader | |
*/ | |
function gl_init(gl, vertexShader, fragmentShader) { | |
var program = gl.createProgram(); | |
var buffer = gl.createBuffer(); | |
addshader(gl, program, gl.VERTEX_SHADER, vertexShader); | |
addshader(gl, program, gl.FRAGMENT_SHADER, fragmentShader); | |
gl.linkProgram(program); | |
if (! gl.getProgramParameter(program, gl.LINK_STATUS)) | |
throw "Could not link the shader program!"; | |
gl.useProgram(program); | |
// Create a square as a strip of two triangles. | |
gl.bindBuffer(gl.ARRAY_BUFFER, buffer); | |
gl.bufferData( | |
gl.ARRAY_BUFFER, | |
new Float32Array([ | |
-1,1, | |
0,1, | |
1,0, | |
-1,-1, | |
0,1, | |
-1,0]), | |
gl.STATIC_DRAW | |
); | |
gl.aPosition = gl.getAttribLocation(program, "aPosition"); | |
gl.enableVertexAttribArray(gl.aPosition); | |
gl.vertexAttribPointer(gl.aPosition, 3, gl.FLOAT, false, 0, 0); | |
gl.uTime = gl.getUniformLocation(program, "uTime"); | |
gl.progress = gl.getUniformLocation(program,"progress"); | |
} | |
/** | |
* This function is called once per frame. | |
* @param gl | |
*/ | |
function gl_update(gl) { | |
gl.uniform1f(gl.progress, progress); | |
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); | |
// Start the next frame | |
requestAnimFrame(function() { gl_update(gl); }); | |
} | |
function start_gl(canvas_id, vertexShader, fragmentShader) { | |
// Make sure the browser supports WebGL. | |
try { | |
var canvas = document.getElementById(canvas_id); | |
var gl = canvas.getContext("experimental-webgl"); | |
} catch (e) { | |
throw "Sorry, your browser does not support WebGL."; | |
} | |
// Initialize gl. Then start the frame loop. | |
gl_init(gl, vertexShader, fragmentShader); | |
gl_update(gl); | |
} | |
// A browser-independent way to call a function after 1/60 second. | |
requestAnimFrame = (function() { | |
return requestAnimationFrame | |
|| webkitRequestAnimationFrame | |
|| mozRequestAnimationFrame | |
|| oRequestAnimationFrame | |
|| msRequestAnimationFrame | |
|| function(callback) { | |
setTimeout(callback, 1000 / 60); | |
}; })(); | |
start_gl("canvas1", getStringFromDOMElement('vs'), getStringFromDOMElement('fs')); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment