Surface Shaders, one year later

Over a year ago I had a thought that “Shaders must die” (part 1, part 2, part 3).

And what do you know – turns out we’re trying to pull this off in upcoming Unity 3. We call this Surface Shaders cause I’ve a suspicion “shaders must die” as a feature name wouldn’t have flied very far.

Read the rest of this entry »

Compiling HLSL into GLSL in 2010

Realtime shader languages these days have settled down into two camps: HLSL (or Cg, which for all practical reasons is the same) and GLSL (or GLSL ES, which is sufficiently similar). HLSL/Cg is used by Direct3D and the big consoles (Xbox 360, PS3). GLSL/ES is used by OpenGL and pretty much all modern mobile platforms (iPhone, Android, …).

Since shaders are more or less “assets”, having two different languages to deal with is not very nice. What, I’m supposed to write my shader twice just to support both (for example) D3D and iPad? You would think in 2010, almost a decade since high level realtime shader languages have appeared, this problem would be solved… but it isn’t!

Read the rest of this entry »

GDC 2010 report

Just returned from exciting (and exhausting) trip to Game Developers Conference 2010. Random notes:

Unity

It seems that everyone is talking about Unity this year. At GDC 2009 some people have heard about us, some others were “where the f*** this came from?!”, and some had no idea what Unity is. This year it’s hard to find anyone who hasn’t heard about Unity. I was surprised by number of AAA developers who are playing around with Unity internally (for prototyping, mobile & whatnot) and/or are big fans of Unity. I like!

We had a cool booth that was very busy at all times. As a bonus, the Unity chairs could be used as weapons!

Awesome quote: CEO of censored (competing middleware company) said: “yeah, Unity is going up, we are going down”. This is taken completely out of context of course.

We were busy demoing upcoming Unity 3 which I think will be quite awesome. Three days before the conference were spent crunching on the demos for GDC :)

Cool Stuff

Only managed to go to two sessions :(

Stephen Hill‘s “Rendering Tools and Techniques of Splinter Cell: Conviction” had interesting bits & pieces of stuff. Nice work on hierarchical Z occlusion and ambient occlusion fields! (probably first time I see AO fields used in actual game production)

Mike Acton‘s “Three Big Lies: Typical Design Failures in Game Programming” was entertaining. Content wise I pretty much knew what to expect. If you aren’t following Mike – do it now! Talk slides are at Insomniac’s site.

RAD‘s Telemetry profiler looks totally sweet. I think they acquired this one and improved it. Some very good UI ideas in there. On a related note, Scaleform’s new profiler looks… kinda inspired by Unity’s (comparison: Scaleform on the left, Unity on the right).

Fun Stuff

Managed to sneak in some fun (dare I say “social”?) stuff.

Rendering folks dinner (thanks Johan!) was awesome, even if it made me feel kinda small & stupid among those super smart guys & gals. Shadow algorithms on receipts FTW! Middleware Meetup (thanks Dan!) was full of friendly competitors :) #gdcdrink tweetup (thanks Mike!) had lots of war stories, PS3 talk and how to do fluid simulation on 360′s pixel shaders.

Screenspace vs. mip-mapping

Just spent half a day debugging this, so here it is for the future reference of the internets.

In a deferred rendering setup (see Game Angst for a good discussion of deferred shading & lighting), lights are applied using data from screen-space buffers. Position, normal and other things are reconstructed from buffers and lighting is computed “in screen space”.

Because each light is applied to a portion of the screen, the pixels it computes can belong to different objects. If in any place of lighting computation you use textures with mipmaps, be careful. Most common use for mipmapped light textures is light “cookies” (aka Gobo).

Let’s say we have a very simple scene with a spot light: Read the rest of this entry »

Four years ago today…

…I took a plane to Copenhagen. Oh, this sounds familiar…

Well ok, it all started a bit before: Read the rest of this entry »

Direct3D GPU Hacks

I’m catching up on various GPU hacks that exist for Direct3D 9 (things like native shadow mapping, render to vertex buffer, etc.). Turns out there’s a lot of them, but all the information is scattered around the intertubes.

So here are the D3D9 hacks known to me in one place.

Let me know if I missed something or got something wrong. I also want to figure out if Intel GPUs/drivers implement any of them.

Improving C#/Mono for Games

A tweet by Michael Hutchinson on C#/Mono usage in games caused me to do a couple of short replies (one, two). But then I started thinking a bit more, and here’s a longer post on what is needed for C# (and more specifically Mono) to be used in games more.

In Unity we use Mono to do game code (well, Unity users are doing that, not us). Overall it’s great; it has tons of advantages, loads of awesome and a flying ninja here and there. But no technology is perfect, right?

Edit: Miguel rightly points out in the comments that Mono team is solving or has already solved some of these issues already. In some areas they are moving so fast that we at Unity can’t keep up!

Read the rest of this entry »

Deferred Cascaded Shadow Maps

Reading “Rendering Technology at Black Rock Studios” made me realize that cascaded shadow maps I did 2+ years ago in Unity 2.0 are probably called “deferred shadowing”. Since I never wrote how they are done… here:

The process is roughly this (all of this is DX9 level tech on PCs; later tech or consoles could and should use more optimizations):

  1. Render shadow map cascades. All of them packed into one shadow map via viewports.
  2. Collect shadows into screen sized render target. This is the shadow term.
  3. Blur the shadow term.
  4. In regular forward rendering, use shadow term in screen space.

More detail:

Render Shadow Cascades

Nothing fancy here. All cascades packed into a single shadow map. For example two 512×512 cascades would be packed into 1024×512 shadow map side by side.

Screen-space Shadow Term

Render all shadow receivers with a shader that “collects” shadow map term. In effect, shadows from all cascades are collected into a screen-sized texture. After this step, original cascaded shadowmaps are not needed anymore.

Unity supports up to 4 shadow map cascades, which neatly fit into a float4 register in the pixel shader. Correct cascade is sampled just once, without using static or dynamic branching. Pixel shader pseudocode:

float4 near = float4 (z >= _LightSplitsNear);
float4 far = float4 (z < _LightSplitsFar);
float4 weights = near * far;
float2 coord =
    i._ShadowCoord[0] * weights.x +
    i._ShadowCoord[1] * weights.y +
    i._ShadowCoord[2] * weights.z +
    i._ShadowCoord[3] * weights.w;
float sm = tex2D (_ShadowMapTexture, coord.xy).r;

Additionally, shadow fadeout is applied here (shadows in Unity can be cast up to specified distance from the camera, and they fade out when approaching that distance).

After this I end up having shadow term in screen space. Note that here I do not do any shadow map filtering; that is done in screen space later.

On PCs in DX9 there is (or there was?) no easy/sane way to read depth buffer in the pixel shader, so while collecting shadows the shader also outputs depth packed into two channels of the render target.

Screen-space Shadow Blur

Previous step results in screen space shadow term and depth. Shadow term is blurred into another render target, using a spatially varying Poisson disc-like filter.

Filter size depends on depth (shadow boundaries closer to the camera are blurred more). Filter also discards samples if difference in depth is larger than something, to avoid blurring over object boundaries. It's not totally robust, but seems to work quite well.

Using shadow term in forward rendering

In forward rendering, this blurred shadow term texture is used. Here shadow term already has filtering & fadeout applied, and the shaders do not need to know anything about shadow cascades. Just read pixel from the texture and use it in lighting computation. Done!

Fin

Back then I didn't know this would be called "deferred" (that would probably have scared me away!). I don't know if this approach is any good, but so far it works quite well for Unity needs. Also, reduces shader permutation count a lot, which I like.

Fixing bugs, in Tom Waits’ words

Mixing a sprint of bug fixing before the release and Tom Waits’ music results in interesting combination. For example, Crossroads describes bug fixing process perfectly:

And that’s where ol’ George found himself out there at the FogBugz
Fixin’ the devil’s bugs
Now, a man figures it’s his bugs and he’ll assign whom he wants
But it don’t always work out that way
You see, some bugs are special for a certain target
A certain platform, or a certain person
And no matter whom you’re assignin’, that’s where the bug ‘ll end up
And in the moment of assigning your mouse turns into a dowser’s wand
And clicks where the bug wants to go.

Uhm. Yeah.

Strided blur and other tips for SSAO

If you’re new to SSAO, here are good overview blog posts: meshula.net and levelofdetail. Some tips and an idea on strided blur below.

Read the rest of this entry »