Skip to content

Instantly share code, notes, and snippets.

@almoce
Last active June 15, 2022 11:37
Show Gist options
  • Save almoce/3c21b5dc061f008606ead0ae34b05f57 to your computer and use it in GitHub Desktop.
Save almoce/3c21b5dc061f008606ead0ae34b05f57 to your computer and use it in GitHub Desktop.
webgl basic point and triangle with shader
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>webgl point</title>
<link rel="stylesheet" href="">
<style>
body {
margin: 0px;
padding: 0px;
}
* {
box-sizing: border-box;
}
canvas {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<script>
const VERT_SRC = `
precision mediump float;
attribute vec2 position;
varying vec4 v_color;
void main() {
gl_Position = vec4(position, 0, 1);
gl_PointSize = 20.0; // set the shader point sizze
}
`
const FRAG_SRC = `
precision mediump float;
uniform vec4 u_color;
void main() {
gl_FragColor = u_color;
}
`
let gl, program
const POINT_BUFFER = [
[-1, 1], // left, up
[0, 1], // mid, up
[1, 1], // right, up
[-1, 0], // left, mid
[0, 0], // mid, mid
[1, 0], // right, mid
[-1, -1], // left, bottom
[0, -1], // mid, bottom
[1, -1], // right, mid
]
const P_COLOR = [
[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]
]
createDomElement()
createProgram()
draw()
window.addEventListener("click", (e)=> {
const x = e.clientX/window.innerWidth * 2 -1
const y = e.clientY/window.innerHeight * -2 + 1
console.log(x,y)
P_COLOR.push([Math.random(),Math.random(),Math.random()])
POINT_BUFFER.push([x,y])
})
function draw() {
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight) // set the viewer port size
gl.enable(gl.BLEND); // enable blend mode
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); // enable alpha
gl.clearColor(0,0,0,1) // set clear color the background, (r,g,b,a)
gl.clear(gl.COLOR_BUFFER_BIT) // clear the cavnas background
gl.useProgram(program) // set gl to use shader program
const u_color = gl.getUniformLocation(program, 'u_color')
const attributeIndex = gl.getAttribLocation(program, 'position')
POINT_BUFFER.forEach((i, idx) => {
gl.vertexAttrib3fv(attributeIndex, [...i, 0.0])
gl.uniform4fv(u_color, [...P_COLOR[idx], 1.0])
gl.drawArrays(gl.POINTS, 0, 1); // draw point, (mode, offset, count)
})
requestAnimationFrame(draw)
}
function createProgram() {
program = gl.createProgram() // create shader program
const vertex = createShader(gl.VERTEX_SHADER, VERT_SRC) // create vertex shader
const frag = createShader(gl.FRAGMENT_SHADER, FRAG_SRC) // create fragment shader
gl.attachShader(program, vertex) // attach vertex shader to program
gl.attachShader(program, frag) // attach fragment shader to program
const attributeIndex = 0
gl.bindAttribLocation(program, attributeIndex, 'position') // bind attribute index to shader program , (shaderProgram, attributeIndex, attributeName)
gl.linkProgram(program) // link the shader program to gl context
}
function createShader(type, source) {
const shader = gl.createShader(type) // create the shader type
gl.shaderSource(shader, source) // set the shader from source
gl.compileShader(shader) // compiele the shader
return shader
}
function createDomElement() {
const canvas = document.createElement('canvas')
canvas.width = window.innerWidth
canvas.height = window.innerHeight
document.body.appendChild(canvas)
gl = canvas.getContext('webgl')
}
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>webgl point</title>
<link rel="stylesheet" href="">
<style>
body {
margin: 0px;
padding: 0px;
}
* {
box-sizing: border-box;
}
canvas {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<script>
const VERT_SRC = `
precision mediump float;
attribute vec2 position;
attribute vec3 a_color;
varying vec4 v_color;
void main() {
gl_Position = vec4(position, 0, 1);
gl_PointSize = 20.0; // set the shader point sizze
v_color = vec4(a_color, 1.0);
}
`
const FRAG_SRC = `
precision mediump float;
varying vec4 v_color;
void main() {
gl_FragColor = v_color;
}
`
let gl, program
const POINT_BUFFER = [
[-1, 1], // left, up
[0, 1], // mid, up
[1, 1], // right, up
[-1, 0], // left, mid
[0, 0], // mid, mid
[1, 0], // right, mid
[-1, -1], // left, bottom
[0, -1], // mid, bottom
[1, -1], // right, mid
]
const P_COLOR = [
[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]
]
let bufferdata = new Float32Array([])
createDomElement()
createProgram()
createBuffer()
draw()
window.addEventListener("click", (e)=> {
const x = e.clientX/window.innerWidth * 2 -1
const y = e.clientY/window.innerHeight * -2 + 1
P_COLOR.push([Math.random(),Math.random(),Math.random()])
POINT_BUFFER.push([x,y])
createBuffer()
})
function draw() {
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight) // set the viewer port size
gl.enable(gl.BLEND); // enable blend mode
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); // enable alpha
gl.clearColor(0,0,0,1) // set clear color the background, (r,g,b,a)
gl.clear(gl.COLOR_BUFFER_BIT) // clear the cavnas background
gl.useProgram(program) // set gl to use shader program
gl.drawArrays(gl.POINTS, 0, POINT_BUFFER.length); // draw point, (mode, offset, count)
requestAnimationFrame(draw)
}
function createBuffer(buff) {
bufferdata = new Float32Array(POINT_BUFFER.length * 5)
POINT_BUFFER.forEach((i, idx) => {
const [x, y] = i
const [r, g, b] = P_COLOR[idx]
bufferdata.set([x,y, r,g,b], idx * 5)
})
const buffer = gl.createBuffer() // create the buffer in gl
gl.bindBuffer(gl.ARRAY_BUFFER, buffer) // bind the buffer created with the buffer type
gl.bufferData(gl.ARRAY_BUFFER, bufferdata, gl.STATIC_DRAW) // set the buffer data
const a_position = gl.getAttribLocation(program, 'position')
gl.enableVertexAttribArray(a_position) // enable the attribute (attributeIndex)
gl.vertexAttribPointer(a_position, 2, gl.FLOAT, false, bufferdata.BYTES_PER_ELEMENT * 5, 0) // set the attribute pointer,
const a_color = gl.getAttribLocation(program, 'a_color')
gl.enableVertexAttribArray(a_color)
gl.vertexAttribPointer(a_color, 3, gl.FLOAT, false, bufferdata.BYTES_PER_ELEMENT * 5, bufferdata.BYTES_PER_ELEMENT * 2)
}
function createProgram() {
program = gl.createProgram() // create shader program
const vertex = createShader(gl.VERTEX_SHADER, VERT_SRC) // create vertex shader
const frag = createShader(gl.FRAGMENT_SHADER, FRAG_SRC) // create fragment shader
gl.attachShader(program, vertex) // attach vertex shader to program
gl.attachShader(program, frag) // attach fragment shader to program
const a_position = 0
const a_color = 1
gl.bindAttribLocation(program, a_position, 'position') // bind attribute index to shader program , (shaderProgram, attributeIndex, attributeName)
gl.bindAttribLocation(program, a_color, 'a_color') // bind attribute index to shader program , (shaderProgram, attributeIndex, attributeName)
gl.linkProgram(program) // link the shader program to gl context
}
function createShader(type, source) {
const shader = gl.createShader(type) // create the shader type
gl.shaderSource(shader, source) // set the shader from source
gl.compileShader(shader) // compiele the shader
return shader
}
function createDomElement() {
const canvas = document.createElement('canvas')
canvas.width = window.innerWidth
canvas.height = window.innerHeight
document.body.appendChild(canvas)
gl = canvas.getContext('webgl')
}
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>webgl point</title>
<link rel="stylesheet" href="">
<style>
body {
margin: 0px;
padding: 0px;
}
* {
box-sizing: border-box;
}
canvas {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<script>
const VERT_SRC = `
precision mediump float;
void main() {
gl_Position = vec4(0.0, 0.0, 0, 1);
gl_PointSize = 100.0;
}
`
const FRAG_SRC = `
precision mediump float;
void main() {
gl_FragColor = vec4(1.0,1.0,1.0, 1);
}
`
let gl, program
createDomElement()
createProgram()
draw()
function draw() {
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight)
gl.clearColor(1, 0, 0, 1)
gl.clear(gl.COLOR_BUFFER_BIT)
gl.useProgram(program)
gl.drawArrays(gl.POINTS, 0, 3);
requestAnimationFrame(draw)
}
function createProgram() {
program = gl.createProgram()
const vertex = createShader(gl.VERTEX_SHADER, VERT_SRC)
const frag = createShader(gl.FRAGMENT_SHADER, FRAG_SRC)
gl.attachShader(program, vertex)
gl.attachShader(program, frag)
gl.linkProgram(program)
}
function createShader(type, source) {
const shader = gl.createShader(type)
gl.shaderSource(shader, source)
gl.compileShader(shader)
return shader
}
function createDomElement() {
const canvas = document.createElement('canvas')
canvas.width = window.innerWidth
canvas.height = window.innerHeight
document.body.appendChild(canvas)
gl = canvas.getContext('webgl')
}
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>webgl point</title>
<link rel="stylesheet" href="">
<style>
body {
margin: 0px;
padding: 0px;
}
* {
box-sizing: border-box;
}
canvas {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<script>
const VERT_SRC = `
precision mediump float;
attribute vec2 position;
varying vec4 v_color;
void main() {
gl_Position = vec4(position, 0, 1);
gl_PointSize = 50.0; // set the shader point sizze
v_color = gl_Position * 0.5 + 0.5; // maping -1,1 to 0,1
// v_color = gl_Position;
}
`
const FRAG_SRC = `
precision mediump float;
varying vec4 v_color;
void main() {
gl_FragColor = vec4(vec3(v_color), 1.0);
}
`
let gl, program
const POINT_BUFFER = [
-1, 1, // left, up
0, 1, // mid, up
1, 1, // right, up
-1, 0, // left, mid
0, 0, // mid, mid
1, 0, // right, mid
-1, -1, // left, bottom
0, -1, // mid, bottom
1, -1, // right, mid
]
const TRIANGLE_BUFFFER = [
0, 0.5, // top point
-0.5, -0.5, // left point
0.5, -0.5 // right point
]
createDomElement()
createProgram()
draw()
function draw() {
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight) // set the viewer port size
gl.enable(gl.BLEND); // enable blend mode
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); // enable alpha
gl.clearColor(0,0,0,1) // set clear color the background, (r,g,b,a)
gl.clear(gl.COLOR_BUFFER_BIT) // clear the cavnas background
gl.useProgram(program) // set gl to use shader program
createBuffer(TRIANGLE_BUFFFER) // create the triangle buffer
gl.drawArrays(gl.TRIANGLES, 0, 3); // draw triangle, (mode, offset, count)
createBuffer(POINT_BUFFER) // create the point buffer
gl.drawArrays(gl.POINTS, 0, POINT_BUFFER.length / 2); // draw point, (mode, offset, count)
}
function createProgram() {
program = gl.createProgram() // create shader program
const vertex = createShader(gl.VERTEX_SHADER, VERT_SRC) // create vertex shader
const frag = createShader(gl.FRAGMENT_SHADER, FRAG_SRC) // create fragment shader
gl.attachShader(program, vertex) // attach vertex shader to program
gl.attachShader(program, frag) // attach fragment shader to program
gl.bindAttribLocation(program, 0, 'position') // bind attribute index to shader program , (shaderProgram, attributeIndex, attributeName)
gl.linkProgram(program) // link the shader program to gl context
}
function createBuffer(buff) {
const buffer = gl.createBuffer() // create the buffer in gl
gl.bindBuffer(gl.ARRAY_BUFFER, buffer) // bind the buffer created with the buffer type
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(buff), gl.STATIC_DRAW) // set the buffer data
const attributeIndex = 0
gl.enableVertexAttribArray(attributeIndex) // enable the attribute (attributeIndex)
gl.vertexAttribPointer(attributeIndex, 2, gl.FLOAT, false, 0, 0) // set the attribute pointer, (${attributeLocation}, ${size}, ${type}, ${normalized}, ${stride}, ${offset})
}
function createShader(type, source) {
const shader = gl.createShader(type) // create the shader type
gl.shaderSource(shader, source) // set the shader from source
gl.compileShader(shader) // compiele the shader
return shader
}
function createDomElement() {
const canvas = document.createElement('canvas')
canvas.width = window.innerWidth
canvas.height = window.innerHeight
document.body.appendChild(canvas)
gl = canvas.getContext('webgl')
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment