Jump to content


Photo

Changing Performance


  • Please log in to reply
18 replies to this topic

#1 acrog2

acrog2

    average user

  • GMC Member
  • 1118 posts

Posted 27 February 2009 - 03:34 AM

Many, if not all, commercial games have a 'performance' or 'detail' settings, or in the case of pc games, many settings such as resolution and different graphics and physics modes, that can be changed to increase the performance of a game at the cost of some graphic detail or physics accuracy. Many of the games are programed in different languages that offer lower level control of the hardware and textures. My discussion is how to apply scalable performance to game maker games.
It is quite obvious that gm has some performance issues, and the performance does not scale well from my experience. It ether lags or it doesn't. 3d is one of the slowest aspects to gm. I don't want this topic to be specific to 3d, but I do foresee a large part of the ideas relating to 3d. Some other areas that gm lags are: (Post any items you would like to see added to the list)
  • 3d
  • particles
  • physics
  • path finding, and other algorithms
  • large resources

One method of improving speed of those items is to just get rid of it. This is only really practical with particles. A lot of the games I have played have options to turn off particles to speed up the gameplay. As particles are purely graphical, there should be no interference with the game by disabling particles, but some effects like blood are eliminated, subtracting from the overall experience.
You obviously can't disable 3d, but you could use pre-canned animations for physics, but then there is the issue of increased memory usage, which could have worse affects on the performance than the physics.

Another issue with gm, is that their is not much significant benefit from simplified algorithms. Take this brute-force method for checking prime numbers:
PRE
for(i=1;i<sqrt(num);i+=1){
if (num div i) = num/i
return 0}
return 1

This is far from the most optimum method, yet it is not much slower than:
PRE
 if (argument0 mod 2 == 0) {
return 2;
}
var add,i,lim;
add[1] = 2;
add[3] = 4;
add[7] = 2;
add[9] = 2;
lim = sqrt(argument0);
for (i = 3; i < lim; i += add[i mod 10]) {
if (argument0 mod i == 0) {
return i;
}
}
return 1;
(I think this was provided by Yourself in an old topic)
The speed of the different methods is hardly noticeable in any real world application.


Sometimes, the performance settings uses algorithms that are faster, but less accurate, such as the application of path finding. So at high performance it uses something like mp_potential_step(), while at quality, it will use mp_potential_path(). The former will get you a good enough ruff estimate, while the latter will find close to the most optimal method. I can't find any other examples of algorithms that have a settable level of precision.

Physics would probably be the most complicated to implement. You could skip on some of the unnecessary calculations, but leaving the major ones that have a noticeable effect, like gravity.

So what methods do you use for varying performance, or do you think that it is a waste of time because of gm's inherent speed issues?

let the discussion begin.

-acrog2
  • 0

#2 KC LC

KC LC

    Ex-Administrator

  • Retired Staff
  • 5309 posts

Posted 27 February 2009 - 12:52 PM

...and the performance does not scale well from my experience. It ether lags or it doesn't. 3d is one of the slowest aspects to gm.

This is false. The frame rate doesn't suddenly drop when you cross some "threshold". It drops gradually, in a very predictable way, as you increase the overhead. The amount of "lag", i.e., reduction in maximum frame rate, is directly proportional to things like:

-- number of 3D primitives and/or models
-- complexity of the d3d transformation stack
-- size and color-depth of the textures

I suppose there could be some abrupt drop in performance when you actually completely fill the video buffer... but good programmers don't let this happen.

The reason many users experience lag in their 3D games -- usually first-person games -- is simply because they draw unnecessary objects. That is, objects that the player cannot see. These are usually objects in front of the player, but that are blocked by room walls, for example. Clever programmers place invisible "thresholds" at strategic locations. When a player crosses a certain threshold, that determines which objects are draw or not draw.

Frankly, I'm amazed how fast 3D can run if you take some time to optimize the code. I recently posted some mechanical simulations that run (if I let them) at 250 - 500 frames/sec. I clamped them at 60 Hz so they'd run the same on all machines. And that's with a background calculation that integrates several differential equations at a 1800 Hz!

