## Tuesday, December 10, 2013

### Never again: point lights

Distant, point, spotlight, am I right? Or maybe you can merge point and spot into an uberlight. No.
Have you ever actually seen a point-light in the real world? It's very rare, isn't it? Even bare-bulbs don't exactly project uniformly in the hemisphere...
If you're working with a baked-GI solution that might not affect you much, in the end you can start with a point, construct a light fixture around it and have GI take care of that. But even in the baked world you'll have analytic lights most often. In deferred, it's even worse. How many games show "blobs" of light due to points being placed around? Too many!
With directional and spots we can circumvent the issue somehow by adding "cookies", 2d projected textures. With points we could use cube textures, but in practice I've seen too many games not doing it (authoring also could be simpler than hand-painting cubes...)
During Fight Night (boxing game) one little feature we had was light from camera flashes, which was interesting as you could clearly see (for a fraction of a second) the pattern they made on the canvas (journalists are all around the ring) and there it was the first time I noticed how much point lights suck.
The solution was easy, really, I created a mix of a point and distant light, which gave a nice directional gradient to the flash without a cone shape of spots. You could think of the light as being a point and the "directional" part being a function that made the emission non constant on the hemisphere.
It's a multiply-add. Do it. Now!

 Minimum-effort "directional" point

Another little trick that I employed (which is quite different) is to "mix" point and directional in terms of the incoming light normal on the shaded point (biasing point normals towards a direction), at the time an attempt to create lights that were "area" somehow, softer than pure points. But that was really a hack...

Nowadays you might have heard of IES lights (see this and this for example), which are light emission profiles often measured by light manufacturers (which can be converted to cubemaps, by the way).

I would argue -against- them. I mean sure, if you're going towards a cubemap based solution sure, have that as an option, but IES are really meaningful if you have to go out in the real world and buy a light to match a rendering you did of an architectural piece, if you are modeling fantasy worlds there is no reason to make your artists go through a catalog of light fixtures just to find something that looks interesting. What is the right IES for a pointlight inside a barrel set on fire?

 A more complicated function
A good authoring tool would be imho just a freehand curve, that gets baked into a simple 1d texture (in realtime, please, let your artists experiment interactively), mapped with light direction dot (light position-shaded point).
If you want to be adventurous, you can take a tangent vector for the light and add a second dot product and lookup. And add the ability of coloring the light as well, a lot of lights have non-constant colors as well, go around and have a look (i.e. direct light vs light reflected out of the fixture or passing through semi-transparent material...).

1d lookups are actually -better- than a cubemap cookies, because if you see in real world example many fixtures generate very sharp discontinuities in the light output, which are harder (require much more resolution) to capture in a cubemap...
Exercise left for the reader: bake the light profile approximating a GI solution, automatically adapting it to the enviroment the light was "dropped" in...

## Sunday, December 8, 2013

### Enhance this!

Don't you hate when people have strong critiques towards a thing, but it happens that it's just that they don't know enough about it? Well, I don't, because then I think of how many times in my youth (and let's say only then) I did the same...

Regardless, today I happen to have a bit of time and I saw yet another post laughing at how stupid the "image enhance" trick used in movies and TV series is, and so you get this nerdrage against nerdrage...

Now think a second about this. Who do you think it's right? C.S.I., which is a huge TV series using arguably some of the best writers and consultants, or the random dude on the net? Do you think they don't know how realistic any of the techniques they use is? Do you think they don't actually and very carefully thread between real science and fiction to deliver a mix that is comprehensible and entertains their audience, telling a story while keeping it grounded in actual techniques used in the field? Don't you think -they- know better, and the result was very consciously constructed?

The same goes of course for anything, really, especially when something is successful, makes a lot of money, has a lot of money behind, you should always bias yourself towards being humble and assuming the professionals making said thing -know better-.

Now, back to the "image enhance" trick. It turns out it is real science. It's called "super-resolution" and it's a deep field with a lot (really, a lot!) of research and techniques behind it.
It's actually common nowadays as well, chances are that if your TV has some sort of SD2HD conversion, well that is super-resolution in action (and even more surprising are all the techniques that can reconstruct depth from a single image, which also ship in many TVs, the kind of models they came up with for that are crazy!).

The scenarios presented in movies are actually -quite- realistic even if the details are fictionalized. True, the interface to these programs won't look like that, maybe they won't be real-time and surely they won't be able to "zoom" in "hundreds" of times, but they surely can help and surely are used.

That is to me a reasonable compromise between fiction and reality, as certainly you can and will use computers to get a legible nameplate for a video that is too low-resolution for the naked eye, or match an otherwise unreadable face against a database of suspects and so on, probably not in quite as glamorous and simple way as the movies show, but fundamentally the idea is sound (and I'm quite sure, used in the real world).
It is a non-realistic representation of a very realistic scenario, which is the best that good fiction should try to achieve, going further is silly. Or are you going to argue that a movie is crap because at night for example you can't really see as clearly as they show, or because they don't let a DNA test take weeks and an investigation several years?

When it comes to videos we can use techniques known as "multiple image" super-resolution, registering (aligning) multiple images (frames in this case, i.e. optical flow), and merging the results, which do work quite well. Also, most fictionalized super-resolution enhances focus on faces or nameplates, which are both much easier to super-resolve because we can "hint" the algorithm with a statistical model (a-priori) which helps tremendously to guide the "hallucination".
And even if hallucinating detail might not hold in a court (the stronger the a-priori model, the more it will generate plausible results but by no means always reliable), it might be very well be used as a hint to direct the investigations (I've never seen a case where it was used in courts, always to try to identify a potential suspect or a nameplate, both cases where having a strong probability, even if it's far from certainty, are realistic).

So, bottom line is, if you think these guys are "stuuuuupid", well then you might want to think twice. Here are some random-ish links (starting points... google scholar for references and so on if you're interested... I couldn't even find many of my favorite ones right now) to the science of super-resolution:
It would take many pages only to survey the general ideas in the field. Don't limit your imagination... Computer science is more amazing than you might think... We reconstruct environments from multiple cameras, or even sweeping video... can capture light in flight, we can read somebody's heartbeat from video, fucking use lasers to see around corners and yes, even take some hints about an environment from corneas...

And by the way, don't bitch about Gravity, try enjoy the narrative instead. You might live a happier life :)

## Thursday, December 5, 2013

### Notes on Epic's area lights

Finally, PBR is becoming mainstream... But, it's not easy, especially if you want to stay "correct". Are you sure your pipeline has no errors? Do you know the errors you have? What is your ground truth? Acquired data? Path traced solutions?

I'm planning to share some of my notes on PBR methods and certain findings and thoughts, this is a starter, on Brian Karis' excellent "representative point" area lighting as explained in Siggraph's 2013 PBR course.

I won't say much about it actually, mostly because my own research is not cleared for publication yet. If I were you though, I would also keep an eye on GPU Pro 5, as Michal Drobot's publication might change the state of the art once more (and I'm not really teasing, to say the truth I haven't tried his method yet and compared it, but I think it's "better").

As a good PBR renderer (or any renderer really) should know what kind of errors it's committing, I implemented an area light integrator and used it to verify a few ideas, including Epic's:

 Blue dots: ground truth. Meshed plot: Epic's
It turns out the representative point solution does not do a great job at "preserving the shape" of the underlying BRDF, and it (quite understandably) just "caps" it with a spherical arc. Also note that at more grazing angles the ground truth is quite different and its cap starts to have a slanted angle as well.

Normalization is also interesting, here I actually thought Epic's method would fare worse (as it seemed to be just an heuristic with not enough justification behind it), but it's actually quite close to ground truth. Always check...

 The smaller, gray mesh is the ground truth, the non-gridded light blue surface is Brian's normalization for the representative point solution, the gridded light blue one is my own version.

It is possible to do better, with varying degrees of complexity. At a given point things start to be needlessly complicated so, when you start looking at data try not to lose track of what your artists want and what makes a perceivable difference.
Don't do my mistake of staying too long in Mathematica to find a perfect solution, without verifying in actual shaders that you've passed the point where it matters...

Arguably for example, for small lights, the "roughness modification" solution is actually better, Brian notes in his writeup that for small lights that is indeed a good method, but you might want to think twice considering if you need big lights or just lights big enough to "correct" for a roughness factor that otherwise would end up wrong in the materials.

 One of my own analytic area approximations
Some other food for thought:

• How much does hemispherical shadowing (area light dipping under the normal hemisphere visibility) does matter?
• Should more of your sky be represented analytically? Note that it is true that the sun itself has a small arc when seen from the earth, but with the scattering that happens in the sky a larger area could be represented as "area light". The advantages are that it would work better with the BRDF and have more "correct" shadowing...

## Sunday, December 1, 2013

### On Mantle

So it seems nobody so far had made a fool of himself being opinionated on AMD's recent Mantle API announcement. Allow me to fill that spot!

- Mantle is a -great- idea!

I think AMD nailed it this time... One of the biggest barriers that all kind of innovations face is adoption. For gaming hardware that's often due to a feedback loop, you need developers to be on board in order for the technology to be utilized but they won't care to invest money if the user base is not there, and the user base won't be there if developers don't commit to making product using a given technology.
That's the reason why for example you don't see most of the big players committing to exclusives early-on when a new console generation comes out, and why for example I still believe Oculus will have a tough time regardless of how amazing it is...

One way out of this is to be somewhat scalable, offering a technology that works without your proprietary stuff but works much better with. E.G. PhysX, the hardware acceleration board for physics in games was initially an extremely bad idea, they sold nothing and they deserved to sell less (I feel for people that wasted their money on that). Nowadays though it works, both because NVidia bought them and made the library to work on their much more popular GPUs, so lowering the barrier of entry, and because they offer a CPU fallback, so it's not exclusive to NVidia's. Great job, and I'd like them to follow a similar suit with GameWorks as well, by the way...

Now, it seems that AMD is not following the suit here, I guess it would be possible to make an emulation layer that fallbacks Mantle on DX11 (or well, parts of it), but they aren't. What they are doing though is to leverage on the fact that all the next-gen consoles are already on AMD's hardware, and that really console game development is incomparably a bigger market than PC gaming (yes, still), so most companies are more than willing to invest to use all kind of proprietary tech if it runs on consoles. Well, in this case they don't even have much of a choice even!

So what AMD really did here is to find a way to leverage the position they have on consoles (which some analysts says it probably doesn't bring huge quantities of cash) to help their PC line as well. By keeping Mantle close at least to PS4's API (as I expect it to be... otherwise all this wouldn't make any sense) they are "recycling" an investment developers already have to make and lowering the barrier of entry. Also, developers already will have a DX11-ish renderer ready for XB1 (and I'll expect Microsoft to similarly keep in sync next versions of DX with the XBone to leverage a similar effect), thus allowing the "PC build" of the game to just be a merge of both technologies studios already have to employ: a XB1-ish renderer and a PS4-ish renderer.

- Why does DirectX 11 suck (not!)?

What are DirectX big issues?

Well mostly they are all related with the fact that doesn't break the tradition of requiring delayed work on draws, requiring the driver to do extra work to keep track of things around and then pull them in to submit to the GPU... The hardware state is not (and won't ever be in an abstraction API) one to one with the DirectX bits of state, so the driver has little choice but to store what DirectX tells to set in the hardware, wait until a draw appears and then look at -all- the state it stored and translate it into the appropriate bits and pieces that go in the hardware. Another way the driver needs to do extra work is that state lifetime is all "wrong" too, certain objects in DirectX can be just updated with new information but that's not possible for a driver as it has to keep the old ones around until the GPU has finished processing them, so you need to make duplicates, patch things and all kind of horrors.

Does this make of DirectX a bad API? I'd argue, it makes it less good than it could have been, surely. But it's still fairly great! State could have been grouped in bigger entities, if a single "set" command sets a lot of state chances are the driver will have more often all the information needed to do some work. State lifetime could have been defaulted to "discard". Many other little adjustments could have been made, remember though there is also a balance with ease of programmability (less of an issue for gamedevs maybe, but DirectX is not only for games) and compatibility with legacy hardware an so on...

- A frigging hundred thousand of drawcalls. And do I care?

Why is Mantle cool for developers? Established that it's not a big investment, so it's approachable, why should we care? Well, one of the biggest bullet-points AMD is putting out there is that the API being faster, slimmer and more low-level will allow for much more drawcalls, more unique objects on screen.

I think this is mostly marketing, and it's unfortunate that AMD didn't yet publish any real numbers of real games doing really better for real. I think it's because for the most, they won't. Now, it is true that there are situations where PC games are CPU and driver-bound, if you have an extremely powerful GPU that might quite often be the case, also there are certain games that are really optimized to generate a LOT of draws, e.g. forward-rendering engines that rely on splitting geometry at light and shader "intersections", or engines that rely on multipass rendering... But still, it's nice to have a speedup in these circumstances, but let's be honest, will the industry really jump on the idea, or rather let PCs to be slightly-less-than-optimal and circumvent that with their extra power?

To answer that I think you should really look at DirectX 11 and the amount of effort the industry did put into that. DirectX 11 came out in 2008, almost six years ago now! How many games have shipped on it? How much better where they compared to DirectX 9? Are there games that are still faster on 9 than 11? What about tools? How much the industry cared? How much did we use Compute shaders? Geometry shaders? Tessellation?
Truth is you will start seeing just now better DirectX11 games because now consoles are on DX11-ish hardware. Before, nobody did really care much, and once your assets are made to work on consoles there is only little you can do to "dress them up" with extra features... Everybody remembers Crysis 2 tessellation issues, but almost all games did the same things, just minor cosmetic dressing in their DirectX11 versions when they cared to put out one. If you have actually worked on DirectX11 you will have found that a big issue is still on driver bugs and various things that don't work as they should...

Really, the API is not perfect. But mostly it's that nobody, not the gamedevs nor the GPU vendors did really invest a lot. I would argue that the performance issues for example are as much a fault of the API as they are a fault of the drivers. It could go faster, even right now, in the end even in the golden era of PC graphics we always worked with the GPU vendors to "carve" certain hot-paths where the drivers were fast, a sort of contract on a language, basically an API inside the API. And I don't believe (I might be wrong) that DX11 doesn't allow for a proper multithreaded driver (or more than it is right now anyways). I think it's that having such things is quite hard and won't make anybody rich, and thus nobody really invested a lot of money in them...

So where does all this leave us? Well, it turns out that we not only are "good" at writing engines that work in the thousands of draws per frame limit but I suspect we still will need to, because not all the platforms will be able to do hundred of thousands. And if not all the platform will, it means that we still will need to think about art assets and graphic techniques in a way that they work on thousands of draws. Once you have a world that works like that you're set, you won't really be able to use that ability of drawing hundreds of thousands.

Nowadays in any game you have, even if you bump the draw distance all the way you still won't generate so much draws. It would be cool probably to think about a new generation of engines that structurally work with an hundred-of-thousands draws assumption, I think it could very well change the way we think about culling, instancing, figure new ways. But I don't think it will happen, I suspect it will remain a marketing thing, and games will go better just because they can be a bit faster on certain hardware configurations at doing the draws they do. At best, we'll have more particles or such dressing-style effects, but I can't really imagine now an application because we're good at doing these things with very few draws already. Anyhow, it will be hard to fully employ any ability that requires to think about assets in different ways, if said ability doesn't work everywhere...

- Mantle and NVidia? Mantle and EA? Mantle and Steam Machines?

Even if AMD says the opposite, I don't think Mantle will be a cross-platform API. Well, I don't even think it will be a cross-generation API. I don't think it SHOULD BE. As I wrote at the beginning, it would be the best if Mantle was as close to PS4 as possible, lowering the investment needed for gamedevs. Even if it works only on the GCN hardware and the GCN will be the architecture they use more or less for this entire console generation, that would be plenty. No gaming-oriented graphics API (and probably no graphics API in general) has really to think with longer timeframes, technology changes anyways.

If Mantle is close to PS4 then probably it won't map perfectly to NVidia's hardware, but I don't think it's hard to believe that the API could run and maybe even well on NVidia's GPUs, there are ways to abstract things just well enough. But I don't think NVidia will join the program, developers will surely be happy if that was the case, but, politics... Also if AMD really wanted to make an "open" API well. they surely shouldn't have been doing it behind closed doors with EA|Dice and nobody else...

Speaking of which... What's in for EA? When I first heard about Mantle I was puzzled and in a way I still am. For the reasons I sketched above I don't think that EA is going to directly make more money from it. I don't think it will be as revolutionary as it could sound to begin with, I see it as an optimization but I will be surprised to see significant graphical features to be locked to Mantle-only. And even if such things existed, we're talking about an influence on less than half of the PC market, that per se is significant only for very few EA games to begin with (only Battlefield?).
I don't really see them selling more copies because of Mantle, to a degree that I even suspected that AMD might have just paid to get Dice on board, or did most of the work themselves for the porting. On the other hand I wouldn't discard the sheer passion of Dice's team for graphics and technology. And I can't really get a feeling of how much Frostbite (and Ignite) as brands per se help marketing EA's games, to a degree where being on top of whatever graphical innovation there is directly strengthens that brand and skews people into thinking that everything Frostbite will be a must-buy...

About Steam Machines, I don't know really. I don't know how Steam Machines will succeed to begin with, even less Mantle on them. They are PCs. They cost in the ballpark of how a PC would (from what we know so far) with a similar hardware, just without Windows, where still the vast majority of games are. And I don't think Valve can really do publish their games on SteamOS only (HL3...) as certain people say, for the same reasons no huge title lands on new consoles at launch. Too small of a market.
Even if SteamOS can just be installed alongside Windows on the PC you already might have, it would simply hurt the sales of the game, piss the Windows Steam users which are the "core" of Valve's market and be a crazy move in every way. Yes, Mantle could run on Linux I guess even easily. But it won't help. You would still need to cover OpenGL for NVidia's hardware anyways, so it doesn't really lower the cost of entry. Unless it gets so crazy popular that some studios will be willing to do Mantle exclusives... Hard to imagine.

- Tl;Dr - Conclusions and expectations

Mantle is a great move for AMD. I hope it will be very easy to port from PS4, if so, we will see titles using it as a performance improvement. That's the minimum expectation, AMD hardware gets a framerate boost on some or many titles depending on how easy it is to port. Both low-end configurations and very high-end (where a single-threaded CPU driver might likely stall the GPU) might get advantage.

I expect also some savings on the GPU side, not only CPU, especially if they expose better ways to control scheduling of draws and compute on the GPU, aiding efficiency, but also from other things like being able to avoid certain operations all-together. Actually I would say there is a lot on compute that is not exposed today by DirectX, being able to schedule that better might be a bigger win than the mostly-marketing stuff that the 100k draws per-frame I think is...

If they expose more of certain GPU details which are not accessible under DirectX/OpenGL, there might even be certain effects that are available only on Mantle. We might see better streaming and texture usage thus enabling nicer textures, so getting some better looks from there instead of just better framerates. Stuff like 3d rendering (rendering the scene twice) might benefit more from Mantle, as they could all kind of algorithms that need to submit the scene to different buffers (think for example more shadowmapped lights etc...).
Overall though my "best" scenario is that it might enable "minor" cosmetic additions that are hard or too expensive to do without it. The kind of things you saw in DirectX10/11 versions of DirectX9 games. I doubt games will look significantly different, I doubt assets will be made exclusively for it. I doubt NVidia will jump on board.

Mantle is interesting also because it will open the "lower lever" layer to researchers and categories which don't usually work on consoles, some good stuff can come out of that, stuff that I can't foresee today and might change the landscape...

But most importantly, it will -surely- tell NVidia and Microsoft to "get their shit together" (having Frostbite on Mantle is enough already to call it a success and make these companies worry, imho). I think Mantle could be cross-platform, I don't think it will be (NVidia won't make it)... which will lead to both a better DirectX (which Microsoft will likely leverage also to make XB1 better) and better drivers... If they feel threatened and they care, put money on that, they might even succeed at making Mantle "obsolete" (less attractive) faster that it will spread... We'll see...

## Sunday, November 3, 2013

### You have failed

Today i was watching Mike Acton's talk at SIEGE 2013 on leadership, and it prompted me to stop the article I was working on to start drafting this. I recommend watching his talk, it's quite good and it talks about the key to leadership: responsibility.

Indeed, leading is about accepting responsibility, it's different from management and its methodologies, and I don't think really it applies only to the people who we identify as "leads". It doesn't come with a tag, really, leadership is a quality that is valuable regardless of your position and most of the good traits of leadership are the same, only the scope, or sphere of influence changes with your job. And that is exactly because leadership it is about responsibility, which is an universal value, even outside the workplace really.

It's maybe even a pet peeve of mine, I hate when we (and we all do to a degree) think about circumstances or the faults of others, without first thinking about what we did or what we can do. Now, among all that responsibility entails there is something that people shy from talking, something very fundamental that we have to discuss, and the reason I'm writing this. Failure.

If you never failed, you didn't try hard enough really, right? To a degree I think we all agree that failure is important, it is a metric of how much you push yourself out your comfort zone but it isn't in any mean a positive thing, I won't make some hippy case for the contrary. We all want to be successful, we want our programs to work, our games to sell, our research to innovate and so on.

Success is good, failure is bad... but on the other hand, we don't just sweep under the rug our failures, right? Failures are problems, problems... well that's something we can work on, it is information, it is learning, it is part of our job, it is part of being responsible.

I find it hard not to be defensive, we instinctively are I think, surely I can be and it requires applying quite some thought and attention to detect these instances in oneself. Even what I just wrote is an example of it, I changed into "I can be" my original "I am" because writing something negative about yourself seems to trigger some internal alarms.

Have you ever experienced a studio head coming in and saying words along the lines of "we didn't do well" and "things didn't work out as we expected" so we have to do some crunch and overtime maybe even throwing in a few hints at how that's kind-of normal in our line of business anyways? Would you not have preferred someone saying I was wrong, I approved these decisions that didn't pan out, now we have to ship and I think this is the best course of action, and of course if you want to talk about alternatives come and we will figure things out?

If that's something that you agree and experienced, then be responsible, and apply the same lesson to yourself as well... Wouldn't it be a better world if we knew for example all the interesting ways a given technique fails, not only the ways it succeeds? Why we can't be open about failures? Honesty leads to facing issues in a positive way, it leads to trust, it is a remarkable value. Managing failure is part of leadership, educating about it is part of leadership, and certainly the more influence on the studio culture you have (or should have) the more you're responsible for these aspects, but really it starts with everyone, leader or not. It's a good skill to learn.

Let go of defensive instincts, they won't make anything better.

## Friday, November 1, 2013

### Battlefield 4 Review (graphics)

UPDATE: I see this have been picked up by some gaming forums. All fine if we take this not -too- seriously, the disclaimer below applies, these are some limited considerations and thoughts I had by putting few hours in the game while waiting for other stuff to finish and so on. I stand to the fact that some things are interesting to think about (beware, might even be technically wrong when I say they do this, could do that, I didn't use any hack to reverse-engineer the game) for people who make games. I see people saying "it's like digital foundry on steroids". No, DF spends weeks to do a really amazing job reversing what they can reverse accurately. I spent little time and had some unsubstantiated rendering thoughts, it's at best different. Anyhow, if it doesn't end up in a flamewar that lets me take this down, I might do it again for other games or publish other stuff I did in the past and kept private. Maybe even do it seriously next time.

So... This ain't gonna buy me any friends I guess. On the other hand I have to say I would be thrilled to see people tell me even the harshest things about my work, I've learned from a great artist who once told me to seek for people that would tear my drawings to pieces. Not that there is anything to tear in DICE's excellent game, just to say, please do dissect my work :)

Also, these are just some things that I've noticed in a few hours of single-player campaign, on my PC at Ultra. It's not comprehensive. It's biased by whatever happens in the first few hours of SP, by my mood the day I played in many other ways. It's not baked by Pix captures nor by any special knowledge, so it's probably ALL WRONG I didn't take enough time to "reverse" anything.
I routinely survey games and their graphics, I consider it part of my job, but often I don't have much time for that. Worse still when the game is good and I end up actually you know, playing it, instead of just looking at rendering tech :)

I hope screenshots will survive blogspot's compression, also notice that most of them are downsized so don't pixel-peel, most images are equivalent to a supersampling AA version...

Ok, so. Let's go.

Frostbite is a great engine and I'm actually thrilled to see what all the various EA studios come up with it, truly can't wait. So as you will imagine and as everybody already will tell you, there is a lot of good stuff... That's why I'll start instead with three things that I think are -wrong-, then move to other observations:

1) J.J.Abrams actually doesn't want his lens flares back
The good: they work well, they are stable (seem even to fade behind occlusions), they are a mix of techniques I guess screenspace, art-authored particles and framebuffer readback to spawn more particles. They look very similar to Crytek ones, and they truly "blind" you.
The bad: they are fucking everywhere! BF3 did this, Crysis3 did this, please let this not spread to other games! It's a shame because they work well, and there are situations where you are blinded by lights that these could really help shape (even if they are cinematic flares, they don't try to replicate what happens with eyes), but they are always turned all the way up all the time and after a bit you'll want to rip your eyes out. It's a form of torture and a huge artistic sin.

2) Everything has specular. In your face! (a.k.a. Rise and Shine)
Specular reflections seem to be turned always (well, very often) to 11. Now, while there are some situations where the intensity of it probably wouldn't be far off (i.e. really wet environments, pouring rain), we can't do perfect reflections yet.
The good: DICE guys being smart as they are do a number of interesting things, there are cubemap reflections but I think these are augmented with reflected "cards" or simple proxy geometry, I guess the latter only for planar reflections (rendered in a prepass, mirrored) but there's more to it, I think I've seen cards "fade" in and out and sometimes I think I've seen faint artifacts from a screenspace reflection method... Not sure, warrants more investigation
The bad: Specular aliasing everywhere, all forms of it (geometry, normalmaps, planar reflections), and I played on PC at very high-res, MSAA and post-AA filters.
From what I can see, analytic lights suffer mostly because textures even when looked up close have many discontinuities with the specular, I know that certain blending tricks help giving you detail, but seems overdone. Quite surprisingly as well, as we know by now many ways to circumvent texture/shader aliasing.

For planar reflections where aliasing is most offensive honestly it almost seems like if they did blur a bit the "cards" buffer (maybe I'm wrong and they don't have one...) it would solve a lot of issues. Still the effect should be applied sparingly, really in CG if you can't do it well, don't do it, sweep it under the rug. Planar reflections are a hack, they work only on some surfaces and this alone is an issue. Plus we can't really occlude too well sharp specular reflections, and occlusion is the key to believable lighting. In some levels, I just wish I had a multiplier I could tune down globally...
Lastly, specular seems always monochromatic, maybe I'm wrong, in real life it's often so, but I remember thinking for some materials to be wrong, could have been art or maybe to save on deferred GBuffer space...

3) Faces
This is the last thing I'll really bitch about. Characters aren't bad, animations are good too, but the shading is off, and again this is quite a surprise. Sometimes faces remind me of L.A.Noire weird low-frequency normalmaps. I wonder if that is indeed because of similar compression of acquired data, DICE has the tech and they used it in previous games... Anyhow, you can still blend that with detail maps driven by skin stretching or so, it's quite "common" tech nowadays. Also, specular. No, this time, the lack of it, which further causes the detail to be quite lacking, if only they had that they would be I think much better, as in general the SSS-ish effects are not bad and tastefully kept "in check" not going into "wax" looks. Looking at the ear edges, it seems a screenspace filter of some sort for SSS, but honestly it could be as well pre-integrated SSS. I don't love the over-bleeding in certain facial expression (normalmap wrinkles), eyes and lips are all "wrong" too. Now, mind you, especially in a deferred renderer doing skin, which is a fairly special material, is hard, but the lack of specular and detail is a mystery.

