0

I've managed to make a webgl example all in one file with no included libraries, and only functions that are being used: https://jsfiddle.net/vmLab6jr/

I'm drawing a square made of 2 triangles and I'm making it move farther away and closer to the camera. I want to understand how this part works:

// Now move the drawing position a bit to where we want to start
// drawing the square.
mvMatrix = [
    [1,0,0,0],
    [0,1,0,0],
    [0,0,1,-12+Math.sin(g.loops/6)*4],
    [0,0,0,1]
];

var mvUniform = gl.getUniformLocation(g.shaderProgram, "uMVMatrix");
gl.uniformMatrix4fv(mvUniform, false, g.float32(mvMatrix));

Why does webgl want a 4x4 matrix to set the position for drawing an object? Or is there a way to use 1x3, like [x,y,z]? Is it because the shaders I'm using we're arbitrarily set to 4x4? I cannot find information on what uniformMatrix4fv() does and when and why it's used and what the alternatives are. Why does the element [2][3] control the z of the object?

I know it has something to do with the frustum matrix being 4x4. And that same spot in the frustum matrix has D, where var D = -2*zfar*znear/(zfar-znear); But to change the x of the object I'm drawing I need to change [0][3] but that slot in the frustum matrix just has a 0.

function makeFrustum(left, right, bottom, top, znear, zfar)
{
    var X = 2*znear/(right-left);
    var Y = 2*znear/(top-bottom);
    var A = (right+left)/(right-left);
    var B = (top+bottom)/(top-bottom);
    var C = -(zfar+znear)/(zfar-znear);
    var D = -2*zfar*znear/(zfar-znear);

    return [
        [X, 0, A, 0],
        [0, Y, B, 0],
        [0, 0, C, D],
        [0, 0, -1, 0]
    ];
}

I've been using this tutorial: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL

genpfault
  • 51,148
  • 11
  • 85
  • 139
Curtis
  • 2,486
  • 5
  • 40
  • 44

1 Answers1

3

WebGL does not want a 4x4 matrix. WebGL is just a rasterization library

All it cares about is you provide a vertex shader that fills in a special variable called gl_Position with a clip space coordinate and then you also provide a fragment shader that sets the special variable gl_FragColor with a color.

No matrices are required to do that. Any matrices you use are yours, provided by you to code you supply. There are no required matrices in WebGL.

That said if you follow these tutorials they will eventually lead you to how to use matrices and how the frustum function works

There's also this Q&A: Trying to understand the math behind the perspective matrix in WebGL

As for your multiple questions

Why does webgl want a 4x4 matrix to set the position for drawing an object?

It doesn't. The shader you provided does.

Or is there a way to use 1x3, like [x,y,z]?

Yes, provide a shader that uses 1x3 math

Is it because the shaders I'm using we're arbitrarily set to 4x4?

Yes

I cannot find information on what uniformMatrix4fv() does and when and why it's used and what the alternatives are.

WebGL 1.0 is based on OpenGL ES 2.0 and so the WebGL spec basically says "look at the OpenGL ES 2.0 spec". Specifically it says

1.1 Conventions

...

The remaining sections of this document are intended to be read in conjunction with the OpenGL ES 2.0 specification (2.0.25 at the time of this writing, available from the Khronos OpenGL ES API Registry). Unless otherwise specified, the behavior of each method is defined by the OpenGL ES 2.0 specification.

As for uniformMatrix4fv the various uniform functions are used to set global variables you declared inside the shaders you provided. These global variables are called uniforms because they keep a uniform value from iteration to iteration of your shaders. That's in contrast to 2 other kinds of shader inputs. One called attributes which generally pull the next set of values out of buffers during each iteration of your vertex shader. The other type are called varyings which you set in your vertex shader and are interpolated for each iteration of your fragment shader.

Community
  • 1
  • 1
gman
  • 100,619
  • 31
  • 269
  • 393
  • Thanks for the help. While you were typing this I was narrowing it down to the fact that my shader is setting gl_Position which wants to be set to a vec4 (mat4?) and I'm wondering why it's not vec3 and what the 4th dimension is. I will read those tutorials – Curtis Dec 11 '16 at 10:03
  • The 4th dimension is because `gl_Position` is actually a 4 dimensional number. WebGL will take the value you put in and divide by `w` before it uses the value. I don't know why it does this but I do know things work because it does. The effect being that `makeFrustum` lets you pick an arbitrary `zNear` and `zFar` and the matrix will end up converting input vertices so z values at zNear become -1 and z values at zFar become +1. Without the magic "it divides by W" that wouldn't work. Why you aren't required to just to the divide by W yourself in the shader I'm not sure though. – gman Dec 11 '16 at 10:09
  • PS: I asked about it here http://stackoverflow.com/questions/41085117/why-does-gl-divide-gl-position-by-w – gman Dec 11 '16 at 10:40