Compare commits

..

7 commits

5 changed files with 96 additions and 100 deletions

View file

@ -1,8 +1,11 @@
.gl-canvas-bg {
display:block;
width: 100vw;
height: 100vh;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: -1;
}

View file

@ -1,4 +1,7 @@
function drawScene(gl, programInfo, buffers, time) {
// Tell WebGL how to convert from clip space to pixels
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clearColor(0.0, 0.0, 0.0, 1.0); // Clear to black, fully opaque
gl.clearDepth(1.0); // Clear everything
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
@ -21,8 +24,8 @@ function drawScene(gl, programInfo, buffers, time) {
// Viewport resolution in pixels
gl.uniform2f(
programInfo.uniformLocations.resolution,
gl.drawingBufferWidth,
gl.drawingBufferHeight,
gl.canvas.width,
gl.canvas.height,
);
{

View file

@ -3,10 +3,6 @@ import { drawScene } from "./draw-scene.js";
main();
/* XXX: TODO: Avoid using alerts! Check return values instead,
* XXX: TODO: or create/use a Result like object.
*/
// Initialize a shader program, so WebGL knows how to draw our data
function initShaderProgram(gl, vsSource, fsSource) {
const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
@ -43,73 +39,14 @@ function loadShader(gl, type, source) {
// See if it compiled successfully
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(
`An error occurred compiling the shaders: ${gl.getShaderInfoLog(shader)}`,
);
gl.deleteShader(shader);
return null;
throw new Error(`An error occurred compiling the shaders: ${gl.getShaderInfoLog(shader)}`);
}
return shader;
}
function main() {
const canvas = document.querySelector("#gl-canvas");
// Initialize the GL context
const gl = canvas.getContext("webgl");
// Only continue if WebGL is available and working
if (gl === null) {
alert(
"Unable to initialize WebGL. Your browser or machine may not support it.",
);
return;
}
// Vertex shader program
const vsSource = `
attribute vec4 aVertexPosition;
void main() {
gl_Position = aVertexPosition;
}
`;
// const fsSource = `
// // is highp wasteful for this shader?
// #ifdef GL_FRAGMENT_PRECISION_HIGH
// precision highp float;
// #else
// precision mediump float;
// #endif
// // shadertoy-like parameters
// // uniform vec2 uResolution;
// uniform float uTime;
// void main() {
// vec2 uv = gl_FragCoord.xy/vec2(300, 300).xy;
// // Time varying pixel color
// vec3 col = 0.5 + 0.5*cos(uTime+uv.xyx+vec3(0,2,4));
// // Output to screen
// gl_FragColor = vec4(col,1.0);
// // gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
// }
// `;
const fsSource = (async () => {
const res = await fetch("../shaders/segfault.glsl");
if (!res.ok) {
const error = `Failed to load fragment shader source ${url}: ${res.status}`;
alert(error);
throw new Error(error);
}
return await res.text()
})();
function renderShader(gl, vsSource, fsSource) {
const shaderProgram = initShaderProgram(gl, vsSource, fsSource);
// Collect all the info needed to use the shader program.
@ -121,8 +58,8 @@ function main() {
vertexPosition: gl.getAttribLocation(shaderProgram, "aVertexPosition"),
},
uniformLocations: {
resolution: context.getUniformLocation(program, "uResolution"),
time: gl.getUniformLocation(shaderProgram, "uTime"),
resolution: gl.getUniformLocation(shaderProgram, "u_resolution"),
time: gl.getUniformLocation(shaderProgram, "u_time"),
},
};
@ -145,5 +82,47 @@ function main() {
requestAnimationFrame(render);
}
requestAnimationFrame(render);
// XXX: TODO: read this guide it's great! https://stackoverflow.com/questions/56998225/why-is-rendering-blurred-in-webgl
// window.addEventListener('resize', render);
}
function fetchShader(name) {
return fetch(`../shaders/${name}`)
.then(res => {
if (!res.ok) throw new Error(`Failed to load fragment shader source ${url}: ${res.status}`);
return res.text();
});
}
function main() {
const canvas = document.querySelector("#gl-canvas");
// Initialize the GL context
const gl = canvas.getContext("webgl");
// XXX: TODO: use `window.addEventListener('resize', ...);`
canvas.setAttribute('width', window.innerWidth);
canvas.setAttribute('height', window.innerHeight);
// Only continue if WebGL is available and working
if (gl === null) {
throw new Error("Unable to initialize WebGL. Your browser or machine may not support it.");
}
// Vertex shader program
const vsSource = `
attribute vec4 aVertexPosition;
void main() {
gl_Position = aVertexPosition;
}
`;
// Fetch fragment shader program
fetchShader("segfault.glsl")
.then(fsSource => {
renderShader(gl, vsSource, fsSource);
});
}

View file

@ -4,16 +4,20 @@
* View this shader on shadertoy: https://www.shadertoy.com/view/t3tSRj#
*/
#ifdef GL_ES
precision highp float;
// is highp wasteful for this shader?
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
uniform float uTime;
uniform vec2 uResolution;
uniform float u_time;
uniform vec2 u_resolution;
/* ==== Text Colouring ==== */
#define PHOSPHOR_COL vec4(1, 1., 1., 1.)
#define BG_COL vec4(0.2, 0.0, 0.2, 0.)
// #define BG_COL vec4(0.2, 0.0, 0.2, 0.5)
#define BG_COL vec4(0.0, 0.0, 0.0, 1.)
/* ======= Text Size ======= */
#define FONT_SIZE vec2(10.,20.)
#define ROWCOLS vec2(80., 24.)
@ -151,9 +155,9 @@ float roundLine(vec2 p, vec2 a, vec2 b) {
b -= a + vec2(1.0,0.);
p -= a;
float f = length(p-clamp(dot(p,b)/dot(b,b),0.0,1.0)*b);
if (uResolution.y < 320.) // attempt to get rid of aliasing on small resolution
if (u_resolution.y < 320.) // attempt to get rid of aliasing on small resolution
return smoothstep(1.0, 0.9, f);
else if (uResolution.y < 720.)
else if (u_resolution.y < 720.)
return smoothstep(0.75, 0.5, f);
else
return smoothstep(1., 0., f);
@ -301,7 +305,7 @@ float vt220Font(vec2 p, float c) {
// https://www.shadertoy.com/view/MsdGWn
//
float textLines(vec2 uvG) {
float wt = 5. * (uTime + 0.5*sin(uTime*1.4) + 0.2*sin(uTime*2.9)); // wobbly time
float wt = 5. * (u_time + 0.5*sin(u_time*1.4) + 0.2*sin(u_time*2.9)); // wobbly time
vec2 uvGt = uvG + vec2(0., floor(wt));
float ll = rand(vec2(uvGt.y, - 1.)) * ROWCOLS.x; // line length
@ -346,33 +350,22 @@ float smokeNoise(vec3 v) {
return fbm5(v) / 2. + 0.5;
}
// ===================================================================
// Graphical Styling / Effects
//
float bloom(vec2 uv2) {
// TODO
c += (textureLod(iChannel0, uvC, 3.) +
textureLod(iChannel0, uvC, 4.) +
textureLod(iChannel0, uvC, 5.))
* smoothstep(0., -SMOOTH*20., stdRS(uvC, -0.02)) * 0.5;
}
void main() {
vec2 uv = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y);
vec2 uvT = ROWCOLS * FONT_SIZE * uv / uResolution.xy;
vec2 uvG = floor(ROWCOLS * uv / uResolution.xy);
vec2 uvC = gl_FragCoord.xy / uResolution;
vec2 uv = vec2(gl_FragCoord.x, u_resolution.y - gl_FragCoord.y);
vec2 uvT = ROWCOLS * FONT_SIZE * uv / u_resolution.xy;
vec2 uvG = floor(ROWCOLS * uv / u_resolution.xy);
vec2 uvC = gl_FragCoord.xy / u_resolution.xy;
vec2 uvNoise = uvC;
vec2 uvNoise = gl_FragCoord.xy / u_resolution.xy;
uvNoise = ceil(uvNoise * ROWCOLS) / ROWCOLS;
float val;
if (uTime < 2.0)
if (u_time < 2.0)
val = textLines(uvG);
else if (uTime < 2.3)
val = rand(uvG * uTime) * 17.;
else if (u_time < 2.3)
val = rand(uvG * u_time) * 17.;
else {
float noise = smokeNoise(vec3(uvNoise * noiseScale, uTime * noiseTimeScale));
float noise = smokeNoise(vec3(uvNoise * noiseScale, u_time * noiseTimeScale));
// Noise is fed through a sigmoid function, then quantised to integer range 0-17
val = (exp(noise) / 2.71828); // increase contrast (normalised 0.0 - 1.0)
val = 1.0 / val;
@ -381,6 +374,6 @@ void main() {
val = pow(18.0, val) - 1.0; // TODO: try changing 18.0 to 200.0 and you'll notice some pretty changes :)
}
gl_FragColor = vt220Font(uvT - uvG * FONT_SIZE, val) * PHOSPHOR_COL + BG_COL;
gl_FragColor = vt220Font(uvT - uvG * FONT_SIZE, val) * PHOSPHOR_COL + BG_COL;
}

18
www/shaders/trivial.glsl Normal file
View file

@ -0,0 +1,18 @@
// is highp wasteful for this shader?
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
uniform float u_time;
uniform vec2 u_resolution;
void main() {
vec2 uv = gl_FragCoord.xy / u_resolution;
vec3 col = 0.5 + 0.5 * cos(u_time + uv.xyx + vec3(0, 2, 4));
gl_FragColor = vec4(col,1.0);
}