![]() |
![]() |
![]() |
#21 |
Lemon. / Core Design
![]() Join Date: Mar 2016
Location: Tier 5
Posts: 891
|
You could look at combining the edge calc with the horizontal span filling, by working downwards from top to bottom
Currently you are writing to memory, then reading back in the 2nd phase.. this will have some overhead. There are other optimisations you could do too with regards to the rendering (ie. removing any loop from the longword writing, and having code that jumps in at the correct point to write out the required number of longs etc..) |
![]() |
![]() |
#22 |
<optimized out>
![]() Join Date: Sep 2020
Location: <optimized out>
Posts: 275
|
I have fixed the bug that caused tanks to calculate their shadows the hard way, I now have an extra 0.1 fps.
So, now to concentrate on the long division bit: Code:
if (transformed->x >= viewingDistance) *projected = (LongPoint3D) { transformed->x, transformed->y * viewingDistance / transformed->x, transformed->z * viewingDistance / transformed->x }; else *projected = *transformed; viewingDistance is currently fixed to 256, and (as the code says) the divisions only happen if the point is at least that far away. Why do I copy the transformed values over to projected in the else part? It seems the only reason is so that there are values in there for my IsFacing test later on. This logic may be flawed. Ok, I have two goals, 1: make the maths stuff that will fit into words, and 2: replace the division with a look up and multiplication of 1/x. Both seem to rely on getting the range of values for x down to something reasonable. and setting my draw distance in line with that. If I use a look up table I need to keep that to a reasonable size. I think I want the draw distance to be around 2km, beyond that object are just a few pixels big and everything breaks down anyway. Anyway, trying to get the divisor to fit into a word, rearranging the calculations gives me: Code:
*projected = (LongPoint3D) { transformed->x, transformed->y / (transformed->x / viewingDistance), transformed->z / (transformed->x / viewingDistance) }; To use a table, with a 2km draw limit and the resolution given by transformed->x / viewingDistance (which is effectivly ">> 8") I think I need a table with 8,192 values, or 16K. Would 16K be considered large for a look up table? Edit: Just replaced the divisions with inline assembly: Code:
if (transformed->x >= viewingDistance) { WORD x = transformed->x >> 8; *projected = (LongPoint3D) { transformed->x, Div32_16(transformed->y, x), Div32_16(transformed->z, x) }; } else *projected = *transformed; Code:
inline WORD Div32_16(const LONG a, const WORD b) { WORD result; asm( " move.l %[a], %[result] \n" " divs %[b], %[result] \n" : // outputs [result] "=&d" (result) : // inputs [a] "g" (a), [b] "dm" (b) : // clobbers "cc" ); return result; } Last edited by Ernst Blofeld; 15 January 2021 at 14:32. |
![]() |
![]() |
#23 | ||
<optimized out>
![]() Join Date: Sep 2020
Location: <optimized out>
Posts: 275
|
Quote:
Quote:
I can post my polygon code up later. |
||
![]() |
![]() |
#24 |
Registered User
Join Date: May 2013
Location: Grimstad / Norway
Posts: 682
|
BTW, are you triple-buffering?
|
![]() |
![]() |
#25 |
<optimized out>
![]() Join Date: Sep 2020
Location: <optimized out>
Posts: 275
|
Yes, I am. I'm a firm believer in triple-buffering.
Last edited by Ernst Blofeld; 15 January 2021 at 18:00. |
![]() |
![]() |
#26 |
<optimized out>
![]() Join Date: Sep 2020
Location: <optimized out>
Posts: 275
|
Update
This is what it looks like now:
There's a big overhead in the profiling code. Not much I can do about that, just need to be cautious with the values. With the profiling disabled I now get 3.25 fps, which is an improvement over the 2 fps I was getting a week ago. I'm now working on different drawing code depending on the distance the object I'm drawing is, i.e. for aircraft: Code:
if (this_Entity3D->transformedCentre.x > 512 * 1024) this_Entity->drawingMode = ENTITY_DRAWING_MODE_NONE; else if (this_Entity3D->transformedCentre.x > 256 * 1024) this_Entity->drawingMode = ENTITY_DRAWING_MODE_DOT; else if (this_Entity3D->transformedCentre.x > 32 * 1024) this_Entity->drawingMode = ENTITY_DRAWING_MODE_MODEL_FAST; else if (this_Entity3D->transformedCentre.x > -32 * 1024) this_Entity->drawingMode = ENTITY_DRAWING_MODE_MODEL_SLOW; else this_Entity->drawingMode = ENTITY_DRAWING_MODE_NONE; Last edited by Ernst Blofeld; 16 January 2021 at 16:38. |
![]() |
![]() |
#27 |
<optimized out>
![]() Join Date: Sep 2020
Location: <optimized out>
Posts: 275
|
3.5 fps now with the above code in place and a simpler rendering process for objects that can be guaranteed to not need near plane clipping.
Does anyone know what FPS the better 3D games used to get (on standard A500s)? Last edited by Ernst Blofeld; 16 January 2021 at 17:00. |
![]() |
![]() |
#28 |
Lemon. / Core Design
![]() Join Date: Mar 2016
Location: Tier 5
Posts: 891
|
I would think at least 10-12 FPS minimum for anything to be playable. Any slower, and things feel really sluggish (or changes in viewpoint become too drastic from one frame to the next)
|
![]() |
![]() |
#29 |
<optimized out>
![]() Join Date: Sep 2020
Location: <optimized out>
Posts: 275
|
|
![]() |
![]() |
#30 |
Registered User
![]() Join Date: Jul 2015
Location: The Netherlands
Posts: 2,693
|
I'm not actually sure that the average Amiga 3D game ran at 12FPS on the A500 though. That seems a bit high to me.
|
![]() |
![]() |
#31 |
Lemon. / Core Design
![]() Join Date: Mar 2016
Location: Tier 5
Posts: 891
|
|
![]() |
![]() |
#32 |
Lemon. / Core Design
![]() Join Date: Mar 2016
Location: Tier 5
Posts: 891
|
There were definitely some that ran at that frame rate though... look at Interphase, that seems to run up to 17fps at points.. obviously, all the old A500 3D games seem to start chugging when scenes get busy, polygons get large etc..
|
![]() |
![]() |
#33 |
Registered User
![]() Join Date: Dec 2017
Location: Gandrup / Denmark
Posts: 127
|
Maybe look at model complexity. I tried to remodel the plane from F18 interceptor, by looking at screenshots, and it came out to about 37 Vertices, and 25 faces.
Compared to the 52 vertices and 49 faces of your model, it might give you some small fps. improvement. |
![]() |
![]() |
#34 | |
<optimized out>
![]() Join Date: Sep 2020
Location: <optimized out>
Posts: 275
|
Quote:
But, making a decent looking model with less detail is a very hard thing to do. |
|
![]() |
![]() |
#35 |
Lemon. / Core Design
![]() Join Date: Mar 2016
Location: Tier 5
Posts: 891
|
for extreme distance, you could just use a pixel plotter.. and maybe plot 1 pixel for various parts of the plane.. the wing tips, 3 dots along the fusalage(the nose, the middle, the end), and one at the top of the tail fin.... you would probably get the similar"scintilation" effect that you'd get rendering polygons at that distance
|
![]() |
![]() |
#36 | |
Registered User
![]() Join Date: Jul 2015
Location: The Netherlands
Posts: 2,693
|
Quote:
Both Deimos and Ernst got fairly low FPS on A500 compared to these numbers and do so consistently. As they both seem to be quite capable coders, it seems to me there's some "missing ingredient" regarding the old-school vs new-school performance difference. No idea what it is, but if older games consistently ran much smoother there must be something going on ![]() |
|
![]() |
![]() |
#37 |
Lemon. / Core Design
![]() Join Date: Mar 2016
Location: Tier 5
Posts: 891
|
I would say that most of the old 3D games were probably written in 100% hand oprimised 68k.
Might be interesting to disassemble something like Interphase. The Assembly Line had a really good 3D engine. I was talking to Andy Beverage about it some time around 1991 when he was in town for a UK game developers conference. They also used the same engine for Cybercon III, and added the ability to draw curves, convincing ellipses and cylinders |
![]() |
![]() |
#38 | |
<optimized out>
![]() Join Date: Sep 2020
Location: <optimized out>
Posts: 275
|
Quote:
The draw distance is very small, objects are constantly "popping in", and it's about 2/3 of the screen once you take the borders into account? It's also very 2D, there's no real height, and apart from the camera, objects don't really seem to rotate 3Dly, so they might be a bit like my tank, only moving around in one plane, which allows you to drop some of the calculations. The lack of height may mean they don't have to do any clipping, they can just ignore bits that fall off the screen as they rasterise the polygons. Also, I'm sure they were better coders than me and not afraid of assembly. Edit: After thinking a bit, I don't think they are doing the traditional full object + camera transform, I think they are moving the objects to their location relative to the camera and then doing something like the 6 multiplication rotation that was in Jobbo's thread the other day to rotate the camera. If I'm right (sometimes it happens) then their calculation phase is about 1/3 of mine Last edited by Ernst Blofeld; 17 January 2021 at 19:57. |
|
![]() |
![]() |
#39 | |
<optimized out>
![]() Join Date: Sep 2020
Location: <optimized out>
Posts: 275
|
Quote:
|
|
![]() |
![]() |
#40 |
<optimized out>
![]() Join Date: Sep 2020
Location: <optimized out>
Posts: 275
|
|
![]() |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
68000 optimisation | Galahad/FLT | Coders. Asm / Hardware | 9 | 20 August 2016 01:29 |
Picasso IV optimisation | Tony Landais | support.Hardware | 10 | 01 September 2006 20:54 |
|
|