How do I do WebGL/OpenGL with only one matrix being passed into the vertex shader?

How do I do WebGL/OpenGL with only one matrix being passed into the vertex shader?
It clogs the vertex shader with unnecessary detail, but every explanation of matrix-based vertex shading I can find passes three matrices into the vertex shader.

Other urls found in this thread:

opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/
opengl-tutorial.org/
twitter.com/NSFWRedditImage

Bump
I've not been able to find this information anywhere, and asking it in SQT or DPT just attracts answers from those who know even less about the topic than me.

Last time I checked you needed 3 coordinates to specify somethings location in 3d space.

Disclaimer, I don't know what vertex shading or matrices are.

Wow
What a high quality post
Certainly lends your name a lot of reputation

I'm not the one struggling with basic OpenGL concepts for days thinking Sup Forums will help.
:3

if you're talking about mvp matrix, you can obviously compute them in processor and send them to gpu like in many examples on the net. otherwise you have to be more precise to state what you want to do

Can you show me such an example then?
I've only been able to find examples where part of the matrix calculation is done in the vertex shader.

you are struggling with basic opengl though

every single vertex + uniforms are passed to a vertex shader

if you only want one uniform matrix just have only one uniform matrix

Easier said than done.
I'm trying it, and I can't get my clipping plane to work right.

if you're struggling with features as basic as literally mvp = projetion * view * model; for questionable reasons then you should start questioning things

opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/

I've read that before.
It doesn't say anything I don't already know, and can't tell me anything useful because it's written for a library I'm not using.
People don't always program their matrix arithmetic in the same way, which means that if a library is used, I can't know how it translates to my own setup of arithmetic.

Why does literally everyone use the MVP system?
It's so inefficient.

how does a nigger who doesnt know about matrices and vertices (dropped out of HS for web development money) get into webgl?

Libraries will do many things for you.
You don't have to know an ounce of linear algebra, although the basic arithmetic of vector and matrix multiplication is pretty easy to learn.

thanks senpai

Because it's how computer graphics is taught
What do you use instead?

I create a combination of a camera and projection matrix every frame, then a model matrix for every object with is multiplied by the aforementioned matrix.
Similar, but far more efficient.
It works for me, except that I can't figure out how to get my clipping planes to work properly.

Explain the theory behind your method.

...

What did you expect from a tripfag

That said, I moused over his filtered post because of your comment and it was indeed quite hilariously bad

Good job, you've moved matrix multiplication off the dedicated hardware designed for efficient matrix multiplication and into the main rendering thread bottleneck.

Isn't CPU-GPU interaction considered a bottleneck too though?
If I'm moving only one matrix to the GPU per object, rather than three, that's a lot better if there's lots of objects.
Not to mention that overall I'm doing less calculation on the CPU due to some of my calculations being per-frame where others would do them per-object per-frame.

>If I'm moving only one matrix to the GPU per object, rather than three, that's a lot better if there's lots of objects.
Why are you updating the camera and projection matrices for every object?

Passing many uniforms is not really a problem if you just pass them in buffers instead of calling glUniformWhatever 30 times per object. You can also bind your less frequently updated (per-frame) data separately.

Works much better with batching, too --- well, until you run into one of those AMD pipeline stall landmines, anyways.

I'm not.
Everyone else does though.

You can pass a single matrix, just compute the modelview-projection matrix in the CPU.
IF you don't know how to create one, you can use helper functions like gluLookAt.
But you need to actually study computer graphics instead of just glueing code.

I don't think you understand the concept.
Every object has a transformation matrix so it can be transformed from object space to world space then camera space and finally clipped and projected on a 2d plane

Yes, the part of the matrix that is not dependent on the object is calculated per frame then passed into the function that creates the rest of the matrix for the object.

>Everyone else does though.
What makes you think this?

>Passing many uniforms is not really a problem if you just pass them in buffers instead of calling glUniformWhatever 30 times per object. You can also bind your less frequently updated (per-frame) data separately.
I think for something like this (i.e. passing a per-object constant matrix) you'd ideally use a push constant at the beginning of the command buffer in charge of drawing the object?

But yeah, uniform buffers are the way to go. Changing a buffer binding takes the same amount of time no matter whether that buffer contains 1 or 3 matrices.

Where do you multiply that matrix? In the CPU?
The GPU is a monster number cruncher and you should do math there

By that logic you should be passing the translation, rotation, scale, etc. matrices into the vertex shader too.

I've never seen code that is otherwise.

There are no such matrices in real implementations, you create one combining everything you know that right?

That's what I do, but it's not what everyone else does.

So, what exactly do you want then?

matrix multiplication is associative
you normally would do:

out = P * V * M * v
where out = output position, P = projection matrix, V = view matrix, M = model matrix, v = vertex position

which is equivalent to:

oout = (P * V * M) * v = PVM * v
PVM = P * V * M

