Created
May 30, 2022 04:26
-
-
Save modster/d4b8ab63f6a68403e49efc6a4824b8a5 to your computer and use it in GitHub Desktop.
GLSL/JavaScript Template Literal Shader Program
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
"use strict"; | |
var vs = `#version 300 es | |
in vec2 a_position; | |
uniform mat3 u_matrix; | |
void main() { | |
// Multiply the position by the matrix. | |
gl_Position = vec4((u_matrix * vec3(a_position, 1)).xy, 0, 1); | |
} | |
`; |
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
<canvas id="canvas"></canvas> | |
<!-- | |
for most samples webgl-utils only provides shader compiling/linking and | |
canvas resizing because why clutter the examples with code that's the same in every sample. | |
See https://webgl2fundamentals.org/webgl/lessons/webgl-boilerplate.html | |
and https://webgl2fundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html | |
for webgl-utils, m3, m4, and webgl-lessons-ui. | |
--> | |
<script src="https://webgl2fundamentals.org/webgl/resources/webgl-utils.js"></script> | |
<script src="https://webgl2fundamentals.org/webgl/resources/m3.js"></script> |
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
function main() { | |
// Get A WebGL context | |
/** @type {HTMLCanvasElement} */ | |
var canvas = document.querySelector("#canvas"); | |
var gl = canvas.getContext("webgl2"); | |
if (!gl) { | |
return; | |
} | |
// setup GLSL program | |
var program = webglUtils.createProgramFromSources(gl, [vs, fs]); | |
// look up where the vertex data needs to go. | |
var positionAttributeLocation = gl.getAttribLocation(program, "a_position"); | |
// lookup uniforms | |
var colorLocation = gl.getUniformLocation(program, "u_color"); | |
var matrixLocation = gl.getUniformLocation(program, "u_matrix"); | |
// Create a buffer and put a 2 points in it for 1 line | |
var positionBuffer = gl.createBuffer(); | |
// Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = positionBuffer) | |
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); | |
var positions = [ | |
-2, -2, | |
2, 2, | |
]; | |
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW); | |
// Create a vertex array object (attribute state) | |
var vao = gl.createVertexArray(); | |
// and make it the one we're currently working with | |
gl.bindVertexArray(vao); | |
// Turn on the attribute | |
gl.enableVertexAttribArray(positionAttributeLocation); | |
// Tell the attribute how to get data out of positionBuffer (ARRAY_BUFFER) | |
var size = 2; // 2 components per iteration | |
var type = gl.FLOAT; // the data is 32bit floats | |
var normalize = false; // don't normalize the data | |
var stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position | |
var offset = 0; // start at the beginning of the buffer | |
gl.vertexAttribPointer( | |
positionAttributeLocation, size, type, normalize, stride, offset); | |
requestAnimationFrame(drawScene); | |
// Draw the scene. | |
function drawScene(now) { | |
resizeCanvasToDisplaySize(gl.canvas); | |
now *= 0.001; // convert to seconds | |
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); | |
// Clear the canvas | |
gl.clearColor(0, 0, 0, 0); | |
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); | |
// Tell it to use our program (pair of shaders) | |
gl.useProgram(program); | |
// Bind the attribute/buffer set we want. | |
gl.bindVertexArray(vao); | |
// Compute the matrices | |
var matrix = m3.rotation(now); | |
// Set the matrix. | |
gl.uniformMatrix3fv(matrixLocation, false, matrix); | |
// Draw in Red | |
gl.uniform4fv(colorLocation, [1, 0, 0, 1]); | |
// Draw the line | |
var primitiveType = gl.LINES; | |
var offset = 0; | |
var count = 2; | |
gl.drawArrays(primitiveType, offset, count); | |
requestAnimationFrame(drawScene); | |
} | |
const canvasToDisplaySizeMap = new Map([[canvas, [300, 150]]]); | |
function onResize(entries) { | |
for (const entry of entries) { | |
let width; | |
let height; | |
let dpr = window.devicePixelRatio; | |
if (entry.devicePixelContentBoxSize) { | |
// NOTE: Only this path gives the correct answer | |
// The other 2 paths are an imperfect fallback | |
// for browsers that don't provide anyway to do this | |
width = entry.devicePixelContentBoxSize[0].inlineSize; | |
height = entry.devicePixelContentBoxSize[0].blockSize; | |
dpr = 1; // it's already in width and height | |
} else if (entry.contentBoxSize) { | |
if (entry.contentBoxSize[0]) { | |
width = entry.contentBoxSize[0].inlineSize; | |
height = entry.contentBoxSize[0].blockSize; | |
} else { | |
// legacy | |
width = entry.contentBoxSize.inlineSize; | |
height = entry.contentBoxSize.blockSize; | |
} | |
} else { | |
// legacy | |
width = entry.contentRect.width; | |
height = entry.contentRect.height; | |
} | |
const displayWidth = Math.round(width * dpr); | |
const displayHeight = Math.round(height * dpr); | |
canvasToDisplaySizeMap.set(entry.target, [displayWidth, displayHeight]); | |
} | |
} | |
const resizeObserver = new ResizeObserver(onResize); | |
resizeObserver.observe(canvas, {box: 'content-box'}); | |
function resizeCanvasToDisplaySize(canvas) { | |
// Get the size the browser is displaying the canvas in device pixels. | |
const [displayWidth, displayHeight] = canvasToDisplaySizeMap.get(canvas); | |
// Check if the canvas is not the same size. | |
const needResize = canvas.width !== displayWidth || | |
canvas.height !== displayHeight; | |
if (needResize) { | |
// Make the canvas the same size | |
canvas.width = displayWidth; | |
canvas.height = displayHeight; | |
} | |
return needResize; | |
} | |
} | |
main(); |
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
body { | |
margin: 0; | |
background-color: white; | |
} | |
canvas { | |
display: block; /* prevents scrollbar */ | |
width: 100vw; | |
height: 100vh; | |
} |
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
"use strict"; | |
var vs = `#version 300 es | |
in vec2 a_position; | |
uniform mat3 u_matrix; | |
void main() { | |
// Multiply the position by the matrix. | |
gl_Position = vec4((u_matrix * vec3(a_position, 1)).xy, 0, 1); | |
} | |
`; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment