繁体   English   中英

如何在 webgl 上使用 `gl.POINTS` 绘制单个像素?

[英]How to draw a single pixel using `gl.POINTS` on webgl?

我正在尝试使用 WebGL 绘制单个像素。 我正在使用gl_PointSize = 1.0gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0) 我预计单个黑色像素。 然而,这就是我的观点的呈现方式:

在此处输入图片说明

也就是说,我得到的是覆盖大约 3x3 区域的灰点。 我如何获得实际的单个像素?

首先,您的画布尺寸是否与其显示尺寸 1x1 像素相匹配? 如果不是,你会得到拉伸像素。 画布有 2 种尺寸 它们的drawingBuffer 的大小和它们显示的大小。 CSS 设置它们显示的大小。 它们的宽度和高度设置了drawingBuffer 的大小。

GL 中的第二个像素由它们的边缘寻址。 换句话说,假设您有 3x1 像素的画布。 有3个像素

-1,1                              1,1
  +----------+----------+----------+
  |          |          |          |
  |          |          |          |
  |          |          |          |
  |          |          |          |
  +----------+----------+----------+
-1,-1                             1,-1

要绘制第一个像素,您需要给出其中心点。 在上图中,第一个像素的中心点是

      -2/3,0

让我们试试吧。 下面的代码绘制到 3x1 像素的纹理,然后将该纹理绘制到 300x100 的画布上,以便我们可以清楚地看到它

 'use strict'; var vs_point = ` attribute vec4 position; void main() { gl_Position = position; gl_PointSize = 1.0; } `; var fs_point = ` precision mediump float; void main() { gl_FragColor = vec4(0, 0, 0, 1); }`; var vs_tex = ` attribute vec4 position; varying vec2 v_texcoord; void main() { gl_Position = position; v_texcoord = position.xy * 0.5 + 0.5; } `; var fs_tex = ` precision mediump float; uniform sampler2D u_texture; varying vec2 v_texcoord; void main() { gl_FragColor = texture2D(u_texture, v_texcoord); } `; // Let's make a 3x1 texture, render to it // then render it to the canvas with gl.NEAREST var canvas = document.querySelector("canvas"); var gl = canvas.getContext("webgl"); var pointProgramInfo = twgl.createProgramInfo( gl, [vs_point, fs_point]); var texProgramInfo = twgl.createProgramInfo( gl, [vs_tex, fs_tex]); var pointBufferInfo = twgl.createBufferInfoFromArrays(gl, { position: { numComponents: 2, data: [ -2/3, 0 ] }, }); var quadBufferInfo = twgl.primitives.createXYQuadBufferInfo(gl); // make a 3x1 pixel texture and attach to framebuffer var framebufferInfo = twgl.createFramebufferInfo(gl, [ { format: gl.RGBA, mag: gl.NEAREST, min: gl.NEAREST, wrap: gl.CLAMP_TO_EDGE, } ], 3, 1); // draw 1 pixel into texture twgl.bindFramebufferInfo(gl, framebufferInfo); gl.useProgram(pointProgramInfo.program); twgl.setBuffersAndAttributes(gl, pointProgramInfo, pointBufferInfo); twgl.drawBufferInfo(gl, pointBufferInfo, gl.POINTS); // put in a clipspace quad twgl.bindFramebufferInfo(gl, null); gl.useProgram(texProgramInfo.program); twgl.setBuffersAndAttributes(gl, texProgramInfo, quadBufferInfo); twgl.drawBufferInfo(gl, quadBufferInfo, gl.TRIANGLES);
 canvas { border: 1px solid red; }
 <script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script> <canvas width="300" height="100"></canvas>

或者作为另一个例子,让我们在画布上绘制随机像素。

重要的部分是像素的位置是

 clipspaceX = (x + 0.5) / destWidth  * 2 - 1;
 clipspaceY = (y + 0.5) / destHeight * 2 - 1;

 'use strict'; var vs = ` attribute vec4 position; void main() { gl_Position = position; gl_PointSize = 1.0; } `; var fs = ` precision mediump float; uniform vec4 u_color; void main() { gl_FragColor = u_color; }`; var canvas = document.querySelector("canvas"); var gl = canvas.getContext("webgl", {preserveDrawingBuffer: true}); // make canvas 1x1 with display gl.canvas.width = gl.canvas.clientWidth * window.devicePixelRatio; gl.canvas.height = gl.canvas.clientHeight * window.devicePixelRatio; gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); var programInfo = twgl.createProgramInfo(gl, [vs, fs]); var positions = new Float32Array(2000); var bufferInfo = twgl.createBufferInfoFromArrays(gl, { position: { numComponents: 2, data: positions, }, }); gl.useProgram(programInfo.program); twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo); function randInt(max) { return Math.random() * max | 0; } var offset = [0, 0]; var color = [0, 0, 0, 1]; var uniforms = { u_offset: offset, u_color: color, }; function render() { var length = positions.length; for (var i = 0; i < length; i += 2) { var x = randInt(gl.canvas.width); var y = randInt(gl.canvas.height); positions[i + 0] = (x + 0.5) / gl.canvas.width * 2 - 1; positions[i + 1] = (y + 0.5) / gl.canvas.height * 2 - 1; } twgl.setAttribInfoBufferFromArray( gl, bufferInfo.attribs.position, positions); var cndx = randInt(3); color[cndx] = 1; color[(cndx + 1) % 3] = 0; twgl.setUniforms(programInfo, uniforms); twgl.drawBufferInfo(gl, bufferInfo, gl.POINTS); requestAnimationFrame(render); } requestAnimationFrame(render);
 canvas { border: 1px solid black; }
 <script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script> <canvas style="width:300px; height:150px;"></canvas>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM