gpt4 book ai didi

javascript - 使用 GL.points 在 WebGL 中绘制单个像素

转载 作者:数据小太阳 更新时间:2023-10-29 05:12:00 27 4
gpt4 key购买 nike

我正在处理 Tavares WebGL tutorial , 并陷入泥泞之中。

我想使用 GL.points 绘制单个像素。我的阵列显然有问题。在 FF 或 Chrome Canary 中查看:

http://codepen.io/anon/pen/EPJVjK

/**
* Creates a program, attaches shaders, links the program.
* @param {WebGLShader[]} shaders. The shaders to attach.
*/
var createGLProgram = function( gl, shaders ) {
var program = gl.createProgram();
for ( var i = 0; i < shaders.length; i += 1 ) {
gl.attachShader( program, shaders[ i ] );
}

gl.linkProgram( program );

// Check the link status
var linked = gl.getProgramParameter( program, gl.LINK_STATUS );
if ( !linked ) {

// Something went wrong with the link
var lastError = gl.getProgramInfoLog( program );
window.console.error( "Error in program linking: " + lastError );

gl.deleteProgram( program );
return null;
}
return program;
};

var myCreateShader = function( gl, shaderScriptText, shaderType ) {

// Create the shader object
var shader = gl.createShader( shaderType );

// Load the shader source
gl.shaderSource( shader, shaderScriptText );

// Compile the shader
gl.compileShader( shader );
return shader;
};

// Get A WebGL context.
var canvas = document.getElementById( "canvas" );

var gl = canvas.getContext( "webgl", { antialias: false } )

var vertexShader = myCreateShader( gl,
`attribute vec2 a_position;

uniform vec2 u_resolution;

void main() {
// convert the rectangle from pixels to 0.0 to 1.0
vec2 zeroToOne = a_position / u_resolution;

// convert from 0 -> 1 to 0 -> 2
vec2 zeroToTwo = zeroToOne * 2.0;

// convert from 0 -> 2 to -1 -> +1 (clipspace)
vec2 clipSpace = zeroToTwo - 1.0;

// Flip 0,0 from bottom left to conventional 2D top left.
gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
}`, gl.VERTEX_SHADER );

var fragmentShader = myCreateShader( gl,
`precision mediump float;

uniform vec4 u_color;

void main() {
gl_FragColor = u_color;
}`, gl.FRAGMENT_SHADER );

var program = createGLProgram( gl, [ vertexShader, fragmentShader ] );
gl.useProgram( program );

// Store color location.
var colorLocation = gl.getUniformLocation( program, "u_color" );

// Look up where the vertex data needs to go.
var positionLocation = gl.getAttribLocation( program, "a_position" );

// Set the resolution.
var resolutionLocation = gl.getUniformLocation( program, "u_resolution");
gl.uniform2f( resolutionLocation, canvas.width, canvas.height);

// Create a buffer.
var buffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, buffer );
gl.enableVertexAttribArray( positionLocation );

// Send the vertex data to the shader program.
gl.vertexAttribPointer( positionLocation, 2, gl.FLOAT, false, 0, 0 );

// Set color to black.
gl.uniform4f( colorLocation, 0, 0, 0, 1);

function drawOneBlackPixel( gl, x, y ) {
// Fills the buffer with a single point?
gl.bufferData( gl.ARRAY_BUFFER, new Float32Array([
x, y,
0, y,
x, 0,
x, 0,
0, y,
0, 0]), gl.STATIC_DRAW );

// Draw one point.
gl.drawArrays( gl.POINTS, 0, 1 );
}


// These tests are supposed to be x,y coordinates from top left.
drawOneBlackPixel( gl, 0, 0 );
drawOneBlackPixel( gl, 1, 1 );
drawOneBlackPixel( gl, 2, 2 );
drawOneBlackPixel( gl, 3, 3 );
drawOneBlackPixel( gl, 4, 4 );
drawOneBlackPixel( gl, 5, 5 );
drawOneBlackPixel( gl, 6, 6 );
drawOneBlackPixel( gl, 7, 7 );
drawOneBlackPixel( gl, 10, 5 );
drawOneBlackPixel( gl, 15, 5 );
drawOneBlackPixel( gl, 20, 5 );
drawOneBlackPixel( gl, 12, 34 );
drawOneBlackPixel( gl, 42, 42 );

问题是像素没有正确渲染。 (0,0) 不在左上角绘制。而应该是像素对 Angular 线的东西却在两个像素 block 中“呈阶梯状”。一个可用的代码笔将是理想的。

作为第二个“奖励”问题,我接下来希望能够在单个 drawArrays 调用(调用 requestAnimationFrame)上批处理多个像素。非常感谢有关如何最好地做到这一点的建议。

附言我读过:

How can I set the color of a pixel on a canvas using WebGL?

但我的错误似乎比这低一些。请不要建议我使用 canvas2D。我想要 webGL 的性能,我正在努力从头开始学习 :)

最佳答案

几件事:

首先,您需要将 gl_PointSize = 1.0; 添加到您的顶点着色器,以告知 webgl 您的 gl.POINT 的大小。

其次,您传入的坐标是每个像素的中心,而不是每个像素的左上角,因此,

function drawOneBlackPixel( gl, x, y ) {
// Fills the buffer with a single point?
gl.bufferData( gl.ARRAY_BUFFER, new Float32Array([
x+0.5, y+0.5]), gl.STATIC_DRAW );

// Draw one point.
gl.drawArrays( gl.POINTS, 0, 1 );
}

就是你想要的。

在这里使用 Codepen:http://codepen.io/anon/pen/pgBjBy .

奖励问题:你需要在这里做的是 gl.buffer 的手动内存管理(gasp)所以你可以做 gl.drawArrays( gl.POINTS, 0, x ) ; 绘制 x 点。例如,如果你想在 (0,0) (1,1), (2,2) 处绘制 3 个点,那么你需要执行 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0.5, 0.5 , 1.5, 1.5, 2.5, 2.5], gl.STATIC_DRAW) 然后是 gl.drawArrays(gl.POINTS, 0, 3);

例如,您可以首先分配一个 Float32Array 并为其分配 4 个点的空间,然后每当您调用 drawOneBlackPixel 时,它都会首先将 Float32Array 设置为 [p1x,p1y,0,0,0,0,0 ,0] 并在下一个 drawOneBlackPixel 上将数组设置为 [p1x,p1y,p2x,p2y,0,0,0,0] 等等。当然,您必须处理其他事情,例如根据需要增长和复制 Float32Array,并在进行更改时将 Float32Array 上传到 GPU。如何处理点的“删除”也是要记住的事情。

关于javascript - 使用 GL.points 在 WebGL 中绘制单个像素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35444202/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com