首先,让我谈谈我的目标。我正在创建另一个像素艺术在线编辑器,并决定只使用WebGL (根本没有Canvas2D )。我太蠢了,因为我对这项技术一无所知,但我正在努力!所以..。问题是:如何改变唯一一个像素的颜色?我与我的另一个“误解”作了斗争,用粒子系统找到了这个答案:
https://stackoverflow.com/a/16465343/4458277
我重写了它,使它看起来更接近我的情况:
https://jsfiddle.net/kurz/rt2n7hmb/1/
正如你所看到的,当你在画布上画画时,有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。“那就去图书馆吧!”-不,又来了!对于“简单”的东西,如画方块,我不想包括大型图书馆。
谢谢!
发布于 2015-08-09 02:58:31
您需要了解的是,您所发布的代码是将一个变量传递给片段着色器,它没有进行任何绘图。碎片着色器正在绘制。
OpenGL是一种在现代显卡上操纵渲染过程不同阶段的工具。它不试图涵盖闪存像素到屏幕缓冲区的用例。(glDrawPixels
被废弃,在ES2.0或WebGL中不可用)
但是,有一些方法可以在应用程序中使用它。
我推荐这些 2 文章来理解先决条件,尽管您应该知道它是针对openGL 3.2和C++的,而不是WebGL和Javascript。因此,您可以忽略诸如上下文创建、纹理加载的方式以及不需要创建VertexArrays等内容。
WebGL解决方案1:
glTexSubImage2D
修改纹理中的1个像素。WebGL解决方案2:
gl_PointSize
(顶点着色器第8行)这个解决方案没有修改精确的像素,我认为解决方案1是一个更好的方法。
为什么要使用Canvas2D:
认为Canvas2D不如WebGL是一个错误,一个是螺丝刀,另一个是锤子。一种很适合用螺丝附着东西,另一种很适合用钉子附着东西。
当您想要操作3d渲染管道时使用WebGL,当您想要操作光栅图像时使用Canvas2D。
TL;DR:
如果您使用Canvas2D,您可以以良好的性能开始制作您今天想要的应用程序。如果您想要使用WebGL,您应该努力理解呈现管道的各个阶段。
发布于 2015-08-08 05:54:35
您的问题的直接答案是,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中实现这一点实在太长了,所以我建议在web上学习一些教程。webgl最好的自动取款机是webgl基础系列。我建议从那里开始。
https://stackoverflow.com/questions/31892414
复制相似问题