Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

3D World - Graphics 2.0 Competition Submission
Started by Matthew Pringle Nov 17 2013 12:04 PM

35 replies to this topic
[TOPIC CONTROLS]
Page 1 of 2 1 2
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

Matthew Pringle

[GLOBAL: userInfoPane.html]
Matthew Pringle
  • Contributor

  • 660 posts
  • Corona SDK

Attached File  comp.png   138.06KB   49 downloads

 

 

I have built a 3D world in Corona using the 2.5D image transforms, snapshots and a lot of complex maths!


 
It loads a tile map from Tiled and uses the 2D Tiled map to generate a camera projecting a 3D world on to a screen, which is a snapshot.


 
The engine also generates the floor at different levels. In the demo the track is separate to the tiled floor and hovers above it.
 
Where the polygons stop drawing, near the top of the screen. That is the horizon which can be altered but in a real game the sky would draw down to that point making it look seamless.
 
This nearly broke me!


[TOPIC: post.html]
#2

LairdGames

[GLOBAL: userInfoPane.html]
LairdGames
  • Contributor

  • 969 posts
  • Corona SDK

WOW, FANTASTIC :)

 

I can see so many games using this.

 

Thanks for the share!

 

Mo



[TOPIC: post.html]
#3

rakoonic2

[GLOBAL: userInfoPane.html]
rakoonic2
  • Contributor

  • 503 posts
  • Corona SDK

Lovely :D

 

Got any framerates benchmarks for devices - am rather curious indeed about that.



[TOPIC: post.html]
#4

Matthew Pringle

[GLOBAL: userInfoPane.html]
Matthew Pringle
  • Contributor

  • 660 posts
  • Corona SDK

Not Yet.
 
The actual drawing of the 3D bit, that doesn't seem to affect the fps too much.
 
The maths however is taking around 16.66 milliseconds per frame which is way too much. I am however calculating every point of the entire world 4 times so once I implement fov on the grid to get just a sample of the entire world I’m hopeful it will run on devices at a decent frame rate.


[TOPIC: post.html]
#5

Matthew Pringle

[GLOBAL: userInfoPane.html]
Matthew Pringle
  • Contributor

  • 660 posts
  • Corona SDK

Oh, if you watch to the end of the vid, you will see where I fixed the texture problem by subdividing the polygons. The bit where tons more points pop in on each tile. That too needs a lot of optimisation.



[TOPIC: post.html]
#6

Matthew Pringle

[GLOBAL: userInfoPane.html]
Matthew Pringle
  • Contributor

  • 660 posts
  • Corona SDK

Just did a quick calc of how much more of the world I'm calculating than I need. Im probably doing in excess of 4000 passes where 120 would be enough.



[TOPIC: post.html]
#7

Matthew Pringle

[GLOBAL: userInfoPane.html]
Matthew Pringle
  • Contributor

  • 660 posts
  • Corona SDK

Im adding in a fov script I developed for Lime a while back.

 

It calculates shadows at the moment and is way too complex, but here is a screen shot of its most basic routine scanning which tiles to render. Implemented in 2D only for the moment.

 

http://forums.coronalabs.com/topic/6453-field-of-view-shadow-casting-demo/

 

Attached File  1.png   23.24KB   32 downloads

 

Edit

 

In a quick test in 3D this simple fov script takes it from 16.66 milliseconds to 3.2 milliseconds to calculate each frame.



[TOPIC: post.html]
#8

rakoonic2

[GLOBAL: userInfoPane.html]
rakoonic2
  • Contributor

  • 503 posts
  • Corona SDK

Now that's more like it - can't wait to see the finished result :)



[TOPIC: post.html]
#9

rakoonic2

[GLOBAL: userInfoPane.html]
rakoonic2
  • Contributor

  • 503 posts
  • Corona SDK

I should add, try to avoid the subdividing if you can - you are introducing t-junctions which can (and likely will) result in sparklies on various devices.

Also, get height in :) You aren't limited like in my mode 7 demo to a single plane per tiled later, so get some ramps and stuff in. Hell, there's no reason you can't have loops and things in. Go crazy!



[TOPIC: post.html]
#10

Matthew Pringle

[GLOBAL: userInfoPane.html]
Matthew Pringle
  • Contributor

  • 660 posts
  • Corona SDK

Yeah I thought subdividing would cause some issues but I cannot see any so far. My original plan was to leave the original polygon underneath or draw a polygon the colour of the tile, but it doesn't seem to be a problem.

 

I may kill the subdivision idea as it makes using tile maps ( with margins / spacing ) a lot harder but at the moment its a good fix while I keep on optimising the engine.

 

The issue with sparkles is that positioning one corner of a polygon off screen, not at infinity, but at an acceptable value, so as to not warp the texture, would also cause the same effect, as its essentially doing the same thing.

 

But at the moment its just a test so the engine changes every time I have an idea.



[TOPIC: post.html]
#11

rakoonic2

[GLOBAL: userInfoPane.html]
rakoonic2
  • Contributor

  • 503 posts
  • Corona SDK

Heh I know the feeling :)

I went over Lerg's skybox thing as he encountered a similar problem, and in fact his solution was completely the opposite from yours and amusingly I think you two should swap solutions :D

 

He moved the skybox further away to avoid clipping the Z == 0 plane, and I think the correct solution in this case *is* subdividing, and in your case I'd suggest just backing the camera further away and not subdividing.

 

Sparklies can show up at odd times. I removed the rotation from retro racer because it was creating sparklies at angles, and that was a minimal test case, despite being 100% sure that each corner of the adjoining polygons used identical values. Happened in the simulator and also on my phone, although maybe they've sorted that now? Might be worth me chucking it back in to check, but the point is I know my phone can show these things so maybe if you are bored one night you could pass me an android build and I'd just take a look.



[TOPIC: post.html]
#12

Matthew Pringle

[GLOBAL: userInfoPane.html]
Matthew Pringle
  • Contributor

  • 660 posts
  • Corona SDK

Ok have tested the unoptimised code...

 

And also on device noticed sparkles, so damn it all to hell. That will need looking at.

 

I just took delivery of an iPod Touch 4G, 256 MB, A4 chip. This currently gets 15 fps so there is hope for older devices.

 

On an iPhone 5S it gets a constant 60fps.

 

If I lose the subdivision then that would help the cause a lot. How do you suggest doing it the other way?



[TOPIC: post.html]
#13

Matthew Pringle

[GLOBAL: userInfoPane.html]
Matthew Pringle
  • Contributor

  • 660 posts
  • Corona SDK

For comparison, the Mode 7 demo you did gets 20-30 on the 4G Touch. So I have a bit to go yet!



[TOPIC: post.html]
#14

Matthew Pringle

[GLOBAL: userInfoPane.html]
Matthew Pringle
  • Contributor

  • 660 posts
  • Corona SDK

I think I might have thought around the subdivision problem.

 

At the moment I'm generating all 4 points for each tile. That needs to be cut down into points in a grid.

 

Then for each tile, if a point goes to infinity I'm going to use the subdivision routine to trace back up the sides of the polygon until I get to a respectable value for the 2 bottom corners. Im hoping this should fix both issues as the wall as the gird will be generated before drawing any polygons ensuring I'm doing the maximum possible to make them all line up.



[TOPIC: post.html]
#15

rakoonic2

[GLOBAL: userInfoPane.html]
rakoonic2
  • Contributor

  • 503 posts
  • Corona SDK

If you *really* wanted to go all out, you could generate sub tile frames from the tile sheet, eg for each sheet you might have 8 additional frames, 1 for each quarter, and 1 for each half, or split it into more (resulting in a huuuge number of frames per tile!), and then when you come to subdivide anything up close, you'd be able to have 'sub-tiles' to texture from.

 

I did something similar in Dungeoneer to make textures line up according to different wall heights. While the frame construction was similar in theory, and it was used for 'chopped up faces' it wasn't for perspective correction up close (and was vastly simpler as it only needed to worry about new vertical versions, not both vertical and horizontal which is what you'd need).



[TOPIC: post.html]
#16

rakoonic2

[GLOBAL: userInfoPane.html]
rakoonic2
  • Contributor

  • 503 posts
  • Corona SDK

Also I wouldn't worry about the mode 7 demo comparision (which I would probably be able to up to 60 fps, but it was haaaacky!), because it uses a much simpler method of getting the end result, and your way of doing things is more flexible, not least of which is the ability to have ramps and what-not, which the mode 7 thing will never be able to manage.

 

Plus of course, as you are putting the 3D transform directly into each tile, and not into an overall snapshot like my demo, you also end up with much sharper graphics, which is never to be sniffed at.



[TOPIC: post.html]
#17

Matthew Pringle

[GLOBAL: userInfoPane.html]
Matthew Pringle
  • Contributor

  • 660 posts
  • Corona SDK

The sub tile division is what Im doing now. Each tile is split into 8 segments and those are drawn when close to the camera, using a sprite sheet, but that causes the sparkles.

 

​I tried zooming the world out by 2 and scaling the screen and the result loosed workable. I looks like it will need additional work though as it seems to throw off a few calculations.



[TOPIC: post.html]
#18

Matthew Pringle

[GLOBAL: userInfoPane.html]
Matthew Pringle
  • Contributor

  • 660 posts
  • Corona SDK

Ok well I give up trying to sort the perspective behind the camera using math. I get close but its not good enough and uses a lot of cycles.

 

I was doing the sprite > subdivision trick. The tile would get divided into 8 sections, but as this only happens close to the screen only a couple of strips are drawn. The problem there being the sparkles.

 

