rendering simple 3d planes (with clipping)

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.
User avatar
pgimeno
Party member
Posts: 3672
Joined: Sun Oct 18, 2015 2:58 pm

Re: rendering simple 3d planes (with clipping)

Post by pgimeno »

mk8 wrote: Sun Apr 03, 2022 5:44 pm sorry about late reply and thanks alot! i know how basic sorting works, so i should be at least able to implement it into your code. the question is, how about performance? would it run with at least a reasonable framerate (~40 FPS) on an average computer? i'm sure mine would handle it, since it's pretty strong, but i have no way to test it out on an average one.
You don't actually need sorting; just enable the depth buffer in love.conf and then use love.graphics.setDepthMode and OpenGL will take care of sorting for you - assuming you don't have half-transparent objects.

The rendering speed depends a lot on the geometry you have. If you go this way you're doing pretty much the same kind of OpenGL that other 3D applications are doing; the main difference, CPU wise, is that it's in Lua. Note that you also need some understanding of OpenGL caveats and optimizations if you want to make it efficient. One way of testing is to disable vsync and check how much faster it runs than one frame time.

mk8 wrote: Mon Apr 04, 2022 5:27 am 1. would

Code: Select all

love.graphics.setDepthMode("lequal", true)
do the sorting, or do i need to mess with the canvas' pixel format or am i completely off with this?
There's no sorting involved per se; setDepthMode just makes the nearest pixel be visible and discards any other pixel behind. I explained it earlier:
The idea is that the [depth buffer] contains the depth of each point; it is initialized to all infinite before rendering anything, because the depth of vacuum is infinite :) Now you start rendering a plane, and for each pixel that the plane touches, you check its depth (normally the Z coordinate of the camera coordinates, which is why it's also called a Z buffer). If it's less than what is already in the buffer, it means it's closer to the camera than what was previously drawn, therefore it's visible and you draw it, and store the new depth in the buffer; otherwise you skip it because it's behind something else.

mk8 wrote: Mon Apr 04, 2022 5:27 am 2. i would obviously like to have more than just 1 texture in the game. would it be faster to create a new 'mesh' of pgimeno's example sort for every texture, or create a single 'mesh' with a spritesheet texture, and set different faces to different uv values to match the desired tile
It depends on how many textures you have. Texture atlases (spritesheets) are always preferred over single textures when possible; just keep in mind that implementations may impose limits on the maximum size of a texture (but IIRC 2048x2048 is guaranteed).

mk8 wrote: Mon Apr 04, 2022 5:27 am 3. how expensive is mesh:setVertex() and mesh:setVertices()? could i call this function for every moving object's face each frame? (there's not gonna be that many moving objects, but each will probably have more than just a few faces)
It's not expensive, but if you just need to change the position or orientation of the object, that's the job for the "model matrix". Typically you have a model placed at (0,0,0) and pointing east, and then you have a matrix that allows changing its position and rotation; you pass it to the shader just before drawing it.

If it's animated (vertices move in relation to each other and not just as a block) then yes, you need to update vertices.

mk8 wrote: Mon Apr 04, 2022 5:27 am 4. and lastly another question about the example code: how many faces would a regular PC be ok with?
That I can't answer. Computers that don't have a graphics card and are limited to software rendering will struggle even with a few triangles. The slowest GPUs typically have more trouble with big images than with the geometry itself. A reasonable cutoff to make it work on old toasters might be a few thousands polygons. If you plan for beefier machines, probably tens or hundreds of thousands.
mk8
Prole
Posts: 35
Joined: Thu Apr 22, 2021 7:11 am

Re: rendering simple 3d planes (with clipping)

Post by mk8 »

