2

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

webgl shader layer not filling canvas

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/[email protected]/lib/p5.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/addons/p5.sound.min.js"></script>
</head>
<body>
  <script src="sketch.js"></script>
</body>
</html>
1
  • it seems that you render texture directly onto NDC, but textures go 0..1, ndc space is -1..1) Commented May 26 at 5:25

1 Answer 1

1

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);
}
// ...
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.