如何使用 javascript 替换 webGL 画布中的像素

问题描述 投票:0回答:1

我想通过首先获取当前值,然后将其替换为稍微修改的新颜色来更改 webGL 画布的一个像素的颜色。对于 2d 画布上下文,这很容易,但我很快就迷失了尝试对 webGl 画布上下文做同样的事情。

这是我首先尝试读取像素颜色,然后用更改后的颜色将其绘制回来。我更喜欢只获取一个数组,更改一个值,然后将其放回去,而不是绘图,但我也找不到这样做的方法。

var gl = canvas.getContext('webgl');
const out = new Uint8Array(4);
gl.readPixels(98, 122, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, out);
out[0] = 255;
var float32Data = new Float32Array(out)
var vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
gl.bufferData(gl.ARRAY_BUFFER, float32Data, gl.DYNAMIC_DRAW);
gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.POINTS, 0, float32Data.length / 3);
javascript webgl
1个回答
0
投票

如果我理解这里的问题就是一个解决方案。

首先,我在画布上绘制(我使用基本的 WebGL 功能,剪刀)。
然后我再次运行绘图指令,但这次目的地不是画布,这就是最可怕的,帧缓冲区(空),而是带有附加纹理的帧缓冲区。

gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.COLOR_ATTACHMENT0,gl.TEXTURE_2D,copietextureEcran,0) 

现在该纹理包含绘图。

然后我构建一个 WebGL 代码来读取该纹理并在其中一个坐标处绘制一个点。

if (gl_FragCoord.xy==vec2(3.5,3.5)) gl_FragColor=vec4(0,1,0,1);  

const canvas = document.querySelector('canvas');
let width=7;
let height=7;
canvas.width=7;
canvas.height=7;
const gl = canvas.getContext('webgl');

function a() {
  gl.viewport(0, 0, width, height);
  gl.clearColor(1,0,0,1);
  gl.clear(gl.COLOR_BUFFER_BIT);
  gl.enable(gl.SCISSOR_TEST);
  gl.scissor(2, 2, 3, 3);
  gl.clearColor(1, 0, 1, 1);
  gl.clear(gl.COLOR_BUFFER_BIT);
  gl.disable(gl.SCISSOR_TEST);
  
  let copietextureEcran = gl.createTexture();
  gl.activeTexture(gl.TEXTURE0);
  gl.bindTexture(gl.TEXTURE_2D, copietextureEcran);
  gl.texImage2D(
    gl.TEXTURE_2D,
    0,             
    gl.RGBA,
    width,
    height,
    0,
    gl.RGBA,
    gl.UNSIGNED_BYTE,
    null
  );  
  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.NEAREST);  
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);  
  
  let fbEcran = gl.createFramebuffer();  
  gl.bindFramebuffer(gl.FRAMEBUFFER,fbEcran);  gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.COLOR_ATTACHMENT0,gl.TEXTURE_2D,copietextureEcran,0);  
  
  gl.viewport(0, 0, 7, 7);  
  gl.clearColor(1,0,0,1);  
  gl.clear(gl.COLOR_BUFFER_BIT);  
  gl.enable(gl.SCISSOR_TEST);  
  gl.scissor(2, 2, 3, 3);  
  gl.clearColor(1, 0, 1, 1);  
  gl.clear(gl.COLOR_BUFFER_BIT);  
  gl.disable(gl.SCISSOR_TEST);
  
}
a();

function b() {  
  let vs=`  
    attribute vec2 aPosition;  
    varying vec2 vtexCoords;
    
    void main() {
      gl_Position=vec4(aPosition,0,1);
      vtexCoords = (aPosition+1.0)/2.0;
    }
  `;
  let fs=`  
    precision highp float;
    
    uniform sampler2D copietextureEcran;
    varying vec2 vtexCoords;
    
    void main() {
      vec4 color = texture2D(copietextureEcran,vtexCoords);
      gl_FragColor = vec4(color);  
      if (gl_FragCoord.xy==vec2(3.5,3.5)) gl_FragColor=vec4(0,1,0,1);
    }
  `;
  
  const vertexShader = gl.createShader(gl.VERTEX_SHADER);
  gl.shaderSource(vertexShader,vs);
  gl.compileShader(vertexShader);
  const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
  gl.shaderSource(fragmentShader,fs);
  gl.compileShader(fragmentShader);
  const program = gl.createProgram();
  gl.attachShader(program,vertexShader);
  gl.attachShader(program,fragmentShader);
  gl.linkProgram(program);
  gl.useProgram(program);
  
  let positionAttributeLocation = gl.getAttribLocation(program, "aPosition");
  let 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.enableVertexAttribArray(positionAttributeLocation);
   gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
   
   gl.bindFramebuffer(gl.FRAMEBUFFER,null);
   gl.viewport(0, 0, 7, 7);
   
   gl.clearColor(0,0,0,1);
   gl.clear(gl.COLOR_BUFFER_BIT);
   
   gl.drawArrays(gl.TRIANGLES, 0, 6);

}
canvas {
  width: 100x;
  height: 100px;
  image-rendering: pixelated;
 }
<canvas id="canvas"></canvas>
<button onclick="b()">Click me</button>

© www.soinside.com 2019 - 2024. All rights reserved.