Created
January 5, 2019 20:54
-
-
Save tchayen/9cbe150c6e240557242a280bd835d1af to your computer and use it in GitHub Desktop.
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
const vertex = ` | |
attribute vec2 a_position; | |
attribute vec3 a_barycentric; | |
uniform mat3 u_matrix; | |
varying vec3 vbc; | |
void main() { | |
vbc = a_barycentric; | |
gl_Position = vec4((u_matrix * vec3(a_position, 1)).xy, 0, 1); | |
}` | |
const fragment = ` | |
#extension GL_OES_standard_derivatives : enable | |
precision mediump float; | |
varying vec3 vbc; | |
const float lineWidth = 1.0; | |
const vec3 color = vec3(0.7, 0.7, 0.7); | |
float edgeFactor() { | |
vec3 d = fwidth(vbc); | |
vec3 f = step(d * lineWidth, vbc); | |
return min(min(f.x, f.y), f.z); | |
} | |
void main() { | |
gl_FragColor = vec4(min(vec3(edgeFactor()), color), 1.0); | |
}` | |
const calculateBarycentric = length => { | |
const n = length / 6 | |
const barycentric = [] | |
for (let i = 0; i < n; i++) barycentric.push(1, 0, 0, 0, 1, 0, 0, 0, 1) | |
return new Float32Array(barycentric) | |
} | |
const setup = (gl, program, vertices, barycentric) => { | |
gl.clearColor(0, 0, 0, 0) | |
const positionLocation = gl.getAttribLocation(program, 'a_position') | |
const barycentricLocation = gl.getAttribLocation(program, 'a_barycentric') | |
const matrixLocation = gl.getUniformLocation(program, 'u_matrix') | |
const positionBuffer = gl.createBuffer() | |
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer) | |
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW) | |
const barycentricBuffer = gl.createBuffer() | |
gl.bindBuffer(gl.ARRAY_BUFFER, barycentricBuffer) | |
gl.bufferData(gl.ARRAY_BUFFER, barycentric, gl.STATIC_DRAW) | |
return { | |
positionLocation, | |
positionBuffer, | |
barycentricLocation, | |
barycentricBuffer, | |
matrixLocation, | |
} | |
} | |
const draw = (gl, program, scene) => { | |
resize(gl) | |
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height) | |
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) | |
gl.useProgram(program) | |
gl.enableVertexAttribArray(scene.positionLocation) | |
gl.bindBuffer(gl.ARRAY_BUFFER, scene.positionBuffer) | |
gl.vertexAttribPointer(scene.positionLocation, 2, gl.FLOAT, false, 0, 0) | |
gl.enableVertexAttribArray(scene.barycentricLocation) | |
gl.bindBuffer(gl.ARRAY_BUFFER, scene.barycentricBuffer) | |
gl.vertexAttribPointer(scene.barycentricLocation, 3, gl.FLOAT, false, 0, 0) | |
const width = 345 | |
const height = 210 | |
const projection = [2 / width, 0, 0, 0, -2 / height, 0, -1, 1, 1] | |
gl.uniformMatrix3fv(scene.matrixLocation, false, projection) | |
gl.drawArrays(gl.TRIANGLES, 0, vertices.length / 2) | |
} | |
const vertices = new Float32Array([45, 95, 50, 185, 0, 80, 45, 95, 0, 80, 100, 0, 190, 85, 270, 35, 345, 140, 190, 85, 345, 140, 255, 130, 190, 85, 255, 130, 215, 210, 190, 85, 215, 210, 140, 70, 140, 70, 45, 95, 100, 0, 140, 70, 100, 0, 190, 85]) | |
const barycentric = calculateBarycentric(vertices.length) | |
const canvas = setUpCanvas() | |
const gl = canvas.getContext('webgl') | |
gl.getExtension('OES_standard_derivatives') | |
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertex) | |
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragment) | |
const program = createProgram(gl, vertexShader, fragmentShader) | |
const scene = setup(gl, program, vertices, barycentric) | |
const render = () => draw(gl, program, scene) | |
render() | |
window.addEventListener('resize', render) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment