HomeHome  CalendarCalendar  FAQFAQ  SearchSearch  MemberlistMemberlist  UsergroupsUsergroups  RegisterRegister  Log inLog in  

Share | 
 

 My two cents/experience

View previous topic View next topic Go down 
AuthorMessage
Paril



Messages : 8
Date d'inscription : 2010-10-14
Age : 23
Localisation : Ontario

PostSubject: My two cents/experience   Fri Mar 25, 2011 6:25 pm

Hey there.

I had Spark sitting on my drive for a bit and thought I'd give it a try. I updated my working copy to the SVN and hooked my Quake 2 engine derivative to Spark to see how it works. I thought I'd post here as well to detail my setup process, problems I faced, and how I think they should be addressed in later versions of Spark.

First and foremost, I had to compile it. Opened the solution in VS2010, linked it to my SDL directory, and built. There was one tiny error on one of the macros (a new thing in the latest trunk version related to FATAL errors) that yelled at me that an else needed a matching "if"; could not find the problem, oddly enough, but I got it working anyways. This was just noted for the developer, I understand that it's a non-stable version Smile

Once I got SPARK compiled, I had to get the binaries and headers working in my engine. I linked up the debug.lib and added Spark.H/Spark_GL.h to the renderer's main source file. Built; no errors, no warnings, no conflicts. So far so good!

Now came the tricky part: what to do to test? I ended up copying the code in the Flake demo and forcing it to run on every renderer frame. My first run was problematic; you see, my engine uses vertex buffers, and SPARK's default GL renderer disables them without my knowledge consent. This was easily fixed by re-enabling the client states. Second problem: SPARK disables GL_TEXTURE_2D without my knowledge as well, so I re-enabled that after rendering. IMO, you should always check to see which states are enabled/disabled already before you assume it was disabled in the first place Smile

I got the Flake demo to work in my little test map; I was happy at this point, however since it used simple points there was obvious distance issues, so I switched over to the quad renderer, which produced crisp quads and proper visual no matter where I was standing.

Now, there were two big issues that I was facing with this particle engine at this point. The first is probably the most important so I'll cover it first: texturing. Texturing is a nightmare in this engine the way it's set up. It only allows for one texture per group. Now, this makes sense only if you're using particle tables, which you are in your samples; yes, these are indeed more efficient, but you also have to take into account the fact that most games have a lot of particle images, and image sizes are quite limited; it would be impossible to use separate textures on particles in the same group. Since there's no real samples in the trunk on how to address these issues (treat it as if each particle used its own texture rather than coords), I believe that at least a real sample should be given on this.

In my opinion, an abstracted way to display a texture on a per-particle basis should be developed whilst leaving your default implementation of a single sheet intact. My engine, for example, allows for materials on textures, the likes of which may change based on the time the object was spawned (known as "material time" internally); this would be impossible to recreate on SPARK.

Side note, I could not understand how to get SPK::Data working to store a simple pointer per particle; how do you implement "swap"? Shouldn't "swap" contain two pointers to SPK::Data rather than particle indexes?

The second issue is more of a side-issue; culling. There seems to be no easy way to do (abstracted/without modifying engine) per-particle culling based on the current situation. In my game, I'd like to cull particles that are behind the view using a simple dot product calculation, however I cannot find any way to intervene the system to stop specific particles from being displayed.

Those are my two cents on the current state of SPARK2. I have to say, however, aside from all of these problems, the API behind SPARK is incredibly clear and commented pretty well. I do propose, though, that you always include examples of each class that the user is expected to inherit if he must use them (such as SPK::Data), otherwise the implementations get lost in forum posts about 'how to use' and all of that.

-P
Back to top Go down
View user profile
Juff
Developer


Messages : 539
Date d'inscription : 2009-07-14
Age : 34

PostSubject: Re: My two cents/experience   Mon Mar 28, 2011 1:41 pm

Hi, thanks for your interesting post. I dont have time right now but i ll take some to answer it later on.
Back to top Go down
View user profile http://spark.developpez.com
Paril



Messages : 8
Date d'inscription : 2010-10-14
Age : 23
Localisation : Ontario

PostSubject: Re: My two cents/experience   Tue Mar 29, 2011 6:49 pm

Thank you.

I'd love to replace my homemade particle system with Spark's system as it seems much more mature - but these little issues prevent seamless integration Sad

Once I have these integrated, I'll look into working on buffered drawing and sorting to make the GL renderer more efficient for you guys.

-P
Back to top Go down
View user profile
Juff
Developer


Messages : 539
Date d'inscription : 2009-07-14
Age : 34

PostSubject: Re: My two cents/experience   Wed Mar 30, 2011 8:44 am

Ok, so to answer your post :


  • First point about OpenGL state that are set/unset within SPARK. I can check every states i'm using within a renderer to restore them at the end but this may be a little hard to maintain and potentially add some overhead. Anyway, I will take a look towards this solution. At the moment it is possible to use the GL attrib stack to save/restore states : Before rendering systems just make a call to the static method GLRenderer::saveGLStates() and after rendering call GLRenderer::restoreGLStates(). The OpenGL states after rendering will be the same as before rendering the particle systems.
  • Regarding point rendering, there is a way to render points in world size and no more in screen size : just make a call to GLPointRenderer::enableWorldSize(true) and then use GLPointRenderer::setWorldScale(float) to set the size. You ll have to call once the static method : GLExtHandler::setPixelPerUnit(float fovy,int screenHeight) to allow the conversion from screen size to world size.
  • About texturing : Having several textures per groups would be nice but unfortunately this will prevent the group from being render in a single pass. And batching a group is essential to get decent rendering performance. Of course, multi texturing could be used with a shader but the default implementation of the renderers were made with compatibility in mind. With the system I have, you can seperate your texture in parts and specify the index per particle with the parameter PARAM_TEXTURE_INDEX. As an interpolator can be attached to this parameter, you can also manage particle texture animation with this system. Moreover, texture 3D can be used to make smoother animations. The system can still be improved. For example allowing to set the zone of the texture per index (a real atlas) and not only seperate the texture in equal parts.
  • SPK::Data is a low level object used to store additional data per particle. In SPARK, data is organized in structure of arrays rather than the classical array of structure. This allows to be more cache friendly and also to allocate only the data needed per particles. In that way the SPK::Data stores data for the whole group and not only for a single particle. The swap only gives the particle indices so that the underlying implementation of SPK::Data knows what to swap (check SPK::ArrayData for an example). The swap is needed as particles data are swapped to always keep alive particles aligned, this allows to avoid costly reorganization of data when a particle dies for instance.
  • For culling on a particle basis, i dont think it is really worth the effort. Culling has to be done per system to me and this is possible as the bounding box of system is provided. Therefore if a system is outside the frustum, it is not rendered at all. A simple dot product per particle culls those behind the view but this is still a special case to me. What about the particles at the left/right of the frustum ? This adds frustum culling per particles which will be 6 dot products per particle. Sound a bit overkilling to me to handle a special case (system half visible).


So to conclude, all you say does not really appear as issues to me. Some stuff are adressable directly, other impose the writing of a custom renderer (with multi texture, per particle culling...) and this is how SPARK was designed : A core base and a customizable render system so that user can implement whatever functionnality they want easily.
Back to top Go down
View user profile http://spark.developpez.com
Paril



Messages : 8
Date d'inscription : 2010-10-14
Age : 23
Localisation : Ontario

PostSubject: Re: My two cents/experience   Wed Mar 30, 2011 1:18 pm

Fair enough; so from what I understand then, SPARK's grouping is what would enable me to use multitexturing? Group one per texture sort of thing?

The near plane culling is more or less to reduce overhead from rendering a shader/material, which takes time to set up and render (multiple passes for certain materials, etc etc..). The other four planes aren't really a concern.

I did not see the save state and load state functions, my apologies! I will use that next time Smile

Texturing is still a little confusing in this engine for GL. I do see where batching is concerned, but you have to take into account the fact that this engine uses several large particle images, and putting them all in one texture won't work for most systems (image size would be way over 8192x8192). My guess is you'd want me to split up the textures into usable groups (ie all explosion-related particles in one texture)?

I'll use the information you provided to try to get my implementation working again, and hopefully get a seamless integration into my engine. The only foreseeable problem is collision; how would I go about allowing collisions with my BSP (which also has movable brushes)? In the current implementation I use a trace function to retrieve solids in the way.

-P
Back to top Go down
View user profile
Juff
Developer


Messages : 539
Date d'inscription : 2009-07-14
Age : 34

PostSubject: Re: My two cents/experience   Thu Mar 31, 2011 5:07 am

I think there s a misunderstanding about texturing. Why are you talking about 8192x8192 textures ? Basically it is one texture per renderer and one renderer for 1 to n groups. So for instance for a fire particle system you have 2 groups : the flames and the smoke. Each group has its own renderer with its own texture. You can check out the fire demo, the explosion demo is even more significative as it uses a lot more different groups. Those demos are in spark 1 not spark 2 but the philosophy is the same.

For collision, you have access to the bounding box of the system, so per system collision is easy. If you want collision per particle, you need to write your own modifier (there is a modifier obstacle that handles collision against zones)
Back to top Go down
View user profile http://spark.developpez.com
Paril



Messages : 8
Date d'inscription : 2010-10-14
Age : 23
Localisation : Ontario

PostSubject: Re: My two cents/experience   Thu Mar 31, 2011 2:12 pm

Oh I see; see, I'm thinking of a renderer as one global system. That tends to be the generic understanding of how a renderer functions. I didn't check the source to the flame, that might be why I wasn't sure. When I thought of one global system, and the fact that one renderer = one texture, that you'd have to put every particle in one table, and the max texture size of most video cards these days is 8192x8192.

Using multiple renderers seems strange in its way; I had figured there was one renderer and you passed the texture data through the group.

-P
Back to top Go down
View user profile
Juff
Developer


Messages : 539
Date d'inscription : 2009-07-14
Age : 34

PostSubject: Re: My two cents/experience   Mon Apr 04, 2011 6:18 am

yes your right, the name may sound confusing. It is not a renderer with its usual meaning.(ie the singleton renderer of a 3D engine). As SPARK is meant to be plugged on any 3D engine, those SPARK renderers objects are meant to be plugged to the underlying 3D engine renderer. Those renderer objects act more as a policy to give to the real underlying renderer so that it knows how to render the particles. It works quite well this way. But you're right that the name is confusing. Actually I find that the name renderer goes well within spark with modifier, emitter... but conflicts with the usual renderer within a 3D engine. If you have a suggestion for another name for the class, dont hesitate !
Back to top Go down
View user profile http://spark.developpez.com
Rampollo



Messages : 14
Date d'inscription : 2011-11-30

PostSubject: Re: My two cents/experience   Fri Feb 08, 2013 6:53 am

wouldn't be more natural callin "renderer" just "material"?
Back to top Go down
View user profile
Juff
Developer


Messages : 539
Date d'inscription : 2009-07-14
Age : 34

PostSubject: Re: My two cents/experience   Fri Feb 08, 2013 7:23 am

Well it is indeed a renderer. A material sounds more like a POD to me...
Moreover I plan to refactor SPARK2 render system and use both renderers and materials. So you can have a renderer with several material to allow multi pass rendering (for postFX effects on particles for instance)
Back to top Go down
View user profile http://spark.developpez.com
Sponsored content




PostSubject: Re: My two cents/experience   Today at 3:44 am

Back to top Go down
 
My two cents/experience
View previous topic View next topic Back to top 
Page 1 of 1

Permissions in this forum:You cannot reply to topics in this forum
 :: English Forum :: Evolution (en)-
Jump to: