SlideShare a Scribd company logo
1 of 55
Download to read offline
Culling the Battlefield
  Daniel Collin (DICE)




Tuesday, March 8, 2011
Overview
    â€șBackground
    â€șWhy rewrite it?
    â€șRequirements
    â€șTarget hardware
    â€șDetails
    â€șSoftware Occlusion
    â€șConclusion


Tuesday, March 8, 2011
Background of the old culling
    â€șHierarchical Sphere Trees
    â€șStaticCullTree
    â€șDynamicCullTree




Tuesday, March 8, 2011
Background of the old culling




Tuesday, March 8, 2011
Why rewrite it?
    â€șDynamicCullTree scaling
    â€șSub-levels
    â€șPipeline dependencies
    â€șHard to scale
    â€șOne job per frustum



Tuesday, March 8, 2011
Job graph (Old Culling)
      Job 0                    DynamicCullJob (Shadow 1, 2, View frustum)


                         Shadow 1
      Job 1               frustum
                                                                     Merge Job


                         Shadow 2
      Job 2               frustum
                                                                     Merge Job



      Job 3                         View frustum                     Merge Job



Bitmasks


Tuesday, March 8, 2011
Requirements for new system

â€șBetter scaling
â€șDestruction
â€șReal-time editing
â€șSimpler code
â€șUniïŹcation of sub-systems


Tuesday, March 8, 2011
Target hardware




Tuesday, March 8, 2011
What doesn’t work well on these systems?
â€șNon-local data
â€șBranches
â€șSwitching between register types (LHS)
â€șTree based structures are usually branch heavy
â€șData is the most important thing to address



Tuesday, March 8, 2011
What does work well on these systems?
â€șLocal data
â€ș(SIMD) Computing power
â€șParallelism




Tuesday, March 8, 2011
The new culling
â€șOur worlds usually has max ~15000 objects
â€șFirst try was to just use parallel brute force
â€ș3x times faster than the old culling
â€ș1/5 code size
â€șEasier to optimize even further



Tuesday, March 8, 2011
The new culling
â€șLinear arrays scale great
â€șPredictable data
â€șFew branches
â€șUses the computing power




Tuesday, March 8, 2011
The new culling




Tuesday, March 8, 2011
Performance numbers (no occlusion)
                                         15000 Spheres
                           Platform           1 Job             4 Jobs

                          Xbox 360           1.55 ms     (2.10 ms / 4) = 0.52

          x86 (Core i7, 2.66 GHz)             1.0 ms     (1.30 ms / 4) = 0.32

                         Playstation 3       0.85 ms     ((0.95 ms / 4) = 0.23

                 Playstation 3 (SPA)         0.63 ms     (0.75 ms / 4) = 0.18




Tuesday, March 8, 2011
Details of the new culling
â€șImprove performance with a simple grid
â€șReally an AABB assigned to a “cell” with spheres
â€șSeparate grids for
â€ș
â€ș Rendering: Static
â€ș Rendering: Dynamic
â€ș Physics: Static
â€ș Physics: Dynamic

Tuesday, March 8, 2011
Data layout
                  EntityGridCell                                       Block
Block*                   Pointer      Pointer           Pointer   positions    x, y, z, r x, y, z, r 

    u8                   Count        Count             Count     entityInfo   handle, Handle, 

   u32                     Total Count                            transformData       
      
     


                             struct TransformData
                             {
                                    half rotation[4];
                                    half minAabb[3];
                                    half pad[1];
                                    half maxAabb[3];
                                    half scale[3];
                             };

Tuesday, March 8, 2011
Adding objects
          ‱ Pre-allocated array that we can grab data from
                                                               AtomicAdd(
) to “alloc” new block
                         4k        4k          


                          EntityGridCell

          Block*              Pointer      Pointer   Pointer
              u8              Count        Count     Count
             u32                Total Count



Tuesday, March 8, 2011
Adding objects

            Cell 0 Cell 1
                                          Cell 4
            Cell 2 Cell 3


Tuesday, March 8, 2011
Removing objects
â€șUse the “swap trick”
â€șData doesn’t need to be sorted
â€șJust swap with the last entry and decrease the count




Tuesday, March 8, 2011
Rendering culling
          ‱ Let’s look at what the rendering expects
                   struct EntityRenderCullInfo
                   {
                       Handle entity;    // handle to the entity
                       u16 visibleViews; // bits of which frustums that was visible
                       u16 classId;      // type of mesh
                       float screenArea; // at which screen area entity should be culled
                   };




Tuesday, March 8, 2011
Culling code
                         while   (1)
                         {
                         
       uint blockIter = interlockedIncrement(currentBlockIndex) - 1;
                          
                         
       if (blockIter >= blockCount) break;
                          
                         
       u32 masks[EntityGridCell::Block::MaxCount] = {}, frustumMask = 1;
                          
      block = gridCell->blocks[blockIter];
                          
                         
       foreach (frustum in frustums, frustumMask <<= 1)
                         
       {
                         
       
     for (i = 0; i < gridCell->blockCounts[blockIter]; ++i)
                         
       
     {
                         
       
     
       u32 inside = intersect(frustum, block->postition[i]);
                         
       
     
       masks[i] |= frustumMask & inside;
                         
       
     }
                         
       }
                          
                         
       for (i = 0; i < gridCell->blockCounts[blockIter]; ++i)
                         
       {
                         
       
       // ïŹlter list here (if masks[i] is zero it should be skipped)
                         
       
       // ...
                         
       }
                         }


Tuesday, March 8, 2011
Intersection Code
                         bool intersect(const Plane* frustumPlanes, Vec4 pos)
                         {
                              ïŹ‚oat radius = pos.w;
                         
    if (distance(frustumPlanes[Frustum::Far], pos) > radius)
                         
    
     return false;
                         
    if (distance(frustumPlanes[Frustum::Near], pos) > radius)
                         
    
     return false;
                         
    if (distance(frustumPlanes[Frustum::Right], pos) > radius)
                         
    
     return false;
                         
    if (distance(frustumPlanes[Frustum::Left], pos) > radius)
                         
    
     return false;
                         
    if (distance(frustumPlanes[Frustum::Upper], pos) > radius)
                         
    
     return false;
                         
    if (distance(frustumPlanes[Frustum::Lower], pos) > radius)
                         
    
     return false;
                          
                         
    return true;
                         }


Tuesday, March 8, 2011
Tuesday, March 8, 2011
See “Typical C++ Bullshit” by
                                @mike_acton




Tuesday, March 8, 2011
Intersection Code
                LHS!
                    bool intersect(const Plane* frustumPlanes, Vec4 pos) Float branch!
                    {
                        float radius = pos.w;
                        if (distance(frustumPlanes[Frustum::Far], pos) > radius)
                             return So what do the consoles
                                    false;
                                            think?
                        if (distance(frustumPlanes[Frustum::Near], pos) > radius)
               LHS!          return false;
                        if (distance(frustumPlanes[Frustum::Right], pos) >Float branch!

                                            :(
                                                                           radius)
                             return false;
                        if (distance(frustumPlanes[Frustum::Left], pos) > radius)
                             return false;
                        if (distance(frustumPlanes[Frustum::Upper], pos) > radius)
              LHS!           return false;
                        if (distance(frustumPlanes[Frustum::Lower], pos) > radius)
                             return false;                               Float branch!

                             return true;
                         }   LHS!                          Float branch!


Tuesday, March 8, 2011
Intersection Code
                         bool intersect(const Plane* frustumPlanes, Vec4 pos)
                         {
                             float radius = pos.w;
                             if (distance(frustumPlanes[Frustum::Far], pos) > radius)
                                  return false;
                             if (distance(frustumPlanes[Frustum::Near], pos) > radius)
                                  return false;
                             if (distance(frustumPlanes[Frustum::Right], pos) > radius)
                                  return false;
                             if (distance(frustumPlanes[Frustum::Left], pos) > radius)
                                  return false;
                             if (distance(frustumPlanes[Frustum::Upper], pos) > radius)
                                  return false;
                             if (distance(frustumPlanes[Frustum::Lower], pos) > radius)
                                  return false;

                             return true;
                         }



Tuesday, March 8, 2011
Intersection Code
â€șHow can we improve this?
â€șDot products are not very SIMD friendly
â€șUsually need to shuffle data around to get result
â€ș(x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1)




Tuesday, March 8, 2011
Intersection Code
â€șRearrange the data from AoS to SoA
               Vec       0   X0   Y0   Z0   W0   VecX   X0   X1   X2   X3
               Vec       1   X1   Y1   Z1   W1   VecY   Y0   Y1   Y2   Y3
               Vec       2   X2   Y2   Z2   W2   VecZ   Z0   Z1   Z2   Z3
               Vec       3   X3   Y3   Z3   W3   VecW   W0   W1   W2   W3

â€șNow we only need 3 instructions for 4 dots!



Tuesday, March 8, 2011
Rearrange the frustum planes
                                                         X0   X1   X2   X3
                         Plane   0   X0   Y0   Z0   W0   Y0   Y1   Y2   Y3
                         Plane   1   X1   Y1   Z1   W1   Z0   Z1   Z2   Z3
                         Plane   2   X2   Y2   Z2   W2   W0   W1   W2   W3
                         Plane   3   X3   Y3   Z3   W3
                         Plane   4   X4   Y4   Z4   W4   X4   X5   X4   X5
                         Plane   5   X5   Y5   Z5   W5   Y4   Y5   Y4   Y5
                                                         Z4   Z5   Z4   Z5
                                                         W4   W5   W4   W5




Tuesday, March 8, 2011
New intersection code
â€șTwo frustum vs Sphere intersections per loop
â€ș4 * 3 dot products with 9 instructions
â€șLoop over all frustums and merge the result




Tuesday, March 8, 2011
New intersection code (1/4)

                         Vec   posA_xxxx   =   vecShuffle<VecMask::_xxxx>(posA);
                         Vec   posA_yyyy   =   vecShuffle<VecMask::_yyyy>(posA);
                         Vec   posA_zzzz   =   vecShuffle<VecMask::_zzzz>(posA);
                         Vec   posA_rrrr   =   vecShuffle<VecMask::_wwww>(posA);

                         // 4 dot products

                         dotA_0123 = vecMulAdd(posA_zzzz, pl_z0z1z2z3, pl_w0w1w2w3);
                         dotA_0123 = vecMulAdd(posA_yyyy, pl_y0y1y2y3, dotA_0123);
                         dotA_0123 = vecMulAdd(posA_xxxx, pl_x0x1x2x3, dotA_0123);




Tuesday, March 8, 2011
New intersection code (2/4)

                         Vec   posB_xxxx   =   vecShuffle<VecMask::_xxxx>(posB);
                         Vec   posB_yyyy   =   vecShuffle<VecMask::_yyyy>(posB);
                         Vec   posB_zzzz   =   vecShuffle<VecMask::_zzzz>(posB);
                         Vec   posB_rrrr   =   vecShuffle<VecMask::_wwww>(posB);

                         // 4 dot products

                         dotB_0123 = vecMulAdd(posB_zzzz, pl_z0z1z2z3, pl_w0w1w2w3);
                         dotB_0123 = vecMulAdd(posB_yyyy, pl_y0y1y2y3, dotB_0123);
                         dotB_0123 = vecMulAdd(posB_xxxx, pl_x0x1x2x3, dotB_0123




Tuesday, March 8, 2011
New intersection code (3/4)

                         Vec   posAB_xxxx   =   vecInsert<VecMask::_0011>(posA_xxxx,   posB_xxxx);
                         Vec   posAB_yyyy   =   vecInsert<VecMask::_0011>(posA_yyyy,   posB_yyyy);
                         Vec   posAB_zzzz   =   vecInsert<VecMask::_0011>(posA_zzzz,   posB_zzzz);
                         Vec   posAB_rrrr   =   vecInsert<VecMask::_0011>(posA_rrrr,   posB_rrrr);

                         // 4 dot products

                         dotA45B45 = vecMulAdd(posAB_zzzz, pl_z4z5z4z5, pl_w4w5w4w5);
                         dotA45B45 = vecMulAdd(posAB_yyyy, pl_y4y5y4y5, dotA45B45);
                         dotA45B45 = vecMulAdd(posAB_xxxx, pl_x4x5x4x5, dotA45B45);




Tuesday, March 8, 2011
New intersection code (4/4)
                         // Compare against radius

                         dotA_0123 = vecCmpGTMask(dotA_0123, posA_rrrr);
                         dotB_0123 = vecCmpGTMask(dotB_0123, posB_rrrr);
                         dotA45B45 = vecCmpGTMask(dotA45B45, posAB_rrrr);

                         Vec dotA45 = vecInsert<VecMask::_0011>(dotA45B45, zero);
                         Vec dotB45 = vecInsert<VecMask::_0011>(zero, dotA45B45);

                         // collect the results

                         Vec resA = vecOrx(dotA_0123);
                         Vec resB = vecOrx(dotB_0123);

                         resA = vecOr(resA, vecOrx(dotA45));
                         resB = vecOr(resB, vecOrx(dotB45));

                         // resA = inside or outside of frustum for point A, resB for point B

                         Vec rA = vecNotMask(resA);
                         Vec rB = vecNotMask(resB);

                         masksCurrent[0] |= frustumMask & rA;
                         masksCurrent[1] |= frustumMask & rB;

Tuesday, March 8, 2011
SPU Pipelining Assembler (SPA)
â€șLike VCL (for PS2) but for PS3 SPU
â€șCan give you that extra boost if needed
â€șDoes software pipelining for you
â€șGives about 35% speed boost in the culling
â€șNot really that different from using intrinsics
â€șAnd coding assembler is fun :)


Tuesday, March 8, 2011
SPA Inner loop (partly)
                         lqd     posA, -0x20(currentPos)
                         lqd     posB, -0x10(currentPos)

                         shufb   posA_xxxx,   posA,   posA,   Mask_xxxx
                         shufb   posA_yyyy,   posA,   posA,   Mask_yyyy
                         shufb   posA_zzzz,   posA,   posA,   Mask_zzzz
                         shufb   posA_rrrr,   posA,   posA,   Mask_wwww

                         // 4 dot products

                         fma     dotA_0123, posA_zzzz, pl_z0z1z2z3, pl_w0w1w2w3
                         fma     dotA_0123, posA_yyyy, pl_y0y1y2y3, dotA_0123
                         fma     dotA_0123, posA_xxxx, pl_x0x1x2x3, dotA_0123

                         shufb   posB_xxxx,   posB,   posB,   Mask_xxxx
                         shufb   posB_yyyy,   posB,   posB,   Mask_yyyy
                         shufb   posB_zzzz,   posB,   posB,   Mask_zzzz
                         shufb   posB_rrrr,   posB,   posB,   Mask_wwww

                         // 4 dot products

                         fma     dotB_0123, posB_zzzz, pl_z0z1z2z3, pl_w0w1w2w3
                         fma     dotB_0123, posB_yyyy, pl_y0y1y2y3, dotB_0123
                         fma     dotB_0123, posB_xxxx, pl_x0x1x2x3, dotB_0123




Tuesday, March 8, 2011
SPA Inner loop
       #   Loop stats - frustumCull::loop
       #   (ims enabled, sms disabled, optimisation level 2)
       #          resmii : 24 (*)         (resource constrained)
       #          recmii : 2              (recurrence constrained)
       #   resource usage:
       #          even pipe : 24 inst. (100% use) (*)
       #                        FX[15] SP[9]
       #          odd pipe : 24 inst. (100% use) (*)
       #                        SH[17] LS[6] BR[1]
       #   misc:
       #          linear schedule = 57 cycles (for information only)
       #   software pipelining:
       #          best pipelined schedule = 24 cycles (pipelined, 3 iterations in parallel)
       #   software pipelining adjustments:
       #          not generating non-pipelined loop since trip count >=3 (3)
       #   estimated loop performance:
       #          =24*n+59 cycles




Tuesday, March 8, 2011
_local_c0de000000000002:
                                      SPA Inner loop
       fma         $46,$42,$30,$29;      /*   +1   */   shufb   $47,$44,$37,$33              /*   +2   */
       fcgt        $57,$20,$24;          /*   +2   */   orx     $48,$15                      /*   +2   */
       selb        $55,$37,$44,$33;      /*   +2   */   shufb   $56,$21,$16,$33              /*   +1   */
       fma         $52,$16,$28,$41;      /*   +1   */   orx     $49,$57                      /*   +2   */
       ai          $4,$4,32;                            orx     $54,$47                      /*   +2   */
       fma         $51,$19,$26,$45;      /*   +1   */   orx     $53,$55                      /*   +2   */
       fma         $50,$56,$27,$46;      /*   +1   */   shufb   $24,$23,$23,$34              /*   +1   */
       ai          $2,$2,32;             /*   +2   */   lqd     $13,-32($4)
       or          $69,$48,$54;          /*   +2   */   lqd     $23,-16($4)
       fma         $20,$18,$26,$52;      /*   +1   */   lqd     $12,-32($2)                  /*   +2   */
       nor         $60,$69,$69;          /*   +2   */   lqd     $43,-16($2)                  /*   +2   */
       or          $62,$49,$53;          /*   +2   */   shufb   $59,$22,$17,$33              /*   +1   */
       and         $39,$60,$35;          /*   +2   */   shufb   $11,$14,$24,$33              /*   +1   */
       nor         $61,$62,$60;          /*   +2   */   shufb   $22,$13,$13,$36
       fcgt        $15,$51,$14;          /*   +1   */   shufb   $17,$23,$23,$36
       and         $58,$61,$35;          /*   +2   */   shufb   $19,$13,$13,$3
       fma         $10,$59,$25,$50;      /*   +1   */   shufb   $18,$23,$23,$3
       fma         $9,$22,$32,$31;                      shufb   $16,$23,$23,$38
       or          $8,$58,$43;           /* +2 */       shufb   $21,$13,$13,$38
       or          $40,$39,$12;          /* +2 */       shufb   $14,$13,$13,$34
       ai          $7,$7,-1;             /* +2 */       shufb   $42,$19,$18,$33
       fma         $41,$17,$32,$31;                     stqd    $8,-16($2)                   /* +2 */
       fcgt        $44,$10,$11;          /* +1 */       stqd    $40,-32($2)                  /* +2 */
       fma         $45,$21,$28,$9;                      brnz    $7,_local_c0de000000000002   /* +2 */
       nop         ;                                    hbrr



Tuesday, March 8, 2011
Additional culling
â€șFrustum vs AABB
â€șProject AABB to screen space
â€șSoftware Occlusion




Tuesday, March 8, 2011
Project AABB to screen space
â€șCalculate the area of the AABB in screen space
â€șIf area is smaller than setting just skip it
â€șDue to FOV taking distance doesn’t work




Tuesday, March 8, 2011
Software Occlusion
â€șUsed in Frostbite for 3 years
â€șCross platform
â€șArtist made occluders
â€șTerrain




Tuesday, March 8, 2011
Why Software Occlusion?
â€șWant to remove CPU time not just GPU
â€șCull as early as possible
â€șGPU queries troublesome as lagging behind CPU
â€șMust support destruction
â€șEasy for artists to control



Tuesday, March 8, 2011
Software Occlusion
â€șSo how does it work?
â€șRender PS1 style geometry to a zbuffer using
 software rendering
â€șThe zbuffer is 256 x 114 ïŹ‚oat




Tuesday, March 8, 2011
Software Occlusion
â€șOccluder triangle setup
â€șTerrain triangle setup
â€șRasterize triangles
â€șCulling




Tuesday, March 8, 2011
Software Occlusion (Occluders)




Tuesday, March 8, 2011
Software Occlusion (In-game)




Tuesday, March 8, 2011
Software Occlusion (In-game)




Tuesday, March 8, 2011
Software Occlusion (In-game)




Tuesday, March 8, 2011
Culling jobs
                                                  Culling Jobs
      Job 0              Occluder Triangles   Rasterize Triangles   Culling   Z-buffer Test



      Job 1              Occluder Triangles   Rasterize Triangles   Culling   Z-buffer Test



      Job 2              Occluder Triangles   Rasterize Triangles   Culling   Z-buffer Test



      Job 3              Occluder Triangles   Rasterize Triangles   Culling   Z-buffer Test



      Job 4              Terrain Triangles    Rasterize Triangles   Culling   Z-buffer Test




Tuesday, March 8, 2011
Occluder triangles
                            Job 0    Inside, Project triangles


                            Job 1    Inside, Project triangles


                            Job 2    Intersecting, Clip, Project


                            Job 3    Outside, Skip

                            Output



Tuesday, March 8, 2011
Occluder triangles
                                     Rasterize Triangles
                Input

                             16 Triangles 16 Triangles 16 Triangles 16 Triangles

            256 x 114 zbuffer                256 x 114 zbuffer           256 x 114 zbuffer




                         Job 0                    Job 1                        Merge step
                                                          <Todo: Fix Colors>
Tuesday, March 8, 2011
z-buffer testing
â€șCalculate screen space AABB for object
â€șGet single distance value
â€șTest the square against the z-buffer




Tuesday, March 8, 2011
Conclusion
â€șAccurate and high performance culling is essential
â€șReduces pressure on low-level systems/rendering
â€șIt’s all about data
â€șSimple data often means simple code
â€șUnderstanding your target hardware



Tuesday, March 8, 2011
Thanks to
â€șAndreas Fredriksson (@deplinenoise)
â€șChristina Coffin (@christinacoffin)
â€șJohan Andersson (@repi)
â€șStephen Hill (@self_shadow)
â€șSteven Tovey (@nonchaotic)
â€șHalldor Fannar
â€șEvelyn Donis


Tuesday, March 8, 2011
Questions?                                                           Email: daniel@collin.com
                                                                     Blog: zenic.org
                                                                     Twitter: @daniel_collin




Battlefield 3 & Frostbite 2 talks at GDC’11:
Mon 1:45                 DX11 Rendering in Battlefield 3                 Johan Andersson
Wed 10:30                SPU-based Deferred Shading in Battlefield 3 Christina Coffin
                         for PlayStation 3
Wed 3:00                 Culling the Battlefield: Data Oriented Design   Daniel Collin
                         in Practice
Thu 1:30                 Lighting You Up in Battlefield 3                Kenny Magnusson
Fri 4:05                 Approximating Translucency for a Fast,          Colin Barré-Brisebois
                         Cheap & Convincing Subsurface Scattering
                         Look


                                       For more DICE talks: http://publications.dice.se
Tuesday, March 8, 2011

More Related Content

Viewers also liked

A Real-time Radiosity Architecture
A Real-time Radiosity ArchitectureA Real-time Radiosity Architecture
A Real-time Radiosity ArchitectureElectronic Arts / DICE
 
5 Major Challenges in Interactive Rendering
5 Major Challenges in Interactive Rendering5 Major Challenges in Interactive Rendering
5 Major Challenges in Interactive RenderingElectronic Arts / DICE
 
Building the Battlefield AI Experience
Building the Battlefield AI ExperienceBuilding the Battlefield AI Experience
Building the Battlefield AI ExperienceElectronic Arts / DICE
 
How data rules the world: Telemetry in Battlefield Heroes
How data rules the world: Telemetry in Battlefield HeroesHow data rules the world: Telemetry in Battlefield Heroes
How data rules the world: Telemetry in Battlefield HeroesElectronic Arts / DICE
 
SPU-Based Deferred Shading in BATTLEFIELD 3 for Playstation 3
SPU-Based Deferred Shading in BATTLEFIELD 3 for Playstation 3SPU-Based Deferred Shading in BATTLEFIELD 3 for Playstation 3
SPU-Based Deferred Shading in BATTLEFIELD 3 for Playstation 3Electronic Arts / DICE
 
Stylized Rendering in Battlefield Heroes
Stylized Rendering in Battlefield HeroesStylized Rendering in Battlefield Heroes
Stylized Rendering in Battlefield HeroesElectronic Arts / DICE
 
Battlelog - Building scalable web sites with tight game integration
Battlelog - Building scalable web sites with tight game integrationBattlelog - Building scalable web sites with tight game integration
Battlelog - Building scalable web sites with tight game integrationElectronic Arts / DICE
 
Stable SSAO in Battlefield 3 with Selective Temporal Filtering
Stable SSAO in Battlefield 3 with Selective Temporal FilteringStable SSAO in Battlefield 3 with Selective Temporal Filtering
Stable SSAO in Battlefield 3 with Selective Temporal FilteringElectronic Arts / DICE
 
Introduction to Data Oriented Design
Introduction to Data Oriented DesignIntroduction to Data Oriented Design
Introduction to Data Oriented DesignElectronic Arts / DICE
 
Future Directions for Compute-for-Graphics
Future Directions for Compute-for-GraphicsFuture Directions for Compute-for-Graphics
Future Directions for Compute-for-GraphicsElectronic Arts / DICE
 
Level Design Challenges & Solutions - Mirror's Edge
Level Design Challenges & Solutions - Mirror's EdgeLevel Design Challenges & Solutions - Mirror's Edge
Level Design Challenges & Solutions - Mirror's EdgeElectronic Arts / DICE
 

Viewers also liked (12)

Bending the Graphics Pipeline
Bending the Graphics PipelineBending the Graphics Pipeline
Bending the Graphics Pipeline
 
A Real-time Radiosity Architecture
A Real-time Radiosity ArchitectureA Real-time Radiosity Architecture
A Real-time Radiosity Architecture
 
5 Major Challenges in Interactive Rendering
5 Major Challenges in Interactive Rendering5 Major Challenges in Interactive Rendering
5 Major Challenges in Interactive Rendering
 
Building the Battlefield AI Experience
Building the Battlefield AI ExperienceBuilding the Battlefield AI Experience
Building the Battlefield AI Experience
 
How data rules the world: Telemetry in Battlefield Heroes
How data rules the world: Telemetry in Battlefield HeroesHow data rules the world: Telemetry in Battlefield Heroes
How data rules the world: Telemetry in Battlefield Heroes
 
SPU-Based Deferred Shading in BATTLEFIELD 3 for Playstation 3
SPU-Based Deferred Shading in BATTLEFIELD 3 for Playstation 3SPU-Based Deferred Shading in BATTLEFIELD 3 for Playstation 3
SPU-Based Deferred Shading in BATTLEFIELD 3 for Playstation 3
 
Stylized Rendering in Battlefield Heroes
Stylized Rendering in Battlefield HeroesStylized Rendering in Battlefield Heroes
Stylized Rendering in Battlefield Heroes
 
Battlelog - Building scalable web sites with tight game integration
Battlelog - Building scalable web sites with tight game integrationBattlelog - Building scalable web sites with tight game integration
Battlelog - Building scalable web sites with tight game integration
 
Stable SSAO in Battlefield 3 with Selective Temporal Filtering
Stable SSAO in Battlefield 3 with Selective Temporal FilteringStable SSAO in Battlefield 3 with Selective Temporal Filtering
Stable SSAO in Battlefield 3 with Selective Temporal Filtering
 
Introduction to Data Oriented Design
Introduction to Data Oriented DesignIntroduction to Data Oriented Design
Introduction to Data Oriented Design
 
Future Directions for Compute-for-Graphics
Future Directions for Compute-for-GraphicsFuture Directions for Compute-for-Graphics
Future Directions for Compute-for-Graphics
 
Level Design Challenges & Solutions - Mirror's Edge
Level Design Challenges & Solutions - Mirror's EdgeLevel Design Challenges & Solutions - Mirror's Edge
Level Design Challenges & Solutions - Mirror's Edge
 

More from Electronic Arts / DICE

GDC2019 - SEED - Towards Deep Generative Models in Game Development
GDC2019 - SEED - Towards Deep Generative Models in Game DevelopmentGDC2019 - SEED - Towards Deep Generative Models in Game Development
GDC2019 - SEED - Towards Deep Generative Models in Game DevelopmentElectronic Arts / DICE
 
SIGGRAPH 2010 - Style and Gameplay in the Mirror's Edge
SIGGRAPH 2010 - Style and Gameplay in the Mirror's EdgeSIGGRAPH 2010 - Style and Gameplay in the Mirror's Edge
SIGGRAPH 2010 - Style and Gameplay in the Mirror's EdgeElectronic Arts / DICE
 
Syysgraph 2018 - Modern Graphics Abstractions & Real-Time Ray Tracing
Syysgraph 2018 - Modern Graphics Abstractions & Real-Time Ray TracingSyysgraph 2018 - Modern Graphics Abstractions & Real-Time Ray Tracing
Syysgraph 2018 - Modern Graphics Abstractions & Real-Time Ray TracingElectronic Arts / DICE
 
Khronos Munich 2018 - Halcyon and Vulkan
Khronos Munich 2018 - Halcyon and VulkanKhronos Munich 2018 - Halcyon and Vulkan
Khronos Munich 2018 - Halcyon and VulkanElectronic Arts / DICE
 
CEDEC 2018 - Towards Effortless Photorealism Through Real-Time Raytracing
CEDEC 2018 - Towards Effortless Photorealism Through Real-Time RaytracingCEDEC 2018 - Towards Effortless Photorealism Through Real-Time Raytracing
CEDEC 2018 - Towards Effortless Photorealism Through Real-Time RaytracingElectronic Arts / DICE
 
CEDEC 2018 - Functional Symbiosis of Art Direction and Proceduralism
CEDEC 2018 - Functional Symbiosis of Art Direction and ProceduralismCEDEC 2018 - Functional Symbiosis of Art Direction and Proceduralism
CEDEC 2018 - Functional Symbiosis of Art Direction and ProceduralismElectronic Arts / DICE
 
SIGGRAPH 2018 - PICA PICA and NVIDIA Turing
SIGGRAPH 2018 - PICA PICA and NVIDIA TuringSIGGRAPH 2018 - PICA PICA and NVIDIA Turing
SIGGRAPH 2018 - PICA PICA and NVIDIA TuringElectronic Arts / DICE
 
SIGGRAPH 2018 - Full Rays Ahead! From Raster to Real-Time Raytracing
SIGGRAPH 2018 - Full Rays Ahead! From Raster to Real-Time RaytracingSIGGRAPH 2018 - Full Rays Ahead! From Raster to Real-Time Raytracing
SIGGRAPH 2018 - Full Rays Ahead! From Raster to Real-Time RaytracingElectronic Arts / DICE
 
HPG 2018 - Game Ray Tracing: State-of-the-Art and Open Problems
HPG 2018 - Game Ray Tracing: State-of-the-Art and Open ProblemsHPG 2018 - Game Ray Tracing: State-of-the-Art and Open Problems
HPG 2018 - Game Ray Tracing: State-of-the-Art and Open ProblemsElectronic Arts / DICE
 
EPC 2018 - SEED - Exploring The Collaboration Between Proceduralism & Deep Le...
EPC 2018 - SEED - Exploring The Collaboration Between Proceduralism & Deep Le...EPC 2018 - SEED - Exploring The Collaboration Between Proceduralism & Deep Le...
EPC 2018 - SEED - Exploring The Collaboration Between Proceduralism & Deep Le...Electronic Arts / DICE
 
DD18 - SEED - Raytracing in Hybrid Real-Time Rendering
DD18 - SEED - Raytracing in Hybrid Real-Time RenderingDD18 - SEED - Raytracing in Hybrid Real-Time Rendering
DD18 - SEED - Raytracing in Hybrid Real-Time RenderingElectronic Arts / DICE
 
Creativity of Rules and Patterns: Designing Procedural Systems
Creativity of Rules and Patterns: Designing Procedural SystemsCreativity of Rules and Patterns: Designing Procedural Systems
Creativity of Rules and Patterns: Designing Procedural SystemsElectronic Arts / DICE
 
Shiny Pixels and Beyond: Real-Time Raytracing at SEED
Shiny Pixels and Beyond: Real-Time Raytracing at SEEDShiny Pixels and Beyond: Real-Time Raytracing at SEED
Shiny Pixels and Beyond: Real-Time Raytracing at SEEDElectronic Arts / DICE
 
A Certain Slant of Light - Past, Present and Future Challenges of Global Illu...
A Certain Slant of Light - Past, Present and Future Challenges of Global Illu...A Certain Slant of Light - Past, Present and Future Challenges of Global Illu...
A Certain Slant of Light - Past, Present and Future Challenges of Global Illu...Electronic Arts / DICE
 
Physically Based Sky, Atmosphere and Cloud Rendering in Frostbite
Physically Based Sky, Atmosphere and Cloud Rendering in FrostbitePhysically Based Sky, Atmosphere and Cloud Rendering in Frostbite
Physically Based Sky, Atmosphere and Cloud Rendering in FrostbiteElectronic Arts / DICE
 
FrameGraph: Extensible Rendering Architecture in Frostbite
FrameGraph: Extensible Rendering Architecture in FrostbiteFrameGraph: Extensible Rendering Architecture in Frostbite
FrameGraph: Extensible Rendering Architecture in FrostbiteElectronic Arts / DICE
 
Photogrammetry and Star Wars Battlefront
Photogrammetry and Star Wars BattlefrontPhotogrammetry and Star Wars Battlefront
Photogrammetry and Star Wars BattlefrontElectronic Arts / DICE
 
Physically Based and Unified Volumetric Rendering in Frostbite
Physically Based and Unified Volumetric Rendering in FrostbitePhysically Based and Unified Volumetric Rendering in Frostbite
Physically Based and Unified Volumetric Rendering in FrostbiteElectronic Arts / DICE
 

More from Electronic Arts / DICE (20)

GDC2019 - SEED - Towards Deep Generative Models in Game Development
GDC2019 - SEED - Towards Deep Generative Models in Game DevelopmentGDC2019 - SEED - Towards Deep Generative Models in Game Development
GDC2019 - SEED - Towards Deep Generative Models in Game Development
 
SIGGRAPH 2010 - Style and Gameplay in the Mirror's Edge
SIGGRAPH 2010 - Style and Gameplay in the Mirror's EdgeSIGGRAPH 2010 - Style and Gameplay in the Mirror's Edge
SIGGRAPH 2010 - Style and Gameplay in the Mirror's Edge
 
SEED - Halcyon Architecture
SEED - Halcyon ArchitectureSEED - Halcyon Architecture
SEED - Halcyon Architecture
 
Syysgraph 2018 - Modern Graphics Abstractions & Real-Time Ray Tracing
Syysgraph 2018 - Modern Graphics Abstractions & Real-Time Ray TracingSyysgraph 2018 - Modern Graphics Abstractions & Real-Time Ray Tracing
Syysgraph 2018 - Modern Graphics Abstractions & Real-Time Ray Tracing
 
Khronos Munich 2018 - Halcyon and Vulkan
Khronos Munich 2018 - Halcyon and VulkanKhronos Munich 2018 - Halcyon and Vulkan
Khronos Munich 2018 - Halcyon and Vulkan
 
CEDEC 2018 - Towards Effortless Photorealism Through Real-Time Raytracing
CEDEC 2018 - Towards Effortless Photorealism Through Real-Time RaytracingCEDEC 2018 - Towards Effortless Photorealism Through Real-Time Raytracing
CEDEC 2018 - Towards Effortless Photorealism Through Real-Time Raytracing
 
CEDEC 2018 - Functional Symbiosis of Art Direction and Proceduralism
CEDEC 2018 - Functional Symbiosis of Art Direction and ProceduralismCEDEC 2018 - Functional Symbiosis of Art Direction and Proceduralism
CEDEC 2018 - Functional Symbiosis of Art Direction and Proceduralism
 
SIGGRAPH 2018 - PICA PICA and NVIDIA Turing
SIGGRAPH 2018 - PICA PICA and NVIDIA TuringSIGGRAPH 2018 - PICA PICA and NVIDIA Turing
SIGGRAPH 2018 - PICA PICA and NVIDIA Turing
 
SIGGRAPH 2018 - Full Rays Ahead! From Raster to Real-Time Raytracing
SIGGRAPH 2018 - Full Rays Ahead! From Raster to Real-Time RaytracingSIGGRAPH 2018 - Full Rays Ahead! From Raster to Real-Time Raytracing
SIGGRAPH 2018 - Full Rays Ahead! From Raster to Real-Time Raytracing
 
HPG 2018 - Game Ray Tracing: State-of-the-Art and Open Problems
HPG 2018 - Game Ray Tracing: State-of-the-Art and Open ProblemsHPG 2018 - Game Ray Tracing: State-of-the-Art and Open Problems
HPG 2018 - Game Ray Tracing: State-of-the-Art and Open Problems
 
EPC 2018 - SEED - Exploring The Collaboration Between Proceduralism & Deep Le...
EPC 2018 - SEED - Exploring The Collaboration Between Proceduralism & Deep Le...EPC 2018 - SEED - Exploring The Collaboration Between Proceduralism & Deep Le...
EPC 2018 - SEED - Exploring The Collaboration Between Proceduralism & Deep Le...
 
DD18 - SEED - Raytracing in Hybrid Real-Time Rendering
DD18 - SEED - Raytracing in Hybrid Real-Time RenderingDD18 - SEED - Raytracing in Hybrid Real-Time Rendering
DD18 - SEED - Raytracing in Hybrid Real-Time Rendering
 
Creativity of Rules and Patterns: Designing Procedural Systems
Creativity of Rules and Patterns: Designing Procedural SystemsCreativity of Rules and Patterns: Designing Procedural Systems
Creativity of Rules and Patterns: Designing Procedural Systems
 
Shiny Pixels and Beyond: Real-Time Raytracing at SEED
Shiny Pixels and Beyond: Real-Time Raytracing at SEEDShiny Pixels and Beyond: Real-Time Raytracing at SEED
Shiny Pixels and Beyond: Real-Time Raytracing at SEED
 
A Certain Slant of Light - Past, Present and Future Challenges of Global Illu...
A Certain Slant of Light - Past, Present and Future Challenges of Global Illu...A Certain Slant of Light - Past, Present and Future Challenges of Global Illu...
A Certain Slant of Light - Past, Present and Future Challenges of Global Illu...
 
Physically Based Sky, Atmosphere and Cloud Rendering in Frostbite
Physically Based Sky, Atmosphere and Cloud Rendering in FrostbitePhysically Based Sky, Atmosphere and Cloud Rendering in Frostbite
Physically Based Sky, Atmosphere and Cloud Rendering in Frostbite
 
FrameGraph: Extensible Rendering Architecture in Frostbite
FrameGraph: Extensible Rendering Architecture in FrostbiteFrameGraph: Extensible Rendering Architecture in Frostbite
FrameGraph: Extensible Rendering Architecture in Frostbite
 
Lighting the City of Glass
Lighting the City of GlassLighting the City of Glass
Lighting the City of Glass
 
Photogrammetry and Star Wars Battlefront
Photogrammetry and Star Wars BattlefrontPhotogrammetry and Star Wars Battlefront
Photogrammetry and Star Wars Battlefront
 
Physically Based and Unified Volumetric Rendering in Frostbite
Physically Based and Unified Volumetric Rendering in FrostbitePhysically Based and Unified Volumetric Rendering in Frostbite
Physically Based and Unified Volumetric Rendering in Frostbite
 

Recently uploaded

Call Girls In Goa 9316020077 Goa Call Girl By Indian Call Girls Goa
Call Girls In Goa  9316020077 Goa  Call Girl By Indian Call Girls GoaCall Girls In Goa  9316020077 Goa  Call Girl By Indian Call Girls Goa
Call Girls In Goa 9316020077 Goa Call Girl By Indian Call Girls Goasexy call girls service in goa
 
Call Girls Agency In Goa 💚 9316020077 💚 Call Girl Goa By Russian Call Girl ...
Call Girls  Agency In Goa  💚 9316020077 💚 Call Girl Goa By Russian Call Girl ...Call Girls  Agency In Goa  💚 9316020077 💚 Call Girl Goa By Russian Call Girl ...
Call Girls Agency In Goa 💚 9316020077 💚 Call Girl Goa By Russian Call Girl ...russian goa call girl and escorts service
 
Dakshineswar Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Se...
Dakshineswar Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Se...Dakshineswar Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Se...
Dakshineswar Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Se...aamir
 
Science City Kolkata ( Call Girls ) Kolkata ✔ 6297143586 ✔ Hot Model With Sex...
Science City Kolkata ( Call Girls ) Kolkata ✔ 6297143586 ✔ Hot Model With Sex...Science City Kolkata ( Call Girls ) Kolkata ✔ 6297143586 ✔ Hot Model With Sex...
Science City Kolkata ( Call Girls ) Kolkata ✔ 6297143586 ✔ Hot Model With Sex...rahim quresi
 
2k Shot Call girls Laxmi Nagar Delhi 9205541914
2k Shot Call girls Laxmi Nagar Delhi 92055419142k Shot Call girls Laxmi Nagar Delhi 9205541914
2k Shot Call girls Laxmi Nagar Delhi 9205541914Delhi Call girls
 
VIP Call Girls Sonagachi - 8250192130 Escorts Service 50% Off with Cash ON De...
VIP Call Girls Sonagachi - 8250192130 Escorts Service 50% Off with Cash ON De...VIP Call Girls Sonagachi - 8250192130 Escorts Service 50% Off with Cash ON De...
VIP Call Girls Sonagachi - 8250192130 Escorts Service 50% Off with Cash ON De...anamikaraghav4
 
↑Top Model (Kolkata) Call Girls Behala ⟟ 8250192130 ⟟ High Class Call Girl In...
↑Top Model (Kolkata) Call Girls Behala ⟟ 8250192130 ⟟ High Class Call Girl In...↑Top Model (Kolkata) Call Girls Behala ⟟ 8250192130 ⟟ High Class Call Girl In...
↑Top Model (Kolkata) Call Girls Behala ⟟ 8250192130 ⟟ High Class Call Girl In...noor ahmed
 
5* Hotels Call Girls In Goa {{07028418221}} Call Girls In North Goa Escort Se...
5* Hotels Call Girls In Goa {{07028418221}} Call Girls In North Goa Escort Se...5* Hotels Call Girls In Goa {{07028418221}} Call Girls In North Goa Escort Se...
5* Hotels Call Girls In Goa {{07028418221}} Call Girls In North Goa Escort Se...Apsara Of India
 
Independent Hatiara Escorts ✔ 8250192130 ✔ Full Night With Room Online Bookin...
Independent Hatiara Escorts ✔ 8250192130 ✔ Full Night With Room Online Bookin...Independent Hatiara Escorts ✔ 8250192130 ✔ Full Night With Room Online Bookin...
Independent Hatiara Escorts ✔ 8250192130 ✔ Full Night With Room Online Bookin...Riya Pathan
 
Book Call Girls in Panchpota - 8250192130 | 24x7 Service Available Near Me
Book Call Girls in Panchpota - 8250192130 | 24x7 Service Available Near MeBook Call Girls in Panchpota - 8250192130 | 24x7 Service Available Near Me
Book Call Girls in Panchpota - 8250192130 | 24x7 Service Available Near Meanamikaraghav4
 
Russian Call Girl South End Park - Call 8250192130 Rs-3500 with A/C Room Cash...
Russian Call Girl South End Park - Call 8250192130 Rs-3500 with A/C Room Cash...Russian Call Girl South End Park - Call 8250192130 Rs-3500 with A/C Room Cash...
Russian Call Girl South End Park - Call 8250192130 Rs-3500 with A/C Room Cash...anamikaraghav4
 
Model Call Girls In Pazhavanthangal WhatsApp Booking 7427069034 call girl ser...
Model Call Girls In Pazhavanthangal WhatsApp Booking 7427069034 call girl ser...Model Call Girls In Pazhavanthangal WhatsApp Booking 7427069034 call girl ser...
Model Call Girls In Pazhavanthangal WhatsApp Booking 7427069034 call girl ser... Shivani Pandey
 
(DIVYA) Dhanori Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(DIVYA) Dhanori Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...(DIVYA) Dhanori Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(DIVYA) Dhanori Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...ranjana rawat
 
Nayabad Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Sex At ...
Nayabad Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Sex At ...Nayabad Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Sex At ...
Nayabad Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Sex At ...aamir
 
Almora call girls 📞 8617697112 At Low Cost Cash Payment Booking
Almora call girls 📞 8617697112 At Low Cost Cash Payment BookingAlmora call girls 📞 8617697112 At Low Cost Cash Payment Booking
Almora call girls 📞 8617697112 At Low Cost Cash Payment BookingNitya salvi
 
College Call Girls New Alipore - For 7001035870 Cheap & Best with original Ph...
College Call Girls New Alipore - For 7001035870 Cheap & Best with original Ph...College Call Girls New Alipore - For 7001035870 Cheap & Best with original Ph...
College Call Girls New Alipore - For 7001035870 Cheap & Best with original Ph...anamikaraghav4
 
Independent Joka Escorts ✔ 8250192130 ✔ Full Night With Room Online Booking 2...
Independent Joka Escorts ✔ 8250192130 ✔ Full Night With Room Online Booking 2...Independent Joka Escorts ✔ 8250192130 ✔ Full Night With Room Online Booking 2...
Independent Joka Escorts ✔ 8250192130 ✔ Full Night With Room Online Booking 2...noor ahmed
 
Contact:- 8860008073 Call Girls in Karnal Escort Service Available at Afforda...
Contact:- 8860008073 Call Girls in Karnal Escort Service Available at Afforda...Contact:- 8860008073 Call Girls in Karnal Escort Service Available at Afforda...
Contact:- 8860008073 Call Girls in Karnal Escort Service Available at Afforda...Apsara Of India
 
Book Paid Sonagachi Call Girls Kolkata 𖠋 8250192130 𖠋Low Budget Full Independ...
Book Paid Sonagachi Call Girls Kolkata 𖠋 8250192130 𖠋Low Budget Full Independ...Book Paid Sonagachi Call Girls Kolkata 𖠋 8250192130 𖠋Low Budget Full Independ...
Book Paid Sonagachi Call Girls Kolkata 𖠋 8250192130 𖠋Low Budget Full Independ...noor ahmed
 
VIP Call Girls Nagpur Megha Call 7001035870 Meet With Nagpur Escorts
VIP Call Girls Nagpur Megha Call 7001035870 Meet With Nagpur EscortsVIP Call Girls Nagpur Megha Call 7001035870 Meet With Nagpur Escorts
VIP Call Girls Nagpur Megha Call 7001035870 Meet With Nagpur Escortsranjana rawat
 

Recently uploaded (20)

Call Girls In Goa 9316020077 Goa Call Girl By Indian Call Girls Goa
Call Girls In Goa  9316020077 Goa  Call Girl By Indian Call Girls GoaCall Girls In Goa  9316020077 Goa  Call Girl By Indian Call Girls Goa
Call Girls In Goa 9316020077 Goa Call Girl By Indian Call Girls Goa
 
Call Girls Agency In Goa 💚 9316020077 💚 Call Girl Goa By Russian Call Girl ...
Call Girls  Agency In Goa  💚 9316020077 💚 Call Girl Goa By Russian Call Girl ...Call Girls  Agency In Goa  💚 9316020077 💚 Call Girl Goa By Russian Call Girl ...
Call Girls Agency In Goa 💚 9316020077 💚 Call Girl Goa By Russian Call Girl ...
 
Dakshineswar Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Se...
Dakshineswar Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Se...Dakshineswar Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Se...
Dakshineswar Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Se...
 
Science City Kolkata ( Call Girls ) Kolkata ✔ 6297143586 ✔ Hot Model With Sex...
Science City Kolkata ( Call Girls ) Kolkata ✔ 6297143586 ✔ Hot Model With Sex...Science City Kolkata ( Call Girls ) Kolkata ✔ 6297143586 ✔ Hot Model With Sex...
Science City Kolkata ( Call Girls ) Kolkata ✔ 6297143586 ✔ Hot Model With Sex...
 
2k Shot Call girls Laxmi Nagar Delhi 9205541914
2k Shot Call girls Laxmi Nagar Delhi 92055419142k Shot Call girls Laxmi Nagar Delhi 9205541914
2k Shot Call girls Laxmi Nagar Delhi 9205541914
 
VIP Call Girls Sonagachi - 8250192130 Escorts Service 50% Off with Cash ON De...
VIP Call Girls Sonagachi - 8250192130 Escorts Service 50% Off with Cash ON De...VIP Call Girls Sonagachi - 8250192130 Escorts Service 50% Off with Cash ON De...
VIP Call Girls Sonagachi - 8250192130 Escorts Service 50% Off with Cash ON De...
 
↑Top Model (Kolkata) Call Girls Behala ⟟ 8250192130 ⟟ High Class Call Girl In...
↑Top Model (Kolkata) Call Girls Behala ⟟ 8250192130 ⟟ High Class Call Girl In...↑Top Model (Kolkata) Call Girls Behala ⟟ 8250192130 ⟟ High Class Call Girl In...
↑Top Model (Kolkata) Call Girls Behala ⟟ 8250192130 ⟟ High Class Call Girl In...
 
5* Hotels Call Girls In Goa {{07028418221}} Call Girls In North Goa Escort Se...
5* Hotels Call Girls In Goa {{07028418221}} Call Girls In North Goa Escort Se...5* Hotels Call Girls In Goa {{07028418221}} Call Girls In North Goa Escort Se...
5* Hotels Call Girls In Goa {{07028418221}} Call Girls In North Goa Escort Se...
 
Independent Hatiara Escorts ✔ 8250192130 ✔ Full Night With Room Online Bookin...
Independent Hatiara Escorts ✔ 8250192130 ✔ Full Night With Room Online Bookin...Independent Hatiara Escorts ✔ 8250192130 ✔ Full Night With Room Online Bookin...
Independent Hatiara Escorts ✔ 8250192130 ✔ Full Night With Room Online Bookin...
 
Book Call Girls in Panchpota - 8250192130 | 24x7 Service Available Near Me
Book Call Girls in Panchpota - 8250192130 | 24x7 Service Available Near MeBook Call Girls in Panchpota - 8250192130 | 24x7 Service Available Near Me
Book Call Girls in Panchpota - 8250192130 | 24x7 Service Available Near Me
 
Russian Call Girl South End Park - Call 8250192130 Rs-3500 with A/C Room Cash...
Russian Call Girl South End Park - Call 8250192130 Rs-3500 with A/C Room Cash...Russian Call Girl South End Park - Call 8250192130 Rs-3500 with A/C Room Cash...
Russian Call Girl South End Park - Call 8250192130 Rs-3500 with A/C Room Cash...
 
Model Call Girls In Pazhavanthangal WhatsApp Booking 7427069034 call girl ser...
Model Call Girls In Pazhavanthangal WhatsApp Booking 7427069034 call girl ser...Model Call Girls In Pazhavanthangal WhatsApp Booking 7427069034 call girl ser...
Model Call Girls In Pazhavanthangal WhatsApp Booking 7427069034 call girl ser...
 
(DIVYA) Dhanori Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(DIVYA) Dhanori Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...(DIVYA) Dhanori Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(DIVYA) Dhanori Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
 
Nayabad Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Sex At ...
Nayabad Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Sex At ...Nayabad Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Sex At ...
Nayabad Call Girls ✔ 8005736733 ✔ Hot Model With Sexy Bhabi Ready For Sex At ...
 
Almora call girls 📞 8617697112 At Low Cost Cash Payment Booking
Almora call girls 📞 8617697112 At Low Cost Cash Payment BookingAlmora call girls 📞 8617697112 At Low Cost Cash Payment Booking
Almora call girls 📞 8617697112 At Low Cost Cash Payment Booking
 
College Call Girls New Alipore - For 7001035870 Cheap & Best with original Ph...
College Call Girls New Alipore - For 7001035870 Cheap & Best with original Ph...College Call Girls New Alipore - For 7001035870 Cheap & Best with original Ph...
College Call Girls New Alipore - For 7001035870 Cheap & Best with original Ph...
 
Independent Joka Escorts ✔ 8250192130 ✔ Full Night With Room Online Booking 2...
Independent Joka Escorts ✔ 8250192130 ✔ Full Night With Room Online Booking 2...Independent Joka Escorts ✔ 8250192130 ✔ Full Night With Room Online Booking 2...
Independent Joka Escorts ✔ 8250192130 ✔ Full Night With Room Online Booking 2...
 
Contact:- 8860008073 Call Girls in Karnal Escort Service Available at Afforda...
Contact:- 8860008073 Call Girls in Karnal Escort Service Available at Afforda...Contact:- 8860008073 Call Girls in Karnal Escort Service Available at Afforda...
Contact:- 8860008073 Call Girls in Karnal Escort Service Available at Afforda...
 
Book Paid Sonagachi Call Girls Kolkata 𖠋 8250192130 𖠋Low Budget Full Independ...
Book Paid Sonagachi Call Girls Kolkata 𖠋 8250192130 𖠋Low Budget Full Independ...Book Paid Sonagachi Call Girls Kolkata 𖠋 8250192130 𖠋Low Budget Full Independ...
Book Paid Sonagachi Call Girls Kolkata 𖠋 8250192130 𖠋Low Budget Full Independ...
 
VIP Call Girls Nagpur Megha Call 7001035870 Meet With Nagpur Escorts
VIP Call Girls Nagpur Megha Call 7001035870 Meet With Nagpur EscortsVIP Call Girls Nagpur Megha Call 7001035870 Meet With Nagpur Escorts
VIP Call Girls Nagpur Megha Call 7001035870 Meet With Nagpur Escorts
 

Culling the Battlefield: Data Oriented Design in Practice

  • 1. Culling the Battlefield Daniel Collin (DICE) Tuesday, March 8, 2011
  • 2. Overview â€șBackground â€șWhy rewrite it? â€șRequirements â€șTarget hardware â€șDetails â€șSoftware Occlusion â€șConclusion Tuesday, March 8, 2011
  • 3. Background of the old culling â€șHierarchical Sphere Trees â€șStaticCullTree â€șDynamicCullTree Tuesday, March 8, 2011
  • 4. Background of the old culling Tuesday, March 8, 2011
  • 5. Why rewrite it? â€șDynamicCullTree scaling â€șSub-levels â€șPipeline dependencies â€șHard to scale â€șOne job per frustum Tuesday, March 8, 2011
  • 6. Job graph (Old Culling) Job 0 DynamicCullJob (Shadow 1, 2, View frustum) Shadow 1 Job 1 frustum Merge Job Shadow 2 Job 2 frustum Merge Job Job 3 View frustum Merge Job Bitmasks Tuesday, March 8, 2011
  • 7. Requirements for new system â€șBetter scaling â€șDestruction â€șReal-time editing â€șSimpler code â€șUniïŹcation of sub-systems Tuesday, March 8, 2011
  • 9. What doesn’t work well on these systems? â€șNon-local data â€șBranches â€șSwitching between register types (LHS) â€șTree based structures are usually branch heavy â€șData is the most important thing to address Tuesday, March 8, 2011
  • 10. What does work well on these systems? â€șLocal data â€ș(SIMD) Computing power â€șParallelism Tuesday, March 8, 2011
  • 11. The new culling â€șOur worlds usually has max ~15000 objects â€șFirst try was to just use parallel brute force â€ș3x times faster than the old culling â€ș1/5 code size â€șEasier to optimize even further Tuesday, March 8, 2011
  • 12. The new culling â€șLinear arrays scale great â€șPredictable data â€șFew branches â€șUses the computing power Tuesday, March 8, 2011
  • 13. The new culling Tuesday, March 8, 2011
  • 14. Performance numbers (no occlusion) 15000 Spheres Platform 1 Job 4 Jobs Xbox 360 1.55 ms (2.10 ms / 4) = 0.52 x86 (Core i7, 2.66 GHz) 1.0 ms (1.30 ms / 4) = 0.32 Playstation 3 0.85 ms ((0.95 ms / 4) = 0.23 Playstation 3 (SPA) 0.63 ms (0.75 ms / 4) = 0.18 Tuesday, March 8, 2011
  • 15. Details of the new culling â€șImprove performance with a simple grid â€șReally an AABB assigned to a “cell” with spheres â€șSeparate grids for â€ș â€ș Rendering: Static â€ș Rendering: Dynamic â€ș Physics: Static â€ș Physics: Dynamic Tuesday, March 8, 2011
  • 16. Data layout EntityGridCell Block Block* Pointer Pointer Pointer positions x, y, z, r x, y, z, r 
 u8 Count Count Count entityInfo handle, Handle, 
 u32 Total Count transformData 
 
 
 struct TransformData { half rotation[4]; half minAabb[3]; half pad[1]; half maxAabb[3]; half scale[3]; }; Tuesday, March 8, 2011
  • 17. Adding objects ‱ Pre-allocated array that we can grab data from AtomicAdd(
) to “alloc” new block 4k 4k 
 EntityGridCell Block* Pointer Pointer Pointer u8 Count Count Count u32 Total Count Tuesday, March 8, 2011
  • 18. Adding objects Cell 0 Cell 1 Cell 4 Cell 2 Cell 3 Tuesday, March 8, 2011
  • 19. Removing objects â€șUse the “swap trick” â€șData doesn’t need to be sorted â€șJust swap with the last entry and decrease the count Tuesday, March 8, 2011
  • 20. Rendering culling ‱ Let’s look at what the rendering expects struct EntityRenderCullInfo { Handle entity; // handle to the entity u16 visibleViews; // bits of which frustums that was visible u16 classId; // type of mesh float screenArea; // at which screen area entity should be culled }; Tuesday, March 8, 2011
  • 21. Culling code while (1) { uint blockIter = interlockedIncrement(currentBlockIndex) - 1;   if (blockIter >= blockCount) break;   u32 masks[EntityGridCell::Block::MaxCount] = {}, frustumMask = 1;   block = gridCell->blocks[blockIter];   foreach (frustum in frustums, frustumMask <<= 1) { for (i = 0; i < gridCell->blockCounts[blockIter]; ++i) { u32 inside = intersect(frustum, block->postition[i]); masks[i] |= frustumMask & inside; } }   for (i = 0; i < gridCell->blockCounts[blockIter]; ++i) { // ïŹlter list here (if masks[i] is zero it should be skipped) // ... } } Tuesday, March 8, 2011
  • 22. Intersection Code bool intersect(const Plane* frustumPlanes, Vec4 pos) { ïŹ‚oat radius = pos.w; if (distance(frustumPlanes[Frustum::Far], pos) > radius) return false; if (distance(frustumPlanes[Frustum::Near], pos) > radius) return false; if (distance(frustumPlanes[Frustum::Right], pos) > radius) return false; if (distance(frustumPlanes[Frustum::Left], pos) > radius) return false; if (distance(frustumPlanes[Frustum::Upper], pos) > radius) return false; if (distance(frustumPlanes[Frustum::Lower], pos) > radius) return false;   return true; } Tuesday, March 8, 2011
  • 24. See “Typical C++ Bullshit” by @mike_acton Tuesday, March 8, 2011
  • 25. Intersection Code LHS! bool intersect(const Plane* frustumPlanes, Vec4 pos) Float branch! { float radius = pos.w; if (distance(frustumPlanes[Frustum::Far], pos) > radius) return So what do the consoles false; think? if (distance(frustumPlanes[Frustum::Near], pos) > radius) LHS! return false; if (distance(frustumPlanes[Frustum::Right], pos) >Float branch! :( radius) return false; if (distance(frustumPlanes[Frustum::Left], pos) > radius) return false; if (distance(frustumPlanes[Frustum::Upper], pos) > radius) LHS! return false; if (distance(frustumPlanes[Frustum::Lower], pos) > radius) return false; Float branch! return true; } LHS! Float branch! Tuesday, March 8, 2011
  • 26. Intersection Code bool intersect(const Plane* frustumPlanes, Vec4 pos) { float radius = pos.w; if (distance(frustumPlanes[Frustum::Far], pos) > radius) return false; if (distance(frustumPlanes[Frustum::Near], pos) > radius) return false; if (distance(frustumPlanes[Frustum::Right], pos) > radius) return false; if (distance(frustumPlanes[Frustum::Left], pos) > radius) return false; if (distance(frustumPlanes[Frustum::Upper], pos) > radius) return false; if (distance(frustumPlanes[Frustum::Lower], pos) > radius) return false; return true; } Tuesday, March 8, 2011
  • 27. Intersection Code â€șHow can we improve this? â€șDot products are not very SIMD friendly â€șUsually need to shuffle data around to get result â€ș(x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1) Tuesday, March 8, 2011
  • 28. Intersection Code â€șRearrange the data from AoS to SoA Vec 0 X0 Y0 Z0 W0 VecX X0 X1 X2 X3 Vec 1 X1 Y1 Z1 W1 VecY Y0 Y1 Y2 Y3 Vec 2 X2 Y2 Z2 W2 VecZ Z0 Z1 Z2 Z3 Vec 3 X3 Y3 Z3 W3 VecW W0 W1 W2 W3 â€șNow we only need 3 instructions for 4 dots! Tuesday, March 8, 2011
  • 29. Rearrange the frustum planes X0 X1 X2 X3 Plane 0 X0 Y0 Z0 W0 Y0 Y1 Y2 Y3 Plane 1 X1 Y1 Z1 W1 Z0 Z1 Z2 Z3 Plane 2 X2 Y2 Z2 W2 W0 W1 W2 W3 Plane 3 X3 Y3 Z3 W3 Plane 4 X4 Y4 Z4 W4 X4 X5 X4 X5 Plane 5 X5 Y5 Z5 W5 Y4 Y5 Y4 Y5 Z4 Z5 Z4 Z5 W4 W5 W4 W5 Tuesday, March 8, 2011
  • 30. New intersection code â€șTwo frustum vs Sphere intersections per loop â€ș4 * 3 dot products with 9 instructions â€șLoop over all frustums and merge the result Tuesday, March 8, 2011
  • 31. New intersection code (1/4) Vec posA_xxxx = vecShuffle<VecMask::_xxxx>(posA); Vec posA_yyyy = vecShuffle<VecMask::_yyyy>(posA); Vec posA_zzzz = vecShuffle<VecMask::_zzzz>(posA); Vec posA_rrrr = vecShuffle<VecMask::_wwww>(posA); // 4 dot products dotA_0123 = vecMulAdd(posA_zzzz, pl_z0z1z2z3, pl_w0w1w2w3); dotA_0123 = vecMulAdd(posA_yyyy, pl_y0y1y2y3, dotA_0123); dotA_0123 = vecMulAdd(posA_xxxx, pl_x0x1x2x3, dotA_0123); Tuesday, March 8, 2011
  • 32. New intersection code (2/4) Vec posB_xxxx = vecShuffle<VecMask::_xxxx>(posB); Vec posB_yyyy = vecShuffle<VecMask::_yyyy>(posB); Vec posB_zzzz = vecShuffle<VecMask::_zzzz>(posB); Vec posB_rrrr = vecShuffle<VecMask::_wwww>(posB); // 4 dot products dotB_0123 = vecMulAdd(posB_zzzz, pl_z0z1z2z3, pl_w0w1w2w3); dotB_0123 = vecMulAdd(posB_yyyy, pl_y0y1y2y3, dotB_0123); dotB_0123 = vecMulAdd(posB_xxxx, pl_x0x1x2x3, dotB_0123 Tuesday, March 8, 2011
  • 33. New intersection code (3/4) Vec posAB_xxxx = vecInsert<VecMask::_0011>(posA_xxxx, posB_xxxx); Vec posAB_yyyy = vecInsert<VecMask::_0011>(posA_yyyy, posB_yyyy); Vec posAB_zzzz = vecInsert<VecMask::_0011>(posA_zzzz, posB_zzzz); Vec posAB_rrrr = vecInsert<VecMask::_0011>(posA_rrrr, posB_rrrr); // 4 dot products dotA45B45 = vecMulAdd(posAB_zzzz, pl_z4z5z4z5, pl_w4w5w4w5); dotA45B45 = vecMulAdd(posAB_yyyy, pl_y4y5y4y5, dotA45B45); dotA45B45 = vecMulAdd(posAB_xxxx, pl_x4x5x4x5, dotA45B45); Tuesday, March 8, 2011
  • 34. New intersection code (4/4) // Compare against radius dotA_0123 = vecCmpGTMask(dotA_0123, posA_rrrr); dotB_0123 = vecCmpGTMask(dotB_0123, posB_rrrr); dotA45B45 = vecCmpGTMask(dotA45B45, posAB_rrrr); Vec dotA45 = vecInsert<VecMask::_0011>(dotA45B45, zero); Vec dotB45 = vecInsert<VecMask::_0011>(zero, dotA45B45); // collect the results Vec resA = vecOrx(dotA_0123); Vec resB = vecOrx(dotB_0123); resA = vecOr(resA, vecOrx(dotA45)); resB = vecOr(resB, vecOrx(dotB45)); // resA = inside or outside of frustum for point A, resB for point B Vec rA = vecNotMask(resA); Vec rB = vecNotMask(resB); masksCurrent[0] |= frustumMask & rA; masksCurrent[1] |= frustumMask & rB; Tuesday, March 8, 2011
  • 35. SPU Pipelining Assembler (SPA) â€șLike VCL (for PS2) but for PS3 SPU â€șCan give you that extra boost if needed â€șDoes software pipelining for you â€șGives about 35% speed boost in the culling â€șNot really that different from using intrinsics â€șAnd coding assembler is fun :) Tuesday, March 8, 2011
  • 36. SPA Inner loop (partly) lqd posA, -0x20(currentPos) lqd posB, -0x10(currentPos) shufb posA_xxxx, posA, posA, Mask_xxxx shufb posA_yyyy, posA, posA, Mask_yyyy shufb posA_zzzz, posA, posA, Mask_zzzz shufb posA_rrrr, posA, posA, Mask_wwww // 4 dot products fma dotA_0123, posA_zzzz, pl_z0z1z2z3, pl_w0w1w2w3 fma dotA_0123, posA_yyyy, pl_y0y1y2y3, dotA_0123 fma dotA_0123, posA_xxxx, pl_x0x1x2x3, dotA_0123 shufb posB_xxxx, posB, posB, Mask_xxxx shufb posB_yyyy, posB, posB, Mask_yyyy shufb posB_zzzz, posB, posB, Mask_zzzz shufb posB_rrrr, posB, posB, Mask_wwww // 4 dot products fma dotB_0123, posB_zzzz, pl_z0z1z2z3, pl_w0w1w2w3 fma dotB_0123, posB_yyyy, pl_y0y1y2y3, dotB_0123 fma dotB_0123, posB_xxxx, pl_x0x1x2x3, dotB_0123 Tuesday, March 8, 2011
  • 37. SPA Inner loop # Loop stats - frustumCull::loop # (ims enabled, sms disabled, optimisation level 2) # resmii : 24 (*) (resource constrained) # recmii : 2 (recurrence constrained) # resource usage: # even pipe : 24 inst. (100% use) (*) # FX[15] SP[9] # odd pipe : 24 inst. (100% use) (*) # SH[17] LS[6] BR[1] # misc: # linear schedule = 57 cycles (for information only) # software pipelining: # best pipelined schedule = 24 cycles (pipelined, 3 iterations in parallel) # software pipelining adjustments: # not generating non-pipelined loop since trip count >=3 (3) # estimated loop performance: # =24*n+59 cycles Tuesday, March 8, 2011
  • 38. _local_c0de000000000002: SPA Inner loop fma $46,$42,$30,$29; /* +1 */ shufb $47,$44,$37,$33 /* +2 */ fcgt $57,$20,$24; /* +2 */ orx $48,$15 /* +2 */ selb $55,$37,$44,$33; /* +2 */ shufb $56,$21,$16,$33 /* +1 */ fma $52,$16,$28,$41; /* +1 */ orx $49,$57 /* +2 */ ai $4,$4,32; orx $54,$47 /* +2 */ fma $51,$19,$26,$45; /* +1 */ orx $53,$55 /* +2 */ fma $50,$56,$27,$46; /* +1 */ shufb $24,$23,$23,$34 /* +1 */ ai $2,$2,32; /* +2 */ lqd $13,-32($4) or $69,$48,$54; /* +2 */ lqd $23,-16($4) fma $20,$18,$26,$52; /* +1 */ lqd $12,-32($2) /* +2 */ nor $60,$69,$69; /* +2 */ lqd $43,-16($2) /* +2 */ or $62,$49,$53; /* +2 */ shufb $59,$22,$17,$33 /* +1 */ and $39,$60,$35; /* +2 */ shufb $11,$14,$24,$33 /* +1 */ nor $61,$62,$60; /* +2 */ shufb $22,$13,$13,$36 fcgt $15,$51,$14; /* +1 */ shufb $17,$23,$23,$36 and $58,$61,$35; /* +2 */ shufb $19,$13,$13,$3 fma $10,$59,$25,$50; /* +1 */ shufb $18,$23,$23,$3 fma $9,$22,$32,$31; shufb $16,$23,$23,$38 or $8,$58,$43; /* +2 */ shufb $21,$13,$13,$38 or $40,$39,$12; /* +2 */ shufb $14,$13,$13,$34 ai $7,$7,-1; /* +2 */ shufb $42,$19,$18,$33 fma $41,$17,$32,$31; stqd $8,-16($2) /* +2 */ fcgt $44,$10,$11; /* +1 */ stqd $40,-32($2) /* +2 */ fma $45,$21,$28,$9; brnz $7,_local_c0de000000000002 /* +2 */ nop ; hbrr Tuesday, March 8, 2011
  • 39. Additional culling â€șFrustum vs AABB â€șProject AABB to screen space â€șSoftware Occlusion Tuesday, March 8, 2011
  • 40. Project AABB to screen space â€șCalculate the area of the AABB in screen space â€șIf area is smaller than setting just skip it â€șDue to FOV taking distance doesn’t work Tuesday, March 8, 2011
  • 41. Software Occlusion â€șUsed in Frostbite for 3 years â€șCross platform â€șArtist made occluders â€șTerrain Tuesday, March 8, 2011
  • 42. Why Software Occlusion? â€șWant to remove CPU time not just GPU â€șCull as early as possible â€șGPU queries troublesome as lagging behind CPU â€șMust support destruction â€șEasy for artists to control Tuesday, March 8, 2011
  • 43. Software Occlusion â€șSo how does it work? â€șRender PS1 style geometry to a zbuffer using software rendering â€șThe zbuffer is 256 x 114 ïŹ‚oat Tuesday, March 8, 2011
  • 44. Software Occlusion â€șOccluder triangle setup â€șTerrain triangle setup â€șRasterize triangles â€șCulling Tuesday, March 8, 2011
  • 49. Culling jobs Culling Jobs Job 0 Occluder Triangles Rasterize Triangles Culling Z-buffer Test Job 1 Occluder Triangles Rasterize Triangles Culling Z-buffer Test Job 2 Occluder Triangles Rasterize Triangles Culling Z-buffer Test Job 3 Occluder Triangles Rasterize Triangles Culling Z-buffer Test Job 4 Terrain Triangles Rasterize Triangles Culling Z-buffer Test Tuesday, March 8, 2011
  • 50. Occluder triangles Job 0 Inside, Project triangles Job 1 Inside, Project triangles Job 2 Intersecting, Clip, Project Job 3 Outside, Skip Output Tuesday, March 8, 2011
  • 51. Occluder triangles Rasterize Triangles Input 16 Triangles 16 Triangles 16 Triangles 16 Triangles 256 x 114 zbuffer 256 x 114 zbuffer 256 x 114 zbuffer Job 0 Job 1 Merge step <Todo: Fix Colors> Tuesday, March 8, 2011
  • 52. z-buffer testing â€șCalculate screen space AABB for object â€șGet single distance value â€șTest the square against the z-buffer Tuesday, March 8, 2011
  • 53. Conclusion â€șAccurate and high performance culling is essential â€șReduces pressure on low-level systems/rendering â€șIt’s all about data â€șSimple data often means simple code â€șUnderstanding your target hardware Tuesday, March 8, 2011
  • 54. Thanks to â€șAndreas Fredriksson (@deplinenoise) â€șChristina Coffin (@christinacoffin) â€șJohan Andersson (@repi) â€șStephen Hill (@self_shadow) â€șSteven Tovey (@nonchaotic) â€șHalldor Fannar â€șEvelyn Donis Tuesday, March 8, 2011
  • 55. Questions? Email: daniel@collin.com Blog: zenic.org Twitter: @daniel_collin Battlefield 3 & Frostbite 2 talks at GDC’11: Mon 1:45 DX11 Rendering in Battlefield 3 Johan Andersson Wed 10:30 SPU-based Deferred Shading in Battlefield 3 Christina Coffin for PlayStation 3 Wed 3:00 Culling the Battlefield: Data Oriented Design Daniel Collin in Practice Thu 1:30 Lighting You Up in Battlefield 3 Kenny Magnusson Fri 4:05 Approximating Translucency for a Fast, Colin BarrĂ©-Brisebois Cheap & Convincing Subsurface Scattering Look For more DICE talks: http://publications.dice.se Tuesday, March 8, 2011