const baseImage = new Image();
baseImage.src = 'https://i.imgur.com/O6aW2Tg.png';
baseImage.crossOrigin = 'anonymous';
baseImage.onload = function() {
render(baseImage);
};
const vertexShaderSource = `#version 300 es
precision mediump float;
in vec2 position;
out vec2 textureCoordinate;
void main() {
textureCoordinate = vec2(1.0 - position.x, 1.0 - position.y);
gl_Position = vec4((1.0 - 2.0 * position), 0, 1);
}`;
const fragmentShaderSource = `#version 300 es
precision mediump float;
precision highp usampler2D;
uniform usampler2D inputTexture;
in vec2 textureCoordinate;
out uvec4 fragColor;
void main() {
fragColor = texture(inputTexture, textureCoordinate);
}`;
function render(image) {
const canvas = document.getElementById('canvas');
const gl = canvas.getContext('webgl2');
if (!gl) {
return;
}
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array([-1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1]),
gl.STATIC_DRAW
);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
const program = webglUtils.createProgramFromSources(gl, [
vertexShaderSource,
fragmentShaderSource,
]);
const positionAttributeLocation = gl.getAttribLocation(
program,
'position'
);
const inputTextureUniformLocation = gl.getUniformLocation(
program,
'inputTexture'
);
const vao = gl.createVertexArray();
gl.bindVertexArray(vao);
gl.enableVertexAttribArray(positionAttributeLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(
positionAttributeLocation,
2,
gl.FLOAT,
false,
0,
0
);
gl.bindVertexArray(null);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
const rawTexture = gl.createTexture();
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, rawTexture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8UI, gl.RGBA_INTEGER, gl.UNSIGNED_BYTE, image);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_BASE_LEVEL, 0);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, 0);
const outputTexture = gl.createTexture();
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, outputTexture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8UI, image.width,
image.height,
0, gl.RGBA_INTEGER, gl.UNSIGNED_BYTE, null);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_BASE_LEVEL, 0);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, 0);
const framebuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D,
outputTexture,
0
);
gl.viewport(0, 0, image.width, image.height);
gl.clearColor(0, 0, 0, 1.0);
// gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.useProgram(program);
gl.uniform1i(inputTextureUniformLocation, 0);
gl.bindVertexArray(vao);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, rawTexture);
gl.drawArrays(gl.TRIANGLES, 0, 6);
gl.bindVertexArray(null);
const pixels = new Uint32Array(4 * image.width * image.height);
gl.readPixels(
0,
0,
image.width,
image.height,
gl.RGBA_INTEGER,
gl.UNSIGNED_INT,
pixels
);
console.log(pixels.slice(0, 40));
}
<canvas id="canvas"></canvas>
<script src="https://webgl2fundamentals.org/webgl/resources/webgl-utils.js"></script>