问题描述
首先,让我谈谈我的目标。 我正在创建另一个像素艺术在线编辑器,并决定只使用WebGL(根本没有Canvas2D)。 我很愚蠢,因为我对这项技术一无所知,但我正在努力! 那么......问题:如何改变唯一一个像素的颜色? 我一直在努力解决另一个“误解”,并用粒子系统找到了这个答案:
我重写了它,使它看起来接近我的情况:
如您所见,在画布上绘制时,有10个像素具有相同的颜色。 这里主要绘制方法:
function mouseMoveEvent(e) {
/*... detect x and y...*/
gl.bindBuffer(gl.ARRAY_BUFFER, particleBuffer);
var data = new Float32Array(2);
data[0] = x;
data[1] = y;
gl.uniform4f(
gl.getUniformLocation(shaderProgram, "color"),
Math.random(),
Math.random(),
Math.random(),
1.0
);
gl.bufferSubData(gl.ARRAY_BUFFER, particleId * particleSize * sizeOfFloat, data);
particleId = (particleId + 1) % vertexBufferSize;
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.POINTS, 0, vertexBufferSize);
}
那么如何将此示例更改为使用唯一颜色绘制的像素?
有些人可能会说:“使用canvas2d!”。 - 不! 我认为未来不是canvas2d。 “所以使用库!”。 - 不,再次! 对于那种“简单”的东西,比如绘制正方形,我不想要包含大型库。
谢谢!
1楼
您需要了解的是,您发布的代码是将变量传递给片段着色器,它没有进行任何绘制。 片段着色器正在进行绘制。
OpenGL是一种在现代图形卡上操纵渲染过程的不同阶段的工具。
它不会尝试将blitting像素的用例覆盖到屏幕缓冲区。
( glDrawPixels
已弃用,在ES 2.0或WebGL中不可用)
但是,有一些方法可以在您的应用程序中使用它。
我推荐两篇来理解先决条件,尽管你应该知道它适用于openGL 3.2和C ++,而不是WebGL和Javascript。 因此,您可以忽略诸如上下文创建,加载纹理的方式以及您不必创建VertexArrays等内容。
WebGL解决方案1:
- 创建一个空纹理。
- 每一帧,在显示此纹理的屏幕上绘制四边形。
-
在鼠标单击时,调用
glTexSubImage2D
修改纹理内的1个像素。
WebGL解决方案2:
-
更改
gl_PointSize
(顶点着色器第8行) - 只画1分
- 不要清除屏幕(javascript第45行)
- 保留webGL屏幕缓冲区(javascript行86或89)
这个解决方案没有修改1个精确的像素,我认为解决方案1是更好的方法
为什么你应该使用Canvas2D:
认为Canvas2D不如WebGL是错误的,一个是螺丝刀,另一个是锤子。 一个非常适合用螺丝固定东西,另一个非常适合用钉子固定东西。
如果要操作3d渲染管道,请使用WebGL,在想要操作光栅图像时使用Canvas2D。
TL; DR:
如果您使用Canvas2D,您可以开始制作您想要的应用程序,并获得良好的性能。 如果要使用WebGL,则应该努力了解渲染管道的各个阶段。
2楼
你的问题的直接答案是gl.uniform4f
是一个全局变量。
所以你实际上是这样做的:
var color = randomColor(); // uniform4f call
for each point:
drawPoint(p.x, p.y,color);
您需要将其更改为:
for each point:
var color = gl.uniform4f(...);
drawPoint(p.x, p.y, color);
但是,我想要注意的是,使用粒子系统进行像素编辑可能不是可行的方法。 想象一下,如果用户反复在同一区域移动会发生什么,那么您将拥有大量冗余数据。 其次,你如何(有效地)支持擦除操作? 还是填写?
最后,我想你想继续使用纹理。 纹理基本上是一个数据数组的奇特名称,但其格式和它可以包含的内容有限制。 但是,GPU可以非常快速地访问它们。 所以你要做的是绘制一个相同尺寸的四边形的四边形,并通过纹理给它单独的像素数据,告诉它要绘制什么。 然后在用户执行操作并重绘时直接操作纹理数据。
包含如何在webgl中实现这一点真的太长了,所以我建议在网上关注一些教程。 webgl最好的一个atm是系列。 我建议从那里开始。