-
I have a picture in jpg format(9248 × 6936, 36.6MB). At first I tried to display it completely in webgl. const VERTEX_SHADER = `
attribute vec2 a_position;
attribute vec2 a_texCoord;
varying vec2 vTexcoord;
void main() {
gl_Position = vec4(a_position * vec2(1.0,-1.0), 0.0, 1.0);
// pass the texCoord to the fragment shader
// The GPU will interpolate this value between points.
vTexcoord = a_texCoord;
}`
const FRAGMENT_SHADER = `
uniform mediump sampler2D u_sourceTexture;
varying mediump vec2 vTexcoord;
void main() {
gl_FragColor = texture2D(u_sourceTexture, vTexcoord);
}` And set the width and height of the canvas to be the same as the width and height of the picture(9248 × 6936): var canvas = document.querySelector("#canvas");
var gl = canvas.getContext("webgl", {preserveDrawingBuffer: true});
gl.canvas.width = image.width
gl.canvas.height = image.height I used that image directly to create the texture: var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
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_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.FLOAT, image); I set the position (-1.0, -1.0) ~ (1.0, 1.0), and texcoord (0.0, 0.0) to (1.0, 1.0) var positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
-1.0, -1.0,
1.0, -1.0,
-1.0, 1.0,
-1.0, 1.0,
1.0, -1.0,
1.0, 1.0
]), gl.STATIC_DRAW);
var texcoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
0.0, 0.0,
1.0, 0.0,
0.0, 1.0,
0.0, 1.0,
1.0, 0.0,
1.0, 1.0,
]), gl.STATIC_DRAW); If I set the viewport equal to the width and height of the image, only part of the texture will be displayed. gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); Everything looks fine, the image fills the canvas, and the canvas has the same width and height as the image. var canvas = document.querySelector("#canvas");
canvas.toBlob((blob) => {
let a = document.createElement('a')
a.download = 'tmp.jpg'
let s = URL.createObjectURL(blob)
a.href = s
a.click()
URL.revokeObjectURL(s)
}, 'image/jpeg', 0.95) Why does the texture fill up the canvas, but not when it is saved? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
There are 3 limits to the size you can make.
WebGL's spec says if you ask for a size that's too large it will try to allocate a smaller size. You can check the size you got by looking at As for actually displaying an image in WebGL you'll only have 9248x6936x4 (and for a moment maybe x3 since the image has to be decompressed, the copied to the GPU process, then uploaded to GPU memory. (that's 3 copies though 2 are temporary) But, why are trying to load an image larger than the screen? As for generating large screenshots, you can use math to generate smaller screenshots and glue them together. See this |
Beta Was this translation helpful? Give feedback.
There are 3 limits to the size you can make.
gl.getParamater(gl.MAX_TEXTURE_SIZE)