**I made a 3d game and it is very simple now. It is like Minecraft. I use Mesh to print the graphics, but the fps only have 7-10! Does anyone know how to make the fps more higher at 3d games? Thank you. **

Since you donâ€™t include any code to look at or any details on what youâ€™re doing other than `Mesh to print graphics`

, all I can say is `start removing things until it goes faster`

. How many meshes do you have, vertices, etc. What version iPad are you using. Give us as much info as you can.

@dave1707 sorry, I forgot to put codeâ€¦

There is all the code from my project.

```
--# Control
Control = class()
function Control:init(x)
end
function Control:draw()
for k , touch in pairs (touches) do
if touch.state == BEGAN then
touchX,touchY = touch.x,touch.y
elseif touch.state == MOVING then
AngleY = AngleY - (touch.y - touchY) / 4
AngleX = AngleX - (touch.x - touchX) / 4
touchX,touchY = touch.x,touch.y
end
end
end
function Control:touched(touch)
end
--# DrawBlock
DrawBlock = class()
function DrawBlock:init(x)
end
function DrawBlock:draw()
perspective ()
for py = 1 , 256 do
for px = 1 , 16 do
for pz = 1 , 16 do
if Blocks [py] [px] [pz] ~= 0 then
for i = 1 , 12 do
DrawBlocksList = {0}
if math.ceil (i / 2) == 1 then
if Blocks [py + 1] [px] [pz] == 0 then
DrawBlocksList [1] = 1
end
elseif math.ceil (i / 2) == 2 then
if Blocks [py] [px] [pz - 1] == 0 then
DrawBlocksList [1] = 2
end
elseif math.ceil (i / 2) == 3 then
if Blocks [py] [px] [pz + 1] == 0 then
DrawBlocksList [1] = 3
end
elseif math.ceil (i / 2) == 4 then
if Blocks [py - 1] [px] [pz] == 0 then
DrawBlocksList [1] = 4
end
elseif math.ceil (i / 2) == 5 then
if Blocks [py] [px - 1] [pz] == 0 then
DrawBlocksList [1] = 5
end
elseif math.ceil (i / 2) == 6 then
if Blocks [py] [px + 1] [pz] == 0 then
DrawBlocksList [1] = 6
end
end
if DrawBlocksList [1] ~= 0 then
for o = 0 , 1 do
BlockMesh.vertices = {vec3 (px * BlockWidth,py * BlockWidth,pz * BlockWidth) + Vertices [i] [1],vec3 (px * BlockWidth,py * BlockWidth,pz * BlockWidth) + Vertices [i] [2],vec3 (px * BlockWidth,py * BlockWidth,pz * BlockWidth) + Vertices [i] [3]}
BlockMesh.texCoords = TexCoords [i % 2 + 1]
if Blocks [py] [px] [pz] == 1 then
if math.ceil (i / 2) == 1 then
if BlockMesh.texture ~= "Cargo Bot:Crate Green 1" then
BlockMesh.texture = "Cargo Bot:Crate Green 1"
end
elseif math.ceil (i / 2) == 4 then
if BlockMesh.texture ~= "Cargo Bot:Crate Green 1" then
BlockMesh.texture = "Cargo Bot:Crate Green 1"
end
else
if BlockMesh.texture ~= "Cargo Bot:Crate Green 1" then
BlockMesh.texture = "Cargo Bot:Crate Green 1"
end
end
elseif Blocks [py] [px] [pz] == 2 then
if BlockMesh.texture ~= "Project:FlatPlanet Dirt" then
BlockMesh.texture = "Project:FlatPlanet Dirt"
end
elseif Blocks [py] [px] [pz] == 3 then
if BlockMesh.texture ~= "Project:FlatPlanet Stone" then
BlockMesh.texture = "Project:FlatPlanet Stone"
end
end
BlockMesh:draw ()
end
end
end
end
end
end
end
end
function DrawBlock:touched(touch)
end
--# SetUp
SetUp = class()
function SetUp:init(x)
Vertices = {
{vec3 (-1 * BlockWidth,0 * BlockWidth,-1 * BlockWidth),vec3 (0 * BlockWidth,0 * BlockWidth,-1 * BlockWidth),vec3 (-1 * BlockWidth,0 * BlockWidth,0 * BlockWidth)},
{vec3 (0 * BlockWidth,0 * BlockWidth,-1 * BlockWidth),vec3 (0 * BlockWidth,0 * BlockWidth,0 * BlockWidth),vec3 (-1 * BlockWidth,0 * BlockWidth,0 * BlockWidth)},
-- Top
{vec3 (-1 * BlockWidth,-1 * BlockWidth,-1 * BlockWidth),vec3 (0 * BlockWidth,-1 * BlockWidth,-1 * BlockWidth),vec3 (-1 * BlockWidth,0 * BlockWidth,-1 * BlockWidth)},
{vec3 (0 * BlockWidth,-1 * BlockWidth,-1 * BlockWidth),vec3 (0 * BlockWidth,0 * BlockWidth,-1 * BlockWidth),vec3 (-1 * BlockWidth,0 * BlockWidth,-1 * BlockWidth)},
-- Front
{vec3 (-1 * BlockWidth,-1 * BlockWidth,0 * BlockWidth),vec3 (0 * BlockWidth,-1 * BlockWidth,0 * BlockWidth),vec3 (-1 * BlockWidth,0 * BlockWidth,0 * BlockWidth)},
{vec3 (0 * BlockWidth,-1 * BlockWidth,0 * BlockWidth),vec3 (0 * BlockWidth,0 * BlockWidth,0 * BlockWidth),vec3 (-1 * BlockWidth,0 * BlockWidth,0 * BlockWidth)},
-- back
{vec3 (-1 * BlockWidth,-1 * BlockWidth,-1 * BlockWidth),vec3 (0 * BlockWidth,-1 * BlockWidth,-1 * BlockWidth),vec3 (-1 * BlockWidth,-1 * BlockWidth,0 * BlockWidth)},
{vec3 (0 * BlockWidth,-1 * BlockWidth,-1 * BlockWidth),vec3 (0 * BlockWidth,-1 * BlockWidth,0 * BlockWidth),vec3 (-1 * BlockWidth,-1 * BlockWidth,0 * BlockWidth)},
-- Bottom
{vec3 (-1 * BlockWidth,-1 * BlockWidth,-1 * BlockWidth),vec3 (-1 * BlockWidth,-1 * BlockWidth,0 * BlockWidth),vec3 (-1 * BlockWidth,0 * BlockWidth,-1 * BlockWidth)},
{vec3 (-1 * BlockWidth,-1 * BlockWidth,0 * BlockWidth),vec3 (-1 * BlockWidth,0 * BlockWidth,0 * BlockWidth),vec3 (-1 * BlockWidth,0 * BlockWidth,-1 * BlockWidth)},
-- Right
{vec3 (0 * BlockWidth,-1 * BlockWidth,-1 * BlockWidth),vec3 (0 * BlockWidth,-1 * BlockWidth,0 * BlockWidth),vec3 (0 * BlockWidth,0 * BlockWidth,-1 * BlockWidth)},
{vec3 (0 * BlockWidth,-1 * BlockWidth,0 * BlockWidth),vec3 (0 * BlockWidth,0 * BlockWidth,0 * BlockWidth),vec3 (0 * BlockWidth,0 * BlockWidth,-1 * BlockWidth)}
-- Left
}
TexCoords = {
{vec2 (1,0),vec2 (1,1),vec2 (0,1)},
{vec2 (0,0),vec2 (1,0),vec2 (0,1)}
}
end
function SetUp:draw()
end
function SetUp:touched(touch)
end
--# GeneratedTerrain
GeneratedTerrain = class()
function GeneratedTerrain:init()
Blocks = {}
for py = 0 , 257 do
Blocks [py] = {}
for px = 0 , 17 do
Blocks [py] [px] = {}
for pz = 0 , 17 do
Blocks [py] [px] [pz] = 0
end
end
end
for px = 1 , 16 do
for pz = 1 , 16 do
Blocks [128] [px] [pz] = 1
Blocks [127] [px] [pz] = 1
for py = 1 , 3 do
-- Blocks [128 - py] [px] [pz] = 2
end
for py = 1 , 124 do
-- Blocks [125 - py] [px] [pz] = 3
end
end
end
Blocks [128] [1] [1] = 1
Blocks [128] [2] [1] = 1
Blocks [128] [1] [2] = 1
end
function GeneratedTerrain:draw()
end
function GeneratedTerrain:touched(touch)
end
--# Main
supportedOrientations (LANDSCAPE_ANY)
function setup()
Variable:init ()
BlockMesh = mesh ()
-- BlockMesh:setColors (255,255,255,255)
end
sprite ()
function draw()
background(176,233,252,255)
lookX,lookY,lookZ = camX + math.sin (math.rad (AngleX)) * 10,camY + math.sin (math.rad (AngleY)) * 10,camZ + math.cos (math.rad (AngleX)) * 10
camera (camX,camY,camZ,lookX,lookY,lookZ)
DrawBlock:draw ()
Control:draw ()
print ("FPS : "..math.floor (1 / DeltaTime))
end
function touched (touch)
if touch.state == ENDED then
touches [touch.id] = nil
else
touches [touch.id] = touch
end
end
--# Variable
Variable = class()
function Variable:init(x)
BlockWidth = WIDTH / 8
DrawBlocksList = {}
-- block
AngleX,AngleY = 180,180
camX,camY,camZ = -300,130 * BlockWidth,BlockWidth
lookX,lookY,lookZ = camX + math.sin (math.rad (AngleX)) * 10,camY + math.sin (math.rad (AngleY)) * 10,camZ + math.cos (math.rad (AngleX)) * 10
-- camera
touches = {}
touchX,touchY = 0,0
-- touch
SetUp:init ()
GeneratedTerrain:init ()
-- init ()
parameter.number ("camX",-1000,1000,-300)
parameter.number ("camY",11000,20000,130 * BlockWidth)
parameter.number ("camZ",-1000,1000,BlockWidth / 2)
parameter.number ("AngleX",-1000,1000,-620)
parameter.number ("AngleY",-1000,1000,-45)
end
function Variable:draw()
end
function Variable:touched(touch)
end
```

@Gai_Gai Unfortunatly it runs at 0 FPS on my iPad Air. All I see is something blue and thatâ€™s it. Any textures or whatever that you use, if theyâ€™re not the built in Codea assets, they canâ€™t be seen by anyone else. Theyâ€™re local to you but blank for us. Maybe you can tell us what weâ€™re supposed to be seeing. Iâ€™m not going to spend any time trying to figure this out. Maybe someone else with a faster iPad will look into it, but itâ€™s too slow for me to do anything.

EDIT: Anytime you post code, put 3~'s on a line before and after the code so it formats correctly. I added them to your code above.

Well, I donâ€™t mean to be rude but I find your code a bit messy and hard to read, so Iâ€™ll just give you tips (but Iâ€™m not an expert):

- I recommend splitting your voxel world (aka blocky world) into chunks (like Minecraft) and each chunk will have a mesh. This way, you can draw only the chunks that are near the camera to reduce the amount of vertices being drawn.
- I recommend culling (I
*think*thatâ€™s the right term!) the meshes. That means you need to get your code to figure out which sides of the blocks are covered. Only if a side is**not**covered by a block, should your code add vertices to the chunkâ€™s mesh for that side of the block. - Also, I see in your draw function,
`BlockMesh:setColors (255,255,255)`

. It just needs to be called once (just after`BlockMesh`

is declared).

