So I just got into WebGL graphics a few months ago and I wrote a class to add a filter to any render. The only problem with it was, the framebuffer texture always returns black. I don't know why and it seems like there isn't more than a handful of examples using multiple shaders so it would help a lot if y'all know anything about this.
Here's my code:
export { FXFilter }
import { Shader } from "./shader.js";
class FXFilter {
constructor(gl,vss,fss) {
// Create a texture to render the triangle to
this.texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, this.texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 400, 400, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
// Create a framebuffer and attach the texture
this.framebuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0);
this.quadbuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.quadbuffer);
var x1 = -1;
var x2 = 1;
var y1 = -1;
var y2 = 1;
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array([
x1, y1,
x2, y1,
x1, y2,
x1, y2,
x2, y1,
x2, y2,
]),
gl.STATIC_DRAW);
this.shader = new Shader(vss,fss);
this.shader.setup(gl);
this.resolutionLocation = gl.getUniformLocation(this.shader.program, "resolution");
this.positionAttributeLocation = gl.getAttribLocation(this.shader.program, "position");
gl.enableVertexAttribArray(this.positionAttributeLocation);
}
render(gl) {
gl.useProgram(this.shader.program);
gl.bindTexture(gl.TEXTURE_2D, this.texture);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.uniform2f(this.resolutionLocation, gl.canvas.width, gl.canvas.height);
gl.bindBuffer(gl.ARRAY_BUFFER, this.quadbuffer);
gl.vertexAttribPointer(this.positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
}
I tried to rearrange the order that I bound the buffers but that gave the same result.
Here's my vertex shader:
attribute vec2 position;
void main() {
gl_Position = vec4(position, 0.0, 1.0);
}
Here's my fragment shader:
precision highp float;
uniform sampler2D u_texture;
uniform vec2 resolution;
void main() {
// convert the rectangle from pixels to 0.0 to 1.0
vec2 zeroToOne = gl_FragCoord.xy / resolution;
// convert from 0->1 to 0->2
vec2 zeroToTwo = zeroToOne * 2.0;
// convert from 0->2 to -1->+1 (clipspace)
vec2 clipSpace = zeroToTwo - 1.0;
gl_FragColor = texture2D(u_texture, clipSpace);
}