Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
What you want to do to speed up blur filters is make them separable. A separable filter is one where you can obtain the result by performing separate operations using the results of previous operations.

A 3x3 blur filter computed by averaging over a square is separable: Compute an image where each pixel is the average of the pixel at that position in the source image, the pixel to its left, and the pixel to its right. Store the result of that, then compute a second image where each pixel is the average of the pixel in the output of the first filter, the pixel above it, and the pixel below it. There, 3x3 blur using only 6 fetches per pixel.

OneEightHundred fucked around with this message at 00:43 on May 5, 2013

Adbot
ADBOT LOVES YOU

Orzo
Sep 3, 2004

IT! IT is confusing! Say your goddamn pronouns!

OneEightHundred posted:

What you want to do to speed up blur filters is make them separable. A separable filter is one where you can obtain the result by performing separate operations using the results of previous operations.

A 3x3 blur filter computed by averaging over a square is separable: Compute an image where each pixel is the average of the pixel at that position in the source image, the pixel to its left, and the pixel to its right. Store the result of that, then compute a second image where each pixel is the average of the pixel in the output of the first filter, the pixel above it, and the pixel below it. There, 3x3 blur using only 6 fetches per pixel.
I think my proposed algorithm can work with 3 fetches per pixel and O(1) memory, or 1 fetch per pixel with O(n) memory where the screen is n x n pixels. Did I make a mistake?

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!

Orzo posted:

I think my proposed algorithm can work with 3 fetches per pixel and O(1) memory, or 1 fetch per pixel with O(n) memory where the screen is n x n pixels. Did I make a mistake?
The two solutions can be combined, what I'm saying is you can handle it as two 1D operations instead of a single 2D operation. It depends where the bottleneck is though: If it's the array access, it probably won't make much difference. If it's the add/mul operations, it'll probably help a lot. If it ever goes above 3x3 though, it should definitely be separable.

Shalinor
Jun 10, 2002

Can I buy you a rootbeer?

Orzo posted:

Whoa now, let's not use the S word. I would view your example as a misuse of singleton. Just because two of my screens share a model doesn't mean I've implemented it as a singleton :)
Every manager in my game is a singleton-style gameobject. Even the ones that just hold data.

Every.

Single.

One.

:getin:

Orzo
Sep 3, 2004

IT! IT is confusing! Say your goddamn pronouns!

Shalinor posted:

Every manager in my game is a singleton-style gameobject. Even the ones that just hold data.

Every.

Single.

One.

:getin:
Missed opportunity:

Every.

Single.

Ton.

:getin:

seiken
Feb 7, 2005

hah ha ha

Orzo posted:

I don't have the pencil and paper handy right now to draw this out, but the first thing that comes to my mind is that you could at least increase your performance by a constant factor by taking advantage of pixels you've already read.

OneEightHundred posted:

The two solutions can be combined, what I'm saying is you can handle it as two 1D operations instead of a single 2D operation. It depends where the bottleneck is though: If it's the array access, it probably won't make much difference. If it's the add/mul operations, it'll probably help a lot. If it ever goes above 3x3 though, it should definitely be separable.

Yeah. Doing the blur as a horizontal blur followed by a vertical blur means you're, roughly speaking per pixel doing 3 loads, 2 adds, divide and store, 3 loads, 2 adds, divide and store. Doing it all at once is 9 loads, 8 adds, divide and store. The difference at 3x3 isn't huge (especially since divides are probably the most expensive operation), but over bigger areas the former method will consist of many fewer operations. (O(n) instead of O(n^2))

The idea with the temporary array which you slide about will only increase the number of operations you end up doing so it's not a good idea, unless it's the reading and writing to the framebuffer in particular which is the most expensive thing (i.e., temporary arrays happen to be way faster to read/write to). I have no idea if this is the case in your crazy QBASIC shennanigans or not. If writing/reading to an array is just as slow as writing/reading the framebuffer then you're just copying pixels around for no reason.

