Jump to content
The Dark Mod Forums

particle request: candle smoke


Springheel

Recommended Posts

Thanks, I've downloaded it. I expect the invisibility problem is down to the filmstrip being handled wrongly. I didn't test filmstrips. I was too knackered after getting back last night to do any testing and just went to bed instead but it'll be my first job tonight. The weird way the particle quads vanish when used on a candle will be findable too, whether or not it's in one of the code snippets you've already pointed out. The way particle life span gets translated into position and rotation and alpha is a long list of calculations but it's not mysterious or difficult to follow. First thing to check is whether that smoking parameter you highlighted manipulated shaderparm 8. That selectively kills off particle quads early according to their age.

Link to comment
Share on other sites

Thanks, I've downloaded it. I expect the invisibility problem is down to the filmstrip being handled wrongly. I didn't test filmstrips.

 

The smoke isn't a filmstrip, it's just a regular .dds image with a blend add material. I can't see any obvious difference between it and other existing particles, though I assume there must be something. One possibility is that it doesn't have an alpha channel, and relies on the additive blend for transparency, but I presume some other particles work the same way.

 

The filmstrip is something I'm experimenting with for candle flames (actually, torch flames use a filmstrip right now too).

Link to comment
Share on other sites

Cheers. Yes I saw it was an ordinary particle just now. I did a step through in the debugger during my lunch break and saw it get drawn by the soft particle code completely normally. Except that it didn't show up of course :-) I have no idea why at this point but I'll figure it out after work. I'll have to put some diagnostic code in the shader program because the engine is drawing it ok.

Film strip is probably working right then, because softening works on the flames in braziers and fireplaces. The unused alpha channel isn't a problem. The softener adjusts the color channels instead. The search continues.

Link to comment
Share on other sites

I have problem 1 of 2 diagnosed: The reason why your new smoke doesn't show up with soft particles turned on. It does show up, it's just incredibly faint. The new candle_smoke material has vertexcolor turned off, probably because the new smoke texture didn't show up at all with it turned on when using the same particle parameters as the rest of the smoke effects, but vertexcolor does need turning on (it's required by the particle system itself, as that's the method it uses to fade particles in and out as they age, and to apply any color settings that you specified). The reason the new smoke texture didn't show up with vertexcolor turned on is that it's *much* darker even in its brightest spots than the existing smokepuff texture, so the smokepuff particle "color" setting of 0.06 0.06 0.06 left it too dark to see. If you change the "color" setting in the particle decl to 0.6 0.6 0.6 or higher instead of 0.06 0.06 0.06 it'll work much better.

 

The reason it looked different with soft particles turned on or off is that the soft particle drawing program assumes that you are using vertexcolor and applies it regardless of whether you used the keyword in the material file. It's required by the particle system so that's probably a reasonable assumption, but I will check later whether there are other materials used in particles that don't use it for whatever reason. If there are any such particles, many of the effects specified in the particle editor wouldn't work for them, but I guess I should test for the keyword in the material file anyway and prevent it being used if the material designer hasn't asked for it, if only to make sure there won't be any particles out there that look different when soft particles are in effect.

 

Now on to the blinking out / bobbing (still not decided which it is!).

Link to comment
Share on other sites

Problem 1.5 out of 2: the gas arrow cloud starting to fade then blinking out. Not tested this one, but I think it was simply because it lasts longer than candle smoke, and candles are set to hide their particle X number of seconds after they get extinguished, where X is set by the "ext_hide_delay" spawnarg.

 

Problem 2 out of 2: Blinking vs bobbing: we were both right!

 

As the procession of particles makes its way upwards, the oldest one at the top blinks out when it gets high enough, but it passes its orientation to the quad below. So yes the top one blinks out, but it appears to jerk downwards because the one below switches to match what it did look like.

 

This vid is at timescale 0.1. To make what's going on visible, I've restricted it to producing just 5 quads instead of 20, I've switched off the fading, and I've increased gravity so they are spread out more:

 

http://youtu.be/nMv_stMh384

 

I'll go examine the code to find out how to fix it.

 

Edit: "ext_hide_delay" is probably on the flame entity, not the candle holder

Link to comment
Share on other sites

Unpack that a bit for me in another thread and sure we'll try it :)

 

I was referring to the limitation to only use alpha-fading in LOD, eg. lod_fadein_range \ lod_fadeout_range

 

http://wiki.thedarkmod.com/index.php?title=LOD

 

If we can do vertexColor fading on LOD objects then LOD fading can be applied universally.

 

It was deemed impossible up to this point for func_statics.

Please visit TDM's IndieDB site and help promote the mod:

 

http://www.indiedb.com/mods/the-dark-mod

 

(Yeah, shameless promotion... but traffic is traffic folks...)

Link to comment
Share on other sites

If we can do vertexColor fading on LOD objects then LOD fading can be applied universally.

 

It was deemed impossible up to this point for func_statics.

 

The problem there is that as soon as we make it transparent, it can't be light-interacting any more. I can't think of an way round that...

 

Is this what's causing the problem described here?

 

I should think so. Seems the effect looks different to different eyes. It looked like bouncing rather than flickering to me too, but it turns out to be neither / both.

Link to comment
Share on other sites

I found the bug. There's a problem with the way the engine handles the randomizing of particles.

 

The engine wants to vary particles so that chimneys etc don't puff exactly in sync or exactly the same every time, but it needs to make sure that from frame to frame individual particle quads don't jump around the place randomly -- they need to appear to move smoothly. Like the rest of the renderer, it's also a stateless system -- no information is carried from one frame to the next. The way it gets to have all those qualities is that it uses a random number generator that spews out the same list of numbers for a given particle stage each frame. When a particle emitter starts up a random number sequence is initialized (seeded) using a few numbers: the particle's time offset, how many cycles it's gone through, and (optionally) shaderparm 5, which lets mappers start 2 identical particles in the same frame without them looking identical. For func emitters, the mapper doesn't have to remember to do it: the game code sets a random time offset before it passes the particle to the renderer for the first time. The starting position, path, and rotation speed of each particle quad are determined by numbers from that sequence, and then the age of the particle quad is used to determine how far along the "path" the quad is. When the next frame comes around, the parameters will be the same so the same sequence of "random" numbers gets generated and the particle quad moves smoothly.

 

How many of the random numbers from the sequence are used for each quad's calculations varies depending on its setup. Particles in a rectangular distribution use 3 random numbers in deciding their starting position. Particles in a cylindrical distribution use 5 for that. And aimed particles use more random numbers to work out their movements than view-aligned particles. But any given particle quad always uses the same number of random numbers each frame. So if the 11th number was used in generating "rotation speed" for a particle quad last frame, the 11th number will be used this frame too. When there are multiple quads in a particle stage (nearly always the case), the extra quads just carry on taking numbers from the same sequence. The second quad might use the 23rd number for rotation speed every frame.

 

The problem starts when the first particle quad dies. It stops consuming numbers from the random number generator, so suddenly quad #2 starts to get its numbers. Quad #2's age is still measured correctly, so it remains in approximately the right place, the right distance from the emitter, but its starting position, angle, and other characteristics are suddenly calculated from quad #1's random number set. And quad #3 will inherit quad #2 old numbers, etc etc.

 

I'm not sure how to fix it yet. It'd be tempting to simply have the code throw away the required number of random numbers when it decides that quad #1 doesn't need to be drawn, but it'd be unacceptable to break the "stateless" design pattern by having it remember how many numbers each quad needed last frame. Likewise it'd be unacceptable to put a list of the counts somewhere, which would mean remembering to update that list if ever we tweak the way particles are drawn. There'll be an elegant fix, I'm sure. I'll carry on looking.

  • Like 1
Link to comment
Share on other sites

EDIT: bad idea in this post! See below instead.

 

I put the decision tree that determines how many random numbers get used on the tracker.

 

I'm not sure there's a elegant fix :-/ The only way I can see to do it without remembering stuff or setting up a hard-coded table is to create an "isDead" flag for particle quads, and instead of having the program move immediately to the next quad when it determines that one is dead, we make it go through the motions that would normally be used to create the quad. But if the flag is set, those routines would simply consume their random numbers while skipping the rest of the calculations and the setting-up of the particle verts. Not exactly elegant, but do-able. Fortunately the code is well-confined -- only 2 functions consume random numbers, and only those 2 plus the function that calll them would need to know about isDead.

Edited by SteveL
Link to comment
Share on other sites

EDIT: bad idea in this post! See below instead.

 

No good, that's a horrendous solution :angry: I started to implement it to test it, but it's going to make an intolerable mess of the code. The ParticleOrigin function is complicated, and threading the "isDead" logic through it will make it almost unreadable, not to mention having to choose between (1) adding loads of replacement code for the complex calculations that don't need to be done, or (2) having to leave variables uninitialized which could lead to bugs later.

 

Going back to the original problem, we want this fixing so that we can use things other than shapeless blobs as particle effects. The new candle smoke, for example. So it's a fix worth having even if we haven't noticed it much with the existing particles (graymans's issue excepted).

 

I'm leaning in favour of a hard-coded function that determines the number of randoms to discard after all. It would replicate the decision tree that I put on the tracker. The cost of that is that for future particle development, the coder will have to remember to update the function if they change the way particles use random numbers. I would put a couple of well-placed comments in the code to draw their attention to the fact. That's much cleaner than the "isDead" implementation, at the cost of imposing a slight burden on future particle system developers. Does it sound reasonable?

Edited by SteveL
Link to comment
Share on other sites

Ok, I'm an idiot. The elegant solution is obvious. Wish I hadn't spent 2 hours thinking aloud in the thread now! :blink:

 

The above suggestions were concerned with how to find the right place in the sequence of random numbers when one or more quads has died and is no longer consuming random numbers.

 

There's no need to solve that problem, because there's no need for all the different quads in the same stage to share a random number sequence in the first place. They can each have their own sequence of random numbers. Instead of initialising the random number generators for each stage, using stage properites like time offset etc, we initialise it for each quad using those same stage properties plus the quad number! That way each quad in each stage gets a repeatable set of numbers of its own.

 

No repeated code, no flags to be passed to complicated functions, no need to touch any code other than the bit that sets up the random number sequence.

 

This will even simplify the existing setup in the engine. Right now the particle system maintains two random number sequences for each particle stage, because for looping/cycling particles there can be quads on screen from two different cycles at once, and we want successive cycles to look different. But if each quad has its own sequence, we don't need special case code for quads that happen to be in a different cycle.

 

There's no peformance cost for having more random number sequences. Each one is just a single number (int) that uses a fixed function to work out the next number.

  • Like 3
Link to comment
Share on other sites

I've finished testing and I've committed it, plus I committed new binaries for it (which also happen to be the first binaries built from our new vs2013 port from greebo), so if you update from svn you can continue refining the new smoke Springheel.

 

As part of this debugging session I discovered another possible improvement. Targeting and activating a func_emitter to turn it on and off is good only for cyclic particle effects, the ones that carry on chugging away forever. You can't trigger a one-off particle effect like candle smoke simply by activating the func_emitter. That's because func_emitters randomize themselves by setting a random time offset when they are activated. That is, they say something lilke, "My start time was 23.84536 seconds ago so calculate my particle quads from there". That's fine if the particle effect is a cycling one, but if it's a one-off effect you usually see nothing coming out, because the random time offset will usually be greater than the time the particle effect lasts. If your particle effect lasts 2 seconds and your triggered func_emitter decides randomly that it started 5.96789 seconds ago, you'll see nothing because the particle system will see that it's past its expiry date and draw nothing. If we change the func_emitter code to use shaderparm5 to randomize its quads instead of setting a time offset, then we'd be able to trigger one-shot particle effects.

  • Like 1
Link to comment
Share on other sites

I've finished testing and I've committed it,

 

I can confirm the smoke is fading nicely. Now I'm just working on how to get the first stage of the smoke particle, which is the single thin strand.

Link to comment
Share on other sites

Cool. By the way in 2.03 you can turn candles (and all light holders) on and off by activating them so an ordinary switch is good for testing even if it looks a bit illogical :) I remember discussing that with Obs who provided the script amendment but can't remember where so it might not be known. If you toggle it on andn off too quickly and repeatedly you can lose your smoke plume as candle flames have a timed event that shuts off the particle 6 seconds after they are extinguished, and the last-but-one switch off can catch you on the next round.

 