My solution, untested as its getting late, is to draw a 1/4 strip the full width of the tile next to where it meets the next tile. The draw the 1/4 tiles on top. This should get rid of the sparkles at the edges of where 1 large polygon meets 4 smaller ones.

 

It will probably only result in 10 extra polygons tops for the whole screen so that itself won't be an issue.



[TOPIC: post.html]
#19

Matthew Pringle

[GLOBAL: userInfoPane.html]
Matthew Pringle
  • Contributor

  • 660 posts
  • Corona SDK

Hey rakoonic

Spent some time optimising it this weekend and on an A4 chip - iPod Touch 4G it gets about 20fps in the current setup. If I double the size of the tiles, which could be offset with more res in the images, it will stick at a steady 30fps.

So I'm thinking that really anything like that will need to be targeted at A5 devices and up. Thats iPad 2, iPhone 4S, iPad Mini and the Touch 5G as well as the newer stuff.

So that in itself is not a problem. Those A4 devices are quite old now and I think with a bit more work it will hold at 60fps on an A5 chip though I do need a test device to check.

If that would be an issue it would be easy enough to drop it to 30fps for older devices with no loss otherwise.

[TOPIC: post.html]
#20

Matthew Pringle

[GLOBAL: userInfoPane.html]
Matthew Pringle
  • Contributor

  • 660 posts
  • Corona SDK

The FOV script is still seeing a lot more tiles than is needed. The yellow dots represent the points.

I dont suppose you know of a script to pick a selection of tiles between 2 angles?

Attached File  1.jpg   34.79KB   24 downloads

[TOPIC: post.html]
#21

rakoonic2

[GLOBAL: userInfoPane.html]
rakoonic2
  • Contributor

  • 503 posts
  • Corona SDK

I must admit I don't.

Dungeoneer uses a really basic one but let's face it, it isn't exactly a programming challenge when the point of view is ever parallel to an axis so it isn't really useful.

 

If I had time I'd have a go as it sounds exactly like the type of challenge I like, but unfortunately I don't have time.

The only thing I could suggest is how I might approach the problem:

 

1) Work out which is the 'general' axis you are looking along (IE which of the 4 main axes you are most aligned to).

2) Calculate the edge lines (IE where to clip the left and right of the view) by working out how much of an offset each of these lines has per unit movement along the main axis found in 1

3) Iterate along the main axis, finding the left and right boundaries by offsetting in their other axis by the values calculated in 2.

4) Between these two values, include all the tiles found, then move one more along the main axis and repeat to find all the tiles.

 

Does that make any sense? I think an image would probably clarify it easily enough but alas, I really won't have time for that until tomorrow.



[TOPIC: post.html]
#22

Matthew Pringle

[GLOBAL: userInfoPane.html]
Matthew Pringle
  • Contributor

  • 660 posts
  • Corona SDK

Thanks, will give that a try.

At the moment the fov script is scanning simple octants which are decided upon by the angle the camera is facing. Its fast but gets too many tiles. I think a slower script might speed things up as it will require less rendering and clipping at the 3d stage.

Im also considering pre-calculating the tiles visible for each degree of rotation at all 4 points of the tile and then using offsets to update for the current camera position. Each degrees will only have 60 tiles top so the table won't get too big. Would only do this for the camera pitch the game will run at for optimum speed but for all other angles I am going to need to calculate realtime.

From my calculations I would lose around 1/2 of the tiles I'm currently plotting so it should give another speed increase.

Got the sparkles sorted as well last night. I subdivide the tile into 8 squares and also 4 horizontal and 4 vertical strips. Only a few of those get drawn as close to the screen, but the way they overlay cancels out any defects.

[TOPIC: post.html]
#23

Matthew Pringle

[GLOBAL: userInfoPane.html]
Matthew Pringle
  • Contributor

  • 660 posts
  • Corona SDK

Put up a new video. Towards the end I'm showing the different subdivisions.



[TOPIC: post.html]
#24

rakoonic2

[GLOBAL: userInfoPane.html]
rakoonic2
  • Contributor

  • 503 posts
  • Corona SDK

I don't suppose you care to share with me the Tiled levels so I can look into this myself? I should have time this week (starting today in fact, hurrah!), and I'm sick of looking at my own crappy tiled level I knocked up with ripped-off assets for that Mode 7 demo!



[TOPIC: post.html]
#25

Matthew Pringle

[GLOBAL: userInfoPane.html]
Matthew Pringle
  • Contributor

  • 660 posts
  • Corona SDK

Here you go.

The tile map is using offsets and margins to stop any oddities happening.

The actual tile map is made in fireworks so they are layered and editable.

Matt

-- Image Sheet Options
layer.imageSheet = {
border = 2,
width = layer.imageTileWidth,
height = layer.imageTileHeight,
numFrames = layer.imageWidth / layer.imageTileWidth * layer.imageHeight / layer.imageTileHeight
}

Attached Files




[topic_controls]
Page 1 of 2 1 2
 
[/topic_controls]