## 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.
Guard13007
Party member
Posts: 132
Joined: Sat Oct 25, 2014 3:42 am
Location: Internet, USA
Contact:

### How do 3D?

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.

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

### Re: How do 3D?

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).

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

### Re: How do 3D?

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.

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

### Re: How do 3D?

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.

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

### Re: How do 3D?

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?

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

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

### Re: How do 3D?

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...

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

### Re: How do 3D?

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. ^

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

### Re: How do 3D?

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 True 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.

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

### Re: How do 3D?

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).

### Who is online

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