tricks of the professionals

Blitz3D Forums/Blitz3D Programming/tricks of the professionals

Jager(Posted 2003) [#1]
ok, time to guess on how some of these modern games do their tricks, and how, possibly it could be recreated in BB3D. I need this as my game has hit a FPS barrier, put 60 figures on my screen and I get 2 FPS on my K& 600 Mhz.

The game I'm talking of is Rome Totalwar where they have the ability of using vast numbers of animated meshes without apparent speed problems? (i would like to know their FPS figures)

I know one trick is to use very low poly figures and quality textures to hide the chuncky figures. I'm using this

Another one is possibly to use 2d Sprites for figures not close to the camera???

Any help would be appreciated.

Time for blitz to jump ahead of the cutting edge. :)


Warren(Posted 2003) [#2]
Yeah, it's just all the obvious stuff. If something is far away from the camera, LOD it to a lower poly version or a sprite.

Figure out what your problem is first though. For example, if it's texture memory thrashing, lowering your polycounts isn't going to help at all.


sswift(Posted 2003) [#3]
One way of speeding up rendering a lot of units is, as you said "sprites".

The correct term though is "Impostors". You render the view of the 3d object from the current camera view, and determine if the angle or distance of the rendered image relative to the camera has changed enough that you need to re-render it.

Unfortunately, if you have a camera which can move around a lot, then you end up having to re-render the impostors almost every frame, which can cost you more than just rendering the object normally. The ideal sorts of titles for using impostors are RTS games with a fixed camera viewing the action from above, or a flight sim, where you need to render clouds made from thousands of particles so that you can allow the player to fly through the clouds.

I use such a technique for rendering my shadow maps. I determine if the shadow map has accumulated too much error, and if so I re-render it. This creates a huge savings on framerate when renderign shadows from static meshes, but until recently I could not really apply these savings to animated meshes because there was no way to determine which frame of an animation the mesh was on.


Jager(Posted 2003) [#4]
I just removed all the textures from the 60 characters, without any improvement in speed. textures isn't the problem.

And after rewatching the RTW teaser movie, I couldn't see any obvious sprites or LOD? plus they say it is all meshes.

Removing animations gives me 12 FPS, from 2 with. I wonder if that's the trick? only have a maximum number of characters animating at one time in the viewing area? .. hmmmm?

Most probably I need to upgrade my computer but I was hoping to test my game and get it running efficently on my 600 MHZ

Also, anyone like to explain multi-threading?


Litobyte(Posted 2003) [#5]
Polycount, polycount, polycount.

And asyncron updates
(do not update all of your objects at every render loop !!!)

You should occlude and LOD all of that mess :-D
EG:
you have 400 soldiers, 800 knights, 1200 swords and shields plus scenery in you scene, ok, let's draw (render) only the 49 or 248 that the scene( camera view ) requires.

Also, use proficently CameraRange.
A small range camera range (such as 1,1000) will allow you to render everything faster.

My game, with a camera range of 0.1, 5000 (which is very wide) rendered at half speed ! (25 fps against 45 fps )

So again:

Models LOD (max 200 polies for unit when far, max 1000 poly when close to them, 4000 poly in cutscenes)
(think also that when camera is far you will look at eg: 500 100-poly units, but when very close to combat action, they will be 5-10 <1000 poly units.

Appropriate CameraRange / Fogging(optional)

Scenery and units occlusion (if applicable).

All that will help a lot!


RexRhino(Posted 2003) [#6]
Jager:

Jager, one of the things I think they do is have a real polygon soldier, that they render one for the synced animations, and then copy it multiple times as a sprite. The benifit of doing this (as opposed to just having the graphics pre-canned as a sprite), is that the sprites are rendered in the same "style" as your graphics card, so it looks pretty seamless.


IPete2(Posted 2003) [#7]
Jager,

I'm not sure if this will help or not. Surface count is a definiote killer of fps with B3d.

Try using a single surface replacement/standin for your soldiers and see what the rendering difference is then.

Textures tend to be a problem when each figure has multiple textures mapped onto them.

We were doing something similar with vehicles, 20 textures per vehicle. It became 'dog slow' suddenly after only 14 different vehicles were on screen. We reduced each of the vehicle textures by making a larger texture map (one or two per vehicle) and remapping everything - one on one.

Suddenly we could have upto 28 different vehicles on screen! A great result.

Hope this helps,

IPete2.


Jager(Posted 2003) [#8]
Thanks all.

Rex, your idea sounds ideal ,I'll try that next.

But I think RTW use all meshes so there must be another trick? (or they lie! heaven forbid! :)


FlameDuck(Posted 2003) [#9]
you have 400 soldiers, 800 knights, 1200 swords and shields plus scenery in you scene, ok, let's draw (render) only the 49 or 248 that the scene( camera view ) requires.
It's called "view frustrum culling" and Blitz3D already does this for you. You just have to make sure all your "units" are seperate entities.

Personally I can get about 500 individual 12 poly objects going at about 30 fps on my PC. You can test yourself by grabing the file "anitest.rar" off my website. For you, that means at least 3000 units on-screen using srites. Oh and if it's anything like "Shogun: Total War" then saying "it's all meshes" while *technically* correct, is still probably stretching the truth a little too far...


Anthony Flack(Posted 2003) [#10]
You mean, it's all meshes, but some of the meshes are quads?

Heh.


Stickman(Posted 2003) [#11]
[It's called "view frustrum culling" and Blitz3D already does this for you.]

Funny..........
I just about finished including my own "view frustrum culling" routien and reduced my poly count down by a 3rd.

Im working on BackFace Culling now,witch should reduce this number even further.

[img
http://members.aol.com/awskyril22/images/culling.jpg]


Jager(Posted 2003) [#12]
I was going to ask Zurk what he was talking about. Stickman, I'm all ears. Are you saying you can soft code a VFC that's at least 30% BETTER than the one currently in BB3D! :O (shock!) WOW! I want! Does this mean a new RenderWorld command?

I would prefer total meshes (as this is probably the future with faster machines) but at the moment sprites seem to be the only way to get adequate response times on a slow computer.

Rex's ideal of on the fly sprites sounds seemless, am testing it now. Luckily there's code available to get the 2D dimensions of a 3D object .. funny that! :) Only problem is you couldn't have a large number of individual soldiers doing different things at once, on the screen (RTW doesn't have that either, is that the indicator they still use sprites?)


Litobyte(Posted 2003) [#13]
Ok, I was fast.
It is right, about what's not inview of the camera, if a separate entity will be not rendered.

But I'm saying, if they are not in view, they should'nt be updated (only type variables x,y,z but not the physic), so basically entities not in view will play hidden, as they were in a table rpg, even if they are not rendered, they are still being calculated. FPS don't decrease only for videomem charge and poly count.


Litobyte(Posted 2003) [#14]
I don't know for an rts game, but what I know, is that if I'd update all of the buddies of my game, always in all their things (movement, thinking, collisions, shadow), I'd kill my application to a lower than 25 FPS with a P3 866 gf2mx32mb. This caused for the too hi poly and for the too much calc.

After the "VIS" routine I added for the enemies, I could have up to 10 "creatures" moving around the level, with no laggs.

1st:
Make asyncronus update, and not consequential (not sure about my english here)

Do not: "for each type-->updatetype" but use the AFTER, NEXT FIRST instruction to make it loop manually, then decide the rate of update of them. (you will know this rate, only juding by yourself looking at your game)

2nd, even better would be

separate the updates routines for your warriors

like:
updateLogic(w.warrior)
updatePhysic(w.arrior)

you will have update phis. in a plain for each type loop,
and the updateLogic, in the contest described above.

Hope it helps.


FlameDuck(Posted 2003) [#15]
I just about finished including my own "view frustrum culling" routien and reduced my poly count down by a 3rd.
If you had bothered to read the *entire* statement, instead of just running your mouth, you would have noticed that part where it says that "it only works on entities". If you want proof grab "anitest.rar" off my site, and add a TrisRendered call. You'll notice that although the ammount of cubes remain constant at all times the number of triangles can fluctuate quite a bit. Especially if you increase the spawn area beyond the view frustrum.
Im working on BackFace Culling now,witch should reduce this number even further.
Nope. Because Blitz also does that for you. Oh, and before you post another screen trying to prove me wrong, note that TrisRendered only returns the number of tris sent to DirectX (that's right, before backface culling) and not the number of triangles *actually* rendered.


Stickman(Posted 2003) [#16]
I did read your entire statement.
I didnt run my mouth, I ran my fingers across the keyboard ....

I did go to your site and I cant seem to get your site to download the file.Keep getting error (page unavalible)

My Tries rendered that was Printed on the My Screen shot was actualy a For\Next loop of COUNTTRIANGLES() command
OF ALL the entites Not Blizes actual TRIESRENDERED command. I guess triesrendered is just a good word for the refrence of.......

Im not tyring to bust your chops,

I would realy like to know that if blitz is culling and clipping all the Tries not in the view spectrum,and
If CountTriangles()or TriesReandered wont return the actual number of tris in view.
then how do I get at what and how many tries are in view and actually being rendered?


Anthony Flack(Posted 2003) [#17]
I have a feeling that your videocard may do some culling of triangles, after blitz has done its thing (and therefore after the counttriangles()


FlameDuck(Posted 2003) [#18]
I did go to your site and I cant seem to get your site to download the file.Keep getting error (page unavalible)
Here's a deep link for you, see if that works.
I would realy like to know that if blitz is culling and clipping all the Tries not in the view spectrum,
No. Blitz culls all *entities* not in view. Culling triangles will probably give you a bigger performance hit than just rendering all the triangles would have.
how do I get at what and how many tries are in view and actually being rendered?
You can't. AFAIK DirectX doesn't count how many triangles it renders. But you know how many triangles you just sent to the render pipeline. Somewhere in between, DirectX and the graphics driver does it's "magic".


Stickman(Posted 2003) [#19]
The DeepLink still gives the same results.

I hate to keep wasting Jagers Post space on this as for its gotten a little off topic( sorry ).

FlameDuck,can I email you a compilled demo to show what Im doing ((( my Freesever wont allow files more then 1.mb they suck.))),where It will use Makebot as the Origin Point and all tries will be Clipped on X,Y,Z of the View Frustrum Triangle from where MakeBot is standing ( as apposed to camera origin).

I just wnat to know if Im wasting my time trying to get somthing to work that I dont even need to do Or Blitz my be doing for me.

As I said Im clipping all "Triangles" at the start of Pipeline before anything else is even Rendedred.


Rob(Posted 2003) [#20]
May I clarify that Blitz will not cull your children if the parent is still visible.

This behaviour may have changed, but check to be sure.


Jager(Posted 2003) [#21]
all eye's on me ,people :)

So your saying Blitz3d is very efficient in using DirectX 3D object commands, which in turn uses the maximum capabilities of most (NVidia) graphics cards????

This would mean professional developers are constrained by these limits as well?

Once again I ask, what is Multi-threading, is that going to be a major boost to modelling performance?


Stickman(Posted 2003) [#22]
Jager,
I just noticed your using a GeForce2 MX400 64mb card.....

I have the same card ( with .3082 drivers )and been noticing that with my screen resolution set heigh ( 1024,768,32 )that it will kill my frame rates teribly bad. Even on profesional games.

Try reducing your screen resolution with blitz's Graphics3D Command to 640,480,16.DO "NOT" Run in windowed Mode, and see if this makes a differance with you programs frame rate.


Jager(Posted 2003) [#23]
stickman, done the changes suggestd but not one ounce of difference.

I think On-The-Fly sprites are the answer, as Rex suggested. Problem is I don't have the programming skills required to do this.

I suspect it would need to ;

(1) load a mesh, texture and adjust it, hide it.
(2) create 50 sprites. locate all.
(3) as cammera moves towards sprites / hidden mesh (or visa versa), backbuffer(?) snapshots of mesh are taken (in relation to camera) then dumped on all sprites.

Sounds doable but needs low level functionality to be so. Would require a method of grabbing 2D image of hidden, animating mesh in same proximity as camera to sprites .. if you know what I mean? %<~~

The beauty of this systems is that figures would look seemless no matter how camera moved, and no stored snimated textures would be required as animations would be picked up from mesh in real time.

Help? :)


Warren(Posted 2003) [#24]
You're still rendering the mesh 50 times, you're just doing it onto a texture rather than into the back buffer. It doesn't magically remove those triangles from the rendering pipeline. It would, in fact, be slower than simply drawing 50 meshes since you're now adding the overhead of the 50 sprites and uploading 50 textures every frame.

You could amortize the cost over several frames if you don't update every sprite every frame I guess. But I imagine the savings are going to be minimal at best.


Stickman(Posted 2003) [#25]
Jager
Are you using a frame limiter (Like Marks RenderTween#)
If not this could help a lot as for each of you models
animations would be only be updated for each call to capture world ( or somthing like that ).

Marks Tweening is excellent at curring frame rate troubles ,its just that where you place the Call to the function in the loop could make a big Change In performance.

All I can say is If it wasnt for RenderTweening ,My View Frustrum Clipping code would Loose more frame rates than its supposed to gain.


Jager(Posted 2003) [#26]
Epicboy, I would have thought only having one mesh to render / animate etc would be a mile better than 50.

I have already seen this, 24 statically loaded sprites run at 35 FPS, 24 meshes animate at 9 FPS ...60 at 2 FPS.

1 mesh runs at around 55 FPS ... so 1 mesh and 50 sprites should run hot. Only problem is making the sprites look like meshes (seemless).

Stickman, not sure what your talking about but have added some code here


While Not KeyDown( 1 )


If MilliSecs() > oldTime
oldTime=MilliSecs()+1000
nfps=frameCount
frameCount=0
Else
frameCount=frameCount+1
EndIf

Text 10,10,nfps+" FPS"

Repeat
elapsed=MilliSecs()-time
Until elapsed

;how many 'frames' have elapsed
ticks=elapsed/period

;fractional remainder
tween#=Float(elapsed Mod period)/Float(period)

For k=1 To ticks
time=time+period
If k=ticks Then CaptureWorld

UpdateGame()
; UpdateSoldiers()

UpdateWorld
;PositionEntity water,Sin(time*.01)*10, 0.3,Cos(time*.02)*10
;PositionEntity water,Sin(time*.01)*10,water_level+Sin(time*.05)*.5,Cos(time*.02)*10

Next

UpdateSoldiers()
ResetTurnValues()

; annimate river
If Float(yy Mod 3) = 0.0
If xx > 16 Then xx = 0
RotateTexture watertexture, 90
EntityTexture water,watertexture, xx
xx=xx+1
EndIf
yy=yy+1

RenderWorld tween#
;Print tween

Color 255,255,255
Text 10,5, nfps+" FPS"
; Text 10,25, "Tween#"+tween#

If MouseHit(1)=True Then CameraPick(camera, MouseX(), MouseY() )

Text 0,40,"PickedX: "+PickedX#()
Text 0,60,"PickedY: "+PickedY#()
Text 0,80,"PickedZ: "+PickedZ#()
Text 0,100,"gLeft: "+gLeft
Text 0,120,"gTop: "+gTop
Text 0,140,"gRight: "+gRight
Text 0,160,"gBottom: "+gBottom
;Text 0,100,"PickedNX: "+PickedNX#()
;Text 0,120,"PickedNY: "+PickedNY#()
;Text 0,140,"PickedNZ: "+PickedNZ#()
;Text 0,160,"PickedTime: "+PickedTime#()
Text 0,180,"PickedEntity: "+PickedEntity()
If PickedEntity() > 0 Then
Text 0,200,"entity name: "+EntityName$( PickedEntity() )
EndIf
;Text 0,200,"PickedSurface: "+PickedSurface()
;Text 0,220,"PickedTriangle: "+PickedTriangle()

; Draw status panel
DrawImage( gStatusPanel, 0, (GraphicsHeight()-gStatusPanelHeight) )

Flip

Wend


Litobyte(Posted 2003) [#27]
Ok, so why don't you please try to read my post, then post again ?

It seems what I'm typing is made invisible but some sort of simpathy ink.


Stickman(Posted 2003) [#28]
I would keep your UpdateSolders() by updategame() on.

Whats your frame rate for tweening set at ?

Next.....
Listen to Zurk173 and sswift they are wright.As for trying to run 50 animated meshes all at once is a lot.

Your going to need to add some kind of Culling,Clipping,Occludding,Whatever to help speed things up so as your not running all animations at all times.

Looking back at some of the responses you have recived,You got your answers ,Now you need to get some code working to make it happen.

For its troubles like this that make game programing the challenge that it is.


Jager(Posted 2003) [#29]
Sorry Zurk etc, thanks for the points given but I feel they are more fine tuning rather than a major speed boost.

My current game design requires at least 200-300 warriors per side, that's 500-600 in total .. any change would require a major FPS boost.

Thanks for the ideas anyway.


Litobyte(Posted 2003) [#30]
You will update only 10 warriors each loop.

Suppouse you are fixed @ 30FPS.
In 1 second, only 300 warriors will be updated.
And the human eye, will almost not see that.

If you need more explanations, feel free to email me.
You can email me @[a mailto:tlintrami@...]


Jager(Posted 2003) [#31]
stickman, frame rate is set to same as Castle demo.


FPS = 30

period=1000/FPS
time=MilliSecs()-period


While Not KeyDown( 1 )

If MilliSecs() > oldTime
oldTime=MilliSecs()+1000
nfps=frameCount
frameCount=0
Else
frameCount=frameCount+1
EndIf

Text 10,10,nfps+" FPS"

Repeat
elapsed=MilliSecs()-time
Until elapsed

;how many 'frames' have elapsed
ticks=elapsed/period

;fractional remainder
tween#=Float(elapsed Mod period)/Float(period)

For k=1 To ticks
time=time+period
If k=ticks Then CaptureWorld

UpdateGame()

UpdateWorld


Next


etc
etc


Stickman(Posted 2003) [#32]
Jager,
That should be Ok ( 30 fps )

Last one. The Big One.......

How Many Polies Per Model ? ( solders )

If each Model is lets say 500 polies each X 50 Models=25000
Polies rendering at once.

Animating the Models won't kill your frame rate ( just try using Hideentity() on all your models after you set them animating and youll see what I mean.

Im gona try and get you a demo to show what Im talking about.( thought Id have it done today but I have to work some overtime at my job. )

In my demo I have 100 cylinders Animating and Moving about at Random all at once and I still can get 85 to 87 frames per second then to show what poly count can do to your FPS,I exchange the cylinders for MakBot,and the frame rate drops down to about 10 fps. Why..........

Each cylinder is a heararchy animation made up of about 50 polies each X 100 = 5000 polies. My Graphics card can handle 5000 polies ( GF MX400 64mb )

On the Other hand MAKBOT Ohhhh around 1000 polies for each Bot X 100 Bots=100,000 polies. Im surprised I havent locked up my PC on that one .

Understand somthing, Most Graphics Cards cant run real time Events with Safly more then 6,000 to 8,000(???)Polies on screen at once ( Oh yes it will draw the Polies,but can it move them around the Screen ??? )

Im not familler with what game your comparing to here but just to make you aware of some of the newest tech. going into games these days.....

PATCHES ( higher-Order surfaces )

Its the ability of a game engine to reduce the amount of polies a model has ( in real time ) in acordance to how many polies are being rendered to the screen ( field of view )

Basicly it will put a cap on the amount of polies to be viewed at one time and if new models are brought into view all the polies in the sceen are reduced a percentage so that the engine will stay within its capped limits.Or somthing to that effect ( much more complex thought )

So what is a good safe number of polies to render to a screen at one time ????
I HAVE NO CLUE. your guess would be as good as mine.

But just so you undrestand
Your going to have to find a way cut back on polies to get your Ideas to work.

Its what every game industy is doing the damdest to tdo the best.

Ill try and email you that demo in the next day or so.

Stickman.........


cyberseth(Posted 2003) [#33]
Blitz culls all entities not in view.


Not from my stand-point. In my FusionBall game none of my 16 players were being culled, and they were all separate entities. That is, I loaded one player mesh and used CopyEntity to make the 16 different players.

The difference between this and creating 100 cubes with the CreateCube() command, is that my players are all treated as one surface even if they are separate entities, able to be moved, rotated and resized as they like. Therefore I wrote my own culling routine which got my game running much faster. If I had 16 separate entities with separate surfaces, now that would be REALLY slow, and not worth Blitz's native culling.

The conclusion: Write your own culling routine, and use CopyEntity when you have more than 1 monster of the same type! The way that I did my culling was:

While KeyHit(1)=0
    For k=1 to frames
        ; GAME UPDATE SECTION
        For p.player = each player
            ShowEntity p\ent
        Next
    Next

    ; GAME DRAWING SECTION
    For p.player = each player
        If Not EntityInView(p\ent,cam) Then HideEntity p\ent
    Next
    RenderWorld
Wend


I'd show all entities for the game update for the sake of collisions etc. Then for rendering I'd hide the ones that weren't necessary. For a FPS with lots and lots of monsters you'd probably want to do it a bit differently.


Jager(Posted 2003) [#34]
Thanks all for help but I have 60 - 1,400 pol warrior meshes in screen, close up, all marching, in sync.




cyberseth(Posted 2003) [#35]
60,000+ polies on screen? No way, you need to cut that down to 6,000 at the most!! You need to do some serious optimilization of your 3d meshes to cut down the amount of polys they use.


Smurfpuss(Posted 2003) [#36]
hmm needs some work on making the poly count smaller i think like i think the textures is the best way to make a modell look good like cheak out warcraft3 it has lowpoly modells but great textures and they don't look that bad
ill say


joncom2000(Posted 2003) [#37]
I agree with cyberseth, that polycount is way to high.
Looking at that screen shot i would say you could get away with using a flat plane or quad for the troops not on the outer edge facing the camera, textured with a snapshot of the mesh troop a the correct angle. Which i belive is the answer some of the others have already given. Probable the way it's being done in RomeTW is some kind of cheat, just a very good one ;-)

Looks good, hope you can solve it.

Jon


Stickman(Posted 2003) [#38]
I got your return email.
As you can see now it is your poly count that is killing your frame rate.
If my demo was to dark try turnning up your monitors Brightness and contrast settings,That sould do it.My PC is in a brightly light room so I need to turn my contrast and Brightness settings to full to even see things.I woundered what the adverse affects on other machiness Might be.

45-50 fps Hmmm not as good as I would have hoped for but for trying to push 4000 to 8000 polies at a time not to bad. and at 800,600,32

Well I hope you make out ok from here.If you whant a beter understanding of things you could do.
I just bought a book called
Tricks of the 3D game Programing GURUs
Its first publishing is June Of 2003
Cant get more advanced than then that

Well Good Luck.


RetroBooster(Posted 2003) [#39]
LOL ok, this is realy bad (talking about the optimalization here) :P so lemme get you one lifesaver piece of advice... You see how all soldiers in the collum are standing perfectly the same except in different positions? So next time you try and pull something like this... render one soldier in the correct orientation onto a texture, then just plant sprites for all the soldiers and texture them with that rendered texture. That's 1400 + 120 = 1520 poly's rendered instead of 1400 x 64 = 89600 I realy shouldn't need to explain the preformance gain here!!! :P


Jager(Posted 2003) [#40]
Retro, that's my original idea, (see first post)

The problem is that predefined sprite textures (soldier rotated 45% for all animated shots) looks crappy on screen and requires a HUGE texture file.

A better way is to have on-the-fly sprites, taking snap shots as the camera/soldier moves. this would be seemless.

The problem with having the mesh on screen is getting clean textures (only soldier, no background) and what happens if the mesh is killed? Better to have a hidden mesh somewhere and 60 sprites. That's what I'm working on at the moment, having fun with hidden cameras.


RetroBooster(Posted 2003) [#41]
A better way is to have on-the-fly sprites, taking snap shots as the camera/soldier moves. this would be seemless.
<- that's what I meanth, you animate 1 soldier in a totaly empty area away from the game field (likefor instance a long distance above it where notthing but black can be seen) there you make a rendering of the current animation position every frame (or every time the camera position changes enough to need changing, incase the model isn't animating).

The problem with having the mesh on screen is getting clean textures (only soldier, no background) and what happens if the mesh is killed? Better to have a hidden mesh somewhere and 60 sprites. That's what I'm working on at the moment, having fun with hidden cameras.
<- as stated above getting clean textures is very simple, also if youfollow my maths to conclusion you'll notice this is actualy what I was talking about, 1 hidden mesh + 120 poly's / 2 = 60 single surface quads, for top preformance, or sprites if the single surface concept eludes you,mind you though it's much better as long asthey are all using the same texture.


Michael Reitzenstein(Posted 2003) [#42]
The trouble with rendering to the backbuffer is that you lose all alpha that was in the model. I *believe* masked textures will work properly, but if your models have any kind of transparency you will have to work it out yourself.

I recently wrote a proceedural texture generator using particles, and the lack of alpha meant I had to Read/Write PixelFast every pixel of every frame. Ouch.


Anthony Flack(Posted 2003) [#43]
I don't know if this is even possible, but I've thought about this before, and being able to render a model directly to a texture with alpha intact would be AWESOME.


Michael Reitzenstein(Posted 2003) [#44]
Absolutely definitely 100%. I believe many cards will not support it (some don't even support blitting to a texture) though.


RetroBooster(Posted 2003) [#45]
Yes Michael, it does limit your model to masked textures only, but on the other hand, for a game like this I wouldn't be bothered with that.


Litobyte(Posted 2003) [#46]
Dynamic LOD on copied entities is the way to go for your game.

soldier A: 100 poly
soldier B: 400 poly
soldier C: 1000 poly

Than subsitute each frame the model to be rendered considering its distance.

And an additional culling function may help also with that.


RetroBooster(Posted 2003) [#47]
As nice as Dyna LOD can be Zurk with these large formations of many models very close to eachother the LOD would have to switch to the higher levels only on a VERY short distance else in the case of the screenshotshow it'd still be 60 level C (1000 poly) models.


Jager(Posted 2003) [#48]
To the gods who control the land of Blitz3D.

Could I have a new function to copy a 2D image of a off-screen mesh to a texture with alpha etc

please, please, please, please.

I believe such a function could give Blitz the ability to produce state-of-the-art war games! (it's the only thing holding me back at the moment)


Anthony Flack(Posted 2003) [#49]
First you must offer a sacrifice.


Michael Reitzenstein(Posted 2003) [#50]
soldier A: 100 poly
soldier B: 400 poly
soldier C: 1000 poly


For a game like that, I would be more inclined to have

soldier A: A quad
soldier B: 50 polies
soldier C: 100 polies
soldier D: 200 polies


Jager(Posted 2003) [#51]
ok, I sacrific my first born to Moloch, ancient god of roast raptor :)



May the gods smile upon me and grant my wish!


IPete2(Posted 2003) [#52]
Can I ask a stupid question?

If they're at a distance away from the camera, what's wrong with not rendering them on the fly, but doing it step by step and saving the sprite textures in a pre-production process?

The sprites can then easily be put in position using types, and they can face any direction - you'll have to pre-process each of the 4 or 8 possible facing directions but it shouldn't be a problem.

This way you don't have to worry about processor overheads and whether the graphics card can blit textures or wait until someone else can write a function for you (which may not work on all graphics cards anyway).

Also it means you can do it now.

IPete2.


Jager(Posted 2003) [#53]
You mean I sacrificed my first born for NOTHING! :( .. sorry Achilles!

Having 8 different facing directions still isn't seemless, It's very obvious when moving the camera around. That's why I want on-the-fly .. I want professional looking sprites that pass for meshes.

I don't see how types will eliminate this problem?

Also, all 60 figures are close up,as per above picture (2 up)

See below, the warriors in the front are sprites, obviously so, the 12 in the rear are meshes. you can see the difference, of how the sprites jump from each 1/8 segment view as the camera moves.




Litobyte(Posted 2003) [#54]
Your render polycount should always be under 10.000 for optimum.

So make your calc, then write something down that render always a scene of < 10.000 polies.

cya


MadJack(Posted 2003) [#55]
Jager

Go for 1/16 segment views to get smoother rotational animation?


Jager(Posted 2003) [#56]
Madjack, oh no! 16 images per figure stance, per animation cycle, per animation type! ug! I'd have a animation data file bigger than a Harddisk :)

Zurk, thanks, I may try to put my meshes on a diet .. again! but i can only go so far.

What's really needed is On-the-fly sprites .. please, please, please, please Oh! gods of the underworld .. I'll pay for a fast function! :)


IPete2(Posted 2003) [#57]
Jager,

I only suggested types for their sheer speed of execution where large numbers of entities/sprites are called for.

I think I see your 'problem' from the shield placements, they look a bit messy. I have to say that like your tenacity, I am just not sure how to go about the request you have asked for - else I would attempt it for you.

IPete2.


Jager(Posted 2003) [#58]
IPete2, please don't tell me your the lead developer at Blitz Research :)


IPete2(Posted 2003) [#59]
Jager,

Hah! No - I wish!- Nah I'm just someone who likes to help when (and if) I can...

James @ Blitz support may be your man, or ask advice from Mark Sibly (THE man behind Blitz), he is very approachable.

Good luck,

IPete2.


Jager(Posted 2003) [#60]
do you know their email addresses?


IPete2(Posted 2003) [#61]
Jager,

blitzsupport@... is James e-mail address.

Mark Sibly is probably still available at: marksibly@...

Hope one of them can help.

regards,

IPete2.


mrtricks(Posted 2003) [#62]
With some of my code, it only slows down above 100,000 polys. I know optimisation is important, but which is MORE important - polycount or surfacecount?


Tranz(Posted 2003) [#63]
I can say quite confidently that surface counts have a greater impact on my frames per second than polycounts do.

This may not hold true for all computers, but it's certainly true in my tests.


Litobyte(Posted 2003) [#64]
If this is true, why this guy complain about 400 soldiers to be displayed, they should be the same surface, as they have the same texture ?


HNPhan(Posted 2003) [#65]
same texture doesnt mean same surface... its a bit more elabporated then that.
and its rather complicated to use single surfacing for complex meshes, but much easier for quads.


Litobyte(Posted 2003) [#66]
Yes but he could have the same mesh, and within the hierarchy, the 400 subchildren. In this way, if the children have a single surf, which is of the same texture of the others, then will be a single surface hierarchic mesh ? Maybe that could speed up things ?

And also he could Hide/Show the children of the "squad" entity.


HNPhan(Posted 2003) [#67]
nope
if he wanted to do that, he'd need to combine all those models into 1 single mesh, and have them assigned to individual bones to have them all in 1 surface, i hear that method isnt as fast as it sounds though.

hide and show should speed up, but u wont be able to use hideentity if its 1 single surface, ud need to move them very very far, outside of the camera range, but i dont think its gonna speed up much faster that way either, Hide and show would though.


jhocking(Posted 2003) [#68]
Zurk, every entity is at LEAST one surface. The number of textures only matters within an entity. Thus 400 child objects are 400 surfaces, assuming each only uses a single texture and regardless of how many textures total are used. 1 texture used on all or 400 different textures doesn't matter (for surface count anyway; 400 different textures might give you problems of vid mem usage.)


jfk EO-11110(Posted 2003) [#69]
Very good optimation tips in this thread. But speed optimation depends on the kind of game. For this Starwars Clones Warriors Scene it might be a good idea to use sprites, although some of them might look a bit like cardboard soldiers. If you want to use alpha Textures you will not only have to reset the alpa bytes of the texture, you will also have to rebuild the complete mesh each frame and add all Quads depending on their Z-Order or distance to the camera. Otherwise you'll come up with the well known z-order problems of alphaed objects.

Adding all Meshes to one mesh that will use only one surface is good idea. But some things must be done to make it work properly. Use only "Mesh"-Commands on the Quads until they are all added together (eg. no "SclaeEntity" or "PositionEntity" etc., use their Mesh-Equivalents). Use PaintMesh instead of EntityTexture etc. For PaintMesh you need a Brush: use the same Brush for all of the Quads. After adding all Meshes together they will all use the same Brush and therefore they will use only one surface. A thing that saves up to 40 Percent of Rendering time, seen in several Demos (Particles aso.)

Resetting the Alphabyte of the texture isn't that hard, at least it should be faster than rendering 100 thousand tris.
I would do something like this:

(the render is already copied to this texture, but alpha information was lost)
setbuffer texturebuffer(tex)
lockbuffer
tw=texturewidth(tex)
th=textureheight(tex)
for j=0 to th-1
 for i=0 to tw-1
  rgb=readpixelfast(i,j)
  if rgb=0
   writepixelfast i,j,rgb
  else
   writepixelfast i,j,rgb or AF000000
   goto done
  endif
 next
 if i<>tw
  for i=tw-1 to 0 step -1
   rgb=readpixelfast(i,j)
   if rgb=0
    writepixelfast i,j,rgb
   else
    writepixelfast i,j,rgb or AF000000
    exit
   endif
  next
 .done
 endif
next
unlockbuffer


this will mask all black texels and will use a semitransparent row on the x-contours of the soldier.

Of course you should use the Mode Bit 256 for this Texture (vram-resident texture manipulations).


GrumpyOldMan(Posted 2003) [#70]
Jager

I've also been looking at Rome Total War (as well as Medieval Total War before that) and the units are all definitely animated low poly figures (MTW was textured quads).Your first point is to cut down on poly size. If you have milkshape download some boned Half Life models and convert to b3d and substitute for your hoplite. Acceptable results with half the poly count, also have a look at some of the Rome Total War screen shots and you can see the chunky look of low poly figures.

I think your main problem is surface choke.

With all due respect to jhocking if you can get the meshes into one single mesh your surface count will drop down from 60 to 1 -IF- you can do the laborious work of renaming the bones and reindexing the mesh tris and bones. The b3d format will allow you to have separate animations as long as it is set up properly.

The main problem at the moment is that there's no utility or plugin to automatically weld b3d's together.

Cheers

GrumpyOldMan


Jager(Posted 2003) [#71]
Oldman, look at my life, I'm alot like you were .. :)

Low pol figures? how low do you recon? I've thinned my hoplite down to 1,700 pols .. I could go lower but don't seem to gain much speed increase (I've removed the helmet on all warriors, which only gave me a minimal increase?) I have noticed a substancial speed reduction from a non-animating mesh to animating one (1/2). (one trick to increase speed - don't animate all at once ... only those totally visible ... hmmmm)

Could you please explain textured quads? As you can see I'm a mug at this! :)

Also, what do you mean my hoplite mesh into 1 surface count?




John Blackledge(Posted 2003) [#72]
Notwithstanding the fact that a lot of this thread has gone over my head (- god help me, can I manage to finish my product without this level of worry? I hope so.)... I just thought that I'd mention that Seth's suggestion of hiding what isn't needed just before Render works beautifully.
His code:

While KeyHit(1)=0
For k=1 to frames
; GAME UPDATE SECTION
For p.player = each player
ShowEntity p\ent
Next
Next
; GAME DRAWING SECTION
For p.player = each player
If Not EntityInView(p\ent,cam) Then HideEntity p\ent
Next
RenderWorld
Wend

- has given me an extra 50% fps!
Thanks, Seth.


GrumpyOldMan(Posted 2003) [#73]
Hi Jager

Here is a musketeer I've been working on, at 393 verts and 778 tris.
<img src=http://home.ozconnect.net/victor/musketeer.jpg>

Textured quads are basically user created and controlled mesh sprites, rather than using the built-in sprite commands - major benefit is being able to merge them into a single surface.

With merging your meshes you also merge the surfaces into one surface. Try loading your hoplite, use Copymesh and then Addmesh to a new mesh (Createmesh), using Positionmesh
to get a spacing between the copies. You'll find there's a significant difference between 60 (or more) individual meshes and one mesh with 60 merged copies. I'm still looking in detail at what Addmesh does to animated b3d meshes.

Cheers

GrumpyOldMan


Jager(Posted 2003) [#74]
Thanks all but GOM, Still a bit vague on ..

''With merging your meshes you also merge the surfaces into one surface. Try loading your hoplite, use Copymesh and then Addmesh to a new mesh (Createmesh), using Positionmesh
to get a spacing between the copies.''

How will adding a new mesh to my copied hoplite mesh help? .. my head hurts .. :)

BTW, my hoplite was 946 vertices, 1592 triangles .. but I've sent him off to Jenny Craig again .. so hopefully by tomorrow no more johna-thin Coleman! :)


GrumpyOldMan(Posted 2003) [#75]
Hi Jager

Have a look at http://www.blitzbasic.co.nz/codearcs/codearcs.php?code=389 and http://www.blitzbasic.co.nz/codearcs/codearcs.php?code=575

Cheers

GrumpyOldMan


Jager(Posted 2003) [#76]
ok, just as a side issue, why can't I LOD a mesh? you can do it for terrain, why not Meshes? Aren't terrains just a mesh?

I've just seen Rob's code but that loads 3 seperate entites of varing detail, it's not automatic like terrain.

Maybe I could construct a low-low-low detail hoplite for far away shots .... hmmmmm ... interesting.

As with surfaces, I must be really dumb, I still don't get it! I know a surface as a triangle of 3 vertices and 1 face? so Milkshape states?

Here's my entity initialization code .. might help?


For x=1 To 60
phalanx2.warrior=CreateWarrior2(x,tx2#,tz2#)
Next

...

Function CreateWarrior2.warrior( Numb,x#,z# )

If Numb = FIRST_ELEM ; if first, load mesh

warrior_object=LoadAnimMesh( "UltraThinHop.b3d" )
hop_texture=LoadTexture( "samtxt.bmp", 4 ) ; 4 = Black for transparent

hopwalk1=ExtractAnimSeq( warrior_object, 1, 30 )
; Hoplite - shield side, spear angled forward
hopwalk2=ExtractAnimSeq( warrior_object, 31, 60 )
; Hoplite - shield front, spear angled forward
hopwalk3=ExtractAnimSeq( warrior_object, 61, 90 )
; Hoplite - shield front, spear leveled
hopwalk4=ExtractAnimSeq( warrior_object, 91, 120 )

ScaleEntity warrior_object,.020,.020,.020
TranslateEntity warrior_object,0,-1.25,0
RotateEntity warrior_object, 90,0,0
EntityTexture warrior_object, hop_texture

HideEntity warrior_object

; To allow mouse click to select object on battlefield
EntityPickMode warrior_object, 3

End If
; then create warrior, copy entity
p.warrior=New warrior
p\entity=CopyEntity( warrior_object )
NameEntity p\entity, "Objects"
p\entity_Type = 1 ; object
p\height_offset = 20

...

PosWarrior( p )

Return p
End Function

...

loop ; includes tweening etc not shown
getkeys()
movesoldiers() ; MoveEntity
end loop


IPete2(Posted 2003) [#77]
Jager,

I can't help you much here, but a surface is the full area of a mesh which makes up a mesh.

i.e. a cube has 6 sides, which is 12 triangles, but it can have just 1 surface. I know this is true, but why it is so I don't understand.

In Quill 3D, you can model a house, and export it, but it will only have 1 surface, even though it has walls, a roof and doors!

Perhaps it is to do with uv mapping? if you break an object into smaller faces and texture each face, I wonder if the surface count goes up?

As I say I don't fully understand it, but I know the cube example above is correct.

The forum could do with a knowldege pool which we can dip into for information, just facts about what we are involved in.

regards,

IPete2.


Jager(Posted 2003) [#78]
Bonehead has finally worked this out

.. as suggested months ago,

(1) use LOD meshes, Even though Blitz doesn't have this functionality (probably because it's too difficult to automatically reduce a user's complex mesh), you can create the reduced meshes yourself. You then SHOW the approprate one depending on distance from camera. Far off figures can be replaced by sprites or even textured blocks, it's too far to see any detail anyway.

(2) Use LoadMesh for a stationary soldier and use this where ever appropriate. This speeds things up substancially! My game will load 3 animated meshes and 1 static one, for each soldier type.

I still think on-the-fly sprites will increase speed even further, and is well worth pursuing.

Surfaces, I cannot get my head around for time being but I have enough to carry on.

Overall, thanks everyone for the help. One BIG advantage of Blitz is the user support and the quality people on this forum. Problem is, how am I going to fit all your names on the credit page??? :)


PaulJG(Posted 2003) [#79]
How about grouping some of them far away entity's ?. I mean, if you know that your gonna have at least 4 marching together - design them all as one object. (instead of 4 seperate ones)

Also.. when you go to do the far away models, if you can be sure which way they are facing - take out all the back polys completely.. I tried something simular, had a model that had 4 different side versions of itself. Saved stacks of rendering time, thanks to a huge decrease of polys.

Just remember though, one surface = 1 texture (unless you go into multitexturing - which will lose you the extra speed you've gained)

Took me a while to work out the relationship of surfaces, think of it like this..take your cube, open it up flat like it was made of paper) - now how many sides does it have ?

2.. but since you dont see the other side at the same time, its only 1

Seems that when you make the surface to start with, you think of a surface that joins each side up, and yet - when you get to texturing.. you gotta think of it differently ???.

We could do with a new naming term !?.


Zephar123(Posted 2003) [#80]
looking at your model you should be able to get it down to around 150 polys and have it look the same.


Mustang(Posted 2003) [#81]
(1) use LOD meshes, Even though Blitz doesn't have this functionality (probably because it's too difficult to automatically reduce a user's complex mesh), you can create the reduced meshes yourself. You then SHOW the approprate one depending on distance from camera. Far off figures can be replaced by sprites or even textured blocks, it's too far to see any detail anyway.


Yes - this the way to do it. Terrains CAN be automatically LODded because they are derived from HEIGHTMAPS, so it's relatively easy/fast to calculate new mesh... other meshes are different story altogether. Reducing polys from say, character mesh, is VERY difficult to do automatically, and reducing polygons also affects lighting and mapping (because they are vertex based) and of course animations... so it almost impossible to do on-the-fly. And hard even if do it "by hand".


Bouncer(Posted 2003) [#82]
Everyone seems to be confused about surfaces.

If you use copyentity in blitz, then entities are treated as a single surface. OR ARE THEY?

And what about if you texture these copied entities with different textures... does it make any difference?

And no quessing, just the ones who know... tell me the truth, I know it's out there ;)


jfk EO-11110(Posted 2003) [#83]
Blitz is making an automatic garbage collection. if you add a mesh with an identic Surface to an other mesh, blitz will use only one of them and free the other one. The same goes for Textures, Sounds and more: If you load them twice Blitz will use an Instance of the first one instead.

Copied Entities use the same Surface, even the same Verices. They only have their own set of "Entity" commands like Rotation aso. "Mesh" commands will affect all of them.

If you use paintmesh to edit the color of a copied Mesh, the Original will chanche its color too.