Edit: also, I don't know how much optimisation QBASIC does but you might be able to squeeze out a couple more cycles by weird little micro-optimisations like storing (1/9) (or whatever your constant divisor is) as a constant and multiplying by it, rather than dividing by it every time. Divides can be slower than multiplications by a fair whack.
Edit 2: assuming you're storing colours as floats, which I guess you may very well not be. In the integer case if you fudge the weights so that the divisor is a power of 2 you could bit-shift, maybe?

seiken fucked around with this message at 01:40 on May 5, 2013

Mug
Apr 26, 2005

Orzo posted:

Cool, while I have your attention can you update the making games megathread with my twitter? https://twitter.com/ericswheeler

The pact is sealed (done).

Unormal
Nov 16, 2004

Mod sass? This evening?! But the cakes aren't ready! THE CAKES!
Fun Shoe

Shalinor posted:

Every manager in my game is a singleton-style gameobject. Even the ones that just hold data.

Every.

Single.

One.

:getin:

I just use regular singleton classes for that. Any huge upsides to making them "real" gameobjects? Then you don't have to worry about cross-scene lifecycles. Though exposure to the editor could be nice, I guess.

Unormal fucked around with this message at 01:36 on May 5, 2013

Baldbeard
Mar 26, 2011

Really sorry for having to ask such a beginner question, but my google skills are failing me on this one. I'm coding a simple game in actionscript and I'm having a hard time getting the collision detection & movement to interact exactly how I want it. I have the smooth 8 direction keyboard movement I want, but I can't figure out how make it so the character can rub up against a wall at a diagonal without going through it OR stopping dead. For example, I want to be able to walk NE with a wall to my E and just move upwards. Think Earthbound.

So far the only way I can get the collision detection to work is to have the character "bounce back" and it looks funny.

Does anyone have any resources on this? It seems like it should be pretty straightforward, but most collision detection tutorials are either grid based movement or totally garbage shooter game stuff.

Shalinor
Jun 10, 2002

Can I buy you a rootbeer?

Unormal posted:

I just use regular singleton classes for that. Any huge upsides to making them "real" gameobjects? Then you don't have to worry about cross-scene lifecycles. Though exposure to the editor could be nice, I guess.
I like the exposure through the editor, and they're capable of all the GameObject stuff you otherwise take for granted (like generic messaging).

... unrelated - am I crazy for making a dialog system that loads off the disk on demand? I'm actually doing it this way to side-step all the potential weirdness of scenes in Unity, but it also occurs to me that having the entirety of all dialogs, ever, loaded into memory in a giant hash map or whatever might be a teensy bit wasteful. (it'll work based on a "every dialog file may have precisely one root node, which must match the filename minus the extension" rule to save on keeping a central index somewhere)

EDIT: VV I realize, but it's still a giant hunk of data that needn't all be loaded at any one time. Loading it all would also take a decent bit of time.

Shalinor fucked around with this message at 01:55 on May 5, 2013

Opinion Haver
Apr 9, 2007

Shalinor posted:

I like the exposure through the editor, and they're capable of all the GameObject stuff you otherwise take for granted (like generic messaging).

... unrelated - am I crazy for making a dialog system that loads off the disk on demand? I'm actually doing it this way to side-step all the potential weirdness of scenes in Unity, but it also occurs to me that having the entirety of all dialogs, ever, loaded into memory in a giant hash map or whatever might be a teensy bit wasteful.

Do you mean, like, the dialog text? Text occupies basically no memory compared to textures or sound.

Mug
Apr 26, 2005

OneEightHundred posted:

What you want to do to speed up blur filters is make them separable. A separable filter is one where you can obtain the result by performing separate operations using the results of previous operations.

A 3x3 blur filter computed by averaging over a square is separable: Compute an image where each pixel is the average of the pixel at that position in the source image, the pixel to its left, and the pixel to its right. Store the result of that, then compute a second image where each pixel is the average of the pixel in the output of the first filter, the pixel above it, and the pixel below it. There, 3x3 blur using only 6 fetches per pixel.

I've read over this a few times and I don't quite get the process you're describing.

So at the moment I want to blur a pixel a 50,40.
I keep a running tally of the sum of colours for RGB. Each pixel I read also has "weight" depending on how "in focus" that pixel is.
I read the pixel at 49,39. Add it's colour to the tally multiplied by out-of-focus weight.
I read the pixel at 50,39. Add it's colour to the tally multiplied by out-of-focus weight.
I read the pixel at 51,39. Add it's colour to the tally multiplied by out-of-focus weight.
I read the pixel at 49,40. Add it's colour to the tally multiplied by out-of-focus weight.
I read the pixel at 50,40. Add it's colour to the tally multiplied by in-focus weight.
I read the pixel at 51,40. Add it's colour to the tally multiplied by out-of-focus weight.
I read the pixel at 49,41. Add it's colour to the tally multiplied by out-of-focus weight.
I read the pixel at 50,41. Add it's colour to the tally multiplied by out-of-focus weight.
I read the pixel at 51,41. Add it's colour to the tally multiplied by out-of-focus weight.
The divide the tally by the sum of all weights (out-of-focus weight * 8 + in-focus-weight) and plot a new pixel at 50,40 with that new colour.

This is the code for it:
code:
    FullClarity = 13 ' At "Full Clarity" (right on the edge of focus), how clear is it?
    FullBlur = 18 ' at "Full blur", the very edge of the screen, how blurry is it?
    CubeSize = 1 'How many pixels does a blur spread on the X and Y axis?
    ClearGap = 100 ' How many pixes are 100% in focus starting from the center of the screen and expanding outwards
    ClearStart = (Height / 2) - ClearGap ' 50  'So, based on that, where exactly does the blur-effect stop taking effect?

    FOR CurrentY = 0 TO ClearStart ' Just the top half of the screen, later a loop called "Twice" mirrors down to the bottom half.
        PercentOfClarity = CurrentY / ClearStart 'So at this point, how in-focus are we, 0 being none, and 1 being full.
        CurrentClarity = FullClarity * PercentOfClarity ' and how much clarity does that translate to?
        PercentOfBlur = 1 - PercentOfClarity ' Using that knowledge, what percentage of the total blur do we need?
        CurrentBlur = FullBlur * PercentOfBlur ' And how much actual blur is that?
        FOR CurrentX = 0 TO Width ' All the way from left-to-right.
            FOR Twice = 0 TO 1 ' This is the mirror that does the top and bottom of the screen
                CurrentRed = 0
                CurrentGreen = 0
                CurrentBlue = 0
                WeightDivider = 0
                FOR CubeY = CubeSize * -1 TO CubeSize ' Grab a square of pixels to consider
                    FOR CubeX = CubeSize * -1 TO CubeSize ' Grab a square of pixels to consider
                        IF NOT StoredPixel(CurrentX + CubeX, ABS((Height * Twice) - (CurrentY + CubeY))) THEN ' If I haven't already read this pixel before
                            StoredPixel(CurrentX + CubeX, ABS((Height * Twice) - (CurrentY + CubeY))) = POINT(CurrentX + CubeX, ABS((Height * Twice) - (CurrentY + CubeY))) ' read it
                        END IF
                        TheReadPixel = StoredPixel(CurrentX + CubeX, ABS((Height * Twice) - (CurrentY + CubeY))) ' Read the RGBA value of a pixel
                        IF CubeX = 0 AND CubeY = 0 THEN 'if this is the current center pixel, use "Clarity" to bring it into focus
                            CurrentFocus = CurrentClarity
                        ELSE ' Otherwise, use "Blur" to take it out of focus
                            CurrentFocus = CurrentBlur
                        END IF
                        CurrentRed = CurrentRed + (_RED32(TheReadPixel) * CurrentFocus)
                        CurrentGreen = CurrentGreen + (_GREEN32(TheReadPixel) * CurrentFocus)
                        CurrentBlue = CurrentBlue + (_BLUE32(TheReadPixel) * CurrentFocus)
                        WeightDivider = WeightDivider + CurrentFocus
                    NEXT
                NEXT
                PSET (CurrentX, ABS((Height * Twice) - CurrentY)), _RGBA(CurrentRed / WeightDivider, CurrentGreen / WeightDivider, CurrentBlue / WeightDivider, 255) ' Plot that pixel, baby.
            NEXT
        NEXT
    NEXT
That pulls about 40fps.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Oh man, nostalgic flash back. I wrote an ASCII console windowing system in QBASIC back when QBASIC first started shipping with DOS and I was but a wee lad, then took a 20 year break from programming. That code really takes me back!

Will you ever open source your game? I would love to read over it one day.

(I certainly understand if you wouldn't)

Mug
Apr 26, 2005

Thermopyle posted:

Oh man, nostalgic flash back. I wrote an ASCII console windowing system in QBASIC back when QBASIC first started shipping with DOS and I was but a wee lad, then took a 20 year break from programming. That code really takes me back!

Will you ever open source your game? I would love to read over it one day.

(I certainly understand if you wouldn't)

Yeah, sure. It's a 15,000 line text document at the moment. If anyone wants to try to understand it, good luck to them!

But yeah, I'll release it with the game.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!

Mug posted:

I've read over this a few times and I don't quite get the process you're describing.

So at the moment I want to blur a pixel a 50,40.
What you'd do is, compute 50,40 as the average of (49,40), (50,40), and (51,40). Do that for every pixel and you'll get a result that's blurred only on the X axis. Now, take what you got from that and run a separate vertical axis blur on it, and when you encounter 50,40, take the average of (50,39), (50,40), and (50,41) from the horizontal-blurred image.

The reason this works is that in the output, (50,39) was computed as the average of (49,39), (50,39), and (51,39), while (50,41) was computed as the average of (49,41), (50,41), and (51,41).

((a+b+c)/3 + (d+e+f)/3 + (g+h+i)/3) / 3 = (a+b+c+d+e+f+g+h+i)/9
.... so the separable filter is identical to a full box filter.


If you're going to do this though, you might want to consider using Gaussian blur instead, which is also separable and tends to look better.

DeathBySpoon
Dec 17, 2007

I got myself a paper clip!
I didn't see this mentioned, but you wouldn't happen to have access to HLSL/GLSL or anything in QBASIC, would you? That would make your speed problems a non-issue, really.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
If you're running this using real QBasic in a DOS emulator like DOSBox (as opposed to a QBasic-compatible environment like QB64), using PEEK/POKE to directly access video memory is also massively faster than using POINT/PSET. I don't remember anything about how to get the addresses for that though.

If you are using QB64, then you could use a C/C++ DLL to handle very expensive operations if that's not too uh... heretical.

OneEightHundred fucked around with this message at 17:55 on May 5, 2013

DancingPenguin
Nov 27, 2012

I ish kakadu.
Entering a GameDev-contest for fun and cash soon, but I am a bit short on time until the deadline.
So I figured going for a simple 2D-game. Anyone here tried LÖVE, and got any good words about it?
I am almost getting desperate enough to use GM Studio(Free), but their license confuses me about if I can use it in a "commercial" aspect.
Please tell me someone got a better suggestion than GM, really not feeling like relying on that piece of crap.

Edit: Seems like I am going for LÖVE, seems like a pretty simple engine to learn. Any input is still appreciated.

DancingPenguin fucked around with this message at 20:34 on May 5, 2013

Bongo Bill
Jan 17, 2012

I've played around with Love2D, and it seems like a very well-made, well-maintained, and well-documented piece of software.

space kobold
Oct 3, 2009


Love2D is great, it's all so clean and easy to get going with. So here's a second vote for it here, especially for beginners or those in need of getting something done fast.

Lately I've been using Moai SDK for my own cross platform Lua games, but I'll always hold a special place in my heart for LÖVE. Moai is just so... convoluted and poorly documented, but it also has commercial backing and a number of useful game oriented constructs, patterns and optimizations. :shrug:

space kobold fucked around with this message at 00:56 on May 6, 2013

Mug
Apr 26, 2005
Can anyone help me with a small math problem? I am trying to get frameskip to skip the correct number of frames but I'm just not 100% sure how to convert deltatime loss into catchup framecount.

Basically. DesiredFPS is 60, which is deltatime 0.16666666666667.
Say the FPS drops to 50, which is deltatime 0.02, how do I translate 0.02 into 10, where 10 is the difference between 50 (current FPS) and 60 (desired FPS)?

Basically, the end code I want is like
IF DeltaTime > 1 / DesiredFrameRate THEN FramesToSkip = (Some Kind of Voodoo Involving DeltaTime and DesiredFrameRate)

Mug fucked around with this message at 05:38 on May 6, 2013

That Turkey Story
Mar 30, 2003

Mug posted:

Can anyone help me with a small math problem? I am trying to get frameskip to skip the correct number of frames but I'm just not 100% sure how to convert deltatime loss into catchup framecount.

Basically. DesiredFPS is 60, which is deltatime 0.16666666666667.
Say the FPS drops to 50, which is deltatime 0.02, how do I translate 0.02 into 10, where 10 is the difference between 50 (current FPS) and 60 (desired FPS)?

Invert the delta values and then calculate the difference.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
If you're running the game world at a fixed framerate, the easiest way is to just increment the simulation time by the fixed deltatime until the simulation time exceeds real time. Just make sure you cap the number of frames run per cycle so you don't freeze if the simulation can't be processed in real time for some reason, or if something causes a severe processing delay (i.e. file IO that gets blocked for a long time by a hard-disk spin-up).

Mug
Apr 26, 2005
I've already got frameskip working, it's just skipping the wrong number of frames.

How do you take a deltatime value and represent it as numerical frames per second?

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
You take its reciprocal. fps = 1 / deltatime.

Mug
Apr 26, 2005

Suspicious Dish posted:

You take its reciprocal. fps = 1 / deltatime.

Hahah, gently caress, thanks man :)

FramesToSkip = UserSettings.MinimumFramerate - (1 / DeltaTime)
Blammo, perfecto.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Think of it this way. To get the delta time per frame, you have 1 second, and N frames, so you divide that 1 second up into N frames, and you know that each frame is 1/N seconds long. That's your delta time:

1 second / 60 frames = 0.1667 seconds per frame

Now, if we have seconds per frame, and we want frames per second, we simply flip the fraction around -- that's the reciprocal.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
That's not really a good way to do skip calculation though, it'll just give you the skip count over 1 second and doesn't really give an answer to how to resolve sub-second frame skips. The way to do frame drops or any other type of timing handling that involves synchronizing events that happen at one interval with another (which also includes doing things like reconciling things that happen periodically in-game at a rate that doesn't divide evenly into frame time) is to accumulate the drift and then resolve it when the drift exceeds the frame time (or do a mathematically-equivalent operation like the catch-up I mentioned).

That is, if you're trying to run frames at ~16.67 msec and they're taking 20 msec, then your simulation time has -3.33 sec of drift. If it does it again, you'll have -6.67 sec of drift. If the drift goes below -16.67 msec, then it means your simulation is more than a full frame behind and you should run an extra frame. Incidentally, that works in multiples: If your simulation is 33.33 msec behind, then it's 2 frames behind. If it drifts over a frame, then it means your simulation is running too fast and you should wait.

Mug
Apr 26, 2005
I can't change simulation time this late in development, I didn't understand this kind of thing back when I started and it's way too late to go back and change all the stuff to do with movement (I spent 2 days trying, it was TERRIBLE).

If a frame takes longer than 1 / DesiredFPS to render, the game skips rendering of the next frame, then checks to see if it's sped up enough to justify rendering a frame after that. It works good, as good as it's gonna get for this project this late in the game.

edit: Also, I don't think I really explained how my frameskip works. It works absolutely fine with subsecond frame drops, I was just loving around with "How many frames did you want to skip?" for a debugging counter. It doesn't actually skip a fixed count, it re-checks "Should I skip again?" after each frameskip.

edit2: And the good news is that frameskip now works really awesome and the game runs real good on the shittest laptop I own.

Mug fucked around with this message at 15:00 on May 6, 2013

Orzo
Sep 3, 2004

IT! IT is confusing! Say your goddamn pronouns!
Speaking of development optimizations, I have what I think is a pretty interesting question.

Right now my game runs at a fixed logical timestep of .003 seconds, or 333 logical updates per second. I want to change that to (1/60), or 60 logical updates per second.

Now, I don't interpolate graphics between physical frames yet, but I'm planning on it. Right now, the engine dumbly renders frames as many times as possible until it hits the next physical timestep. So, even though I might be hitting 500 frames a second, most of those are wasted, so the visual framerate is dependent on the physical updates.

Okay, so here's my question. My engine is 2D and renders quads. Nothing more. Everything is sent to the graphics pipeline via a structure that has 4 vertices. The interpolation programming would be so simple if I could just interpolate between two quads. The math is simple enough, sure, but has anyone here ever tried doing this before? There are definitely some potential artifacts--for example, quickly a square 90 degrees would result in a quad that was smaller than the original one--but maybe these 'dramatic' changes (a sudden rotation of 90 degrees is not really a candidate for interpolation anyway) can be ignored by the interpolation algorithm.

The other way to do it, of course, is to actually interpolate between the two transformation nodes, but that's more complex code-wise and I want to keep things simple if possible.

Shalinor
Jun 10, 2002

Can I buy you a rootbeer?

Orzo posted:

The other way to do it, of course, is to actually interpolate between the two transformation nodes, but that's more complex code-wise and I want to keep things simple if possible.
Given that everything is quads, you could very easily make every render call pass 2 matrices and a lerp value. Or you could compose the matrices in the vertex fragment from input pos/scale/rot data, etc. Smoothly lerping between two arbitrary chunks of geometry would be harder, but not impossible. You'd have to compose your vertex buffer per-frame as a write-only / throw-away, packing each frame's next and last vert data.

If you're just talking two matrices and a lerp, that would seem to be within the realm of reason to do in the vertex fragment, including on-demand matrix composition. You... might?... bump up against the maximum register count on your input structure, but I think you could do it. You'd just be stowing a lot of your additional data in UV and binormal registers et al.

Normally, this would be impractical, because you'd have no bandwidth left for anything else - but in your case, they're just quads. You'll be fine. I'd go for it.

Shalinor fucked around with this message at 17:23 on May 6, 2013

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!

Orzo posted:

There are definitely some potential artifacts--for example, quickly a square 90 degrees would result in a quad that was smaller than the original one--but maybe these 'dramatic' changes (a sudden rotation of 90 degrees is not really a candidate for interpolation anyway) can be ignored by the interpolation algorithm.
In my opinion, the best thing to do is have both a lerp target state and an actual target state, which can be different. That overcomes some other issues with interpolation as well, a big one being objects that are created and destroyed: If you only use frame states to do interpolation, and a projectile hits something and despawns, what do you do with that projectile in the period between those frames? If it disappears, then it will look odd that the projectile disappeared for a short bit and then the effects of it took place. If it just uses frame states for interpolation, then it'll linger in place for the intermediate time since it doesn't have a new position.

If you're using a lerp target, then you can make it be the projectile at its impact location: The projectile will then interpolate toward its new location, but will still despawn elegantly when the frame range changes. You can do the same thing to handle other instantaneous changes like teleporting or abruptly changing state.

Orzo
Sep 3, 2004

IT! IT is confusing! Say your goddamn pronouns!

OneEightHundred posted:

In my opinion, the best thing to do is have both a lerp target state and an actual target state, which can be different. That overcomes some other issues with interpolation as well, a big one being objects that are created and destroyed: If you only use frame states to do interpolation, and a projectile hits something and despawns, what do you do with that projectile in the period between those frames? If it disappears, then it will look odd that the projectile disappeared for a short bit and then the effects of it took place. If it just uses frame states for interpolation, then it'll linger in place for the intermediate time since it doesn't have a new position.

If you're using a lerp target, then you can make it be the projectile at its impact location: The projectile will then interpolate toward its new location, but will still despawn elegantly when the frame range changes. You can do the same thing to handle other instantaneous changes like teleporting or abruptly changing state.
Yeah, I had sort of considered issues like that too, but I wasn't sure if it would matter or not. After all, we're talking about a very short period of time. If a projectile dies and its particles spawn .03 seconds later, is that really going to be that noticeable? I don't know. I know that smooth motion of objects is important--because 30fps is very different than 60fps--but whether or not creation and destruction of objects at a higher tick rate matters is going to be a subjective analysis thing.

Shalinor: Hadn't even thought of offloading this to the GPU. Might be an interesting approach. Followup:

1) How do you lerp between two matrices? I Googled this and didn't really find anything definitive. It would seem that you'd need the original components, instead.

2) ...and the original components aren't that simple either when you start taking parent transforms into account. I don't just have translation/scaling/rotation, because an entity's transform is relative to its parent transform. So there's no upper bound on the number of transformation components.

3) However, if my original approach works--just lerping between the 4 vertices that make a quad (and I think it might, for small movements, which is all I'm concerned about anyway)--that's definitely something that could be done in a shader.

Spatial
Nov 15, 2007

Orzo posted:

1) How do you lerp between two matrices? I Googled this and didn't really find anything definitive. It would seem that you'd need the original components, instead.
I just tried it: lerping each component of the two matrices seems to work fine.

Edit: I do know the crazy side effects this can cause, I just didn't think it would matter with the tiny differences in this context.

Spatial fucked around with this message at 22:11 on May 6, 2013

scissorman
Feb 7, 2011
Ramrod XTreme
Can you recommend any game engines with support for C++11 ?

I'm currently using openframeworks but it seems that some of its internals are incompatible with C++11.
Since I haven't really gotten beyond the initial design, I would like to switch now if possible.

Rottbott
Jul 27, 2006
DMC

Spatial posted:

I just tried it: lerping each component of the two matrices seems to work fine.
Lerping each vector is ok so long as it's only for very small changes. For lerping between adjacent frames it should be ok.

However it will cause skew, so it's not good for lerping between arbitrary matrices, although you could re-orthonormalize the matrix afterwards. If you were doing that it might be better to decompose the matrix into position/rotation/scale and lerp each of those, then recompose the matrix.

Shalinor
Jun 10, 2002

Can I buy you a rootbeer?

Spatial posted:

I just tried it: lerping each component of the two matrices seems to work fine.
While this... will kind of work... please step back for a second and think about what you're doing. What you're lerping is the basis vectors of a space + their spatial offset. This will result in a distorted space and, depending on target vs start matrix, may easily result in a degenerate matrix.

So no. What you actually want to do is lerp the 3 basis vectors, likely represented as quaternions and with slerp instead of lerp, and the position independently. Though even that will result in distorted spatial basis. Ideally you'd lerp/slerp the components that go into those vectors (rotation, scale, position) and then compose the matrix from the result.

Splat
Aug 22, 2002

Orzo posted:

Speaking of development optimizations, I have what I think is a pretty interesting question.

Right now my game runs at a fixed logical timestep of .003 seconds, or 333 logical updates per second. I want to change that to (1/60), or 60 logical updates per second.

Now, I don't interpolate graphics between physical frames yet, but I'm planning on it. Right now, the engine dumbly renders frames as many times as possible until it hits the next physical timestep. So, even though I might be hitting 500 frames a second, most of those are wasted, so the visual framerate is dependent on the physical updates.

Okay, so here's my question. My engine is 2D and renders quads. Nothing more. Everything is sent to the graphics pipeline via a structure that has 4 vertices. The interpolation programming would be so simple if I could just interpolate between two quads. The math is simple enough, sure, but has anyone here ever tried doing this before? There are definitely some potential artifacts--for example, quickly a square 90 degrees would result in a quad that was smaller than the original one--but maybe these 'dramatic' changes (a sudden rotation of 90 degrees is not really a candidate for interpolation anyway) can be ignored by the interpolation algorithm.

The other way to do it, of course, is to actually interpolate between the two transformation nodes, but that's more complex code-wise and I want to keep things simple if possible.

Why do you want to nuke the logical update rate?

Orzo
Sep 3, 2004

IT! IT is confusing! Say your goddamn pronouns!

Splat posted:

Why do you want to nuke the logical update rate?
It's overkill. From what I understand, most commercial games run perfectly fine at about 60 logical frames a second. Having thousands of particles impacts my performance severely.

Adbot
ADBOT LOVES YOU

Splat
Aug 22, 2002

Orzo posted:

It's overkill. From what I understand, most commercial games run perfectly fine at about 60 logical frames a second. Having thousands of particles impacts my performance severely.

Are you able to run w/ variable timestep?

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply