Smooth Operator: Programming the little things that games can't do without

Post on 10-May-2015

227 views 0 download

Tags:

description

Looking at the big picture, video games appear to be a kind of immensely intricate machinery. However, when up close, they are clearly made of many small and simple things that only create a smooth experience when working in harmony. A gameplay programmer must exhibit tremendous attention to detail that never becomes a game's killer feature, but is still necessary to make the game - whether indie or AAA - believable and enjoyable. In this talk I will discuss the need for smooth colour blends and organic movement, and the elementary techniques and their mathematics that get the job done, such as interpolation and noise. All of this from a gameplay programmer's point of view, as a series of case studies from our upcoming FPS game: The Adventurer.

Transcript of Smooth Operator: Programming the little things that games can't do without

Smooth OperatorProgramming the little things that games can't do without

WGK 2012 · August 31, 2012

Leszek GodlewskiProgrammerleszek.godlewski@thefarm51.com

www.thefarm51.com

Hello, target audience!

www.thefarm51.com

● Beginner programmers● You can learn some cool stuff (hopefully)

● Beginner gameplay programmers● Intermediate programmers

● Maybe you'll learn a thing or two● Seasoned gameplay programmers

● You'll be bored to death :(

Far from done

www.thefarm51.com

WORK INWORK INPROGRESSPROGRESS

All game footage in these slides is work in progress and is not representative of final quality of the game.

Why so smooth?

www.thefarm51.com

● Rough and sharp things are, well, rough and sharp● We all like pleasant stuff● Jerky movement and rough transitions create

an impression of being unfinished, unprofessional, lacking polish

● Few processes in nature happen instantly● Kinematics: movement derives from velocity,

velocity derives from acceleration● Physical and chemical reactions all take time

www.thefarm51.com

Organic motionVideo source: http://youtu.be/geg3ck3OT5Y

www.thefarm51.com

Organic motionImage source: http://commons.wikimedia.org/wiki/File:1-D_kinematics.svg

Visual feedback of game logic

www.thefarm51.com

● Gameplay logic is usually driven by a set of variables

● These variables are also used for visual feedback, either directly or indirectly (visual variables are derived from them in some way)● Discrete variables – potentially rough

transitions, often need smoothing out for appearance

● Continuous ones – usually less problematic

Visual feedback of game logic

www.thefarm51.com

● Discrete transitions can be smoothed out for visuals by interpolation● It's not nearly as bad in reality as you may think

after taking a class in numerical methods!

Lerp

www.thefarm51.com

● Mother of all interpolations! Used since antiquity

● Alpha term aka time● y = α · y0 + (1 – α) · y1● α [0; 1]∈

Why alpha is cool

www.thefarm51.com

● It's simply percentage! (normalization FTW)● It's absurdly easy to convert lerps into

higher-order exponential interpolation! y = xz

Why alpha is cool

www.thefarm51.com

● It's elementary to reverse its direction! αi = (1 – α0)

z

● It's trivial to make it time-dependent! α(t) = α(t - 1) + Δt · v

Moar interpolation!

www.thefarm51.com

● Lerp can also be applied to vectors, Euler angles etc. (component-wise, using the same alpha term)

● Quaternions can be slerped● Polynomial interpolation, eg. cubic

(results in a C1 function), exponential, sine interpolation

● Ease-in, ease-out, ease-in-ease-out● Decelerating interpolation:

f(t) = f(t – 1) + α · [t – f(t – 1)]

What's that noise?

www.thefarm51.com

● Entropy is a major natural force● In opposition to order and regularity● Humankind strives for the latter

● Need to simulate entropy for believable natural and organic features

● Lots of academic research on noise● Random number generators● Noise pattern algorithms

What's that noise?

www.thefarm51.com

● Noises can be combined for procedural textures

● No memory/bandwidth limits● No mapping problem● Limitless possibilities of effects

www.thefarm51.com

Case 1: Generic character animation

Case 1: Generic character animation

www.thefarm51.com

● Skeletal animation data consists of key frames

● Need to interpolate (aka “inbetween”, or “tween”) between key frames for continuous motion independent of simulation speed

● But this is handled by animation playback code● Non-blended animation transitions look

bad● I mean, really, REALLY bad!● The effect is known as “popping”

www.thefarm51.com

PoppingVideo clip: 01-popping.m4v

Popping

www.thefarm51.com

Solution:● Interpolate the skeleton poses

resulting from the contributing animations

● Lerp bone translations● Slerp bone quaternions

www.thefarm51.com

Animation blendingVideo clip: 02-blending.m4v

Animation blending

www.thefarm51.com

Yeah, I know – nothing fancy, every game has it...

www.thefarm51.com

Case 2: Camera target following

Case 2: Camera target following

www.thefarm51.com

Challenges:● Camera can translate and rotate● Target can move as well!

● Fortunately, we can ignore target rotation● Target translation changes angle delta to

target!

Moving target problem

www.thefarm51.com

angledelta

viewer

target angle delta

viewer

target

t = t0 t = t1

www.thefarm51.com

Iteration 1: LerpVideo clip: 03-lerp.m4v

Iteration 1: Lerp

www.thefarm51.com

● That's awful!● Direct result of lerping – no easing, motion feels

absolutely inorganic● Therefore we need an interpolation with ease

www.thefarm51.com

Iteration 2: Decelerating interpolationVideo clip: 04-decel.m4v

Iteration 2: Decelerating interp.

www.thefarm51.com

● Okay, so that actually looks fine!... sometimes● But only as long as the initial angle delta is

not extreme...● This is ease-out only● We need to ease-in, too!

Iterations 3..n

www.thefarm51.com

Fast-forward through some trial, lots of error and a bit of despair...

Iteration n + 1

www.thefarm51.com

How about this:● At start, compute initial angle delta

Δ0 = Θc(0) - Θt(0)● Store the current angle delta to target Δ(t)● Compensate for target translation by adding

the delta of deltas to camera rotation (we need to go deeper!)

Θc(t) = Θc(t – 1) + Δ(t) – Δ(t – 1)● Interpolate over Δ0 with a simple ease-in-

ease-out

www.thefarm51.com

Iteration n + 1Video clip: 05-compensation.m4v

Iteration n + 1

www.thefarm51.com

● Phew! That'll do.● The delta of deltas compensates almost

perfectly for target movement● Only the most extreme of cases may still

cause problems (very fast-moving target, very short distance to target)

● Ease-in-ease-out makes for a nice, smooth feeling

www.thefarm51.com

Case 3: Flashlight

Case 3: Flashlight

www.thefarm51.com

Challenges:● Spotlight must be aligned correctly with the

1st person mesh● But 1st person mesh is drawn in a different FOV!

● Spotlight must change size and colour according to the flashlight state

● Normal light – static shape, dynamic colour● Focused light – dynamic shape and colour● Dead battery – static shape, dynamic colour,

blinking

Light alignment vs FOV

www.thefarm51.com

Light alignment vs FOV

www.thefarm51.com

Light alignment vs FOV

www.thefarm51.com

Light alignment vs FOV

www.thefarm51.com

Light alignment vs FOV

www.thefarm51.com

Light alignment vs FOV

www.thefarm51.com

Off to an easy start● Light is obviously rendered at global

FOV● Configurable offset from camera● Dynamic light influence switched off

for 1st person meshes to avoid artifacts

www.thefarm51.com

Oops! Gimbal lock!Video clip: 06-gimbal.m4v

Oops! Gimbal lock!

www.thefarm51.com

● Quick fix: use quaternions instead for composing the rotations together

QuatToRotator( QuatProduct( QuatInvert( QuatFromRotator(Rotation)), QuatFromRotator(SocketRotation) ))

From logic to visuals

www.thefarm51.com

● Logic control variables● Current item state (discrete)● Remaining battery power (continuous)

● Light cone size (continuous)● Derived from state transition and, if focused, from

battery power● Light brightness and colour (continuous)

● Derived from state transition and battery power● Light blink state (when the battery is dying)

Light cone size

www.thefarm51.com

● Recap: drive light volume mesh scale and spotlight cone angle by state and battery power

● For state, let's try a helper variable and a lerp (0: unfocused, 1: focused)

if (IsFlashLightBeamActive()) FocusAlpha = FMin(1.f, FocusAlpha + DeltaTime * FocusSpeed);else FocusAlpha = FMax(0.f, FocusAlpha - DeltaTime * FocusSpeed);

Bonus!

www.thefarm51.com

● FocusAlpha may be easily applied to drive visuals by beam focus, such as FOV

FREE!!!FREE!!!

Light cone size

www.thefarm51.com

● Recap: drive light volume mesh scale and spotlight cone angle by state and battery power

● Final light cone scale:ConeScale = Lerp(1.f, ((1.f – PowerBlinkThreshold) * Power ** 2.f + PowerBlinkThreshold) * FocusSizeMultiplier, FocusAlpha);

www.thefarm51.com

Light cone sizeVideo clip: 07-size.m4v

Light brightness & colour

www.thefarm51.com

● Recap: drive spotlight brightness by state and battery power, and colour by battery power only

● Brightness is a piece of cake:NewBrightness = Lerp( UnfocusedBrightness, FocusedBrightness, FocusAlpha * Power);

Light brightness & colour

www.thefarm51.com

● Recap: drive spotlight brightness by state and battery power, and colour by battery power only

● Colour is just as easy:NewColor = LerpColor( LowBatteryLightColour, FullBatteryLightColour, Power);

www.thefarm51.com

Light brightness & colourVideo clip: 08-colour.m4v

Light blinking

www.thefarm51.com

● A little noise will come in handy:if (bDeadBattery) bBlinking = Power < 0.925 && Rand(100) < 8;else if (Power <= PowerBlinkThreshold) bBlinking = Power <= 0.f || FRand() < (1.f - Power / PowerBlinkThreshold);

www.thefarm51.com

Light blinkingVideo clip: 09-blinking.m4v

www.thefarm51.com

Flashlight in actionVideo clip: 10-flashlight.m4v

General tips

www.thefarm51.com

● Fractions are your best friends!● Alpha term is usually just a floating point

division away● Bias and scaling is easy

● Easing is cheap● Use whenever motion or transition feels robotic

● Ordinary rand() is often noisy enough● Plenty of other noise functions available if not

www.thefarm51.com

Questions?

Thank you!

Like us on Facebook!http://www.facebook.com/farm51http://www.facebook.com/ProjectAdventurer

leszek.godlewski@thefarm51.com

www.thefarm51.com