Texture detail
Now on some of the truly great stuff. On PC, details are amazing, especially textures and particles. Aliasing aside, materials are impressive, even more than Crysis 3 where everything had detail but mostly due to tiled detail textures used everywhere, especially I think to modify specular and give materials an unique microdetail. Here, I couldn't really see tiling, which means either they use very big textures or they do tiled details with some sort of distortion/blending tricks to hide it, or I'm not good at this :) Also material variation on the surfaces is great, you can't really see decals or layers, if they are doing them (which I'm sure they are) everything blends very, very well.

Geometric detail
Geometric detail is mostly due to having a lot of objects :) They don't seem to be doing tessellation, at least for displacement mapping, at all (which is not a bad choice), and I'm not sure if some surfaces do POM or not, honestly I'm not good at spotting that (especially certain techniques that don't simulate reliefs very well can be subtle).
Debris is everywhere, both authored in the level and due to destruction and particles. It's really great, things fly around all the time and it doesn't look unnatural. Also, no shimmer, no aliasing, small particles seem to be pre-blurred when depth of field is on (I think). It's actually easier (even if might not matter in a deferred, non baked renderer) to light correctly small instanced objects that large ones.
I couldn't see any particular shading trick applied to the vegetation (but I didn't look very hard, the levels I've played weren't very lush) but one thing it does great is that grass always bends out of the way and it's really hard to "clip" into it.

Destruction is everywhere and it seems mostly precomputed. At least in the campaign, some objects always shatter in the same way, while others shatter progressively, and other events seem scripted, like some cars always explode with a granade and some other never. All in all, it works great. Also the fact that there is always something that moves, cloth, paper, dust, foliage and so on really helps to sell the world as “living”, it’s really a perfect“touch”.
Lastly, I couldn't really see LODs crossfading or dissolving, small objects stay around long enough you won't notice they were gone, but that's also expected on PC on Ultra, I should try consoles...

Lighting
Pure deferred has its pros and cons, of course it's hard to bake much when things are always shattering and changing. Overall business as usual, does a good job with many lights on screen, and the analytic BRDF used seems quite "physically based".
They seem to use sparingly SSAO (Nvidia's HBAO I guess at ultra), really just a touch and with quite a huge radius, so you won't see "cartoon shading" silhouettes. It seems almost not randomized at all so you get sometimes the "stadium lights" effect (which I prefer to low-freq noise of some randomized AOs), if you look closely though sometimes there seems to be a 2x2 pattern that survives blurring. Blurring is detectable by the halos sometimes you get. There is a certain trade-off between large radius of occlusion and artifacts around characters, legs and so on, but most of the times it's not detectable so, good work there.
Honestly is great that we don't see SSAO-horrors like on Far Cry 3 or worse Deus Ex human revolution, but I wish sometimes it was used more, for "arealight" contact shadow kind of effects (bias it towards the sky! don't do radial SSAOs) and to shadows lights that are not dynamically shadowed, I wonder if they encode directional occlusion at all.

As far as scene lighting goes, I couldn't really see any dynamic GI going on (e.g. in the prison scene where there are large floodlights rotating around) and sometimes, especially in interior scenes it kind-of suffers from "deferred flatness", which is also a product I think of not having enough specular occlusion (i.e. on cubemap specular). If you can I'd say, always bake a good occlusion term, possibly directional, offline, or really invest in great directional SSAO or other methods, occlusion is fundamental.
Sometimes, rarely I have to say, things fail more spectacularly than others and you can see a lot of environment/ambient lighting going wrong. This of course is not aided by the fact that often scenes are so shiny...

There appear to be linear (tube) lights, and they seem to have no specular (but might be that it was just an artistic choice), other than that it seems we still have point, spots and directional sun, which is a shame. I think any deferred renderer nowadays has to invest in more "exotic" lights, lights always come with some sort of "shaping" device and in real world you won't easily see a perfect "spot" with a perfect falloff, things are weird, broken, spill, focus and so on. Also, it's really hard to fake ambient lighting with points.
Sometimes there seems to be "scattering", but I think it's mostly due to either placed flares or tuning up the bloom to a very large radius (I might be totally wrong). Both methods work well, but it's not the lovely scatter The Order 1886 is showing us, especially the idea of using bloom means also that sometimes the light is very softly spilled indoors, but overall again, well enough. God rays from the sun are also well done. Sometimes it's possible to go through a door and see the fog on the other side disappear, probably it's due to these settings having "volumes" of tuning, hard to say and to spot. Underwater adds DOF and grain.

Non occluded lights
This I want to remark. If you don't have a source of occlusion for a given light or BRDF piece, prefer not have that part at all (or be subtle). It is amazing how much difference it makes, I already wrote it, I'll do it again, occlusion is fundamental. Specular occlusion is fundamental. At least around silhouette edges, just "cast a ray".

Other stuff
I think it might have "thin wire" AA of sorts on rods and small branches and so on. Not sure if it's there or I just want it to be there because I really think is a good idea. Seems though strange that a lot of rods don't shimmer much and often become exactly pixel sized. I don't know, I disabled AA, changed resolutions, still not sure. If it's there, it doesn't fade-to-alpha, so what I would do is to increase the diameter or wires to keep them pixel-sized until they're far enough they can quicky fade into not-existing.
Sky sometimes seems to be "tacked on" and too low-res. In most games sky seems fake. I'm not yet entirely sure why.
Smoke. Sometimes it seems almost to be accumulated/blurred in a separate buffer and then composited on top, I didn't spot any particularly fancy volumetric lighting either. It warrants more investigation. On ultra, I couldn't detect any artifact from subsampling particles, I guess that's not done or if it is, it's done very well (which is hard).

Water. On average great, worse if higher waves/interaction with objects. Sometimes just fucking AMAZING.

DOF blur is smart, I almost never see it "before the focal plane", which is ok, that is harder to do, and as I wrote, better to hide an effect than show artifacts. On ultra it's "sprite DOF" so I guess it uses compute and append buffers to create lists of particles. Which makes it surprising that the artists chose a "catadioptric lens" kind-of bokeh shape, which would be nice in "sampling" kind of DOFs (as you sample around a circle, not inside a disc) but seems unnecessary here. I guess it's there to make a "statement", kind of like the lens flares... We'll grow past these effects and start using them with taste as now we see done with SSAO (more often). On lower settings it goes towards a simple "blur based" DOF which unfortunately bleeds quite a bit :/ Motion blur, pretty standard stuff, doesn't bleed out of silhouettes it seems so nothing particularly fancy.

Final score: great!
Sometimes really unbelievably good. I wish on PC it had a supersampling AA mode, as with proper supersampling some scenes are really amazing. It does: resolution scale > 100%

## Friday, October 18, 2013

### Controlling light

Qui habet aures audiendi, audiat

 Gregory Crewdson - behind the scenes

## Thursday, October 10, 2013

### Mathematica Manipulate[] example

Addendum to the Mathematica 101 post. I was working today and noticed that this little device is fun to use, and thus wanted to post it. Variable names have been changed to protect the innocent. I might even add more to this post in the future...

This is what I do often with Mathematica, I have some data computed/acquired somehow and I want to look at it from a few angles and try to find an analytic expression, without knowing all the underlying math, because either it's too hard to find a closed solution or I'm just not good enough.
Anyhow finding approximations even on paper would require assumptions that you have to check anyhow, and a good way to check them is to compare with the computed/acquired data. Other times you know a perfectly find analytic expression but want to fit a second one that's cheaper to compute.

With Manipulate is easy to explore a parametric function, given one. But most often I'm not entirely sure of the parametric form to use to begin with! Fear not, as in Mathematica everything is an expression, of course you can Manipulate expressions as well...

The code and graphs are captures in the two screenshots below, click on them to see the original size.

## Sunday, October 6, 2013

### Wolfram's Mathematica 101

After a lengthy preamble, I'll try to explain the language in the http://learnxinyminutes.com/ style, so you might prefer to skip down to the last section.

This will appear in a shorter form also on AltDevBlogADay

- Introduction

I've been using Wolfram's Mathematica since my days in university. I wasn't immediately sold as initially I saw it as a computer algebra system and preferred Maple's more math-friendly syntax for that, but with time it became a great tool in my arsenal of languages.
The way I see Mathematica fit in today's rendering engineer (or game developer in general) work is that of a data analysis tool, mostly. We increasingly have to deal with data, either acquired (e.g. measured BRDFs) or simulated (e.g. integrals of the rendering equation), get "a sense" of it, compare it with our realtime rendering models, and try to derive the right approximations for the sea of things we still can't directly solve.

What makes Mathematica good for this job, a better tool than say C++, are a few key features: it's an interactive, exploratory environment, it has strong visualization and manipulation abilities, it has a rich library providing almost everything you could think of, it's a concise language, and it has a great community (see http://mathematica.stackexchange.com/ and http://www.wolfram.com/broadcast/video.php?channel=311) and great documentation.

Two notes, before looking at the language. First, you might notice that on the technical level there are alternatives that can compete. We want a prototyping language, with lots of libraries, an interactive shell, solid visualization abilities… Python fits the bill as well, most probably Matlab and a number of its clones (Scilab, Octave), Maple and a number of others.
So why should you be interested in even learning Mathematica, if you can do most of the same things in Python, which is free? In my view, the money you pay for Wolfram's system is well spent because of the packaging. Many of the functions might be exactly the same you get in other systems (e.g. Lapack for linear algebra), but Mathematica packages them in a consistent syntax, with astonishingly good documentation, great support, testing and so on.

The second remark is, as might have noticed, that didn't mention the CAS aspects. Perhaps surprisingly, computer algebra is not the most important part for my job, as more often than not you're dealing with integrals that can't be analytically solved, or with directly with raw data. Nonetheless, Mathematica being a CAS is a great perk, as being able to easily manipulate your expressions makes also the numerical experiments more flexible, and Wolfram's is undoubtedly the best CAS out there (Sage, Maxima and so on can help, but aren't close).
Also, don't think that CAS can magically solve maths if you don't know it. It's true that it gan greatly help, as you might have forgotten all the myriads of formulas used to solve limits, derivatives, integrals or to transform trigonometric expressions and so on. But you still have to know what you're doing, sometimes even "better" than doing it yourself in a way that often we solve equations under some mental assumptions that don't hold true in general (i.e. range of the variables, domains, periodicity), and if you don't realize that, and tell the system, Mathematica won't be able to solve sometimes even "obvious" equations.

I've always encouraged my companies to get a few distributed seats of Mathematica, but remember, if you just need the occasional solution of an analytic expression, Sage, Maxima (both can be tried online) or even Wolfram Alpha can work wel. On iOS I use MathStudio but PocketCAS and iCAS (based on Reduce) look promising as well.

- Mathematica's language

It stands to reason that a CAS is built on top of a symbolic language that supports programmatic manipulation of its own programs (code as data, a.k.a. homoiconicity), and indeed this is the case here. The most famous homoiconic language is Lisp, and indeed you're familiar with the Lisp family of languages, Mathematica won't be too far off, but there are a few notable differences.
While in Lisp everything is a list, in Mathematica, everything is an expression tree. Also, expressions in mathematica can have different forms, that is, input (or display) versions of the same internal expression node. This allows you for example to have equations entered in the standard mathematical notation (TraditionalForm) via equation editors or in a textual form that can be typed without auxiliary graphical symbols (InputForm) and so on. Mathematica's environment, the notebook, is not a purely textual one, but supports graphics, so even images and graphs can be displayed as output or input, inside equations, while still maintaining the same internal representation.

Mathematica is an interactive environment, but it's not a standard REPL (read-eval-print loop), instead it relies on the concept of "notebooks" which are a collection of "cells". Each cell can be evaluated (shift-enter) and it will yield an output cell underneath them, thus allowing for changes and re-evaluation of cells in any order. Cells can also be marked as not containing Mathematica code but just text, thus the notebook is a mix of code and documentation which enables a sort of "literary programming" style.
For completeness it's worth noticing that Mathematica also has a traditional text-only interface that can be invoked by running the Kernel outside the notebook environment, which has only textual input and output and has only the standard REPL you would expect, but there's little reason to use it. There is also a more "programming" oriented environment called the Workbench, an optional product that can make your life easier if you write lots of Mathematica code and need to profile, debug and so on.

- By example crash course. In a notebook, put each group in a separate cell and evaluate.

Note: Mathics
is an OpenSource implementation based on SciPy and Sage. It also has an online interface so you can try I expect most of the code below!

(* This is a comment, if you're entering this in a notebook remember that to evaluate the content of a cell you need to use shift-enter or the numeric pad enter *)

(* Basic math is as expected, but it's kept at arbitrary precision unless you use machine numbers *)
(1+2)*3/4
(1.+2.)*3./4.
(* % refers to the last computed value *)
%+2
(* Functions are invoked passing parameters in square braces, all built-in functions start with capitals*)
Sin[Pi/3]
(* N[] forces evaluation to machine numbers, using machine numbers makes evaluation faster, but will defeat many CAS functions *)
N[Sin[Pi/3]]
(* Infix and postfix operators all have a functional form, use FullForm to show *)
FullForm[Hold[(1+2)*3/4]]
(* Each expression in a cell will yield an output in a separate output cell. Expressions can be terminated with ; if we don't want them to emit output, which is useful when doing intermediate assignments that would yield large outputs otherwise *)
1+2;

(* Assigning a symbol to an expression *)
x = 10
(* If a symbol is not yet defined, it will be kept in its symbolic version as the evaluation can't proceed further *)
y = x*w
(* This will recursively expand z until it reaches expansion limit and errors out *)
z = z+1
(* Clears the previous assignments. It's not wise to assign as globals such common symbols, we use these here for brevity and will clear as needed *)
Clear[x,y,z]

(* Evaluation is controlled by symbols attributes *)
x = 10
(* y will be equal to "x*2", not 20 as := is the infix version of the function SetDelayed, which doesn't evaluate the right hand...*)
y := x*2
(* …that's because SetDelayed has attribute HoldAll, which tells the evaluator to not evaluate any of its arguments. HoldAll and HoldFirst attributes are one of the "tricky" parts, and a big difference from Lisp where you should explicitly quote to stop evaluation *)
Attributes[SetDelayed]
(* As many functions in Mathematica are supposed to deal with symbolic expressions and not their evaluated version, you'll find that many of them have HoldAll or HoldFirst, for example Plot has HoldFirst to not evaluate its first argument, that is the expression that we want to graph *)
Plot[Sin[x], {x, 0, 6*Pi}]
(* The Hold function can be used to stop evaluation, and the Evaluate function can be used to counter-act HoldFirst or HoldAll *)
Hold[x*2]
y:=Evaluate[x*2]
y

(* A neat usage of SetDelayed is for memoization of computations, the following pi2, the first time it will be evaluated, will set itself to the numerical value of Pi*Pi to 50 decimal points *)
pi2:=pi2=N[Pi*Pi,50]
pi2

(* Defining functions can be done with the Function function, which has attributes HoldAll *)
fn=Function[{x,y}, x*y];
fn[10,20]
(* As many Mathematica built-ins, Function has multiple input forms, the following is a shorthand with unnamed parameters #1 and #2, ended with the & postfix *)
fn2=#1*#2&
fn2[10,20]
(* Third version, infix notation. Note that \[Function] is a textual representation of a graphical symbol that can be more easily entered in Mathematica with the key presses: esc f n esc, many symbols can be similarly entered, try for example esc theta esc *)
fn3={x,y}\[Function]x*y
fn3[10,20]

(* A second, very common way of defining functions is to use pattern matching and delayed evaluation, the following defines the fn4 symbol to evaluate the expression x*y when it's encountered with two arguments that will matched to the symbols x and y *)
fn4[x_,y_]:=x*y
fn4[10,20]
(* _ or Blank[] can match any Mathematica expression, _h matches only expressions with the Head[] h *)
fn5[x_Integer,y_Integer]:=x+y
fn5[10,20]
fn5[10,20.]
(* A symbol can have multiple matching rules *)
fn6[0] = 1;
fn6[x_Integer] := x*fn6[x - 1]

fn6[3]

(* In general pattern matching is more powerful than Function as it's really an evaluation rule, but it's slower to evaluate, thus not the best if a function has to be applied over large datasets *)
(* Note that pattern matching can be used also with =, not only :=, but beware that = evaluates RHS, in the following fnWrong will multiply y by 3, not by the value matching test at "call" site, as test*y gets fully evaluated and test doesn't "stay" a symbol, it evaluates to its global value *)
test = 3;

fnWrong[test_, y_] = test*y

(* Lists are defined with {} *)
a={1,2,3,{4,5},{aa,bb}}
(* Elements are accessed with [[index]], indices are one-based, negative wrap-around *)
a[[1]]
a[[-1]]
(* Ranges are expressed with ;; or Span *)
a[[2;;4]]
(* From the beginning to the second last *)
a[[;;-2]]
(* Vectors and matrices are just appropriately sized lists and lists of lists *)
b={1,2,3}
m={{1,0,0},{0,1,0},{0,0,1}}
(* . is the product for vector, matrices, and tensors *)
m.b

(* Expression manipulation and CAS. ReplaceAll or /. applies rules to an expression *)
(x+y)/.{x->2,y->Sin[Pi]}
(* Rules can contain patterns, the following will match only the x symbols that appear to a power, match the expression of the power and replace it *)
Clear[x];
1+x+x^2 +x^(t+n)/.{x^p_->f[p]}
(* In a way, replacing a symbol with a value in an expression is similar to defining functions using := or = and pattern-matching, but we have to manually replace the right symbol... *)
expr = x*10
expr/.x->5
(* Mathematica has lots of functions that deal with expressions, Integrate, Limit, D, Series, Minimize, Reduce, Refine, Factor, Expand and so on. We'll show only some basic examples. Solve finds solution to systems of equations or inequalities *)
Clear[a];
Solve[x^2+a*x+1==0, x]
(* It returns results as list of replacement rules that we can replace into the original equation *)
eq=x^2+a*x+1
sol=Solve[eq==0, x]
neweq=eq/.sol[[1]]
(* Simplifying neweq yields true as the equation is satisfied *)
Simplify[neweq]
(* Assumptions on the variables can be made *)
Simplify[Sqrt[x^2], Assumptions -> x < 0]
(* fn7 will compute the Integral and Derivative every time it's evaluated, as Function is HoldAll, fn8, using Evaluate, will force the definition to be equal to the simplified version which yields correctly back the original equation *)
fn7[x_]:=Function[x,D[Integrate[x^3,x],x]]
fn8[x_]:=Function[x,Evaluate[Simplify[D[Integrate[x^3,x],x]]]]

(* Many procedural programming primitives are supported *)
If[3>2,10,20]
For[i = 0,i < 4,i++,Print[i]]
n=1; While[n < 4,Print[n];n++]
Do[Print[n^2],{n,4}]
(* Boolean operators are C-like for the most, only Xor is not ^ which means Power instead *)
!((1>2)||(4>3))&&((1==1)&&(5<=6))
(* Equality tests can be chained *)
(5>4>3)&&(1!=2!=3)
(* == compares the result of the evaluation on both sides, === is true only if the expression are identical *)
v1=1;v2=1;
v1==v2
v1===v2
(* Boolean values are False and True. No output is Null *)

(* With, Block and Module can be used to set symbols to temporary values in an expression *)
With[{x = Sin[y]}, x*y]
Block[{x = Sin[y]}, x*y]

Module[{x = Sin[y]}, x*y]

(* The difference is subtle. With acts as a replacement rule. Block temporarily assigns the value to a symbol and the restores the previous definition. Module creates an unique, temporary symbol, which affects only the occurrences in the inner scope. *)
m=i^2
Block[{i = a}, i + m]
Module[{i = a}, i + m]
(* In general prefer Block or With, which are faster than Module. Module implements lexical scoping, Block does dynamic scoping *)
(* Block and Module don't require to specify values for the declared locals, With does. The following is fine with Block, not with With*)
Block[{i},i=10;i+m]

(* Data operations. Table generates data from expressions *)
Table[i^2,{i,1,10}]
(* Table can generate multi-dimensional arrays, i.e. matrices *)
Table[10*i+j,{i,1,4},{j,1,3}]
MatrixForm[%]
(* List elements can be manipulated using functional programming primitives, like Map which applies a function over a list *)
squareListElements[list_]:=Map[#^2&,list]
(* Short-hand, infix notation of Map[] is /@ *)
squareListElements2[list_]:=(#^2&)/@list
(* You can use MapIndexed to operate in parallel across two lists, it passes to the mapped function *)
(* A more complete version of the above that is defined only on lists and asserts if the two lists are not equal size. Note the usage of ; to compound two expressions and the need of parenthesis *)
On[Assert]
addListsAssert[list1_List,list2_List]:=(Assert[Length[list1]==Length[list2]]; MapIndexed[Function[{element,indexList},element + list2[[indexList[[1]]]] ], list1])
(* Or Thread can be used, which "zips" two or more lists together *)
(* There are many functional list manipulation primitives, in general, using these is faster than trying to use procedural style programming. Extract from a list of the first 100 integers, the ones divisible by five *)
Select[Range[100],Mod[#,5]==0&]
(* Group together all integers from 1...100 in the same equivalence class modulo 5 *)
Gather[Range[100],Mod[#1,5]==Mod[#2,5]&]
(* Fold repeatedly applies a function to each element of a list and the result of the previous fold *)
myTotal[list_]:=Fold[#1+#2&,0,list]
(* Another way of redefining Total is to use Apply, which calls a function with as arguments, the elements of a list. The infix shorthand of Apply is @@ *)
myTotal2[list_]:=Apply[Plus,list]

(* Mathematica's CAS abilities also help with numerical algorithms, as Mathematica is able to infer some information from the equations passed in order to select or optimize the numerical methods *)
(* NMinimize does constrained and unconstrained minimization, linear and nonlinear, selecting among different algorithms as needed *)
Clear[x,y]
NMinimize[{x^2-(y-1)^2, x^2+y^2<=4}, {x,y}]
(* NIntegrate does numerical definite integrals. Uses Monte Carlo methods for many-dimensional integrands *)
NIntegrate[Sin[Sin[x]], {x,0,2}]
(* NSum approximates discrete summations, even to infinites *)
NSum[(-5)^i/i!,{i,0,Infinity}]
(* Many other analytic operators have numerical counterparts, like NLimit, ND and so on... *)
NLimit[Sin[x]/x,x->0]
ND[Exp[x],x,1]

(* Mathematica's plots produce Graphics and Graphics3D outputs, which the notebook shows in a graphical interface *)
Plot[Sin[x],{x,0,2*Pi}]
(* Graphics are objects that can be further manipulated, Show combines different graphics together into a single one *)
g1=Plot[Sin[x],{x,0,2*Pi}];
g2=Plot[Cos[x],{x,0,2*Pi}];
Show[g1,g2]
(* GraphicsGrid on the other hand takes a 2d matrix of Graphics objects and displays them on a grid *)
GraphicsGrid[{{g1,g2}}]
(* Graphics and Graphics3D can also be used directly to create primitives *)
Graphics[{Thick,Green,Rectangle[{0,-1},{2,1}],Red,Disk[],Blue,Circle[{2,0}]}]
(* Most Mathematica functions accept a list of options as the last argument. For Plots an useful one is to override the automatic range. Show by default uses the range of the first Graphics so it will cut the second plot here: *)
Show[Plot[x^2,{x,0,1}],Plot[x^3,{x,1,2}]]
(* Forcing to show all the plotted data *)
Show[Plot[x^2,{x,0,1}],Plot[x^3,{x,1,2}], PlotRange->All]

(* Very handy for explorations is the ability of having parametric graphs that can manipulated. Manipulate allows for a range of widgets to be displayed next to the output of an expression *)
Manipulate[Plot[x^p,{x,0,1}],{{p,1},1,10}]
Manipulate[Plot3D[x^p[[1]]+y^p[[2]],{x,0,1},{y,0,1}],{{p,{1,1}},{1,1},{5,5}}]
(* Manipulate output is a Dynamic cell, which is special as it get automatically re-evaluated if any of the symbols it capture changes. That's why you can see Manipulate output behaving "weirdly" if you change symbols that are used to compute its output. This allows for all kind of "spreadsheet-like" computations and interactive applications. *)

(* Debugging functional programs can be daunting. Mathematica offers a number of primitives that to a degree help. Monitor generates a temporary output that shows the computation in progress. Here the temporary output is a ProgressIndicator graphical object. Evaluations can be aborted with Alt+. *)
Monitor[Table[FactorInteger[2^(2*n)+1],{n,1,100}], ProgressIndicator[n, {1,100}]]
(* Another example, we assign the value of the function to be minimized to a local symbol, so we can display how it changes as the algorithm progresses *)
complexFn=Function[{x,y},(Mod[Mod[x,1],Mod[y,1]+0.1])*Abs[x+y]]
Plot3D[complexFn[x,y],{x,-2,2},{y,-2,2}]
Block[{temp},Monitor[NMinimize[{temp=complexFn[x,y],x+y==1},{x,y}],N[temp]]]
(* Print forces an output from intermediate computations *)
Do[Print[Prime[n]],{n,5}]
(* Mathematica also supports reflection, via Names, Definition, Information and more *)

(* Performance tuning. A first common step is to reduce the number of results Mathematica will keep around for % *)
\$HistoryLength=2
(* Evaluate current memory usage *)
MemoryInUse[]
(* Share[] can sometimes shrink the memory usage by making Mathematica realize that certain subexpressions can be shared, it prints the amount of bytes saved *)
Share[]
(* Reflection can be used to know which symbols are taking the most memory *)
Reverse@Sort[{ByteCount[Symbol[#]],#}&/@Names["`*"]]
(* Timing operations is simple with AbsoluteTiming *)
AbsoluteTiming[Pause[3]]
(* Mathematica's symbolic evaluation is relatively slow. Machine numbers operations are faster, but slow compared to other languages. In general Mathematica is not made for high-performance, and if that's needed it's best to directly go to one of the ways it supports external compilation: LibraryLink, CudaLink, and OpenCLLink *)
(* On the upside, many list-based operations are trivially parallelizable via Parallelize *)
Parallelize[Table[Length[FactorInteger[10^50+n]],{n,20}]]
(* The downside is that only a few functions seems to be natively parallelized, mostly image-related, and many others require manual parallelization via domain-splitting. E.G. integrals *)
sixDimensionalFunction=Function[{a,b,c,d,e,f},Re[(a*b+c)^d/e+f]];
Total[ParallelTable[NIntegrate[sixDimensionalFunction[a,b,c,d,e,f],{a,-1,1},{b,-1,1},{c,-1,1},{d,-1,1},{e,-1,1},{f,-1+i/4,-1+(i+1)/4}],{i,0,7}]]
(* Even plotting ca be parallelized, see http://mathematica.stackexchange.com/questions/30391/parallelize-plotting. Intra-thread communication is expensive, beware of the amount of data you move! *)
(* There is a Compile functionality that can translate -some- Mathematica expressions into bytecode or C code, even parallelizing, but it's quite erratic and requires planning from the get-go of your code. See http://mathematica.stackexchange.com/questions/1803/how-to-compile-effectively/ http://mathematica.stackexchange.com/questions/1096/list-of-compilable-functions*)

- Parting thoughts
Clearly, it's impossible to cover all the library functionality that Mathematica offers. But for that the documentation is great, and usually a bit of search there and if it fails, on the stackexchange forums, will yield a very elegant solution for most issues.
Performance can be tricky, and can require more effort than using directly native CPU and GPU languages, on the other hand, support for external CPU and GPU functions is great and Mathematica is capable of invoking external compilers from strings of sourcecode, and you can use Mathematica as a template metaprogramming language, even with a bit of effort converting its expressions into other language equivalents (a good starting point is CForm[]). Being a very strong pattern-matching engine, quite some magic is possible.

Next time I might write something that shows in practice how Mathematica, via it's numerical and visualization abilities enables exploration of possible approximations of expensive rendering formulas... Stay tuned.