thanks!
pgimeno wrote: Thu Apr 07, 2022 12:34 am You don't actually need sorting; just enable the depth buffer in love.conf and then use love.graphics.setDepthMode...
so dumb question, but that means doing t.window.depth=true? wiki says the field determines "the number of bits per sample in the depth buffer", so i just feel this should be a number? (16, 24 and 32 are used in PixelFormat, so should it be one of those?)
pgimeno wrote: Thu Apr 07, 2022 12:34 am It's not expensive, but if you just need to change the position or orientation of the object, that's the job for the "model matrix". Typically you have a model placed at (0,0,0) and pointing east, and then you have a matrix that allows changing its position and rotation; you pass it to the shader just before drawing it.

If it's animated (vertices move in relation to each other and not just as a block) then yes, you need to update vertices.
yeah, i meant exactly animations. but i was also thinking of clearing the vertices every frame and creating new ones, which would basically allow me to do love.draw, except in 3d. reason being, my world is gonna update, possibly quite often (players will be able to place/break things), and i can't think of a good system to store the faces so that i can delete them later when needed (a single item is composed of different faces with different textures), so i'm rather thinking of recreating the faces on every frame and the ones that get deleted just won't be regenerated and will be gone. i'm only going to work with rectangular faces (voxels, basically. i really like voxelart), so complicated calculations are not gonna be needed.
pgimeno wrote: Thu Apr 07, 2022 12:34 am ... - assuming you don't have half-transparent objects.
yeah, that's a shame. i obviously don't need them nor will i implement them myself, but my game was supposed to be user-customizable, meaning they can also change the textures to whatever they want (something like resourcepacks in minecraft). i could implement a filter that makes every opacity 1, but that wouldn't look great. considering all this, i might actually consider doing this in defold, godot or unity... but i'll at least try it with love. thank you for your knowledge
hippity hoppity ur code is my property (thanc in advanc)
User avatar
pgimeno
Party member
Posts: 3672
Joined: Sun Oct 18, 2015 2:58 pm

Re: rendering simple 3d planes (with clipping)

Post by pgimeno »

mk8 wrote: Thu Apr 07, 2022 12:24 pm so dumb question, but that means doing t.window.depth=true? wiki says the field determines "the number of bits per sample in the depth buffer", so i just feel this should be a number? (16, 24 and 32 are used in PixelFormat, so should it be one of those?)
32 means the buffer is made of standard 32-bit single-precision floats as far as I know. 16 and 24 are reduced precision floats. Apparently many applications use 24. OpenGL allows you to decide whether to sacrifice precision in the depth buffer for video memory. The better the precision, the lesser the risk of "Z fighting" when one face is occluding another but they have a little gap between them. Without enough precision, the gap might not be visible to the Z buffer, which will see them as being at the exact same depth, resulting in a characteristic flicker caused by the operations and roundings applied to each of the pixels. Poor precision can also lead to issues of somewhat ragged intersection lines when the intersection between two faces should be straight and clean. But more precision = more video memory used. Keep in mind that the buffer configured via t.window.depth has the dimensions of the Löve window.

mk8 wrote: Thu Apr 07, 2022 12:24 pm yeah, i meant exactly animations. but i was also thinking of clearing the vertices every frame and creating new ones, which would basically allow me to do love.draw, except in 3d. reason being, my world is gonna update, possibly quite often (players will be able to place/break things), and i can't think of a good system to store the faces so that i can delete them later when needed (a single item is composed of different faces with different textures), so i'm rather thinking of recreating the faces on every frame and the ones that get deleted just won't be regenerated and will be gone. i'm only going to work with rectangular faces (voxels, basically. i really like voxelart), so complicated calculations are not gonna be needed.
Löve is very capable of doing voxel games. Just take a look at the demo at viewtopic.php?f=5&t=86350 (at the bottom of the first post)