you just have to compute PVM on the cpu and send it to the shader
if you do something more complex that just drawing triangles you might need the individual matrices, that's why everyone sends all the 3 matrices

First google result for “opengl tutorial”: opengl-tutorial.org/

First tutorial that introduces model, view, projection matrices:
opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/
They upload one matrix per frame

Okay, next?

>Similar, but far more efficient

"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil."

yeah, just ship your JIT-compiled javascript apps using electron and chromium in the background, who cares if a calculator takes 500 MB of disk space and 1 second to load?

Doesn't count, it uses a library and thus translates poorly to raw GL.

If gl_Position.w is nonzero, how do I get clipping planes to behave correctly?

wtf are you doing
show the vertex shader code

var vertexShaderColoured3D = `#version 300 es
precision mediump float;

in vec3 vertexPosition;
in vec3 vertexColour;
uniform mat4 matrix;
out vec3 colour;

void main() {
colour = vertexColour;
vec4 position = matrix * vec4(vertexPosition, 1.0);
gl_Position = vec4(position);
}


And the projection matrix:
projection: function (w, h, n, f, s, p) {
f--;
n--;
return [
2*s/((w+h)/h), 0, 0, 0,
0, 2*s/((w+h)/w), 0, 0,
0, 0, 2/(f-n), p,
0, 0, (f+n)/(n-f), 1
];
},
(n and f being near and far, for the clipping plane)

What do you consider raw GL anyway? Modern GL doesn't really even have matrix operations outside GLSL arithmetic, so of course one should use a library to handle them.
Writing one might be a useful learning experience, but getting everything right can be pretty hard if you don't know exactly what you're doing.

are you sure that projection formula is correct?
also why don't you use a library like glm for the cpu code?

R = P * V * M;

glUniformMatrix4fv(matLocation, false, &R.x.x);

Well, I did write my own code for handling the matrices.
I've carefully verified that it behaves mathematically correctly, many times in many ways out of doubt, and yet it gives different results to matrix code used in many tutorials; which is why I distrust the matrix code used in a tutorial if I can't read it and test it to make sure it behaves as expected and not in some weird way that the programmer of the library believes is more sensible.

>are you sure that projection formula is correct
Yes, as long as gl_Position.w is 1.0.

If not, it looks perfectly fine except that the clipping planes are wrong.

what values do you pass to the function?

>Doesn't count, it uses a library and thus translates poorly to raw GL.
The fuck is wrong with you?!

It literally uses glUniformMatrix4fv, which is a regular OpenGL call

Width, height (of canvas)
Near, far (Clipping of camera)
Scale, perspective (Also from camera, both are 1 for standard 3D)

what values for near and far

>yes, all these well-established matrix math libraries all contain obvious bugs and produce incorrect matrices, clearly only my own code is correct
holy shit; you'll make it far, bud

Ideally, near would be zero or just above zero for a normal-looking camera, and whatever value I put into far would be the distance objects would render up until.
Instead, objects render much further than far, and I have to have near as -10 for it to look normal.

I love snip posting

>Ideally, near would be zero
Think again.

Or just above zero.
I'm aware of the issue of crazy things that happen when an object is rendered at a distance of zero.

0 is not a valid near plane value, it leads to mathematical instability (you cannot project something on a point then put it on a screen)
and a far plane too big can lead to z fighting

it depends on how you place the objects in the world
the near plane should be as high as possible such that no should intersect it or fall between it and the camera position and the far plane should be enough to fit the whole scene

if you use a 24bit depth buffer then the minimum distance between 2 triangles that won't cause z-fighting will be something like dmin = (far - near) / 2^24
if your objects are closer than dmin then the far plane is too far

actually i'm wrong about the dmin, I forgot that the z is exponential, so forget about that part

don't try crazy near and far values like 0.01 and 100000.
1 and 100 should be enough

I know the issues, but I just want to know how to get it so that my near and far are what they are specified as.
It was simple when gl_Position.w was 1, but to fix graphical issues I had to make gl_Position.w equal position.w (where position is matrix*vec4(vertexPosition, 1)

your code works with the matrices separated?
the shader code is correct, something about the matrix must be wrong, i'm 100% sure

I did have the projection matrix separate at one point.
And you claim that the matrix is wrong, but back when my shader said gl_Position = vec4(position.xy/position.z, 1.0) it worked perfectly fine.
Now that I think about it, if gl_Position.xyz is divided by gl_Position.w, and gl_Position.w is in my current code position.w...
How on earth does that even work? I'm dividing x and y by position.w where I used to divide by position.z, yet it still looks mostly the same.

wtf are you saying

>gl_Position = vec4(position.xy/position.z, 1.0)
that's not valid code
first argument is a vec2 and second is a scalar, you cannot create a vec4 from 3 values

Whoops, I mean position.xy/position.z, position.z, 1.0

when computing the projection did you take into account the fat that glsl matrices are column major?

fact*

No, I didn't know that nor do I know what that means, I just transposed it if it didn't work.