@Open sauce
meh =/ at least not for now
@Jasoco
Monkeyman! I know him. Smart fellow, that one. He always overcomplicates his code, though. =P Like, something that can be done in 5 lines, he does in 20, with all sorts of weird algorithms that don't fit very well with Lua. Maybe he's too used to other languages, I don't know.
Either way, as for texturing, I did indeed whip up some simple math. Although I used the 3D coordinates. It just seemed simpler, and I'm using the 3D coordinates for other things anyway, like shading and the zbuffer. So... First off, I do everything with triangles. They're just a lot easier to work with, and even if you do stuff with quads you will basically just end up doing the same thing twice anyway.
Now, I assume you know about UV coordinates... It's basically just the 2D coordinates for each pixel, but on the polygon. And the way I set up my shader is I have my triangle with 3D vertices a, b, c and its normal n. I also have the intersection (p) for the current pixel, which is basically just the 3D position of the pixel (which lies inside the triangle). So, for the sake of visualizing this, imagine a = down left, b = up, c = down right.
ab = b - a
ac = c - a
This means that a + ab = b, and a + ac = c. So what we assume with the UV coordinates, is this:
a + ac*u + ab*v = p
Both the lines ab and ac have normals of their own, perpendicular to the normal of the triangle. These are equal to:
ab_n = cross(n, ab)
ac_n = cross(n, ac)
The points (a + ac*u) and p both lie on the same plane, ab_n. Similarily, the points (a + ab*v) and p both line on the same plane, ac_n. We also know that for a plane where v is a point on the plane and n is its normal, the point p lies somewhere on the plane if and only if (p - v) dot n = 0. So we plug that in for u first:
dot((a + ac*u) - p, ab_n) = 0
dot(a + ac*u - p, ab_n) = 0
dot(a, ab_n) + u*dot(ac, ab_n) - dot(p, ab_n) = 0
u*dot(ac, ab_n) = dot(p, ab_n) - dot(a, ab_n)
u*dot(ac, ab_n) = dot(p - a, ab_n)
u = dot(p - a, ab_n) / dot(ac, ab_n)
Do the same for v, and we get:
v = dot(p - a, ac_n) / dot(ab, ac_n)
Then to apply that to a texture, you just do the same as I did earlier:
a + ac*u + ab*v
Only with texture coordinates instead:
at + (ct - at)*u + (bt - at)*v
So... In actual GLSL code, that would be: (assuming we already have a,b,c, at,bt,ct, n, p, ab,ac, textureMap)
Code: Select all
vec3 ab_n = cross(n, ab);
vec3 ac_n = cross(n, ac);
float u = dot(pos - a, ab_n) / dot(ac, ab_n);
float v = dot(pos - a, ac_n) / dot(ab, ac_n);
vec2 texCoord = at + (ct - at)*u + (bt - at)*v;
vec4 texColor = texture2D(textureMap, texCoord);
This might not be the proper way to do it, but I didn't find any proper way to do it online, so I just came up with this. It does seem to work, and it's also rather fast, so I'm good with that. =) One thing to note is that this is not only for texture mapping. Once you have the UV coordinates, you can do stuff like normal mapping and color interpolation as well, as I showed earlier.
I took the liberty of making a picture: (not sure if it's gonna be understandable, but oh well xD)
(this turned out quite fancy-looking, it looked simpler in my head)
One thing I would like to point out is that you should send all the stuff to the shader with one call. I've noticed that if there's anything that drastically reduces performance, it's shader:send. What I do is send all the vectors as an array. I even use 3D vectors for my 2D texture coordinates just so I don't have to send a separate vec2 array, because it really takes up a lot of time. So all you should be sending is the texture map + an array of all your vectors. Then you just unfold that array in the shader. By doing this you will probably see your fps double.
On a different note... I have been experimenting with multiple rigid bodies, and them colliding together. I found that it is a complete bitch, because there are so many things that go wrong, including: sliding, jittering, sinking, bouncing, so many things. Not to mention the actual collision checking. Anyway, I made this scene of 20 objects, 10 cubes, 10 tetrahedrons. It's running only 1 iteration per frame, and also uses some extra weird magic to make tetrahedron collisions work, which basically means I can't stack 'em, as they will just slide/sink/bounce off if I have like 3 of 'em stacked. But it makes for a nice little "pool" of objects, that I can just move around, and they all propagate the force, meaning if one hits another, it gets pushed, and it can continue to push others, in a chain like fashion, you know. Anyway, here's a pic, but I imagine I'll get a video up later on: (all of these objects are doing physics stuff with the static scene, as well as all the other objects)
Lastly, I would like to point out that the other video I made (
https://www.youtube.com/watch?v=_1OhoPTLaIc), the one with the reflections, it does not use a shader at all. It doesn't even use canvases. =P
Follow the potato. Achieve enlightenment.