3D rendering on Codea

One more thing: in lua, arrays (tables) start at 1, not 0.

Point 5 is a big saving. With quality at 2 then I got a FPS of about 8.8 with your original code (all other settings as defaults). Once I’d implemented point 5, I got up to 13.5. That’s half as much again.

@Andrew_Stacey

Thanks for the help Andrew :slight_smile:

For point 1, it is indeed the fastest projection possible I believe, you can change the camera position for a negligible fps loss, but not the direction you look at, if you see what i mean.

For point 2, after implementing point 5, it is only an fps gain when a LOT of triangles are culled, so I removed it.

For point 3, totally, i mentionned in the comment it could be simplified, wanted people to “see” i was doing the distance formula :slight_smile:

for point 4, i’ve been toying with the idea after implementing point 5.
After optimizing the code structure, i hit the 60fps cap at quality 3, and 25fps at quality 2, which is incredible, but I cannot get the depth sorting to work.

here is some pseudocode (tris is my list of vec2):

-- without depth sorting i do this for each poly
for each polygon(a,b,c)
ins(tris, a)
ins(tris, b)
ins(tris, c)
end
p.vertices = tris
p:draw()

Now, if i want to add depth sorting, i could do something like that (I need to shift the insert order so that final result is correct, right ?):

for each polygon(a,b,c)
ins(tris, depth, c)
ins(tris, depth, b)
ins(tris, depth, a)
end
p.vertices = tris
p:draw()

