Hi All.
I am currently trying to make a P5 WebGL version of a Diagonal Blades P5 program I made previously. The standard version renders properly (with the biggest blades aligned to the left side) but in the WebGL version it seems to skew the blades at the bottom by an amount of the width of the canvas (leaving half of the rendered canvas black). This is not a homework exercise but I love making graphics and learning new things, but P5 WebGL has got me stumped.
I have the standard p5 version here: Diagonal-Blades by Boleeman -p5.js Web Editor
and the WebGL p5 version here:
The WebGL p5 version has 3 files:
sketch.js:
let bladeShader;
let shaderBuffer;
let bladeMultiplier = 3;
let colorProgress = 0.0;
let isInverted = false;
function preload() {
bladeShader = loadShader('vertex.vert', 'fragment.frag');
}
function setup() {
createCanvas(1024, 1024);
pixelDensity(1);
shaderBuffer = createGraphics(1024, 1024, WEBGL);
shaderBuffer.pixelDensity(1);
shaderBuffer.noStroke();
}
function draw() {
background(0);
shaderBuffer.shader(bladeShader);
bladeShader.setUniform('u_resolution', [1024.0, 1024.0]);
bladeShader.setUniform('u_bladeMultiplier', float(bladeMultiplier));
bladeShader.setUniform('u_colorProgress', colorProgress);
bladeShader.setUniform('u_isInverted', isInverted);
// Build a perfect 2-triangle quad spanning from -1 to 1.
// Triangle One
shaderBuffer.vertex(-1, -1, 0, 0, 0);
shaderBuffer.vertex( 1, -1, 0, 1, 0);
shaderBuffer.vertex(-1, 1, 0, 0, 1);
// Triangle Two
shaderBuffer.vertex( 1, -1, 0, 1, 0);
shaderBuffer.vertex( 1, 1, 0, 1, 1);
shaderBuffer.vertex(-1, 1, 0, 0, 1);
shaderBuffer.endShape();
// Render the WebGL layer on our 2D viewport
image(shaderBuffer, 0, 0);
drawUI();
}
function drawUI() {
fill(0, 150);
noStroke();
rect(10, 10, 310, 68, 5);
fill(255);
textSize(12);
text("Blades Multiplier: " + bladeMultiplier + " (U = More / D = Less)", 20, 28);
text("Spectrum Shift: " + Math.floor(colorProgress * 100) + "% (▲ / ▼ Keys)", 20, 46);
text("Blueprint Mode: " + (isInverted ? "ON" : "OFF") + " (I = Toggle) | S = Save", 20, 64);
}
function keyPressed() {
if (key === 'u' || key === 'U') {
bladeMultiplier++;
} else if (key === 'd' || key === 'D') {
if (bladeMultiplier > 1) {
bladeMultiplier--;
}
}
if (keyCode === UP_ARROW) {
colorProgress = (colorProgress + 0.01) % 1.0;
} else if (keyCode === DOWN_ARROW) {
colorProgress = (colorProgress - 0.01 + 1.0) % 1.0;
}
if (key === 'i' || key === 'I') {
isInverted = !isInverted;
}
if (key === 's' || key === 'S') {
image(shaderBuffer, 0, 0);
let filename = isInverted ? 'neon_blueprint_blades' : 'radial_diagonal_blades';
saveCanvas(filename, 'png');
drawUI();
}
}
vertex.vert:
attribute vec3 aPosition;
attribute vec2 aTexCoord;
varying vec2 vTexCoord;
void main() {
vTexCoord = aTexCoord;
gl_Position = vec4(aPosition, 1.0);
}
and fragment.frag:
precision mediump float;
varying vec2 vTexCoord;
uniform vec2 u_resolution;
uniform float u_bladeMultiplier;
uniform float u_colorProgress;
uniform bool u_isInverted;
#define TWO_PI 6.28318530718
float lerp(float start, float stop, float amt) {
return start + (stop - start) * amt;
}
void main() {
float x = floor(vTexCoord.x * u_resolution.x);
float y = floor((1.0 - vTexCoord.y) * u_resolution.y);
float angle = u_colorProgress * TWO_PI;
float cosA = cos(angle);
float sinA = sin(angle);
float safeY = (y == 0.0) ? 0.001 : y;
float r1 = floor(x / safeY);
float g1 = floor(0.1 * x - y);
float b1 = floor(mod(u_bladeMultiplier * x, safeY));
r1 = clamp(r1, 0.0, 255.0);
g1 = clamp(g1, 0.0, 255.0);
b1 = clamp(b1, 0.0, 255.0);
float gBoost = g1 * 6.0;
if (gBoost > 255.0) gBoost = 255.0;
// Matrix maps
float r = sign(r1) * floor(abs(r1 * (0.299 + 0.701 * cosA + 0.168 * sinA) + gBoost * (0.587 - 0.587 * cosA + 0.330 * sinA) + b1 * (0.114 - 0.114 * cosA - 0.497 * sinA)) + 0.5);
float g = sign(r1) * floor(abs(r1 * (0.299 - 0.299 * cosA - 0.328 * sinA) + gBoost * (0.587 + 0.413 * cosA + 0.035 * sinA) + b1 * (0.114 - 0.114 * cosA + 0.292 * sinA)) + 0.5);
float b = sign(r1) * floor(abs(r1 * (0.299 - 0.300 * cosA + 1.250 * sinA) + gBoost * (0.587 - 0.588 * cosA - 1.050 * sinA) + b1 * (0.114 + 0.886 * cosA - 0.203 * sinA)) + 0.5);
// Horizon Masking
if (x > 400.0 && y < 450.0) {
float xFactor = (x - 400.0) / 624.0;
float yFactor = (450.0 - y) / 450.0;
float horizonMask = pow(xFactor * yFactor, 0.7);
r = lerp(r, 0.0, horizonMask);
g = lerp(g, 0.0, horizonMask);
b = lerp(b, 0.0, horizonMask);
}
r = clamp(r, 0.0, 255.0);
g = clamp(g, 0.0, 255.0);
b = clamp(b, 0.0, 255.0);
if (u_isInverted) {
r = 255.0 - r;
g = 255.0 - g;
b = 255.0 - b;
}
gl_FragColor = vec4(r / 255.0, g / 255.0, b / 255.0, 1.0);
}
Not sure if anyone can work out why/where the skewing is happening in the WebGL shader version? I have tried many approaches to try to fix the problem but nothing seems to work.
The attached png pictures hopefully explain the problem.
P5 WebGL output render:
Standard P5 render:




