Thursday, 16 January 2014

Tech Feature: SSAO and Temporal Blur


Screen space ambient occlusion (SSAO) is the standard solution for approximating ambient occlusion in video games. Ambient occlusion is used to represent how exposed each point is to the indirect lighting from the scene. Direct lighting is light emitted from a light source, such as a lamp or a fire. The direct light then illuminates objects in the scene. These illuminated objects make up the indirect lighting. Making each object in the scene cast indirect lighting is very expensive. Ambient occlusion is a way to approximate this by using a light source with constant color and information from nearby geometry to determine how dark a part of an object should be. The idea behind SSAO is to get geometry information from the depth buffer.

There are many publicised algorithms for high quality SSAO. This tech feature will instead focus on improvements that can be made after the SSAO has been generated.



SSAO Algorithm
SOMA uses a fast and straightforward algorithm for generating medium frequency AO. The algorithm runs at half resolution which greatly increases the performance. Running at half resolution doesn’t reduce the quality by much, since the final result is blurred.

For each pixel on the screen, the shader calculates the position of the pixel in view space and then compares that position with the view space position of nearby pixels. How occluded the pixel gets is based on how close the points are to each other and if the nearby point is in front of the surface normal. The occlusion for each nearby pixel is then added together for the final result. 

SOMA uses a radius of 1.5m to look for nearby points that might occlude. Sampling points that are outside of the 1.5m range is a waste of resources, since they will not contribute to the AO. Our algorithm samples 16 points in a growing circle around the main pixel. The size of the circle is determined by how close the main pixel is to the camera and how large the search radius is. For pixels that are far away from the camera, a radius of just a few pixels can be used. The closer the point gets to the camera the more the circle grows - it can grow up to half a screen. Using only 16 samples to select from half a screen of pixels results in a grainy result that flickers when the camera is moving.
Grainy result from the SSAO algorithm
Bilateral Blur
Blurring can be used to remove the grainy look of the SSAO. Blur combines the value of a large number of neighboring pixels. The further away a neighboring pixel is, the less the impact it will have on the final result. Blur is run in two passes, first in the horizontal direction and then in the vertical direction.

The issue with blurring SSAO this way quickly becomes apparent. AO from different geometry leaks between boundaries causing a bright halo around objects. Bilateral weighting can be used to fix the leaks between objects. It works by comparing the depth of the main pixel to the depth of the neighboring pixel. If the distance between the depth of the main and the neighbor is outside of a limit the pixel will be skipped. In SOMA this limit is set to 2cm.
To get good-looking blur the number of neighboring pixels to sample needs to be large. Getting rid of the grainy artifacts requires over 17x17 pixels to be sampled at full resolution.

Temporal Filtering 
Temporal Filtering is a method for reducing the flickering caused by the low number of samples. The result from the previous frame is blended with the current frame to create smooth transitions. Blending the images directly would lead to a motion-blur-like effect. Temporal Filtering removes the motion blur effect by reverse reprojecting the view space position of a pixel to the view space position it had the previous frame and then using that to sample the result. The SSAO algorithm runs on screen space data but AO is applied on world geometry. An object that is visible in one frame may not be seen in the next frame, either because it has moved or because the view has been blocked by another object. When this happens the result from the previous frame has to be discarded. The distance between the points in world space determines how much of the result from the previous frame should be used.

Explanation of Reverse Reprojection used in Frostbite 2 [2]
Temporal Filtering introduces a new artifact. When dynamic objects move close to static objects they leave a trail of AO behind. Frostbite 2’s implementation of Temporal Filtering solves this by disabling the Temporal Filter for stable surfaces that don’t get flickering artifacts. I found another way to remove the trailing while keeping Temporal Filter for all pixels.


Shows the trailing effect that happens when a dynamic object is moved. The Temporal Blur algorithm is then applied and most of the trailing is removed.

Temporal Blur 

(A) Implementation of Temporal Filtered SSAO (B) Temporal Blur implementation 
I came up with a new way to use Temporal Filtering when trying to remove the trailing artifacts. By combining two passes of cheap blur with Temporal Filtering all flickering and grainy artifacts can be removed without leaving any trailing. 

When the SSAO has been rendered, a cheap 5x5 bilateral blur pass is run on the result. Then the blurred result from the previous frame is applied using Temporal Filtering. A 5x5 bilateral blur is then applied to the image. In addition to using geometry data to calculate the blending amount for the Temporal Filtering the difference in SSAO between the frames is used, removing all trailing artifacts. 

Applying a blur before and after the Temporal Filtering and using the blurred image from the previous frame results in a very smooth image that becomes more blurred for each frame, it also removes any flickering. Even a 5x5 blur will cause the resulting image to look as smooth as a 64x64 blur after a few frames.

Because the image gets so smooth the upsampling can be moved to after the blur. This leads to Temporal Blur being faster, since running four 5x5 blur passes in half resolution is faster than running two 17x17 passes in full resolution. 

Upsampling
All of the previous steps are performed in half resolution. To get the final result it has to be scaled up to full resolution. Stretching the half resolution image to twice its size will not look good. Near the edges of geometry there will be visible bleeding; non-occluded objects will have a bright pixel halo around them. This can be solved using the same idea as the bilateral blurring. Normal linear filtering is combined with a weight calculated by comparing the distance in depth between the main pixel and the depth value of the four closest half resolution pixels.

Summary 
Combining SSAO with the Temporal Blur algorithm produces high quality results for a large search radius at a low cost. The total cost of the algoritm is 1.1ms (1920x1080 AMD 5870). This is more than twice as fast as a normal SSAO implementation.

SOMA uses high frequency AO baked into the diffuse texture in addition to the medium frequency AO generated by the SSAO.

Temporal Blur could be used to improve many other post effects that need to produce smooth-looking results.

Ambient Occlusion is only one part of the rendering pipeline, and it should be combined with other lighting techniques to give the final look.


References
  1. http://gfx.cs.princeton.edu/pubs/Nehab_2007_ARS/NehEtAl07.pdf 
  2. http://dice.se/wp-content/uploads/GDC12_Stable_SSAO_In_BF3_With_STF.pdf 

 // SSAO Main loop

//Scale the radius based on how close to the camera it is
 float fStepSize = afStepSizeMax * afRadius / vPos.z;
 float fStepSizePart = 0.5 * fStepSize / ((2 + 16.0));    

 for(float d = 0.0; d < 16.0; d+=4.0)
 {
        //////////////
        // Sample four points at the same time

        vec4 vOffset = (d + vec4(2, 3, 4, 5))* fStepSizePart;
        
        //////////////////////
        // Rotate the samples

        vec2 vUV1 = mtxRot * vUV0;
        vUV0 = mtxRot * vUV1;

        vec3 vDelta0 = GetViewPosition(gl_FragCoord.xy + vUV1 * vOffset.x) - vPos;
        vec3 vDelta1 = GetViewPosition(gl_FragCoord.xy - vUV1 * vOffset.y) - vPos;
        vec3 vDelta2 = GetViewPosition(gl_FragCoord.xy + vUV0 * vOffset.z) - vPos;
        vec3 vDelta3 = GetViewPosition(gl_FragCoord.xy - vUV0 * vOffset.w) - vPos;

        vec4 vDistanceSqr = vec4(dot(vDelta0, vDelta0),
                                 dot(vDelta1, vDelta1),
                                 dot(vDelta2, vDelta2),
                                 dot(vDelta3, vDelta3));

        vec4 vInvertedLength = inversesqrt(vDistanceSqr);

        vec4 vFalloff = vec4(1.0) + vDistanceSqr * vInvertedLength * fNegInvRadius;

        vec4 vAngle = vec4(dot(vNormal, vDelta0),
                            dot(vNormal, vDelta1),
                            dot(vNormal, vDelta2),
                            dot(vNormal, vDelta3)) * vInvertedLength;


        ////////////////////
        // Calculates the sum based on the angle to the normal and distance from point

        fAO += dot(max(vec4(0.0), vAngle), max(vec4(0.0), vFalloff));
}

//////////////////////////////////
// Get the final AO by multiplying by number of samples
fAO = max(0, 1.0 - fAO / 16.0);

------------------------------------------------------------------------------ 

// Upsample Code
 
vec2 vClosest = floor(gl_FragCoord.xy / 2.0);
vec2 vBilinearWeight = vec2(1.0) - fract(gl_FragCoord.xy / 2.0);

float fTotalAO = 0.0;
float fTotalWeight = 0.0;

for(float x = 0.0; x < 2.0; ++x)
for(float y = 0.0; y < 2.0; ++y)
{
       // Sample depth (stored in meters) and AO for the half resolution 
       float fSampleDepth = textureRect(aHalfResDepth, vClosest + vec2(x,y));
       float fSampleAO = textureRect(aHalfResAO, vClosest + vec2(x,y));

       // Calculate bilinear weight
       float fBilinearWeight = (x-vBilinearWeight .x) * (y-vBilinearWeight .y);
       // Calculate upsample weight based on how close the depth is to the main depth
       float fUpsampleWeight = max(0.00001, 0.1 - abs(fSampleDepth – fMainDepth)) * 30.0;

       // Apply weight and add to total sum
       fTotalAO += (fBilinearWeight + fUpsampleWeight) * fSampleAO;
       fTotalWeight += (fBilinearWeight + fUpsampleWeight);
}

// Divide by total sum to get final AO
float fAO = fTotalAO / fTotalWeight;

-------------------------------------------------------------------------------------

// Temporal Blur Code

//////////////////
// Get current frame depth and AO

vec2 vScreenPos = floor(gl_FragCoord.xy) + vec2(0.5);
float fAO = textureRect(aHalfResAO, vScreenPos.xy);
float fMainDepth = textureRect(aHalfResDepth, vScreenPos.xy);   

//////////////////
// Convert to view space position
vec3 vPos = ScreenCoordToViewPos(vScreenPos, fMainDepth);

/////////////////////////
// Convert the current view position to the view position it 
// would represent the last frame and get the screen coords
vPos = (a_mtxPrevFrameView * (a_mtxView
Inv * vec4(vPos, 1.0))).xyz;

vec2 vTemporalCoords = ViewPosToScreenCoord(vPos);

       
//////////////
// Get the AO from the last frame

float fPrevFrameAO = textureRect(aPrevFrameAO, vTemporalCoords.xy);

float f
PrevFrameDepth = textureRect(aPrevFrameDepth, vTemporalCoords.xy);

/////////////////
// Get to view space position of temporal coords

vec3 vTemporalPos =
ScreenCoordToViewPos(vTemporalCoords.xy, fPrevFrameDepth);
       

///////
// Get weight based on distance to last frame position (removes ghosting artifact)

float fWeight = distance(vTemporalPos, vPos) * 9.0;

////////////////////////////////
// And weight based on how different the amount of AO is (removes trailing artifact)
// Only works if both fAO and fPrevFrameAO is blurred
fWeight += abs(
fPrevFrameAO - fAO ) * 5.0;

////////////////
// Clamp to make sure atleast 1.0 / FPS of a frame is blended

fWeight = clamp(fWeight, afFrameTime, 1.0);       
fAO = mix(fPrevFrameAO , fAO , fWeight);
   
------------------------------------------------------------------------------



Friday, 10 January 2014

People of Frictional: Marcus Johansson

This is the fourth part in a series. See all of them here.

Who am I?
Hi! My name is Marcus Johansson and I'm a 3d artist who's been with Frictional Games since January 2009. When I think of that date it doesn't sound that long, but then I realize it's actually 5 years ago.
I started as an intern for 6 months, and after that went straight on to full time.

For most of this 5 year span I've had to work in a corner of the living room, but I finally moved into a 3-room apartment a year ago. Having a dedicated office really helps at home as my other half doesn't share the same working hours as me.

My workspace. (Yes, I made that ugly foot-stand from a old table piece.)
Background
Meetup fun on big toys!
I've always been curious about how things work. At a young age seeing my step dad fixing anything from broken electronics to cars really got me hooked on figuring things out and trying to fix and create stuff myself.

I didn't have a gaming system or computer at home when I was small, but I played NES/SNES at my friend's house every chance I got. It wasn't until I was 12 that I saved up to buy my first gaming system, a Playstation that I spent most of my time playing FF VII and THPS2 on.

At 15, after finding odd jobs here and there and managing to save up enough cash, I bought my first computer, managing to build it from parts without breaking anything. Although not a single physical part is in my current computer it still feels like it's the same one, as I've made incremental updates ever since.

In high school I managed to make a few games in Flash by myself, but later teamed up with a programmer friend and we managed to make a few multiplayer games. We had a Flash gaming site with a working community system up and running for a while, even managing to get a few hundred members, but we didn't take it much further.

 I found these old screenshots from our old game community.

After school I found a course at a large university targeted towards game development. As I didn’t know much about gamedev aside from my Flash/web experiences, I jumped in with both feet without doing much research. Turned out that the course was just an assembly of modules the university had been running for years already; they'd slapped on the game development tag to lure students in. I wasn't learning anything that would get me into the industry.

I realised my mistake and did some proper research, finding a much better programme called Gamemaker that had the art and programming aspects separated. I applied to the art course and got accepted.

I started off in September 2007 and focused on modelling and texturing. The course and teachers were good but it was up to you to make the most out of it. It would have been easy just to pass, but I wanted more than that, so along with a few other students I stayed at the school late at night trying to get good at this thing. The fact that I'd wasted almost a year of my time and student loan on a bad course made me more serious about getting it right this time.

All this hard work finally landed me an internship at Frictional Games after graduating and I've been here ever since.

Since I got my foot into Frictional's basement I haven't touched my portfolio at all. It's still up at www.hadex.se with the stuff I showed to apply for the internship. There are only 4 images, but I figured that it's better to show a few good things than lots of average ones. Keep it short and honest - at least that's what I'd want to see. Same with the letter you apply with; show that you want the position but don't use too much grease or it will feel cheesy and dishonest.

(Looking at these images today with a lot more experience, I wouldn't keep any of them for my portfolio!)

So - if you are looking to get into the industry make sure you find a course that has actual game-making modules on it!

What do I do?
I'm one of the 3D artists at Frictional Games and I do a little bit of everything on the visual side - except that I can’t draw. If there's someone else out there that can’t draw like me, you can still make it as a 3D artist as long as you have a good eye for things and are willing to learn and work hard.

I remember that back when I started here I thought some of the deadlines for the early Amnesia development were very stressful. If I could talk to that version of me today I would tell him to enjoy that nice and relaxing time. But I guess he would be too arrogant and wouldn't listen anyway!

Back then I'd get a task to create a batch of 2-4 different models in the same style along with their measurements and sketches. An example task might be to create a large table, a small table and a chair all as a set. Then I'd just have to model and texture those, and then move on to the next batch.

Although I'm still modelling and texturing smaller props it's now only a small portion of my responsibilities. My main job is to build levels based on an initial design. This usually means that I end up creating modular assets like walls, ceiling, floors, pipes, cables and so on; creating gameplay and story-driven objects; adding detail objects; creating particle systems; creating decals; and making smaller rigs and animations. I send out requests to our outsourcers for extra models and 2D art that I know I won't have time to do if I want to get the level built. I also talk with the animators that we contract to for larger animations.

It can be stressful to try and deal with all of this at the same time, especially as our levels are bigger and more fleshed out than ever before. But this range of tasks is what makes the job so varied and fun for me; your work can be completely different from month to month.

At Frictional we start by focusing on the most important story and gameplay aspects of each level, but at the same time I like to get in a bit of lighting and add some particles in order to spice up the visuals whenever I can. You don't want to leave all of the polishing work until the last few weeks!

Thomas puts a ton of work into designing the levels, but it's up to us 3D artists to kick off this vision and make it into an environment that you can walk around in. You start with a huge level design document and are not really sure where to begin at first, but once you get going and the level comes alive piece by piece it's a great feeling. You get the 'this is my level' feeling after a while even if the initial design isn't yours. I prefer it this way as each level ties perfectly in with each other and the story, instead of having each level builder also be the level designer.

Here is an example of making a room come to life following design and concept.
(click to see big version)

There's a quick insight into what I do in the company.

I usually don't write these sort of things but I hope it was a decent read for you.


Wednesday, 18 December 2013

People of Frictional: Marc Nicander

Third post in the series. You can read the other posts here.

Who am I:
I'm Marc Nicander, I started working for Frictional Games as a freelance artist back in 2006 and got hired full-time when development on Amnesia started in 2008. When I was freelancing I was still a student so I did my work in my 13 square meter student apartment but I have since managed to get a larger space. This is what my current workplace looks like.


Background:
My first real contact with games was back in 1989 when my parents gave me a NES for Christmas. It was the most amazing thing and I spent countless hours in front of the TV playing games like Super Mario Bros, Zelda and Megaman. It also made an impact on my other hobby, drawing. My drawings changed from being things inspired by comics to mostly being Nintendo characters and home-made Megaman bosses.

When I was in 9th grade I got hold of 3D Studio Max and started playing around with 3D for the first time. I remember it being quite confusing - it wasn't easy to figure out how everything worked on my own. I got together with a friend who knew C++ and we managed to make 2 games. The first was an adventure game with pre-rendered 3D backgrounds, the second a shoot'em up that we entered in a PC Gamer competition. We didn't win anything for it, and working as a game developer in the future felt like a far-off dream.

So, instead, I went on a Media Technology course at Karlsham to study 3D, where I learned Maya, film-making and video editing. While on the course, I discovered a different programme that hadn't been listed when I first applied, a 2-year course called School of Future Entertainment (SOFE) that focused on games programming and 3D for film and games. After my 3 year of Media Technology I applied to SOFE, and it's there that I first found out about Frictional Games.

One night when I was working late on a school project a friend, Emil, called me over to his desk. He had been working late nights on a secret project. We were the only ones left there that night, and he wanted to show it off to someone even though he wasn't supposed to. He was doing models for an extension to the Penumbra tech demo, and to say I was amazed is probably an understatement. The way the game used physics for all the interactions was beyond anything I had experienced in any other game at that point, and it got harder to play other games afterwards when I knew what was possible.

When Frictional started building Penumbra they needed freelance artists to create in-game models for props, and this is where I started my Frictional career. I created 3 objects for Penumbra:Overture: a flare, a lock and an engine. I continued freelancing during the development of Penumbra:Black Plague and worked mostly with props but also built some of the levels. After Black Plague was released work started on the HPL2 engine and I was tasked with building levels for the expansion Requiem. We had feedback complaining about Black Plague's levels mostly being a series of boxes on a single plane and my main goal in Requiem was to fix that. It's one of the reasons why the third level in Requiem is all about climbing.

When development on Amnesia started in 2008 I was hired full time and I was happy to finally have a secure income. Little did I know what was waiting around the corner...

What do I do?
I'm one of the four 3D artists working at Frictional Games. My work is to create the world described in the design documents. This means creating a lot of props, making textures and creating levels. I still do most of my 3D work in Maya but thankfully I no longer have to build full levels in it like I did when I was working on Penumbra:Black Plague.

To further illustrate what I do for those of you who aren't in game development, I'll show you an example of how I make a simple prop. I start out with a basic object, in this case a cube. As you can see in picture A, the cube is built with planes between vertex-points. By adding vertices and moving them around as seen in picture B I can shape the cube into anything I like. If I add more basic objects and modify them I can end up with the result in picture C.






When I'm done with the basic object I save it as a low poly (low detail) object and start adding more details to it. This new model will become the high poly (high detail) object you can see in picture D. We'll use this highly detailed model to trick the viewer into believing that the low poly object in the game is more detailed than it really is. We'll show examples of this in our upcoming artist blog posts along with level building and concept artwork.

(Note: Model is not from SOMA...)


Thursday, 12 December 2013

The Five Foundational Design Pillars Of SOMA

First, here is a new video from SOMA showing off an environment captured directly from within the game:



Now moving on to the main topic of this post: The foundational design pillars of SOMA. When creating a game I think it is crucial to have a few basic rules that underlie all other decisions. That way it is much easier to keep everything on track and get the final game to play out as intended. For SOMA our intention is to craft an experience where players become deeply connected and affected by the game's world and themes.

Here are the five cornerstones that we hope will let us achieve this:


1) Everything is story
First up, we want the player to constantly feel as if they are inside a flowing narrative. It is so common that a game is distinctly split into story and puzzle/action moments. We want to blur the boundaries here and make it impossible to distinguish between the two. Whatever the player does it should feel as if it is part of the story. We do not want to have sections that simply feel like blockers to the next narrative moment. From start to finish the player should be drenched in a living, breathing world of storytelling.

A good example is how we design puzzles. Instead of having the puzzle by itself, as a separate activity, it always springs from and is connected to some aspect of the story. For instance, if the player encounters a locked door, there are more reasons for getting it open than simply to progress. There are always short term narrative reasons and rewards for getting it unlocked. On top of this, the very act of solving it results in the player taking part of a narrative scene.

Encounters with hostile beings are handled in the same way. A creature will never attack you without good reason; they never do it out of pure gameplay necessity. We want every encounter to feel like a bit of storytelling is happening. To get this working properly, almost every single creature has unique AI.


2) Take the world seriously
This leads us to the next point: that every detail in an environment is connected to the story somehow. Nothing should be written off as simply a requirement for gameplay or exposition. For instance, if you find an audio log you will be able to learn more about the story by pondering its placement alone. There should be no need to "double-think"; the game's world should be possible to evaluate on its own terms.

We constantly think about what each character would have done in a situation, and shape the environment accordingly. For instance, in one level, we started out with scratches on the walls but later realized the character had access to a whiteboard pen and changed the graphics accordingly.

It's so easy to justify design "because the game needs it" even if it doesn't make sense to the story. But for each such thing you do, the less seriously the player will approach the environment. In SOMA a big part of the game is to ponder the situation you are in.Therefore it's crucial that players consider the world from a story view, and in order for that to happen we must provide them the opportunity to do so.


3) The player is in charge
When you invest this much in a setting, it's important to make sure that players feel connected to it. In order to this we need to put a bigger responsibility on the player. An environment quickly loses its sense of realism if it is extremely streamlined and does not allow you to make choices. The player must be the one that drives the narrative forward.

The game never tells the player exactly how to progress. There may be hints and other implicit guidance, but in the end it must be the player that figures out what to do next. If a game is constantly flashing up cues with objectives or showing arrows pointing where to go, the player will never take on the world at a deeper level. If it takes some effort to progress, players are forced to understand and mentally map the surroundings in a way they would not do otherwise.


4) Trust the player
This brings us to the next point: that we trust players to act according to the story. We do not force players to notice events by use of cutscenes and similar, but assume they will properly explore the environment and act in a rational fashion. We simply set up situations and then let the player have full control over their actions.

This means that we will let players do stupid things even if they might break the experience a bit. For instance, if they skip talking to a character with important information then they are on their own after that. And if they get hints that a dangerous creature is approaching, they need to figure out that hiding is the best course of action by themselves.

While we do our utmost to make the narrative unfold in a fluent and intuitive way, we will not cater to players that make irrational decisions. The environment is set up to be taken seriously and we expect the players to do so too.



5) Thematics emerge through play
Now for our last foundational design rule: that the game's thematics will emerge through play. SOMA is meant to explore deep subjects such as consciousness and the nature of existence. We could have done this with cutscenes and long conversations, but we chose not to. We want players to become immersed in these thematics, and the discussions to emerge from within themselves.

It feels wrong to just shove information down the player's throat. What I find so exciting about having these thematics in a game is that the player is an active participant. There are plenty of books and movies that cover these sort of subjects, but videogames provide a personal involvement that other mediums lack. We want to explore this to the fullest degree

Just like all of the other design goals, there is a bit of risk in this. It requires the player to approach the game in a certain way and it will be impossible to make it work for everyone. But for those people where it succeeds, it will be a much more profound experience. I also find that it is when you are dealing with uncertainties that you are doing the most with the medium, and am extremely excited to see how far it will take us.


Tuesday, 10 December 2013

Editor feature: New color picker

Hey there! So I finally dropped by to write a quick post on our stuff after quite a long hiatus (exactly 3 years, 3 months and 8 days long according to my last post) and Thomas pretty much took over the blog. Right now most of you might be wondering who's typing even . The name is Luis and I mainly code the tools we use here at Frictional (also the ones you might have been using for making your own Amnesia custom stories) After the quick introduction, here comes a little editor feature showoff.

If you ever used the Amnesia tools yourself, it's more than probable that you already know about this little buddy here:



One could say it is functional. I mean, you actually can pick a color by using it. But it had a little problem. It sucked, and real bad I must add.

When you are editing a level and need to pick a color for anything, be it the diffuse color for a light or the color multiplier for some illumination texture, you are probably going to need a nice system that allows for quick tweaking with not much sweat. This is definitely not the case of our old color picker, mainly because of two reasons: the RGB color space and lack of immediate preview of changes.

Selecting a color in the RGB color space is pretty straightforward you might think. And it is indeed, you only need to set the values for the Red, Green and Blue components and you are all set. That's it. Okay, but what if you need to choose from a range for a particular color tonality? How are you supposed to know which RGB values you need to set for that? Summing up, RGB is a pretty uninintuitive system when it comes to edition, so we pretty much had to update the color picker to use the HSB color model as well.
This model describes colors as follows:
  • the H value, ranging from 0 to 360, controls the hue for the resulting color; 
  • S, which stands for saturation and ranges from 0 to 100, indicates, in layman terms, how washed the color will look, with 0 being white and 100 equalling the original hue color (for a B value of 100); 
  • and finally B, standing for brightness and ranging from 0 to 100 as well, is quite self explanatory and sets how bright the final color will be, with 0 meaning black and 100 meaning the color that is set by the other 2 parameters.
As for the immediate preview, anyone who used the old picker knows that you had to exit the picker in order to apply and see the changes. When you need to tweak things, which involves constantly changing values and checking out how it looks, this setup is bound to get old and annoying way quicker than you would want it to. To fix this, the new picker can change the target color on the fly, letting the user see the end result in the scene while modifying the values.

Another upgrade that speeds things up a lot is going as visual as possible. No matter which parameter you are editing, being able to change it via a slider or some other graphical tool that you can click on will always help tons. The drawback of these, though, is that it's very likely that you spend more time on them than needed just because they are so fun to use.

After all this long-ish introduction, just say hi to our new color picker:



And see it in action in this short demo video:






Sunday, 8 December 2013

People of Frictional: Jens Nilsson

Second post in the series. Thomas Grip posted the first, which you can read here.

Who am I
I'm Jens Nilsson, one of the people that started the company in 2006. Back then my work space was dubbed the "Pink Room" and in it all the Penumbra and Amnesia magic happened. The previous occupant of the apartment had a young girl and that room was the girl's room. We did not get around to give it some new paint until the year before we moved out. I dug and dug but could unfortunately not find a picture of it. Anyway, I've always had the luxury of having a dedicated room to work in and currently I am located in a cozy attic space.


Background
I got an urge to make my own games when I was seven years old and the family got a C64. Spent a great deal of time copying the code from the Basic manual and got stuff printing, balloons flying and even the C64 making sounds. Did I understand anything of it beyond the end command "run"? Nope.

My first actual working modification of a game was around 1990 when we had a game called "Italien 90" which was a game written in Basic for the C64. The game was a simple text based football manager for the world cup in Italy 1990. As it was a Basic program you could pause the game, scroll through the code and make changes. I'm sorry Thomas Ravelli, but you got replaced by Jens Nilsson and my stats were all top 9 values. While at it, the rest of the Swedish team got top 9 values as well but they got to keep their names. Sweden won the world cup, over and over, which was quite similar to how they performed in the real competition (group c).

The following years I did not spend much time trying to create anything, kept it to gaming only. Instead I spent a great deal of time playing instruments, at first the piano and later the guitar. I eventually started playing in bands and music was the main occupation during the years 1988 to 2002. In 1995 the family acquired the first computer since the C64, which was an Apple Macintosh 5200. With it some craving for trying to create something with games came back. As in my younger days, actually programing something was not on the table, rather modifying games was what I did the most. Mainly Bungie's game series Marathon, it had third party tools available so you could create and edit content for the game. For anyone interested the Marathon games are available for free through the Aleph One project.

Not very pretty deathmatch level for Marathon.
In 1996/1997 the family computer got bumped to an Apple Macintosh 6400. With this my two interests started to merge and I began using the computer to record and make music.

One day in 1997 I was reading the latest news on insidemacgames.com and there was a post about the next game from Brian Greenstone. He had announced that his next game was going to be freeware and because of it he asked if there were anyone interested in helping out making graphics, music and such. I had no clue at all about how/what to do in terms of music for a game, but I figured I should at least mail and offer to help out. I got a positive response and for the next couple of months we sent emails back and forth. Brian sending new builds and I sent my attempts at making music for it. As this was in 1997 it took time to send or receive an email with a large attachment, as much as 30 minutes. Always with the risk of the dialup connection breaking. Tough times. In the end I only did one track, the one used for the menu. Regardless, I had gotten my first taste of working with some actual game development.

  
 Video of the game Nanosaur (only a few seconds of my music at the start…). 

I finished high school in 1998 and in 1999 I turned my "music for games"-hobby into a self-employment business. The following years I did a lot of small projects, some that never got released, but quite a few that did. Lot's of the work I did was for free, or for little pay, what I earned I mostly spent on getting new gear and software. The main "pay" was gaining experience and contacts. I increasingly did less and less music and more and more sound design. These projects gave opportunities to do tasks other than audio. Scripting, design and such all got some leveling up. Running a small business also required me to get up to speed in all sort of departments. I needed to make websites, understand how to invoice, bookkeep, market, customer relations, international work/pay and all the taxation rules that goes with it, and so forth. Experience that turned out to be quite handy as we started Frictional Games.

Thanks to the wonderful Wayback machine I can show a saved version of my old site. Listed are all the game projects that got released up to 2006.

Captain Bumper, cool and forgotten Mac game.

From 2002 to 2006 I attended a game development program at the Gotland University College. We did some fun projects as part of the education. My favorite is probably the large, foot controlled, floor projected Pong game that we created at the end of the first year. Overall the education was quite chaotic, lots of changes as to what the purpose of it should be. Because of that the quality of the education was lacking. It did allow for a lot of free time, I spent that time doing other projects through my self-employment business. A friend in class one day told me about a guy that he met online. It was some strange dude that was making a horror game and my friend was helping him out making graphics for it. A couple of months later I got in contact with that guy as well, it turned out to be Thomas and his Unbirth project. I did a bit of sound design for it and well, yeah, I think Thomas pretty much covered the rest of how we went from there to Energetic, to the Penumbra Tech Demo and ending up starting Frictional Games.

Four player Pong clone.
What do I do?
I have headed up the audio department, where I have done most of the sound work and design of the sound while working with Mikko Tarmina as our composer. For Amnesia, Kaamos Sound helped out making sounds. For Soma, Kaamos and Samuel Justice are doing all the sound work with Mikko doing his magic with the music. Other game work has been level scripting, level editing, level optimization and design.

I take care of our servers, both for development and for the public sites. This involves setting up and making everything running properly, it could be something as simple as registering a domain, researching and installing a bug tracker, it could be writing the code and server scripts for websites or making sure everything is backed up on a running schedule. I do, or did, lots of our customer support, these days we have a very nice forum community that does way too much of it (in particular one guy…). Like Thomas I also have a slew of small stuff that is done from time to time.
Two rows of not games.
In addition to the server management, what I pretty much only do at the moment is managing the company side of things. This is all sort of stuff not related to game development: Partners, agreements, salaries, taxes, bookkeeping, sales reports, buying equipment, paying invoices, sending invoices, reading and writing a never ending stream of emails and so on and on. At the moment I am not doing any game development due to two reasons. First, we have grown to 12 people and have numerous contractors, partners and service providers. It all requires a bit more time to manage these days. Second, currently only working three days a week, so I have less time than what I used to have (hmm, I can think of quite a few years when we worked seven days…). Next year I'm going back to full time again and with it I should be back to a bit of the game development work.
Four reasons to work three days a week.
If you are thinking, "Oh, the poor sod. From game development to office rat". No, not really! I've always been the most interested in the whole of it, to run a company as well as to do creative work. The main perk with Frictional Games has always been the wide variety of things to do.

I did not go much into details about how I actually do the various things that I do. If you are interested and have any questions about it, just post a comment and I'll do my best to give you a prompt answer.