mk8 wrote: Thu Apr 07, 2022 12:24 pm
pgimeno wrote: Thu Apr 07, 2022 12:34 am ... - assuming you don't have half-transparent objects.
yeah, that's a shame. i obviously don't need them nor will i implement them myself, but my game was supposed to be user-customizable, meaning they can also change the textures to whatever they want (something like resourcepacks in minecraft). i could implement a filter that makes every opacity 1, but that wouldn't look great. considering all this, i might actually consider doing this in defold, godot or unity... but i'll at least try it with love. thank you for your knowledge
I'm not saying half transparent objects are impossible to draw. However, they are a pain for OpenGL in general. It's not about the engine or framework, it's about the way that OpenGL and other rendering systems (Vulkan, Metal, Direct3D, whatever) work. Typically, first you draw everything solid using the depth buffer; then you disable the depth buffer and draw the transparent things in order from back to front. But "from back to front" is not so trivial as it may seem. See http://www.opengl-tutorial.org/intermed ... nsparency/ for more on this. Minetest has had serious issues with transparent object rendering until just last year; you looked at a pool through a window and the pool appeared empty.

There's a solution to the transparency problem if you limit the maximum of half-transparent objects you can have per pixel, which uses as many canvases as that maximum, and a lot of GPU processing time. It basically consists of implementing multiple sorted depth buffers, such that you draw all layers in the correct order in the end. But it's not worth the complexity, really. I can look up the paper if interested.
User avatar
kicknbritt
Citizen
Posts: 98
Joined: Sat May 30, 2015 2:15 am
Location: Chicago, IL/Anchorage,AK

Re: rendering simple 3d planes (with clipping)

Post by kicknbritt »

There are also g3d and 3Dream engine (3Dream is a bit heavier but has really strong rendering abilities). g3d is super, super easy.
Lovr works absolutely fine with desktop. I would recommend using this engine, although your going to need to join the Lovr slack for help.
Actually, I wrote a voxel engine in Love2d and moved it to Lovr.

Word of advice, you really have to tap into luas ffi for the data structures you use to hold the chunks. From what I've seen Luas GC simply
cannot handle chunk mesh recalculation. Even on a lower gc cycle intensity setting it quickly becomes impossible for the garbage collector to handle so much garbage coming out of chunk's mesh loading and unloading. And remember every chunk modification is essentially loading the mesh all over again. I spent months on this issue and my only solutions were either creating mesh data using ffi or instanced block faces (which has a lot of caveats and likely just isn't a great solution)

Also, I tried the same thing with Godot. Aside from https://github.com/Zylann/godot_voxel, if you are not writing the logic in C# in Godot you are going to have a super bad time with gdscript (its horrifically slow).
"I AM THE ARBITER!!!" *Pulls out Energy sword and kills everything*
User avatar
pgimeno
Party member
Posts: 3672
Joined: Sun Oct 18, 2015 2:58 pm

Re: rendering simple 3d planes (with clipping)

Post by pgimeno »

kicknbritt wrote: Fri Apr 08, 2022 9:43 pm Lovr works absolutely fine with desktop. I would recommend using this engine, although your going to need to join the Lovr slack for help.
I gave up with Lovr when I tested the hello world program and didn't work for me. From time to time I check again, but that doesn't seem to ever get fixed.
User avatar
kicknbritt
Citizen
Posts: 98
Joined: Sat May 30, 2015 2:15 am
Location: Chicago, IL/Anchorage,AK

Re: rendering simple 3d planes (with clipping)

Post by kicknbritt »

pgimeno wrote: Sun Apr 10, 2022 12:47 pm
kicknbritt wrote: Fri Apr 08, 2022 9:43 pm Lovr works absolutely fine with desktop. I would recommend using this engine, although your going to need to join the Lovr slack for help.
I gave up with Lovr when I tested the hello world program and didn't work for me. From time to time I check again, but that doesn't seem to ever get fixed.
Actually you know what. Did you try rotating the screen to find the 'hello world' text?
By default, lovr starts in a dual screen mouse control mode thingy.
That would be pretty funny if you only needed to rotate the camera.

Try the attached shadows example I grabbed from the lovr slack. Drag with mouse to look around.
Attachments
shadow test.7z
(858.25 KiB) Downloaded 154 times
"I AM THE ARBITER!!!" *Pulls out Energy sword and kills everything*
User avatar
pgimeno
Party member
Posts: 3672
Joined: Sun Oct 18, 2015 2:58 pm

Re: rendering simple 3d planes (with clipping)

Post by pgimeno »

kicknbritt wrote: Sun Apr 10, 2022 7:35 pm Actually you know what. Did you try rotating the screen to find the 'hello world' text?
By default, lovr starts in a dual screen mouse control mode thingy.
That would be pretty funny if you only needed to rotate the camera.

Try the attached shadows example I grabbed from the lovr slack. Drag with mouse to look around.
Not sure, I'm pretty busy right now but my program was just the hello world from the main page:

Code: Select all

function lovr.draw()
  lovr.graphics.print('hello', 0, 1.7, -1, .5)
end
and it showed nothing right away. If that's actually supposed to happen, then I would suggest changing it to something that works out of the box without having to do anything in order to show it.
User avatar
pgimeno
Party member
Posts: 3672
Joined: Sun Oct 18, 2015 2:58 pm

Re: rendering simple 3d planes (with clipping)

Post by pgimeno »

kicknbritt wrote: Sun Apr 10, 2022 7:35 pm Actually you know what. Did you try rotating the screen to find the 'hello world' text?
By default, lovr starts in a dual screen mouse control mode thingy.
That would be pretty funny if you only needed to rotate the camera.
Tried now. I tried to move the mouse alone, and while clicking left/mid/right, and to move the mouse wheel, to no avail. I only get a black screen.

The no game screen looks like this: http://www.formauri.es/personal/pgimeno ... nogame.png

And importantly, I get a segfault on exit, with this backtrace:

Code: Select all

#0  0x00007ffff35104dc in ?? () from /usr/lib/libnvidia-glcore.so.340.107
#1  0x00007ffff35120b5 in ?? () from /usr/lib/libnvidia-glcore.so.340.107
#2  0x00005555555b26f0 in lovrGpuDestroy () at <lovr_path>/src/modules/graphics/opengl.c:1361
#3  0x00005555555a6df8 in lovrGraphicsDestroy () at <lovr_path>/src/modules/graphics/graphics.c:215
#4  0x000055555557dcb4 in luax_module__gc (L=0x40000378) at <lovr_path>/src/api/api.c:37
#5  0x00007ffff795b937 in lj_BC_FUNCC () at buildvm_x86.dasc:809
#6  0x00007ffff7937938 in gc_call_finalizer (g=g@entry=0x400003b8, L=L@entry=0x40000378, mo=<optimized out>, o=o@entry=0x4000b5f8) at <lovr_path>/deps/luajit/src/lj_gc.c:475
#7  0x00007ffff79379f6 in gc_finalize (L=L@entry=0x40000378) at <lovr_path>/deps/luajit/src/lj_gc.c:521
#8  0x00007ffff7938918 in lj_gc_finalize_udata (L=L@entry=0x40000378) at <lovr_path>/deps/luajit/src/lj_gc.c:528
#9  0x00007ffff7952a51 in cpfinalize (L=0x40000378, dummy=<optimized out>, ud=<optimized out>) at <lovr_path>/deps/luajit/src/lj_state.c:236
#10 0x00007ffff795bca6 in lj_vm_cpcall () at buildvm_x86.dasc:1179
#11 0x00007ffff7952d66 in lua_close (L=0x40000378) at <lovr_path>/deps/luajit/src/lj_state.c:262
#12 0x000055555557c8c6 in main (argc=2, argv=<optimized out>) at <lovr_path>/src/main.c:172
User avatar
kicknbritt
Citizen
Posts: 98
Joined: Sat May 30, 2015 2:15 am
Location: Chicago, IL/Anchorage,AK

Re: rendering simple 3d planes (with clipping)

Post by kicknbritt »

