The level on Halo: Reach where you fly the starfighter (which is the best level in any of the Halo games I've played to date (admittedly I haven't played Combat Evolved (or Wars, but that doesn't count)) has "inspired" me to make a space combat game. I'm not writing any serious code yet because I haven't thought up a name or story, but I've been writing "pre-code". At the moment I'm working on two things mainly; one is the map generator (since it's a space-based sidescroller I want to generate maps on-the-fly) and the other is the particle system. I'm also writing the kind of "infrastructure" of the game engine (primitives like Vector and Color classes as well as an Animator class for, well, animating things) as I go along.
Anyway, my question is about recommendations for particle effects. How do other people do them?
Currently I have a Particle class and a SmokeParticle class. My idea is for the Particle class to deal with common Particle stuff, like updating the position and velocity based on constant acceleration, a given time, and the equations v = u + at and s = vt - 1/2 at2. The SmokeParticle class will then make itself expand (using the Animator class) and increase it's luminosity (as the particles expand they go from black to white). When it reaches a certain size its Update method will return "false" and the game will delete it. Something which I somehow only just thought about is the fact that the probably the entire game will be in space, so I don't know how the particles will move. I guess they'll have a certain acceleration depending on the force of the explosion and then continue moving at the same speed "forever" (read: until I delete them).
Does this sound like a good method of programming smoke? And what about other particle effects? I probably won't need to deal with water in space but I'll need fire and plasma for explosions and the thrusters of ships.
Thanks! I haven't gotten to the graphics stage yet, I'm still trying to figure out how everything will work first.
[edit] I guess one advantage of making a space game is that I don't have to make any sound effects... Or at least, no difficult ones like explosions or anything. Just some beeping sounds for the cockpit controls and stuff like that.
Yeah, they will spread out, and I will decrease the alpha channel but also they should go from a darker to a lighter grey. I'll play around with it and see how it goes, anyway.
Perhaps particles can be given a specific velocity depending on what created them, and why it created them. Example, an exploding ship could send out shrapnel particles flying in all directions, but only send smoke in the direction opposite to its own velocity. Having some sort of global particle handling system would simplify effects like these drastically.
I was thinking of having every particle handle its own physics so that instead of programming them spreading out, it's an emergent behaviour. I have a Particle class and I'll have a SmokeParticle class, and then a Smoke class which consists of multiple SmokeParticles. That's what I was planning to do for every particle effect.
Here's a question: How would I make particles glow?
That's what the additive blending is for. Well, more or less. It lets the brightness build up as the particles accumulate.
When it comes to a glowing effect (as in, the light spreads out from the particles) I'd suggest looking into bloom shaders. You'll need to implement multiple frame-buffers to let yourself render to a texture, which is necessary for bloom. This may also require a set of frame-buffers for both standard objects and bloom-rendered objects, since I don't think you'd want your ship to be glowing as well. This will bring up some issues when it comes to depth-testing, so I might suggest using separate render-buffers in each frame-buffer and then using a unified depth buffer.
An alternative would be a sort of "optimal" particle, which would have a texture of infinite size and each pixel would contain a transparency that would be calculated based on the inverse-square law. This isn't possible, of course, and creating something similar to it (read: as close as possible, with 8096x8096 textures) in Photoshop would require the use of 16-bit (or even 24-bit, depending on how anal-retentive you want to be about it) channels, which may lead to some compatibility issues when it comes to loading those images.
As such, creation of such intricate particles would be better left to procedural methods, where floats would be used in each channel to properly preserve the luminosity of each pixel.
Definitely not an easy question to answer. The simplest method is to just throw bloom everywhere. The next best would be to implement the smart-bloom, and after that would be the procedurally-generated particles.
Something you could also do as a cool project would be to render each particle to a frame-buffer as a point, and apply a pixel shader which would "grow" the effect. I'd imagine that this would give much nicer (and more accurate) results. The only issue I can really think of (aside from the intense GPU processing) would be doing proper depth-testing with such an effect, but I can't imagine it being too complex.
I'll see what I can find in one of my books on this. I'll get back to you in a minute.
What I've Found:
- If you were using DirectX, you could make use of its exclusive geometry shader to produce and manage particle data directly on the GPU (theoretically, would require DirectX 10 or later)
- Bright-pass filters are pixel-shaders which retain the brightness of already-bright pixels, and dim darker pixels. This can be used for emphasis and providing a sort of placebo-bloom
- "Streaking" of light effects can be done by rendering to a frame-buffer and, instead of using a call to glClear, rendering a transparent quad over the whole scene. This can also be applied for cheap motion-blur effects.
Personally, I like the idea of combining bright-pass filters with bloom. The book (Real-Time Rendering) gives a demonstration of the two in conjunction, and the results are stunning. It also mentions the separation of rendering for objects that require bloom, which is good to know because the above post was just off the top of my head.
is a bit of an overstatement. I went into a few too many conceptual topics for my own fun there (I love development of visual effects in games), and didn't really put much emphasis on the truly recommended option. I apologize for that.
Basic bloom on the entire scene should be fine. You can forget about unintentionally making meteors glow, and work out the separation of filtering later. Once you've got the bloom effect down, the rest should be fairly easy. There are plenty of resources out there for implementing bloom, and the concept in itself isn't too complex.
EDIT: To comment on the original point of the topic, which was the logic of handling particles, management of particle effects isn't all too complex. At least, so long as your not doing anything like Boom Boom Rocket (http://www.youtube.com/watch?v=MNcSgzKaaIo). For the most part, you'll be spending time tweaking fade rates and messing around with how colors blend to make the best-looking effect.
If you're just making explosions, let each particle manage themselves. If you're getting into particle effects which need to be "coordinated," then let the particle manager handle everything. But letting a particle do its own thing doesn't really have an advantage over being controlled by a particle system. In fact, handling logic within the particle system itself is often simpler than having to separate the code. But when you get into more complex things (i.e. particle collisions, particle attractors, etc., not just "coordinated" effects), advantages begin to show themselves.
All I want the particles for is explosions and the engines of spaceships, so I don't think I need much co-ordination between particles. If I give them an initial velocity and constant acceleration they should do the rest by themselves as I described in the OP. Hopefully, that'll be all the co-ordination I need. If I do need more co-ordination it shouldn't be too hard to add it in later since every type of particle will be implementing the same interfaces and deriving the same classes.
NGen wrote:
"a lot" is a bit of an overstatement. I went into a few too many conceptual topics for my own fun there (I love development of visual effects in games), and didn't really put much emphasis on the truly recommended option. I apologize for that.
It's fine, good even. I get the same way - whenever I explain even the smallest subset of a topic to someone, I inevitably end up describing everything I know and think about the subject.
NGen wrote:
Basic bloom on the entire scene should be fine. You can forget about unintentionally making meteors glow, and work out the separation of filtering later. Once you've got the bloom effect down, the rest should be fairly easy. There are plenty of resources out there for implementing bloom, and the concept in itself isn't too complex.
I'll do that and see how it turns out. If I need to fix any glowing meteors I can do that afterwards.
Before bothering with bloom, I'd try just using the additive blending. Apply the above glBlendFunc when rendering "bright" particles and then swap back to glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA). The effect might be enough for your purposes, and glow might not be necessary. I just pulled up a program I made a while ago using additive blending, if you want to try out the effect:
glBlendFunc is available in practically all versions of OpenGL (even OpenGL ES, as I've found) and shader support is subjective. I used SFML in that program, so I can't confirm anything else on that subject. As with any other exotic OpenGL program using SFML, the integration wasn't exactly difficult. So, to directly answer your question, I just use whatever is required for the functionality that I need. My graphics card has OpenGL 3.1 support and my desktop has OpenGL 4.0 support, so the specific version for a feature isn't something that I worry about.
Generally I've used the SDL and SFML and have avoided GLUT, as I don't like how it takes control of program flow away from me. When I need some serious speed with 2D I might move to HGE, which provides plenty of utilities for those sorts of applications, but it relies on DirectX 8 and forgoes any shader support. In general I've been looking to get into DirectX, as it caters directly to game development and has a few interesting features (like that geometry shader I mentioned before) that OpenGL lacks.
I'm assuming your toolset for this sort of thing is pretty similar?
Well, my graphics card supports OpenGL 3.3 but I only have Mesa 7.11 (OpenGL 2.1) on Linux and 4.0 (OpenGL 1.3!) on Windows, which I'm working on fixing (it's harder than it sounds).
I'm planning to use SMFL with OpenGL as well (although from what I've been reading it's starting to sound like OpenGL sucked prior to 3.3...).