Search this blog

03 November, 2012

Addendum to Mathematica and Skin Rendering

Update: there was a typo in the shader code, I didn't update the screenshot...

A shader code snippet following my work on Penner's scattering approximation. I'm actually rather sure it can be done better and for cheaper, especially if you "clamp" the radius range to a narrower window, currently it goes too broad on one side while trying to go back to a standard, not wrapped N dot L for large radii, it's not really useful. But, I've already given the Mathematica code so you can do better...

float3 PSSFitFunction(float NdL, float r)
{
   float3 a0 = {0.0605, 0.2076, 0.2243};
   float3 a1 = {0.0903, 0.1687, 0.2436};
   float3 a2 = {-0.0210, -0.0942, -0.1116};
   float3 a3 = {0.6896, 0.6762, 0.6480};
   float3 a4 = {-0.1110, -0.5023, -0.6703};
   float3 a5 = {0.8177, 0.9119, 0.9209};

   float3 t = NdL.xxx * (a0*r+a1) + (a2*r+a3);
   float3 fade = saturate(a4*r+a5);
  
   return t*t*t * fade + saturate(NdL) * (1-fade);
}

02 November, 2012

How does GPU Compute work?

A presentation I made over the last month, an introduction to GPUs and GPU compute for the "non GPU" programmer. A couple of slides target the videogame industry but otherwise it's pretty general. If you want a good testbed to start playing, this previous post might help.

http://www.scribd.com/doc/111876741/GPU-Compute

Preparing for live presentation
Notes and ideas for the presentation...

08 October, 2012

Notes on optimizing a deferred renderer

Oh my, I forget to post things... Space Marine, a game that I'm very fond of having been part of. The second third person action done by Relic, and the first multi-platform console game of a studio well known for incredible PC RTS titles. It came out maybe a bit short on content (cuts, time...) but it's a technically excellent game and it's plenty of fun too (it's one of the few games I had fun playing multiplayer on the 360).

Its rendering does most of the things a modern deferred should do, quite a few things that only an handful of other titles manage to pull off (i.e. almost zero latency) and a couple of novel things as well (the way it does Oren-Nayar, its "world occlusion", the DOF/MB filter, the hair lighting trickery and some other details).


The people working on it were a-m-a-z-i-n-g, I was "overseeing" the rendering performance across the platforms and I was surprised to see that we managed to more than double rendering performance in the six months before shipping, to a solid thirty (I would have bet it was not possible, when I joined. They proved me wrong).
Most of the work described in the notes was done near the end of the product (i.e. shadows, post effects, ssao were rewritten from scratch, software occlusion added, SIMD and threading everywhere, I had a list of more than twenty tasks per each platform and I'd say more than 80% of them were done by the end).

This presentation was done a while ago now, it started as something I wrote internally as a post-mortem for other studios to see, then I removed some implementation details and presented it (thanks to Relic's openness when it comes to sharing knowledge) at a very informal meeting of rendering professionals I organize sporadically here in Vancouver. The version I'm uploading was cleaned up even more (well, censored... mostly replaced images with public screenshots of the game) to be able to publish it online... but then forgot, until today, when I got someone asking me for this material again.

It's not much of a "presentation", it's more notes written in powerpoint, as it was originally meant not to be presented live but to just be read by people.

07 October, 2012

Supersampling and antialiasing distance fields

Just found this note cleaning up my stuff, thought I might as well post it...

We had some issues with using signed distance fields for font rendering and antialiasing. The idea is to conceptually similar to doing a two dimentional marching squares and then computing the area of the resulting convex polygon.

If you can't (or don't want to read) my horrible note, the "algorithm" samples four taps of the distance field (use ddx/ddy UV for the width) on a (unit) square and then walks the vertices and edges of the square counterclockwise (first a vertex, then an edge, then the next vertex and so on).

The polygon is constructed by taking the coordinates of all the vertices that are inside the distance field and computing an intersection point for all the edges that are between two in-out vertices. The polygon area (which equals the coverage) is computed incrementally using the determinant method. All unrolled in a shader.

Jason Peng, an incredibly talented UBC student implemented this at Capcom Vancouver. He tells me it worked :)


P.S. You'll notice that I write counterclockwise and then draw all the arrows clockwise... :) Stupid me.

11 September, 2012

A hunch

Have you noticed how nice realtime raytracing looks? I was just watching this recent video by Sam Lapere done with Jakko Bikker's famous Brigade renderer. Yes it's noisy, and the lighting is simple, and the models are not complex. But it has a given quality to it, for sure, it feels natural and well lit.

I have a hunch.

It's not (mostly) because of the accuracy in the visibility solution. Nor it is because of the accuracy (which, at least in that scene, does not even seems to be a factor) of the BRDF and material representation. I think that with our skimpy realtime GPU rasterization hacks we are technically capable of producing materials and occlusions of a good enough quality.

I suspect that where games often fall is on finding the right balance. Raytracing does not need this balancing at all, diffuse, ambient specular, they all bounce around as a single entity, and light simply is. In the realtime rasterization world, this unity does not exist, we have components and we tune them and shape them. We start with a bit of diffuse and subtract shadows and add ambient and subtract its occlusion and sprinkle specular on top. Somehow... And sometimes this complex mix is just right, most often, plain wrong.

It's artist's fault? Is it too complex to get right? I think, not, it should not be. In many cases, it's not hard to take references for example, and meaningful ones, measures and measures that split a real world scene into components, devise experiments and validate our effects. Know what we are doing...

It's that often us, rendering engineers, work on technical features and not their quality. We do "SSAO" and add some parameters and if the artists say they're happy we move on, this is our relationship with the image, it's a producer-consumer one.

I think this is irresponsible, and we should be a little more responsible than that, work a bit more closely together. Observe, help, understand, light is a technical and artistic matter, and often we underestimate how much complexity and technicality there is into things that are not strictly complex routines in code. If you think about it, until a couple of years ago, we were still doing all wrong math on colors, and the solution is a simple pow(col,2.2) in code, but still, we did it spectacularly wrong, and called ourselves engineers. We should really understand way better what we do, both its physics and the perception of the physics.