0 Favourites

set blur strength to sprite speed

This forum is currently in read-only mode.
  • hi folks!

    sorry if this sounds a little vague, but i was just wondering different possibilities regarding some kind of (motion) blur.

    now, i was fiddling with the built in motion blur, which looks oh so nice, but is also REALLY heavy on the computer.

    i was thinking of using a little more modest implementation through effects, layer effects mostly, since i would like to be able to choose which layers are blurred.

    BUT, the big question:

    is there any possible way to make even just the basic blur strenth adjustments in relation to the sprite's speed? meaning that the faster the player goes the more blur is applied to a specific layer.

    would clamping be the way to go?

    i know how i could make it work when the player crosses a certain speed the blur gets applied, but its blocky and doesnt look good. i would like it to be (completely) seamless, hence i was thinking clamping. but i just dont know a proper conditioning or events needed for that.

    so, if anyone has any great ideas i would be very interested to hear them.

    thanks for reading!

  • To establish a relation between the sprite's speed and the blur's strength, you first need two anchor points. For example, the min and max speed values, where the blur is at zero and full strength.

    You then calculate a relative value with

    (current - min) / (max - min)

    where current is the sprite's current speed, and min and max the anchor points of the speed. If min happens to be 0 you can omit it in the calculation.

    The relative value is in the range [0,1] (but can exceed 1, if current will exceed max), so you might need to convert it to the value range that is needed for the blur's strength.

  • once again, thanks for replying, tulamide!

    hmm, sorry to sound like a complete idiot, but how exactly would that translate into a working condition/event? do i need to use private variables?

    i'd appreciate a rough example of code to give some guidelines <img src="smileys/smiley4.gif" border="0" align="middle" />

    this could be really useful info to implement to somewhere else also i think.

  • Here is an example that takes the speed of the car behavior and transforms it into a percentage value (ranged 0-100%), the width of a bar (ranged 0-500 px) and an angle (ranged 90-360�)

    Hope it helps :)

    http://db.tt/RXruUIYx

  • awesome, much appreciated! that works like a charm.

    although, TWO things:

    ever since i started using construct, ive had a hard time with speed and conditions needed to compare it.

    first, how would that code work with just a sprite? meaning, how would i compare the speed value? and the max speed value?

    second, i started wondering how would that be translated into using a physics behavior?

    i think i understand the basic logic you showed in that example, though the car behavior makes it (sort of) easy,because it already has the conditions for the speeds of the object. sorry to bother this much,but ive noticed ive stumbled upon this same (compare any kind of speed)issue for countless of times now, and i would be really happy to get rid of it by learning how to properly compare speed in any possible situation.    <img src="smileys/smiley36.gif" border="0" align="middle" />

  • Construct 3

    Buy Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Buy Now Construct 3 users don't see these ads
  • So, the real question isn't how to set two values in relation, but how to determine speed?

    I already answered that in a thread somewhere here on the forums, but I'll try to summarize it (although I can't guarantee that it will be the simplest description. I tend to say more than would be needed^^)

    Speed is "distance over time". To measure speed, you can either set a fixed distance and measure the time passed, or set a fixed time and measure the distance passed.

    When you move your sprite with your own events you don't need to measure anything - you already know the speed. For example, if moving a sprite by

    Sprite.X = Sprite.X + 10 * TimeDelta

    then the speed is 10 px/s at any time. It almost looks like a rule: n * TimeDelta = n px/s

    You may also have acceleration/decceleration, but let's not make it too complicated. I just mention that these dynamics are a part of n. Something like

    (10 + 20 * TimeDelta) * TimeDelta

    still can be reduced to

    n = (10 + 20 * TimeDelta)

    and therefore the rule still applies.

    If you don't have access to the values, you need to measure the speed. The simplest way is to just measure the distance moved per tick. Create three PVs (lastX, lastY, dist), set the first two to the position of the sprite at start of layout and then

    + Always

    -> Set dist to distance(lastX, lastY, Sprite.X, Sprite.Y)

    -> Set lastX to Sprite.X

    -> Set lastY to Sprite.Y

    You now have a speed value at any time. dist is the speed, expressed as px/tick. You can even extrapolate that to px/s by using TimeDelta:

    -> Set Text to FormatDecimal((Sprite('dist') / TimeDelta), 1) & " px/s"

    The rest is up to you. You have to decide at which speed value the blur has to be at full strength, either by calculating or by trial and error.

    EDIT: The simple example above as a .cap -> http://db.tt/enNzNAQr

  • thanks so much for explaining it so well!

    oh and both the relation and the speed comparison were really helpful and pretty much crucial for what im trying to do.

    i have used lastx and lasty before, but only for determining movement angles. that dist variable now makes alot more sense, ive seen it used before but really didnt know what exactly it was used for.

    well, i guess i'll be fooling around with this new knowledge for the rest of the day, see if i can get anything done with it. im still a little confused on how to translate all that knowledge into a working set of conditions and event, but eh, i guess i'll just have to GET it.

    but thanks again, i think i gained +2 int from this thread already <img src="smileys/smiley4.gif" border="0" align="middle" />

  • spoke too soon i guess... <img src="smileys/smiley9.gif" border="0" align="middle" />

    "The rest is up to you. You have to decide at which speed value the blur has to be at full strength, either by calculating or by trial and error."

    thats exactly where i get lost <img src="smileys/smiley36.gif" border="0" align="middle" />

    im not eally sure how the code should look when applying the max value of speed(dist)

    in this code its easy to understand, since i already have the max speed value ready to be used in expressions:

    FormatDecimal(Sprite[Car].Speed / Sprite[Car].MaxSpeed * 100, 1) & "%"

    but using the dist value, i dont have the max speed, so, should i just use (Sprite('dist') / TimeDelta) two times to measure the start speed AND max speed, or should there be a different expression? i guess im just cofused about the code formula itself, even though i understand basically what im trying to achieve and how.

    sorry if i sound like everything has to be explained in the way a child would understand <img src="smileys/smiley36.gif" border="0" align="middle" />

  • Hmm, I just don't know how to explain it other than "by trial and error"

    dist is just a variable, and like all variables it can be of different values. It may be at 2 or at 10 or at 20 and changing a lot throughout the game. You'd first run the game and have a look at what situation you want the blur to be most prominent. With the events implemented, you could constantly fill a text box with the current speed value. This way you see the current speed at the moment where you want the blur to be at full strength. This value is your max-speed-value.

    Example: You experiment with your game and see that the sprite has a current speed of 20 at the moment where you want the blur to be at full strength. And you decide the minimum speed to be 0.

    Then the calculation would be

    dist / 20

    and that will produce a relative number in the range [0, 1] for 0 <= dist <= 20

  • i just meant that im not sure about the way the code should be made, i tried some variations, but didnt get any results.

    but if we go by your example in your post:

    max speed is 20

    condition----> always

    event---->    sprite-set blur to FormatDecimal((Sprite('dist') / 20), 1) going by your code, is this correct or am i missing something completely obvious? <img src="smileys/smiley36.gif" border="0" align="middle" />

  • Well, yes, you are missing 2 things <img src="smileys/smiley4.gif" border="0" align="middle" />

    1) FormatDecimal is a function that outputs a string, I used it to format the string in the text box. Just omit it.

    2) Sprite('dist') / 20 will be a relative number [0, 1] If the blur shader you're using accepts a strength value in that range, then everything's ok. Else you need to transform the value just like in the first cap, I uploaded here, but for the value range the blur shader expects.

    You are close to a result. Step by step we will get it right. <img src="smileys/smiley2.gif" border="0" align="middle" />

  • i have to admit i really suck at this... <img src="smileys/smiley24.gif" border="0" align="middle" />

    after a few hours and big pile of ripped hair on my keyboard, i admit defeat. theres just something i cant figure out for the life of me and i dont even know what it is <img src="smileys/smiley36.gif" border="0" align="middle" />

    though i fear its something really simple and in your face- stuff. i tried like a million different things, resulting in pretty much me placing random stuff with my eyes closed hoping to get it.

    but no such luck, maybe im just stupid.   <img src="smileys/smiley4.gif" border="0" align="middle" />

  • but no such luck, maybe im just stupid.   <img src="smileys/smiley4.gif" border="0" align="middle"> You definitely are not!

    There's so many things that could prevent a desired result. For example, whatever the blur effect is you're using, it might not expect the value range that you use. Or it might be programmed to not be reliably alterable in runtime. There is a lot that might not work.

    I extended my "speed measurement" example. This time the sprite has a "pattern" effect and the left scale of the sprite is changed from 100% to 0% while gaining speed (from 0 to 80 px/s). It uses nothing more than the calculations and rules I explained in this thread.

    http://db.tt/nnzTp9e5

  • turned out i wasnt THAT far off yesterday when i gave up <img src="smileys/smiley36.gif" border="0" align="middle" />

    i managed to finally produce somewhat satisfying results, using "Blur motion" effect on a layer. didnt try any other blur methods yet, but it looks atleast promising. although one extra question came to my head(not really surprising issue since i kinda knew to expect it):

    since all this you have shown me takes notice of the sprites movement, whatever the direction, there needs to be some sort of "leeway" at the beginning of the calculation for the sprite's speed. for example:

    when the player jumps, it causes slight blur to be applied and i would assume that would start to cause a strain for the eyes. so i got to think. how would all this be calculated NOT from the start, but allowing some speed to build up before the blur starts appearing?

    for example, the speed value is calculated at the moment from 0px/s to, say 100px/s. to prevent the blur flickering, it would have to be within the values of for example from 20px/s to 100px/s. just to allow some starting movement and jumping in place without the blur?

  • If you carefully look at some of the older posts, you will find the almost appropriate formula

    relative value = (current - min) / (max - min)

    If we test this with values, the results are almost right. For current = 20 and current = 100, while max = 100 and min = 20 we get

    rv = (20 - 20) / (100 - 20) = 0 / 80 = 0

    rv = (100 - 20) / (100 - 20) = 80 / 80 = 1

    The only problem is that current could become less than 20, e.g. 0:

    rv = (0 - 20) / (100 - 20) = -20 / 80 = -0.25

    To avoid that there are a few solutions. The easiest from my point of view is to just cut out everything below 0 by making it being 0 too:

    rv = max((current - min) / (max - min), 0)

    max(a, b) will return the higher of the two values. For the example of current being 0 it would result in

    rv = max((0 - 20) / (100 - 20), 0) = max(-20 / 80, 0) = max(-0.25, 0) = 0

    EDIT

    You can also limit everything to certain angles. Angle detection works almost the same as speed detection, just exchange the "distance between points" expression with the "angle between points" expression. You'd store the current angle in a pv and use a condition that compares this pv with the allowed angles before calculating the blur strength and else set the blur strength to 0.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)