@dave1707 I changed the texture, I think now you can see the texture.And thank for teach me how to use the â€ś~~~â€ť. I think the problem that solw down the fps is the mesh, can you teach me how to use the mesh that it does not solw down the fps? Thank you.

@Kolosso , I already â€ścullingâ€ť the mesh that between two blocks, It is better than the original one, but it only take fps higher a little (like 1-2). I try to put the DrawBlock:Draw as a comment but the fps is still low, and is a stop all the DrawBlocks class, the for is about 60. Does change the DrawBlock.vortex need a lot of time?

Is it culling every frame? If it is then I believe thatâ€™s the problem. The vertices for the mesh only need to be set once unless the blocks will be changing. If *thatâ€™s* the case, it should re-mesh only when thereâ€™s a block change.

@Kolosso You mean one block use one mesh? I can try that. Because I use only one Mesh to draw all of the blocks and I change the vertices every block.

Thatâ€™s not really what I meant. If there is not that many blocks, you should use 1 mesh for all of them. If there are lots of blocks, you should split the blocks into chunks where each chunk has itâ€™s own mesh. You should make the vertices for your meshes once, at the setup function. Then draw the meshes in the draw function. Then change the vertices for the meshes when a block changes.

@Kolosso But the blocks I draw is 16*16 (a chunk), and the xyz of a block in a chunk is not the same, I need to change the xyz(vertices) every block, how can I make this faster?(easier?)

why are you changing vertices? Why not just translate the blocks?

@Ignatz Is my way inefficient? I was telling @Gai_Gai that they should split the world into chunks, and make each chunk own a mesh that draws only the sides of the blocks that are visible. Then replace those meshes whenever a block changes (example: a block placed).

@Gai_Gai That is close to what I mean. You only need to make the vertices for your blocks once. Then you draw the meshes in the draw function. If there is a change, you remake the vertices of the meshes.

@Gai_Gai One thing thatâ€™s slowing things down is the print statement in draw(). Comment that out. You never or almost never want to put a print statement in draw().