For the single strand, are you thinking of a filmstrip, or a static texture that rises upward slowly? I'm wondering whether the second option might be possible, either with a clamped texture on a rising particle quad with the lower part of the strand hidden in the candle body. or an unclamped texture that has "translate" settings so it scrolls its picture into view. Hmm thinking again I'm not sure translate works on particles. They set their own texture coords.

Link to comment
Share on other sites

For the single strand, are you thinking of a filmstrip, or a static texture that rises upward slowly?

 

To be honest, I have no idea. I'm mostly just muddling through and experimenting.

I'll happily take suggestions. :)

Link to comment
Share on other sites

Well, I thought I had it, but I've run into a problem. The smoke is two stages (like the original). Both stages are slightly offset so they start at the right spot...the thin stage 1 starts right at the wick and the thicker stage 2 starts above it. So it looks like the small wisp spreads out into the thicker smoke. This works great when the candle is vertical. But when the candle is lying on its side, the stages are offset horizontally, even though the smoke is world aligned and goes up. That means the small wisp and the thicker smoke are actually beside each other instead of one atop the other.

 

Is there a way to solve this? i vaguely remember an issue like this with movable torches, but I can't remember what the solution was.

post-9-0-35308900-1417378360_thumb.jpg

Link to comment
Share on other sites

The slider underneath Time Offset and Dead Time controls how strong 'gravity' is for these particles. Negative numbers indicate 'up' whereas positive numbers indicate 'down'. Checking the "World Gravity" box indicates the gravity should be aligned with the world gravity, otherwise it is aligned with the normal (direction) of the particle emitter.

 

This sounds like the issue you're having.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recent Status Updates

    • Petike the Taffer  »  DeTeEff

      I've updated the articles for your FMs and your author category at the wiki. Your newer nickname (DeTeEff) now comes first, and the one in parentheses is your older nickname (Fieldmedic). Just to avoid confusing people who played your FMs years ago and remember your older nickname. I've added a wiki article for your latest FM, Who Watches the Watcher?, as part of my current updating efforts. Unless I overlooked something, you have five different FMs so far.
      · 0 replies
    • Petike the Taffer

      I've finally managed to log in to The Dark Mod Wiki. I'm back in the saddle and before the holidays start in full, I'll be adding a few new FM articles and doing other updates. Written in Stone is already done.
      · 4 replies
    • nbohr1more

      TDM 15th Anniversary Contest is now active! Please declare your participation: https://forums.thedarkmod.com/index.php?/topic/22413-the-dark-mod-15th-anniversary-contest-entry-thread/
       
      · 0 replies
    • JackFarmer

      @TheUnbeholden
      You cannot receive PMs. Could you please be so kind and check your mailbox if it is full (or maybe you switched off the function)?
      · 1 reply
    • OrbWeaver

      I like the new frob highlight but it would nice if it was less "flickery" while moving over objects (especially barred metal doors).
      · 4 replies
×
×
  • Create New...