How do 3D?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
Guard13007
Party member
Posts: 132
Joined: Sat Oct 25, 2014 3:42 am
Location: Internet, USA
Contact:

How do 3D?

Post by Guard13007 » Mon May 07, 2018 6:20 pm

After 11.0 was announced, I thought docs would pop up on the wiki pretty quickly explaining how to do 3D stuff, but it seems that either the way it works is via tricks I am completely unfamiliar with, or it's just not documented yet.

Can anyone ELI5 for me? I have very little knowledge within 3D. I'm okay with 2D, but I don't know how to even begin with 3D.

User avatar
pgimeno
Party member
Posts: 2484
Joined: Sun Oct 18, 2015 2:58 pm

Re: How do 3D?

Post by pgimeno » Mon May 07, 2018 8:31 pm

That topic was discussed in another thread, starting here: viewtopic.php?p=218844#p218844

If you keep reading, I posted a couple demos there, the second of which is a pretty simple 3D projection library (too simple to be usable for doing actual 3D though, but hopefully usable as a learning tool for understanding the concepts).

User avatar
Guard13007
Party member
Posts: 132
Joined: Sat Oct 25, 2014 3:42 am
Location: Internet, USA
Contact:

Re: How do 3D?

Post by Guard13007 » Tue May 08, 2018 1:06 am

I saw that thread, but didn't glean much from it. I can look for the demos posted there and examine source, but I was hoping there was a resource that attempted to explain things without me having to reverse engineer code.

User avatar
pgimeno
Party member
Posts: 2484
Joined: Sun Oct 18, 2015 2:58 pm

Re: How do 3D?

Post by pgimeno » Tue May 08, 2018 1:56 am

Well, the gist of it is to create a mesh (or more, depending on how many textures you need) that has full 3D data, then a vertex shader that accepts an extern (uniform) matrix rather than using LÖVE's built-in one. You build the matrix, pass it to the shader, and draw the mesh. How to build the matrix is a bit tricky, but it's the same for every OpenGL application so there's plenty of info online.

For doing things properly, you also need to enable backface culling and a depth buffer, which are the new features that LÖVE 11.0 adds to allow working with 3D, but I haven't tried to do that yet.

User avatar
Guard13007
Party member
Posts: 132
Joined: Sat Oct 25, 2014 3:42 am
Location: Internet, USA
Contact:

Re: How do 3D?

Post by Guard13007 » Tue May 08, 2018 3:59 am

So a lot of what I have to do to get it to work is hands-on in-depth, not very much abstraction or simplification provided by Love?

Because I don't know how to do ANY of that. o.o

KayleMaster
Party member
Posts: 223
Joined: Mon Aug 29, 2016 8:51 am

Re: How do 3D?

Post by KayleMaster » Tue May 08, 2018 6:13 am

Unfortunately it seems that's the case. (I'm in your same position)

User avatar
ivan
Party member
Posts: 1703
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: How do 3D?

Post by ivan » Tue May 08, 2018 7:00 am

A good introduction to the math involved with 3D is to start out with points or vertices then figure out how to rotate them along X,Y and Z.
Guard13007 wrote:
Tue May 08, 2018 3:59 am
So a lot of what I have to do to get it to work is hands-on in-depth, not very much abstraction or simplification provided by Love?
Well, it is called Love2D for a reason...

User avatar
pgimeno
Party member
Posts: 2484
Joined: Sun Oct 18, 2015 2:58 pm

Re: How do 3D?

Post by pgimeno » Tue May 08, 2018 10:04 am

Guard13007 wrote:
Tue May 08, 2018 3:59 am
So a lot of what I have to do to get it to work is hands-on in-depth, not very much abstraction or simplification provided by Love?
That's right.

Love3D is a library aimed mainly at enabling depth buffers and backface culling, through calling OpenGL functions via FFI. It's all it does to get basic 3D working, really; the rest is done with the methods I've mentioned. The inclusion in the core of depth buffers and backface culling, obviates the need for Love3D, and it's the kind of support LÖVE 11.0 adds for 3D.