pgimeno wrote: Mon Apr 25, 2022 8:11 pm
kicknbritt wrote: Sun Apr 10, 2022 7:35 pm Actually you know what. Did you try rotating the screen to find the 'hello world' text?
By default, lovr starts in a dual screen mouse control mode thingy.
That would be pretty funny if you only needed to rotate the camera.
Tried now. I tried to move the mouse alone, and while clicking left/mid/right, and to move the mouse wheel, to no avail. I only get a black screen.

The no game screen looks like this: http://www.formauri.es/personal/pgimeno ... nogame.png

And importantly, I get a segfault on exit, with this backtrace:

Code: Select all

#0  0x00007ffff35104dc in ?? () from /usr/lib/libnvidia-glcore.so.340.107
#1  0x00007ffff35120b5 in ?? () from /usr/lib/libnvidia-glcore.so.340.107
#2  0x00005555555b26f0 in lovrGpuDestroy () at <lovr_path>/src/modules/graphics/opengl.c:1361
#3  0x00005555555a6df8 in lovrGraphicsDestroy () at <lovr_path>/src/modules/graphics/graphics.c:215
#4  0x000055555557dcb4 in luax_module__gc (L=0x40000378) at <lovr_path>/src/api/api.c:37
#5  0x00007ffff795b937 in lj_BC_FUNCC () at buildvm_x86.dasc:809
#6  0x00007ffff7937938 in gc_call_finalizer (g=g@entry=0x400003b8, L=L@entry=0x40000378, mo=<optimized out>, o=o@entry=0x4000b5f8) at <lovr_path>/deps/luajit/src/lj_gc.c:475
#7  0x00007ffff79379f6 in gc_finalize (L=L@entry=0x40000378) at <lovr_path>/deps/luajit/src/lj_gc.c:521
#8  0x00007ffff7938918 in lj_gc_finalize_udata (L=L@entry=0x40000378) at <lovr_path>/deps/luajit/src/lj_gc.c:528
#9  0x00007ffff7952a51 in cpfinalize (L=0x40000378, dummy=<optimized out>, ud=<optimized out>) at <lovr_path>/deps/luajit/src/lj_state.c:236
#10 0x00007ffff795bca6 in lj_vm_cpcall () at buildvm_x86.dasc:1179
#11 0x00007ffff7952d66 in lua_close (L=0x40000378) at <lovr_path>/deps/luajit/src/lj_state.c:262
#12 0x000055555557c8c6 in main (argc=2, argv=<optimized out>) at <lovr_path>/src/main.c:172
Super super wierd.
I honestly have no clue whats happening here.
Maybe your gpu is unsupported or something?
Your just dragging the 'test' folder onto 'lovr.exe' correct?

I would maybe reach out to them on slack. All the maintainers and stuff are there, they're pretty easy going.
"I AM THE ARBITER!!!" *Pulls out Energy sword and kills everything*
User avatar
pgimeno
Party member
Posts: 3672
Joined: Sun Oct 18, 2015 2:58 pm

Re: rendering simple 3d planes (with clipping)

Post by pgimeno »

kicknbritt wrote: Tue Jun 07, 2022 3:44 pmSuper super wierd.
I honestly have no clue whats happening here.
Maybe your gpu is unsupported or something?
Your just dragging the 'test' folder onto 'lovr.exe' correct?
I don't drag anything, I type `lovr .` from bash which I presume is equivalent.

My GPU info:
OpenGL vendor string: NVIDIA Corporation
OpenGL renderer string: GeForce 210/PCIe/SSE2
OpenGL core profile version string: 3.3.0 NVIDIA 340.107
OpenGL core profile shading language version string: 3.30 NVIDIA via Cg compiler

kicknbritt wrote: Tue Jun 07, 2022 3:44 pmI would maybe reach out to them on slack. All the maintainers and stuff are there, they're pretty easy going.
I'm not on slack, discord or github, nor plan to. I guess they're not in a free network (as in freedom, i.e. not an "all your data are belong to us" company) where they can be reached? IRC or Jabber maybe? Perhaps email? My email is in my homepage: http://www.formauri.es/personal/pgimeno/
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 14 guests