I'm probably not doing this talk a lot of justice, since to be honest I had a bit of a hard time understanding the speakers and the slides whizzed by sometimes.  Naughty Dog folks clearly do some serious tech crunching though.  :)  Too bad they still think LISP is cool.... shudder...

 


 

 

The Technology of Uncharted: Drake’s Fortune

Christophe Balestra & Pal-Kristian Engstad

Naughty Dog

 

Codename “Big”.   3 yr project.  10 people on 12 month prepro.  70 people by the end, +5 contractors.  6 design, 18 programmers, approx 50 artists.

 

Started the project with zero lines of code.   Old internal programming language, transition to C++.  Work quickly on shaders with experience from PS2 tech.  Prototyped shaders on PC.  Animation was priority #1.   Also started tools over from scratch.  Over-designed first set of tools.  Extend what you have vs changing pipeline completely.   Tools not stable = not good, unhappy artists.

 

Tools:  Keep them simple!  People will actually use the tools this way.  Have a few tools rather than a centralized uber-tool.  Easier to expand one tool among several than a huge one.  Expanding your current set of tools.

 

Cygwin:  Like a linux shell.  Helps controlling people’s environment.  All tools must be run from cygwin. 

 

BAM: Asset manager.  Everything is always “live”, don’t want people isolated.  If there is a problem, just fix it.  Check-out, check-in, but no sync!  Every checkin is automatically propagated without any explicit step.  If something wrong happens, probably something wrong with the tool, so fix it immediately.  Linux server, using symlinks.   All data on the network.

 

BuildBig:  GUI tool to describe what actors and levels are made of.  Actor made of skeleton + animations.  Level = static geometry.  Everything stored in MySQL, ok at first but then changelists killed it – bad idea.  Switched to text files and Perforce. 

 

BA / BL – simple command line tools.  Build Actors / Build Levels.  Compression, format conversion for BA.  BL generates the lighting files and other processing.  Express stats on assets for artists.  Help artists determine efficiency of mesh / SPU conversion. 

 

Visibility:  During BL a PVS is pre-computed per level.  Render the level with OpenGL from sample points.  Tree, each cell contains sample points.  Computed once a day and re-used caches. 

 

Distributed Build:  Using ND internal distributed system.  Very simple, runs command line tools.  Output stored in MySQL.  So scripts call the executables to distribute to the work. 

 

Shaders:  Uber-shader file.  Use #define to build features.   Not great for dependencies, lots of shader recompilation.  Mitigated by distributed build system.  Shaders compiled during BA/BL process.  Each actor level contains its own shader code.

 

Material Editor:  GUI tool connected to Maya to create shaders.  Select .fx file, choose features.  Artists loved it but it was not very stable.  Next version will connect directly to the game. 

 

Charter:  Maya too slow, so created GUI tool to create game-play contents.  Regions, Nav-meshes, spawners, cover points.  Quick iteration time.  5 seconds between editor and game. 

 

Remember, building good GUIs is hard, you can’t just put your junior programmers on it.

 

DC: Data Compiler.  LISP based, used originally to define data structures.  Added scripting to it.  Render settings, AI, animation trees, region scripts.  Realtime linking for fast iteration. 

 

Static lighting: Global Illumination.  Direct color, indirect color, direction per vertex.  Blend realtime shadows with this static lighting.  Moving objects used light probes & SH.  Objects look around and pick the closest one.  Convert SH to cubemap (via SPU).  Not texture bound.  Biggest problem: Too slow, and couldn’t be distributed.

 

TAME: GUI tool for managing text localization.  Very important, very helpful!  Producers in Europe and Japan can manage everything independently.

 

Fileserver: We love Linux, Linux is fast.  Game connects to our own file system running under linux using the PS3 debug port.  80 MB / sec.  Cached files to devkit.

 

Programmer Pipeline:  Linux again.  1 Linux box for every 2 programmers.  Use putty to connect to it.  Fast, multithreaded build. SN Debugger.

 

Artist Pipeline:  Maya & ZBrush.  Material Editor, BuildBig, BA/BL.

 

Designers:  Charter, BuildBig, BA/BL, DC

 

86 MB level loading heap.  8 megs for mesh processing, stolen from movie memory.  2 MB water  memory.  5 MB of script memory, 4 MB for sound memory.

 

FIOS:  All IO done with FIOS.  Everything compressed with Edge.  Stream a lot and all the time: levels, actors, sounds, music, textures.  Never read data off directly, everything is precached via HD.  Want to maintain audio and overlap with gameplay. 

 

Loading Scheme:  Levels and actors are .pak files, made of 512k pages.  Heap of 172 pages.  No fragmentation.  Did suck to use a 512k page for a 100k asset.  So there was some page relocation at runtime. 

 

Texture Streaming:  HD on every PS3 is *huge*.  Very easy to do, 3 days of work.  Adds a lot to the quality of the game.  Everyone must stream textures!  Defragment memory every frame.  Move up to 16 MB per frame.  Simple collapsing mechanism, just move each block forward.  Maximize 120 MB texture usage.  Needed a 20 MB buffer to seed loading of next level. 

 

Collisions:  Sphere, convex polytope, capsule.  Wrote their own system.  Concave geometry, kd-tree Polygon soup.  SPU elf per shape.  32 objects per batch.  ~ 500 asynch ray casts every frame.

 

Physics:  Split world into “islands”.  One SPU job (solver) per island.  Successive Relaxation LCP solver.  General constraint system: rag-doll motion animation.  Anim generated in Maya then extract parameters for ragdoll.

 

SPUS:  lots of stuff.  Scene traversal, water, decompression, particles, etc.  Using only 30% of SPUs.

 

Animation:  Using SPUs to decompress and blend animation tree.  Blend tree with up to 25 animations, use DC to describe animation states.  Layered animation system (running + weighted shooting, etc.)

 

Scene Traversal:  Visible frustrum culling, PVS lookup, sorting, render setup, mesh processing setup.  Sorting and setup on the PPU, everything else on SPU.  Goal to get everything independently on the SPUs.

 

Mesh Processing:  SPUs to offload RSX.  Decompression, skinning, backface culling. Also collision with rendered geometry: decals, IK.  Get exact positions. 

 

Scene Rendering:  5 phases: Shadows, dynamic lighting, opaque geom, alpha blend geom, post processing effects.

 

Sunlight Shadow:  Tried many solutions, but all had problems.  Idea from Killzone:  Reduce flickering: fixed world space sample points.  Shimmering caused from slight differences in maps due to movement, so wanted to fix that.  So use stable grid, just scroll around on it.  SSM: orthographic shadow map.  How to determine resolution?  Cascaded shadow maps. 

 

Shadow blockers > shadow pass > depth buffer

Opaque geom. pass

 

Dynamic lighting:  Render opaque dyn lit geom..  Generate world normal and specular exponent in screen space.  Divide screen into a grid, and then figure out which lights interact those.  Render quads over those and accumulate light.  Do everything in screen space! 

 

Opaque rendering:  easy, shadows and lights already done.  Just have to do materials.  Output is HDR.

 

Alpha-blended geometry (water).  Uses color buffer, water mesh, shadow depth.  Reflection rendered in separate pass, used as texture.

 

Particles:  Sim and render setup done on SPUs.  Wrote specific shaders for each particle.  Switch to sample buffer if framerate spikes.

 

Lots of post effects.  Blur, DoF, tonemap, saturate, distortion.  Adds a lot to the game!

 

Try to keep it as simple as possible.