For more information, I think that looking at the example of love3d or of my lib is your best bet. Love3d loads the mesh through the iqm library, which will probably be harder to follow than my code.

But OK, here's how to create a mesh with 3D data (schematic), basically copied from my example:

Code: Select all

-- Maximum number of vertices - preferably a multiple of 4
-- if you're going to draw rectangles.
local vmax = 3000

-- Attribute types.
-- Three components for the position are what gives us 3D.
-- Two components for the texture UV is the usual.
local atypes = {
  {"VertexPosition", "float", 3},
  {"VertexTexCoord", "float", 2},
}

-- Create the mesh. Note we use "triangles" because that way
-- we can separate them.
local mesh = love.graphics.newMesh(atypes, vmax, "triangles", "dynamic")

-- Send the vertices to the mesh. If you want to draw quads,
-- you also need setVertexMap.
mesh:setVertex(1, x1, y1, z1, u1, v1)
mesh:setVertex(2, x2, y2, z2, u2, v2)
mesh:setVertex(3, x3, y3, z3, u3, v3)
mesh:setVertex(4, x4, y4, z4, u4, v4)

-- The first triangle is made by vertices 1, 2 and 3
-- The second triangle is made by vertices 3, 2 and 4.
-- That gives us a rectangle.
local vmap = {1,2,3, 3,2,4}
mesh:setVertexMap(vmap)

-- Only draw the first 6 vertices in the vertex map in this example.
mesh:setDrawRange(1, 6)
Now the shader. It's basically the same as the default given in love.graphics.newShader but with an extern matrix:

Code: Select all

local shader = love.graphics.newShader[[
    extern mat4 proj;
    vec4 position(mat4 transform, vec4 vertex)
    {
      // ignore love2d's matrix and use our own
      return proj * vertex;
    }
]]
love.graphics.setShader(shader)
Now you need a math library capable of handling the 3D projection matrices. I only know cpml, so that's the only one I can recommend. Build the matrix, send it to the shader, and draw the mesh. Strictly speaking, you don't always need a math library for certain use cases; my example doesn't use one, it just adds a 4x4 matrix multiplication function.

All of the above could be done in 0.10. As I said, I haven't used depth buffers or backface culling yet, so no idea how to enable them.
ivan wrote:
Tue May 08, 2018 7:00 am
Well, it is called Love2D for a reason...
That. ^

User avatar
zorg
Party member
Posts: 3058
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: How do 3D?

Post by zorg » Wed Nov 14, 2018 3:18 pm

pgimeno wrote:
Tue May 08, 2018 10:04 am
All of the above could be done in 0.10. As I said, I haven't used depth buffers or backface culling yet, so no idea how to enable them.
Sorry for the somewhat-necroing, but since you referred to this post in another thread, i thought i expand on these two "missing pieces";

For depth buffers, love.graphics.newCanvas would be used with parameters similar to these:

Code: Select all

canvas = love.graphics.newCanvas(width, height, {type = "2d", format = "depth32f", readable = true})
I'm not sure either whether one wants readable to be true or not, but i'm sure someone will correct me eventually.

For backface culling, love.graphics.setMeshCullMode would be used.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.

User avatar
pgimeno
Party member
Posts: 2484
Joined: Sun Oct 18, 2015 2:58 pm

Re: How do 3D?

Post by pgimeno » Wed Nov 14, 2018 9:15 pm

zorg wrote:
Wed Nov 14, 2018 3:18 pm
For depth buffers, love.graphics.newCanvas would be used with parameters similar to these:

Code: Select all

canvas = love.graphics.newCanvas(width, height, {type = "2d", format = "depth32f", readable = true})
I'm not sure either whether one wants readable to be true or not, but i'm sure someone will correct me eventually.
That creates it, but you still need to tell LÖVE to use it, via love.graphics.setCanvas{depthstencil = canvas} (note the use of curly braces).

Alternatively, you don't need to create and set a canvas: just set t.window.depth in love.conf (or the depth parameter in love.graphics.setMode) to something sensible like 32, and then you can use love.graphics.setDepthMode("less", true).

Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 57 guests