That obviously doesn’t work since p.vertices needs to be sorted with no holes (has to be 1, 2, 3, 4, etc…can’t be 1, 4, 25, 97.
If you have any idea to normalize the depth value, or a way to circumvent this, i’d be glad to hear it.
For now, i’m back to using table.sort, so down to around 35-40fps in quality 3

For point 5, indeed, huge fps boost thanks a lot ! I had no idea you could have more than three points in a “mesh()” (had tried table.insert with p.vertices but it didn’t work). When you said you implemented it, i realised I had to work on a table then do p.vertices = table. Huge fps boost thanks :slight_smile:

for point 6, i had thought of using textures to simulate wireframe, but I didn’t know you apply an image to a mesh, thought it had to come from an external file and I didn’t want to “hack” codea. I plan to try and implement at a later time !

for point 7, i’m now using table.insert everywhere (i changed it to a “local ins = table.insert”, seem to gain 1 fps. f.visible is something I forgot to update. f.visible doesn’t actually exist anymore,was old code.
But in my draw loop, i had a check with “if f then”, that way if no faces are visible at all (all culled), program wouldn’t crash. It’s now completely gone though, since i remove backface culling

Thanks for the help, i’ll update the posted code soon.

Ok, so…anger time :stuck_out_tongue:
First, with my original code, in quality 2, i’m at 5.9fps, then 11fps with point 5 implemented.
How do you get 8.8fps, then 13.5fps with point 5 implemented ? Why is my iPad slower ? hate that, heh :slight_smile:

iPad 1 vs. iPad 2?

I’m on an iPad2, maybe that’s the rest.

One minor thing. I found the fps almost impossible to read. If you use textMode(CORNER) then it effectively left-justifies the text so it doesn’t jump around so much (need to adjust the coordinates). I also got it to display a more averaged fps by saving the last 100 deltatimes and getting an average from them.

Okay, so to the sort. I’ve been experimenting off-and-on and have nothing definite yet. I’ve been looking at binary trees, but as yet no saving. It is quicker to sort a table of pure numbers than of objects, but I’m not sure how to exploit that. Also, the vertices will be in roughly the same order each time so a merge sort maybe be quicker than quicksort - I guess that table.sort is a quick sort - but then you have to remember the order from frame to frame.

hey, ok i think i found a reasonable way.
I’m keeping my last optimization, where i was getting 60fps in quality 3
what I do is the

-- for all triangles
ins(tris, depth, a)
ins(tris, depth, b)
ins(tris, depth, c)

-- remove the "holes" in tris
local tri = {}
for k, v in pairs(tris) do
  tri = v
end

I got a graphical glitch somewhere, some polygons are messed up, but it’s running at 50/55 fps

edit: nm… fixing all glitches and adding color brings me to the same fps approx as before… /cry

Just tried it via linked lists and got a stackoverflow!

@Andrew says “I’m no programmer…”

Feh. I’m no mathematician, and I was a math major for two years. You are more a programmer than I am a mathematician.

To be fair - being a programmer is easier. :slight_smile:

@Xavier texture parameters are implicitly set as follows:

Texture filtering: use smooth() and noSmooth(). smooth = bilinear, noSmooth = nearest neighbour.

Texture wrapping: all textures are clamped to edge UNLESS the texture size is a power-of-two, in which case we use repeat. The reason for this is because non-power-of-two textures can only user clamp-to-edge on PowerVR hardware.

So if you want to repeat your texture, make sure it’s rendered into a power of two image (e.g. 512x512).

@simeon

Oh thanks a lot for the explanation, I had no idea of that limitation and was using a random picture from the library

@bortels: I’m no mathematician. Though I’m (‘was’ to be exact) a programmer, I’m no visual programmer. Both you and @Andrew, also some other as well, have impressed me by what you’ve done using Codea. Compare to you and @Andrew, I’m almost nothing. :slight_smile:

@bortels: I’m no mathematician. Though I’m (‘was’ to be exact) a programmer, I’m no visual programmer. Both you and @Andrew, also some other as well, have impressed me by what you’ve done using Codea. Compare to you and @Andrew, I’m almost nothing. :slight_smile:

@bee Everyone has his/her way. You might be good at solving. I might be good at thinking. But we all share. Thus, I might borrow what you are excellent.

hahaha…hahahaahaha…HAHAHAAHAHAHAHAHAHA

60fps in quality 3 at last !!! :smiley:
The final optimization process was extremly complicated and hard to implement, but i’ll try and detail it here:

  1. use brain
  2. Decide I can get easy fps increase by only calling the z ordering once every few frames
  3. profit

hahahah…HAHAHAHAAHAH… I should slap myself for not thinking about it earlier :frowning:

I’ll update the code in a couple of minutes, also using wireframe textures now. It’s not ideal, but it does the job.

Going to work on dynamic textures now, then shadowing (by coloring the texture), this should be fun

Cheers,

Xavier

Excellent. I’ve been playing with different sort methods, but none beat quicksort. However, I suspect that it’s becuase I’m not implementing them optimally, and quicksort is builtin. Maybe if there were more hardcoded sorts there’d be more of a level playing field.

When I’ve seen your solution used before, then the system switches to wireframe when the shape is being moved, only switching back when it’s worth the computational time to recompute the face ordering.

I’ll take a look at your code in a bit, but I’ve just employed step one of your optimisation process and believe that I have a new Step 2 for you. You only need to call the z-ordering when something happens that changes what is in front of what (and the key point is that this is not the same as the distances of the faces from the eye). The two actions that I can think of in your setting that do thus are:

  1. Adding more faces
  2. Translating the coordinates

In particular, changing the heights (noise) does not change this relationship. The point is that changing the heights moves a face on a line anchored at the centre of the pseudo-globe. For two faces, the line for pne is always in front of (or behind) the line for another so no matter where on the line the faces are placed, the one on the front line can be rendered after the one on the back line. So you work out the right ordering at the start by looking at the z-levels for the faces with no height variation, the keep this orderong and only update it if one of the two things above occurs.

(I’m not a programmer, but I am a geometer so I’m more sure - not absolutely - that this is right, more than I am about sorting algorithms)

I might try to implement this with your revised code later today if I get a chance.

Have been pretty busy with work, but I managed to find the time to add in proper controls:

  1. One finger color or height painting (meaning use the fingers to change the geometry and paint the map)
  2. Pinch to zoom in or out
  3. Two finger swipe for rotations

It feels really cool :slight_smile: Finger painting is pretty nice so far and butter smooth, but user input is not completely precise (some issues with depth).

I’m using vertex color for now, will work on painting on an actual texture when i fix this precision issue :frowning:

I’ll update the code tomorrow if I find the time to make color picking friendly !

@Xavier I think many people are waiting for your update. Now the Codea 1.3.1 is approved. It makes code exporting easier.

It wont let me copy the program can you put it on there a different way please

@sanit - Hey, I sort of put a hold on working with finger painting, as I’m not happy enough with it.
I’m done with lightning (calculating the normals/shading as i’m generating the texture) and it looks gorgeous. I’m now plan on working on blending textures with it (based on height values) so I could get an actual terrain renderer.

However, generating the texture is rather slow (a 128*128 one kills the framerate).
Unless I’m using a very low resolution (and then it’s not pretty), playing with light position to see real time shading isn’t as fun as I’d hoped :frowning:
A possible tweak would be to pre-calculate the shadow maps and store them, but that’s barbaric :confused:

@jakeallstars - Hey there. Updated the link to be more iPad friendly