how do I fill the full canvas with the full webgl shader layer? The canvas is filling the full window width and height, but the webgl shader layer is stuck to the top right quadrant of the screen at 25% of the canvas size
I'm trying to define the width and heigh in terms of the grooveLayer (my shader layer) that is drawing the sand texture to no avail
sketch.js
let grooveLayer, grooveShader, sound, fft;
let pebbles = [];
let patterns = [];
let mode = 0;
let timer = 0;
let drawProgress = 0;
function preload() {
grooveShader = loadShader('default.vert', 'grooveDepth.frag');
//sound = loadSound('../files/oi1.mp3');
}
function setup() {
createCanvas(windowWidth, windowHeight, WEBGL);
initGrooveLayer();
fft = new p5.FFT();
sound.loop();
for (let i = 0; i < 4; i++) {
let px = random(0.2, 0.8);
let py = random(0.2, 0.8);
pebbles.push([px, py]);
}
resetPattern();
}
function draw() {
timer++;
fft.analyze();
let bass = fft.getEnergy('bass');
let treble = fft.getEnergy('treble');
let morph = map(treble, 0, 255, 0, 1);
if (timer % 600 === 0 || bass > 200) resetPattern();
drawProgress += 0.015; // ⏱️ slowly increase drawn angle
grooveLayer.clear();
grooveLayer.background(0);
grooveLayer.push();
grooveLayer.translate(-width/2, -height/2);
grooveLayer.stroke(255);
grooveLayer.strokeWeight(1.2);
for (let p of patterns) {
grooveLayer.beginShape();
for (let a = 0; a < TWO_PI * drawProgress; a += 0.02) {
let r = p.radius + a * p.radiusGrowth * map(bass, 0, 255, 0.5, 2);
let x = width * 0.5 + cos(a + p.offset) * r;
let y = height * 0.5 + sin(a + p.offset + morph) * r;
if (mode === 1) y += sin(a * 3.0 + p.offset) * 30;
if (mode === 2) r += sin(a * 8.0 + p.offset) * 5;
grooveLayer.vertex(x, y);
}
grooveLayer.endShape();
}
grooveLayer.pop();
shader(grooveShader);
grooveShader.setUniform('u_texture', grooveLayer);
grooveShader.setUniform('u_resolution', [grooveLayer.width, grooveLayer.height]);
let normPebs = [];
for (let p of pebbles) normPebs.push(p);
grooveShader.setUniform('u_pebbles', flatten(normPebs));
grooveShader.setUniform('u_pebbleCount', pebbles.length);
noStroke();
rect(-grooveLayer.width / 2, -grooveLayer.height / 2, grooveLayer.width, grooveLayer.height);
}
function resetPattern() {
patterns = [];
let num = int(random(4, 7));
let spacing = random(10, 25);
let growth = random(0.5, 2.5);
for (let i = 0; i < num; i++) {
patterns.push({
radius: i * spacing,
radiusGrowth: growth,
offset: random(TWO_PI)
});
}
mode = (mode + 1) % 3;
timer = 0;
drawProgress = 0; // Reset progress for new pattern
}
function flatten(arr) {
return arr.flat();
}
function initGrooveLayer() {
grooveLayer = createGraphics(windowWidth, windowHeight, WEBGL);
grooveLayer.noFill();
grooveLayer.clear();
}
function windowResized() {
resizeCanvas(grooveLayer.width, grooveLayer.height);
initGrooveLayer();
}
default.vert
// default.vert
attribute vec3 aPosition;
attribute vec2 aTexCoord;
varying vec2 vTexCoord;
void main() {
vTexCoord = aTexCoord;
gl_Position = vec4(aPosition, 1.0);
}
grooveDepth.frag
// grooveDepth.frag
precision mediump float;
uniform sampler2D u_texture;
uniform vec2 u_resolution;
varying vec2 vTexCoord;
void main() {
vec2 texel = 1.0 / u_resolution;
float center = texture2D(u_texture, vTexCoord).r;
float left = texture2D(u_texture, vTexCoord - vec2(texel.x, 0.0)).r;
float right = texture2D(u_texture, vTexCoord + vec2(texel.x, 0.0)).r;
float up = texture2D(u_texture, vTexCoord - vec2(0.0, texel.y)).r;
float down = texture2D(u_texture, vTexCoord + vec2(0.0, texel.y)).r;
vec3 normal = normalize(vec3(left - right, up - down, 1.0));
vec3 lightDir = normalize(vec3(-0.6, -0.6, 1.0));
float diff = max(dot(normal, lightDir), 0.0);
vec3 sand = vec3(0.43, 0.39, 0.33);
vec3 color = sand + diff * 0.2;
gl_FragColor = vec4(color, 1.0);
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Zen Sand Audio Garden</title>
<style>
html, body {
margin: 0;
padding: 0;
overflow: hidden;
background: black;
}
canvas {
display: block;
position: fixed;
top: 0;
left: 0;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/p5@1.4.0/lib/p5.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/p5@1.4.0/lib/addons/p5.sound.min.js"></script>
</head>
<body>
<script src="sketch.js"></script>
</body>
</html>
Create a custom clip-space quad by supplying four vertex(x, y, z, u, v)
points in normalized device coordinates (–1 to +1)
with matching UV (0 to 1)
then close the shape:
// …
noStroke();
beginShape();
vertex(-1, -1, 0, 0, 0);
vertex( 1, -1, 0, 1, 0);
vertex( 1, 1, 0, 1, 1);
vertex(-1, 1, 0, 0, 1);
endShape(CLOSE);
}
// ...