Particles can be optimized too, without much loss of quality. For example, many beginners make the mistake of creating particle explosions whenever they need them. Instead, the particle system, particle definitions, and emitters can all be defined ahead of time. Each particle system is assigned a flag to determine whether its DRAW event is executed.

When the flag is set by some event, the DRAW event is executed ONLY ONE TIME, and then the flag is reset for the next event. The explosion still occurs over many frames because of the particle lifetimes.

There are many ways to optimize GML code (or any code). The key is asking which calculations are really needed in the STEP / DRAW events, and which ones can be pre-calculated in the Creation event. And for STEP event calculations, you can further optimize them by identifying duplicate calculations (such as trig calls for the same angle) and doing them ONCE at the start of the STEP event and then re-using the results.

None of these ideas are specific to GML. They're all just common sense.
  • 1

#3 TheMyst

TheMyst

    GMC Member

  • New Member
  • 166 posts

Posted 27 February 2009 - 05:37 PM

Another thing to take into account would be monitor resolution and the resolution the game is run at. Allowing the player to change the resolution from say 1680x1050 to 800x600 would be an embarassingly easy way to increase overall performance. You also have to remember that performance all boils down to what hardware the user has.
  • 0

#4 Yourself

Yourself

    The Ultimate Pronoun

  • Retired Staff
  • 7343 posts
  • Version:Unknown

Posted 27 February 2009 - 10:13 PM

Clever programmers place invisible "thresholds" at strategic locations.


Typically called portals.
  • 0

#5 acrog2

acrog2

    average user

  • GMC Member
  • 1118 posts

Posted 28 February 2009 - 01:28 AM

@KC LC
Those are some good ideas as far as speeding up a game, but I was thinking more along the line of accuracy/performance trade off.

take this example of calculating the area of a irregular sprite. It checks to see how many non-transparent pixels there are. It is as optimized as I could get it, but is still slow due to the use of surface_get_pixel()
PRE
//returns the number of pixels in a sprite
//arg0 = sprite
//arg1 = image index
//returns pixel count
var sur , i, j, que, ctest;
que = ds_queue_create()
sur = surface_create(sprite_get_width(argument0), sprite_get_height(argument0))
ctest = make_color_rgb(237,198,36)
surface_set_target(sur)
draw_clear(ctest)
draw_sprite(argument0,argument1, sprite_get_xoffset(argument0), sprite_get_yoffset(argument0))
surface_reset_target()
pc = 0
for(i=0;i<sprite_get_width(argument);i+=1)
for(j=0;j<sprite_get_height(argument0);j+=1){
if surface_getpixel(sur,i,j) = ctest{
ds_queue_enqueue(que,i)
ds_queue_enqueue(que,j)
}
}
cp = ds_queue_size(que)/2
surface_set_target(sur)
draw_clear(c_white)
draw_sprite(argument0,argument1, sprite_get_xoffset(argument0), sprite_get_yoffset(argument0))
surface_reset_target()
while ds_queue_size(que) > 0{
if surface_getpixel(sur, ds_queue_dequeue(que), ds_queue_dequeue(que)) = c_white
pc +=1
}
surface_free(sur)
ds_queue_destroy(que)

return sprite_get_width(argument0)*sprite_get_height(argu
ment0) - pc


Then this rough estimate:
PRE
wh = max(sprite_get_width(argument0) ,sprite_get_height(argument0))
sur = surface_create(wh,wh)
surface_set_target(sur)
draw_clear(c_white)
draw_sprite(argument0,0,0,0)
ctest = surface_getpixel(sur,0,wh)
for(i=0;i<wh*sqrt(2);i+=1){
if surface_getpixel(sur,i,i) != ctest
a = i break
}
for(i=wh;i>0;i-=1){
if surface_getpixel(sur,wh-i,wh-i) != ctest
b = i break
}
surface_reset_target()
surface_free(sur)
return sqr(b-a)


The second method is far faster, but the accuracy is far from that of the first method, which is pixel perfect.
  • 0

#6 KC LC

KC LC

    Ex-Administrator

  • Retired Staff
  • 5309 posts

Posted 01 March 2009 - 12:35 PM

Those are some good ideas as far as speeding up a game, but I was thinking more along the line of accuracy/performance trade off.

Maybe a good example of trade-off between speed and accuracy is the full Verlet integration versus the simple Taylor approximation. The Verlet update for position is:

$x(t+\Delta t) = 2x(t) - x(t-\Delta t) + a(t)\Delta t^{2}$ (Check this pinned topic if you can't read these.)

Combining the forward and backward terms is sort of like an interpolation to the equations of motion -- and that helps with stability. Trouble is, I usually have to iterate the EoM many times per display step anyway... so I'm not sure there's any benefit. I just use a simple integrator:

$x(t+\Delta t) = x(t) + v(t)\Delta t$
$v(t+\Delta t) = v(t) + a(t)\Delta t$

No need to keep track of old positions, so it's a lot simpler/faster. Anyway, I find this works fine.

Another place there's REAL time saving (at the expense of accuracy) is how you apply constraints. Like when you have fast-moving objects colliding with each other and with walls -- they can get "stuck". The usual solution is to constrain the objects to some minimum separation R. So you apply this between object pairs when they collide, and iterate at the end of each time-step to removed any overlap between them:

$x_{c}(t) = x_{u}(t) +0.5\Delta x(\left |\Delta x \right |-R)/\left |\Delta x \right |$
(where the c and u refer to the constrained and unconstrained positions)

Works great, but it's pretty time-consuming if you have lots of objects. So to save time, I use one of two options:

1. Only apply/iterate the constraint every Nth step
2. Don't apply it at all. Instead put a "user button" that activates N iterations of the constraint equations when a player pushes. The player only presses the button if things get stuck in walls (or to each other).

Number (2) isn't very professional :P but it's better than having the game freeze and forcing the player to re-start.
  • 0

#7 gamer freak

gamer freak

    Voice of Logic

  • New Member
  • 402 posts

Posted 01 March 2009 - 06:53 PM

@KC LC
Those are some good ideas as far as speeding up a game, but I was thinking more along the line of accuracy/performance trade off.

take this example of calculating the area of a irregular sprite. It checks to see how many non-transparent pixels there are. It is as optimized as I could get it, but is still slow due to the use of surface_get_pixel()

PRE
//returns the number of pixels in a sprite
//arg0 = sprite
//arg1 = image index
//returns pixel count
var sur , i, j, que, ctest;
que = ds_queue_create()
sur = surface_create(sprite_get_width(argument0), sprite_get_height(argument0))
ctest = make_color_rgb(237,198,36)
surface_set_target(sur)
draw_clear(ctest)
draw_sprite(argument0,argument1, sprite_get_xoffset(argument0), sprite_get_yoffset(argument0))
surface_reset_target()
pc = 0
for(i=0;i<sprite_get_width(argument);i+=1)
for(j=0;j<sprite_get_height(argument0);j+=1){
if surface_getpixel(sur,i,j) = ctest{
ds_queue_enqueue(que,i)
ds_queue_enqueue(que,j)
}
}
cp = ds_queue_size(que)/2
surface_set_target(sur)
draw_clear(c_white)
draw_sprite(argument0,argument1, sprite_get_xoffset(argument0), sprite_get_yoffset(argument0))
surface_reset_target()
while ds_queue_size(que) > 0{
if surface_getpixel(sur, ds_queue_dequeue(que), ds_queue_dequeue(que)) = c_white
pc +=1
}
surface_free(sur)
ds_queue_destroy(que)

return sprite_get_width(argument0)*sprite_get_height(argu
ment0) - pc


Then this rough estimate:
PRE
wh = max(sprite_get_width(argument0) ,sprite_get_height(argument0))
sur = surface_create(wh,wh)
surface_set_target(sur)
draw_clear(c_white)
draw_sprite(argument0,0,0,0)
ctest = surface_getpixel(sur,0,wh)
for(i=0;i<wh*sqrt(2);i+=1){
if surface_getpixel(sur,i,i) != ctest
a = i break
}
for(i=wh;i>0;i-=1){
if surface_getpixel(sur,wh-i,wh-i) != ctest
b = i break
}
surface_reset_target()
surface_free(sur)
return sqr(b-a)


The second method is far faster, but the accuracy is far from that of the first method, which is pixel perfect.


You can save it to a bmp file, and then read the bytes to get the color. It would probably be much faster in this case. You can check out the scripts I made for reading a bmp here: http://gmc.yoyogames...howtopic=419921
  • 0

#8 acrog2

acrog2

    average user

  • GMC Member
  • 1118 posts

Posted 01 March 2009 - 09:45 PM

Those are some good ideas as far as speeding up a game, but I was thinking more along the line of accuracy/performance trade off.

Maybe a good example of trade-off between speed and accuracy is the full Verlet integration versus the simple Taylor approximation.

That is exactly what I was talking about. So if the performance setting was set at performance, it would use the approximation, but in detail mode, the actual calculations would be use. I need to run some test to see how much of a performance gain there is in using the Taylor approximation vs. Verlet integration.

-acrog2
  • 0

#9 KC LC

KC LC

    Ex-Administrator

  • Retired Staff
  • 5309 posts

Posted 02 March 2009 - 04:28 PM

I need to run some test to see how much of a performance gain there is in using the Taylor approximation vs. Verlet integration.

Tests are always useful. But the results will depend on the PDEs you're integrating, and the number of iteration steps you can cut. So the results will apply case-by-case.

It's like a cost-benefit analysis. The benefit of using full Verlet depends on whether its overhead increase is smaller than the overhead you save in evaluating the PDE themselves. If you're evaluating several PDEs per iteration -- like displacement and angle for multiple objects -- and you can reduce the number of iterations by some fair amount, you might save time.

If (delta-time increase for Verlet) * (Number of iterations) < (PDE evaluation time + Taylor integration time) * (number of iterations saved)

...you'll save time.
  • 0

#10 hanson

hanson

    GMC Member

  • GMC Member
  • 444 posts
  • Version:GM8

Posted 04 March 2009 - 04:54 AM

Another factor in 3d applications is the level of detail(lod) of models drawn on the screen. Often based off the distance from camera to object, a highly detailed model is drawn when player is very close to object, a bit less detail as it gets further away, and so on until eventually replacing it with a billboard(flat face rotated to face camera) at the lowest detail system and/or not drawing it at all when it is unnecessary. Allowing the user to decrease lod for all models displayed will improve the drawing speed when implemented correctly. I believe that textures are also subject to lod methods, and one can use smaller textures that trade off quality for speed.

-hanson
  • 0

#11 GeEom

GeEom

    GMC Member

  • GMC Member
  • 218 posts

Posted 04 March 2009 - 05:52 PM

to break from the theoretical perfection that is the expert forum, a large proportion of mem. usage can be leaks, and as a full leak check on a complete game will take you 'lots of time * (1/patience) * code length' its always the best option to program with intent to close all the variables you asign in one design session, or atleast make note of what variables have been called and when they will become useless, so you can add remove points later

anyway
i find in my games, mostly top down, i have a high graphical effect:gameplay feature ratio, but alot is progressive
in my current work, where you play as a tank, skid marks are placed as objects, under certain circumstances, they have no effect on gameplay atall, in my notated plans ive said that before my first alpha release i will alow on my basic graphics page : low medium or high skid FX, high being all inclusive, medium having a higher alarm period with a higher alpha negative (less smoothe fade, but a large % of each objects active mem. usage) and a less acurate placement system, whereas low disables this purely graphical option.

the same is easily found in all good games, do we realy need particle effects on EVERY projectile, is a custom particle maelstrom nessesary upon each explosion, wont effect explosion do (of not, high graphics all the way, but think of the poor people with only laptops and school computers, remember if a game is marketable from the indie developing world, aka us, then its hitting those who simply cannot run stalker clear sky, etc.)

there are always variables that you can step down,

another good point is never use extended functions beyond need, GM has alot of function sub sections for , lets say, draw, but if you dont need to colour, dont put the processor thru that extra 60 bytes that works out that you want the default colour!
  • 0

#12 Qwertyman

Qwertyman

    C&D Games

  • New Member
  • 1178 posts

Posted 07 March 2009 - 07:01 PM

Physics would probably be the most complicated to implement. You could skip on some of the unnecessary calculations, but leaving the major ones that have a noticeable effect, like gravity.

Frankly I don't see how the original post was made into an expert's topic. In a physics application, you don't just 'skip' some 'unnecessary' calculations, while leaving 'major' equations like 'gravity.' The only type of physics engine where gravity is calculated differently than other forces would be an extremely simple one. Generally, most forces are treated the same. Different forces have different equations to determine their magnitude. For instance, drag varies with velocity, whereas gravity does not. However, once the magnitude is obtained, all the forces are added up a la d'Alembert and applied to the object.

If you're programming physics into a game, you only add the type of physics you need. You don't code a drag simulation only to have the user take this out later. Generally physics have an integral part in game play. Sometimes they are just there for pretty effects, but making a physics engine efficient is the same regardless, as I am about to explain.

The way you make physics run 'faster' is to decrease the precision. You can do this a bunch of different ways, for instance, you can decrease the number of steps per second you calculate the physical world. You can decrease the collision detection accuracy. You can calculate using single or double precision. But you don't just say, "Calculate gravity but nothing else." I mean, technically you can, but just calculating gravity leads to objects falling through the world floor. And like I mentioned earlier, gravity is calculated in much the same manner as other forces. Therefore, what you are really describing is decreasing the overall amount of calculations you need to make, which is taken care of by my explanation.

Another way you increase physics efficiency is by coding right. However, this is a programmer's choice and not the user's, so it doesn't bear any relevance to this topic.

Physics engines really require their own topic, and aren't really related to 3d engine efficiency at all.
  • 0

#13 -=ReNeX=-

-=ReNeX=-

    GMC Member

  • New Member
  • 403 posts

Posted 11 March 2009 - 05:40 PM

when i was developing my 3d game, i had a very fast computer, about 2.8ghz. But in the middle of the developing it broke, so i had to switch to the old P4 (by old, i mean a defective version of a Willamette core, known for being slow).
and the game ran at 4% speed.
After that, i was forced to create a detail system, since i could not even test the game at that speed.

the detail level can be changed by the user at the options screen, and goes from 0 to 3.

the detail level directly interferes with:
-the number of steps for round basic shapes
-the strength of distance lod for these shapes (so for example they draw '8-5*lod+detail' steps)
-the number of polygons for rounding each cell of the 3d terrain and the splatting layer
-the amount of filtered textures
-the complexity for building models (there are 3 levels for each model, progressively simpler)
-the number of subdivisions for the shadow polygon
-the number of rounding routines applied to the script that returns the terrain level
-the number of steps between each 3d sound update
-the usage of dynamic lighting, flexible nature effects and water spitting

and the following optimization methods are always active:
-at the room start, an algorythm returns a cropped 'zfar', so that the z-buffer has a higher precision
-when the player is not facing the sun, the script that checks whether the sun is hidden does not execute
-when the characters are in the air, 70% of their physics is disabled
-when the module of the difference between the vector pointing outwards the camera and the vector pointing towards the given instance is larger than the projection angle, the instance goes invisible
-optional wheather effects, such as rain, drops on the camera glass, lightning etc. are made using simple 2d primitives, and drawn over the 3d scene using an ortho projection
-3D sound is calculated only every 1/3 second
-regular gradient sky is drawn using an unhidden 100x100x100 skybox (using the GmNomonic extension)
-3D sounds that do not require doppler are simulated using pan and volume
-racing place calculation only happens when characters move a reasonable distance
-every static object consisting of more than 2 basic shapes is made a global model reused by similar objects
-all sound is low-sample, compressed wav_EX format to improve filesize and loading time (even if that costs on kernel usage)
-unused resources are freed to save memory (memory usage does not exceed 80MB under normal conditions)
-alternate input devices are checked only if they are selected
-80% of image resources do not preload
-every script uses internal vars whenever possible
-2d-triangle collision only calculated when specified object is close enough to the specified triangle
-nature effects, such as trees, bushes, grass, are set in wide groups controlled by a single instance
-collisions are treated in objects of which there are fewer instances
-game courses are encrypted, compressed, binary files of 5KB each (that includes terrain, texture coords, positions, walls, instances etc.) using the SDT format*
-scripts have been heavily optimized, removing crap and condensing algorythms
-big image resources are compressed and included as gif and exported only upon room loading before first use
-big sound resources follow that too with the wave_EX format (a 3MB file becomes 400KB)

after all that, in the medium detail, the game runs now at 92+-8% speed, in the same computer.

And i really agree that gm is extremely slow with 3d transforms:

(no Lod, higher detail setting, drawing the whole environment)
fps---number of characters
400---0
120---1
50---2
30---3

if it was not for that, i would have made the game 60fps.
And its not about my code; its about the complexity of the character model, that requires exclusive transforms for each component. that would be different if gm had some compiled transform functions, such as 'd3d_transform_add_rotation(xadd,yadd,zadd)' instead of 'd3d...x(xadd) d3d...y(yadd) d3d...z(zadd)' since most of the time they are called in this order.

And about disabling parts of the physics, i actually use that: when the character is on the air, it should not be able to accelerate, brake, turn, rotate, receive friction etc. so i "skip some unnecessary calculations" (70%) and it simply falls and checks the ground, that are the "major" equations. And somehow the physics is related to the 3D speed as soon as it is 3D physics: the more complex the environment, the more complex the physics, affecting the overall render efficiency.
Previous comparation, without physics:

fps---number of characters
400---0
230---1
130---2
80---3

and probably, 2D physics for the same purpose would be so light it would not even bother the speed at all.


*i created the SDT format, it saves terrain as cells and instances as vectors for a really tiny filesize, and loads reasonably fast, using a single step.

Edited by -=ReNeX=-, 11 March 2009 - 05:45 PM.

  • 0

#14 Rexhunter99

Rexhunter99

    GMC Member

  • GMC Member
  • 922 posts

Posted 21 March 2009 - 01:17 PM

You can save it to a bmp file, and then read the bytes to get the color. It would probably be much faster in this case. You can check out the scripts I made for reading a bmp here: http://gmc.yoyogames...howtopic=419921


What's cool about 24-bit BMP images is that we can load the color as a LONG INTEGER and use that as a GM color constant :GM072: for example:

byte1 = 255 //Red
byte2 = 0 //Green
byte3 = 0 //Blue
byte4 = 0 //Alpha

And the long integer it returns is exactly the same as the constant, c_red

So we won't actually need to read each color component as a byte but all the 4 values as a constant color value.

Edited by James_ogden, 21 March 2009 - 01:20 PM.

  • 0

#15 acrog2

acrog2

    average user

  • GMC Member
  • 1118 posts

Posted 21 March 2009 - 03:32 PM

@ReNeX Those are some important optimization tips, and I like how you implamented a single detail control that controls everything that is purely graphical or does not have a large affect on the gameplay.

@James_ogden The gm color constants are nothing more than the decimal representation of the color in hex format of: RRGGBB.

-acrog2
  • 0

#16 Rexhunter99

Rexhunter99

    GMC Member

  • GMC Member
  • 922 posts

Posted 04 April 2009 - 07:36 AM

@James_ogden The gm color constants are nothing more than the decimal representation of the color in hex format of: RRGGBB.

-acrog2

Duh,

0xAARRGGBB (or 0xRRGGBBAA (I think it's actually BBGGRR ;))

But the GM constants are made up of four bytes (GM runs using strings or doubles, but we'll consider it to be a long integer for beneficial purposes)
  • 0

#17 smart_monkey

smart_monkey

    GMC Member

  • GMC Member
  • 91 posts

Posted 06 April 2009 - 03:37 AM

I have made a benchmarking test for my 3d game. It tells you what level of graphics is appropriate for you computer by seeing if the FPS went below 40 with the amount of particles.

Any 3D game I have written normally goes down to the amount of particles or the view distance. Physics have never slowed down a game for me unless you wrote some terrible code which I highly doubt if you were able to write the physics yourself.

I have also used/seen a system where if the fps drops down, the view distance and detail of every object was dropped untill to fps started going faster again. I think Crime Life III has that system. Its very effective as you wouldnt need a options menu to set graphical settings.

But over all of this, I prefer limiting the particles or if its a 3D level, do simple things like make the level smaller in segments or make objects active only when you can see them. Like KC LC said, its common sense. Just compare everything to real life.

I cant see behind me so why do I draw it?
Everything loses detail the futher it is away from me. I could use that.


Thats what I base my performance features. I think there is some tutorial that helps with 3D speed and I have never seen a good 2D game lag.
  • 0

#18 blue_chu_jelly

blue_chu_jelly

    Shut your FMaj7

  • GMC Member
  • 228 posts

Posted 06 April 2009 - 12:21 PM

when 3d objects are further than a certain distance away you could always draw pre-rendered sprites in place of the actual polygons.
  • 0

#19 -=ReNeX=-

-=ReNeX=-

    GMC Member

  • New Member
  • 403 posts

Posted 28 July 2009 - 07:45 PM

My last bulky post here is from a long time ago, 4 months... During this time i improved the game detail so much that it needed some more fresh LOD techniques. So i returned to this topic to update the list.
They are:

-at the beginning, the camera is set a zfar value exactly equal to the room's diagonal, so that nothing important is cut and it gets improved precision for the z-buffer.

-all game objects were turned into models, except for dynamic shapes (which had their number reduced).

-all repeated transformations were turned into generic scripts, which were confirmed to speed up.

-every simple/small object were turned into a screenshot texture for a billboard.

-every texture larger than 64x64 is made a gif, exported and loaded only on the loading proccess of the room where it will have its first use.

-every half a second, a script runs on every heavy object (complicated composite shapes) setting it invisible if it is not inside the view pyramid, or if it is raining, if it is beyond the fog. also, there is a maximum distance at which it automatically becomes invisible.

-since trees (or a lunar module) are too big and/or obvious to simply disappear like rocks or grass, they become billboards after the max distance. It caused popping, though, that was later solved by manually calculating an average lighting level based on fixed, fine tuned ratios in the beginning of the room, then using that as the base color to draw the background. Works smooth and fast, and the popping can only be noticed if you are directly looking at it.

This scene has 174 trees, of which only 3 are actually 3D, due to the low detail selected. Also, there are 62 bush groups with 5 bushes each. The average fps is 70%, which is GREAT compared to previous versions.
Posted Image

-All basic-shape step-count lod calculations were removed, and replaced by the usage of models to speed up.

-When in distance, the physics for the opponent cars is run only each 3 speps, with tripled force values to balance, and their sound is updated only each 4 steps, until it becomes not audible at all, at which point it is stopped.

-Tire marks are only created each 2 steps for the player and 3 for the other cars, and slowly vanish. also: they instantly disappear when not inside the view pyramid.

-When a car/object is invisible by distance, it does not generate any effect instances (like smoke) or updates sound.

-All distance calculations that compared with fixed values were replaced by a script that does not require a sqrt() call, which speeded up a lot.

-If the count of each effect instances are too high, they will degenerate much faster to recover the speed.

-the terrain model, which is the biggest model, uses a small tiled texture and has a very little triangle count (4 tris per cell), and it is culled. Also, no more corner rounding. it made it look much better, but it bugged the height script and was very heavy, with 12 tris per cell.

-all heavy proccesses (like big arrays, textures, files, exports, sounds, lighting, and textures) are preloaded during the loading proccess for the room, so it does not interfere with the game speed.


Even though a bit specific for racing games, some of these techniques are useful for most 3d environments, and some even 2D environments. Just wanted to share what i found during the development of the game.

--And in the end, another bulky post from -=ReNeX=- xD!
  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users