PageSourceSearch

http://www.adriancourreges.com/blog/

html adriancourreges.com collected 2026-09-24 18:36:03 UTC 104,193 bytes, 3,156 lines download raw bytes

1
2<!DOCTYPE html>
3<!--[if IEMobile 7 ]><html class="no-js iem7"><![endif]-->
4<!--[if lt IE 9]><html class="no-js lte-ie8"><![endif]-->
5<!--[if (gt IE 8)|(gt IEMobile 7)|!(IEMobile)|!(IE)]><!--><html class="no-js" lang="en"><!--<![endif]-->
6<head>
7  <meta charset="utf-8">
8  <title>Adrian Courrèges</title>
9  <meta name="author" content="Adrian Courrèges">
10
11  
12  <meta name="description" content="Rendering in games can be a complex topic, different approaches with their own tradeoffs are available,
13new techniques arise, others fall out of &hellip;">
14  
15
16	<link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png">
17	<link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png">
18	<link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png">
19	<link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png">
20	<link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png">
21	<link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png">
22	<link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png">
23	<link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png">
24	<link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png">
25	<link rel="icon" type="image/png" sizes="192x192"  href="/android-icon-192x192.png">
26	<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
27	<link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png">
28	<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
29	<link rel="manifest" href="/manifest.json">
30	<meta name="msapplication-TileColor" content="#ffffff">
31	<meta name="msapplication-TileImage" content="/ms-icon-144x144.png">
32	<meta name="theme-color" content="#ffffff">
33
34  <!-- http://t.co/dKP3o1e -->
35  <meta name="HandheldFriendly" content="True">
36  <meta name="MobileOptimized" content="320">
37  <meta name="viewport" content="width=device-width, initial-scale=1">
38  
39  
40  
41  
42  
43  <meta property="og:locale" content="en_US" />
44  <meta property="og:type" content="article" />
45  <meta property="og:title" content="Adrian Courrèges" />
46  <meta property="og:description" content="Rendering in games can be a complex topic, different approaches with their own tradeoffs are available,
47new techniques arise, others fall out of &hellip;" />
48  <meta property="og:url" content="http://www.adriancourreges.com/blog/" />
49  <meta property="og:site_name" content="Adrian Courrèges" />
50  
51  <meta name="twitter:site" content="@ado_tan" />
52  <meta name="twitter:creator" content="@ado_tan" />
53  <meta name="twitter:title" content="Adrian Courrèges" />
54  <meta name="twitter:description" content="Rendering in games can be a complex topic, different approaches with their own tradeoffs are available,
55new techniques arise, others fall out of &hellip;" />
56  
57  
58   <meta name="twitter:card" content="summary" />
59   <meta name="twitter:image" content="http://www.adriancourreges.com/favicon-96x96.png" />
60   <meta property="og:image"  content="http://www.adriancourreges.com/favicon-96x96.png" />
61  
62  
63
64  <link rel="canonical" href="http://www.adriancourreges.com/blog/">
65  <link href="/favicon.ico" rel="icon">
66  <link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css">
67  <link href="/atom.xml" rel="alternate" title="Adrian Courrèges" type="application/atom+xml">
68  
68<script src="/javascripts/modernizr-2.0.js"></script>
68
69  
69<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
69
70  
70<script>!window.jQuery && document.write(unescape('%3Cscript src="./javascripts/lib/jquery.min.js"%3E%3C/script%3E'))</script>
70
71  
71<script src="/javascripts/octopress.js" type="text/javascript"></script>
71
72  <!--Fonts from Google"s Web font directory at http://google.com/webfonts -->
73<!-- <link href="https://fonts.googleapis.com/css?family=PT+Serif:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css"> -->
74<link href="https://fonts.googleapis.com/css?family=PT+Sans:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css">
75
76
77  
78  
78<script type="text/javascript">
79    var _gaq = _gaq || [];
80    _gaq.push(['_setAccount', 'UA-10661328-1']);
81    _gaq.push(['_trackPageview']);
82
83    (function() {
84      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
85      ga.src = 'https://www.google-analytics.com/ga.js';
86      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
87    })();
88  </script>
88
89
90
91</head>
92
93<body   >
94  <header role="banner"><hgroup>
95  
96  <h1>Adrian <br/>Courrèges</h1>
97  
98  
99  
100</hgroup>
101
102</header>
103  <nav role="navigation">
104  
105<ul class="main-navigation">
106  <!-- <li><a href="/">Home</a></li>  -->
107  <li><a href="/projects/">Projects</a></li>
108  <li><a href="/blog/">Blog</a></li>
109  <li><a href="/about/">About</a></li>
110</ul>
111
112</nav>
113  <div id="main">
114    <div id="content">
115      <div class="blog-index">
116  
117  
118  
119    <article>
120      
121  <header>
122    
123      <h1 class="entry-title"><a href="/blog/2020/12/29/graphics-studies-compilation/">Graphics Studies Compilation</a></h1>
124    
125    
126      <p class="meta">
127        
128
129
130
131
132
133
134
135
136  
137
138
139<time datetime="2020-12-29T22:05:00+01:00" pubdate data-updated="true">Dec 29<span>th</span>, 2020</time>
140        
141      </p>
142    
143  </header>
144
145
146  <div class="entry-content"><p><img class="right" src="/img/blog/2020/gfx/gfx_studies.jpg" width="500"/></p>
147
148<p>Rendering in games can be a complex topic, different approaches with their own tradeoffs are available,
149new techniques arise, others fall out of fashion&hellip;
150Studios using in-house engines need to make choices that will fit the type of game they&rsquo;re aiming for.<br/>
151It can be very interesting to know which decisions were actually made to ship the final product, what worked and what didn&rsquo;t.</p>
152
153<p>There are several resources available online detailing game post-mortems, whether it&rsquo;s
154<a href="https://en.wikipedia.org/wiki/Game_Developers_Conference">GDC</a> /
155<a href="https://en.wikipedia.org/wiki/SIGGRAPH">Siggraph</a> talks
156or even content hosted by game studios themselves.<br/>
157But not everything is available: public documentation requires time and effort, with little
158direct return-on-investment for the studio besides good PR among developers. And that&rsquo;s when the
159company doesn&rsquo;t simply prohibit employees from disclosing any information publicly.</p>
160
161<p>Below is a collection of frame breakdowns I gathered online (including a few of mines), all written by volunteers
162and enthusiasts who decided to reverse-engineer some games and document their findings.</p>
163
164<div><style>
165.property_table td {
166    vertical-align: middle !important; 
167    line-height: 1.0;
168}
169.property_table tbody tr td:nth-child(2) div {
170    display: block;
171    max-width: 114px;
172    min-width: 50px;
173    margin-top: 0px;
174    overflow: hidden;
175    box-shadow: rgba(0,0,0,0.15) 0 1px 4px;
176}
177.property_table tbody tr td:nth-child(2) img {
178    border: none !important;
179    max-width: 100%;
180    max-height: 100%;
181    display: block;
182    transition: transform 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94);
183    transform: scale(1.0);
184}
185.property_table tbody tr td:nth-child(2) img:hover {
186    transform: scale(1.1);
187}
188.property_table tbody tr td:nth-child(3) {
189  font-style: italic;
190}
191.property_table tbody tr td:nth-child(4) {
192    font-size: 115%;
193    font-weight: bold;
194}
195.sortable_header div {
196    transition: background 0.1s;
197}
198.sortable_header:hover div{
199    background: linear-gradient(#7b7b7b,#373737);
200}
201</style></div>
202
203
204
205
206<div class="auto_scroll_x" style="margin-bottom: 1.5em;">
207<table class="property_table">
208    <thead>
209        <tr>
210            <th id="gfxstudies_gamerelease"><div>Game&nbsp;Release&nbsp;<span class="column_sort">&#9660;</span> </div></th>
211            <th id="gfxstudies_gametitle" colspan="2"><div>Game&nbsp;Title&nbsp;<span class="column_sort">&#9660;</span> </div></th>
212            <th><div> Link </div></th>
213            <th id="gfxstudies_author"><div>Author&nbsp;<span class="column_sort">&#9660;</span> </div></th>
214            <th id="gfxstudies_published"><div>Published&nbsp;<span class="column_sort">&#9660;</span> </div></th>
215        </tr>
216    </thead>
217    <tbody id="gfxstudies_list">
218        
219
220    <tr>
221    
222        <td class="gfxstudies_gamerelease"> 2002/12/13 </td>
223        
224        <td>    
225            <div style="border-radius: 0.3em;"> 
226                <img src="/img/blog/2020/gfx/zeldaww.jpg"> 
227            </div> 
228        </td>
229        
230        <td class="gfxstudies_gametitle"> Zelda - Wind Waker (GC) </td>
231        
232        <td style="white-space: nowrap;"> 
233          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://medium.com/@gordonnl/wind-waker-graphics-analysis-a0b575a31127" target="_blank">Analysis</a></span>
234        </td>
235        
236        <td class="gfxstudies_author" style="white-space: nowrap;"> 
237          by <a style="white-space: nowrap;" href="https://cinemont.com" target="_blank">Nathan Gordon</a> 
238        </td>            
239        
240        <td class="gfxstudies_published"> 2016/11/06 </td>
241        
242    </tr>
243
244    <tr>
245    
246        <td class="gfxstudies_gamerelease"> 2002/12/13 </td>
247        
248        <td>    
249            <div style="border-radius: 0.3em;"> 
250                <img src="/img/blog/2020/gfx/zeldaww.jpg"> 
251            </div> 
252        </td>
253        
254        <td class="gfxstudies_gametitle"> Zelda - Wind Waker (GC) </td>
255        
256        <td style="white-space: nowrap;"> 
257          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://polycount.com/discussion/104415/zelda-wind-waker-tech-and-texture-analysis-picture-heavy" target="_blank">Analysis</a></span>
258        </td>
259        
260        <td class="gfxstudies_author" style="white-space: nowrap;"> 
261          by <a style="white-space: nowrap;" href="https://www.artstation.com/warby" target="_blank">Soenke Seidel</a> 
262        </td>            
263        
264        <td class="gfxstudies_published"> 2012/08/23 </td>
265        
266    </tr>
267
268    <tr>
269    
270        <td class="gfxstudies_gamerelease"> 2005/10/18 </td>
271        
272        <td>    
273            <div style="border-radius: 0.3em;"> 
274                <img src="/img/blog/2020/gfx/sotc.jpg"> 
275            </div> 
276        </td>
277        
278        <td class="gfxstudies_gametitle"> Shadow of the Colossus (PS2) </td>
279        
280        <td style="white-space: nowrap;"> 
281          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://www.froyok.fr/blog/2012-10-breakdown-shadow-of-the-colossus-pal-ps2/" target="_blank">Analysis</a></span>
282        </td>
283        
284        <td class="gfxstudies_author" style="white-space: nowrap;"> 
285          by <a style="white-space: nowrap;" href="https://www.froyok.fr" target="_blank">
285Léna Piquet</a> 
286        </td>            
287        
288        <td class="gfxstudies_published"> 2012/10/07 </td>
289        
290    </tr>
291
292    <tr>
293    
294        <td class="gfxstudies_gamerelease"> 2007/02/16 </td>
295        
296        <td>    
297            <div style="border-radius: 0.3em;"> 
298                <img src="/img/blog/2020/gfx/supcom.jpg"> 
299            </div> 
300        </td>
301        
302        <td class="gfxstudies_gametitle"> Supreme Commander </td>
303        
304        <td style="white-space: nowrap;"> 
305          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="http://www.adriancourreges.com/blog/2015/06/23/supreme-commander-graphics-study/" target="_blank">Analysis</a></span>
306        </td>
307        
308        <td class="gfxstudies_author" style="white-space: nowrap;"> 
309          by <a style="white-space: nowrap;" href="http://www.adriancourreges.com/" target="_blank">Adrian Courrèges</a> 
310        </td>            
311        
312        <td class="gfxstudies_published"> 2015/06/23 </td>
313        
314    </tr>
315
316    <tr>
317    
318        <td class="gfxstudies_gamerelease"> 2009/11/17 </td>
319        
320        <td>    
321            <div style="border-radius: 0.3em;"> 
322                <img src="/img/blog/2020/gfx/assassinscreed2.jpg"> 
323            </div> 
324        </td>
325        
326        <td class="gfxstudies_gametitle"> Assassin&#8217;s Creed II </td>
327        
328        <td style="white-space: nowrap;"> 
329          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://www.froyok.fr/blog/2015-12-breakdown-assassins-creed-ii-2/" target="_blank">Analysis</a></span>
330        </td>
331        
332        <td class="gfxstudies_author" style="white-space: nowrap;"> 
333          by <a style="white-space: nowrap;" href="https://www.froyok.fr" target="_blank">Léna Piquet</a> 
334        </td>            
335        
336        <td class="gfxstudies_published"> 2015/12/05 </td>
337        
338    </tr>
339
340    <tr>
341    
342        <td class="gfxstudies_gamerelease"> 2011/08/23 </td>
343        
344        <td>    
345            <div style="border-radius: 0.3em;"> 
346                <img src="/img/blog/2020/gfx/dehr.jpg"> 
347            </div> 
348        </td>
349        
350        <td class="gfxstudies_gametitle"> Deus Ex: Human Revolution </td>
351        
352        <td style="white-space: nowrap;"> 
353          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="http://www.adriancourreges.com/blog/2015/03/10/deus-ex-human-revolution-graphics-study/" target="_blank">Analysis</a></span>
354        </td>
355        
356        <td class="gfxstudies_author" style="white-space: nowrap;"> 
357          by <a style="white-space: nowrap;" href="http://www.adriancourreges.com/" target="_blank">Adrian Courrèges</a> 
358        </td>            
359        
360        <td class="gfxstudies_published"> 2015/03/10 </td>
361        
362    </tr>
363
364    <tr>
365    
366        <td class="gfxstudies_gamerelease"> 2011/10/18 </td>
367        
368        <td>    
369            <div style="border-radius: 0.3em;"> 
370                <img src="/img/blog/2020/gfx/batmanac.jpg"> 
371            </div> 
372        </td>
373        
374        <td class="gfxstudies_gametitle"> Batman: Arkham City </td>
375        
376        <td style="white-space: nowrap;"> 
377          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://www.froyok.fr/blog/2012-09-breakdown-batman-arkham-city/" target="_blank">Analysis</a></span>
378        </td>
379        
380        <td class="gfxstudies_author" style="white-space: nowrap;"> 
381          by <a style="white-space: nowrap;" href="https://www.froyok.fr" target="_blank">Léna Piquet</a> 
382        </td>            
383        
384        <td class="gfxstudies_published"> 2012/09/21 </td>
385        
386    </tr>
387
388    <tr>
389    
390        <td class="gfxstudies_gamerelease"> 2012/02/21 </td>
391        
392        <td>    
393            <div style="border-radius: 0.3em;"> 
394                <img src="/img/blog/2020/gfx/syndicate2012.jpg"> 
395            </div> 
396        </td>
397        
398        <td class="gfxstudies_gametitle"> Syndicate (2012) </td>
399        
400        <td style="white-space: nowrap;"> 
401          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://www.froyok.fr/blog/2024-01-breakdown-syndicate/" target="_blank">Analysis</a></span>
402        </td>
403        
404        <td class="gfxstudies_author" style="white-space: nowrap;"> 
405          by <a style="white-space: nowrap;" href="https://www.froyok.fr" target="_blank">
405Léna Piquet</a> 
406        </td>            
407        
408        <td class="gfxstudies_published"> 2024/01/31 </td>
409        
410    </tr>
411
412    <tr>
413    
414        <td class="gfxstudies_gamerelease"> 2013/09/17 </td>
415        
416        <td>    
417            <div style="border-radius: 0.3em;"> 
418                <img src="/img/blog/2020/gfx/gtav.jpg"> 
419            </div> 
420        </td>
421        
422        <td class="gfxstudies_gametitle"> GTA V </td>
423        
424        <td style="white-space: nowrap;"> 
425          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="http://www.adriancourreges.com/blog/2015/11/02/gta-v-graphics-study/" target="_blank">Analysis</a></span>
426        </td>
427        
428        <td class="gfxstudies_author" style="white-space: nowrap;"> 
429          by <a style="white-space: nowrap;" href="http://www.adriancourreges.com/" target="_blank">Adrian Courrèges</a> 
430        </td>            
431        
432        <td class="gfxstudies_published"> 2015/11/02 </td>
433        
434    </tr>
435
436    <tr>
437    
438        <td class="gfxstudies_gamerelease"> 2014/02/25 </td>
439        
440        <td>    
441            <div style="border-radius: 0.3em;"> 
442                <img src="/img/blog/2020/gfx/clos2.jpg"> 
443            </div> 
444        </td>
445        
446        <td class="gfxstudies_gametitle"> Castlevania: Lords of Shadow 2 </td>
447        
448        <td style="white-space: nowrap;"> 
449          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="http://www.elopezr.com/castlevania-lords-of-shadow-2-graphics-study/" target="_blank">Analysis</a></span>
450        </td>
451        
452        <td class="gfxstudies_author" style="white-space: nowrap;"> 
453          by <a style="white-space: nowrap;" href="http://www.elopezr.com" target="_blank">Emilio López</a> 
454        </td>            
455        
456        <td class="gfxstudies_published"> 2015/11/28 </td>
457        
458    </tr>
459
460    <tr>
461    
462        <td class="gfxstudies_gamerelease"> 2014/09/30 </td>
463        
464        <td>    
465            <div style="border-radius: 0.3em;"> 
466                <img src="/img/blog/2020/gfx/mesom.jpg"> 
467            </div> 
468        </td>
469        
470        <td class="gfxstudies_gametitle"> Middle-earth: Shadow of Mordor </td>
471        
472        <td style="white-space: nowrap;"> 
473          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="http://www.elopezr.com/the-rendering-of-middle-earth-shadow-of-mordor/" target="_blank">Analysis</a></span>
474        </td>
475        
476        <td class="gfxstudies_author" style="white-space: nowrap;"> 
477          by <a style="white-space: nowrap;" href="http://www.elopezr.com" target="_blank">Emilio López</a> 
478        </td>            
479        
480        <td class="gfxstudies_published"> 2017/12/27 </td>
481        
482    </tr>
483
484    <tr>
485    
486        <td class="gfxstudies_gamerelease"> 2014/10/06 </td>
487        
488        <td>    
489            <div style="border-radius: 0.3em;"> 
490                <img src="/img/blog/2020/gfx/alienisolation.jpg"> 
491            </div> 
492        </td>
493        
494        <td class="gfxstudies_gametitle"> Alien Isolation </td>
495        
496        <td style="white-space: nowrap;"> 
497          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://gen-graphics.blogspot.com/2018/01/inside-alien-isolation-graphics.html" target="_blank">Analysis</a></span>
498        </td>
499        
500        <td class="gfxstudies_author" style="white-space: nowrap;"> 
501          by <a style="white-space: nowrap;" href="https://gen-graphics.blogspot.com/" target="_blank">Gen Afanasev</a> 
502        </td>            
503        
504        <td class="gfxstudies_published"> 2018/01/16 </td>
505        
506    </tr>
507
508    <tr>
509    
510        <td class="gfxstudies_gamerelease"> 2015/05/18 </td>
511        
512        <td>    
513            <div style="border-radius: 0.3em;"> 
514                <img src="/img/blog/2020/gfx/witcher3.jpg"> 
515            </div> 
516        </td>
517        
518        <td class="gfxstudies_gametitle"> The Witcher 3: Wild Hunt </td>
519        
520        <td style="white-space: nowrap;"> 
521          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://astralcode.blogspot.com/2018/11/reverse-engineering-rendering-of.html" target="_blank">Analysis</a></span>
522        </td>
523        
524        <td class="gfxstudies_author" style="white-space: nowrap;"> 
525          by <a style="white-space: nowrap;" href="https://astralcode.blogspot.com/" target="_blank">Mateusz / Astralis</a> 
526        </td>            
527        
528        <td class="gfxstudies_published"> 2017/09/07 </td>
529        
530    </tr>
531
532    <tr>
533    
534        <td class="gfxstudies_gamerelease"> 2015/06/23 </td>
535        
536        <td>    
537            <div style="border-radius: 0.3em;"> 
538                <img src="/img/blog/2020/gfx/batmanak.jpg"> 
539            </div> 
540        </td>
541        
542        <td class="gfxstudies_gametitle"> Batman: Arkham Knight </td>
543        
544        <td style="white-space: nowrap;"> 
545          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="http://morad.in/2020/04/03/unmasking-arkham-knight/" target="_blank">Analysis</a></span>
546        </td>
547        
548        <td class="gfxstudies_author" style="white-space: nowrap;"> 
549          by <a style="white-space: nowrap;" href="http://morad.in" target="_blank">Balázs Török</a> 
550        </td>            
551        
552        <td class="gfxstudies_published"> 2020/04/03 </td>
553        
554    </tr>
555
556    <tr>
557    
558        <td class="gfxstudies_gamerelease"> 2015/09/01 </td>
559        
560        <td>    
561            <div style="border-radius: 0.3em;"> 
562                <img src="/img/blog/2020/gfx/mgsv.jpg"> 
563            </div> 
564        </td>
565        
566        <td class="gfxstudies_gametitle"> Metal Gear Solid V:<br/>The Phantom Pain </td>
567        
568        <td style="white-space: nowrap;"> 
569          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;
569<a href="http://www.adriancourreges.com/blog/2017/12/15/mgs-v-graphics-study/" target="_blank">Analysis</a></span>
570        </td>
571        
572        <td class="gfxstudies_author" style="white-space: nowrap;"> 
573          by <a style="white-space: nowrap;" href="http://www.adriancourreges.com/" target="_blank">Adrian Courrèges</a> 
574        </td>            
575        
576        <td class="gfxstudies_published"> 2017/12/15 </td>
577        
578    </tr>
579
580    <tr>
581    
582        <td class="gfxstudies_gamerelease"> 2015/11/10 </td>
583        
584        <td>    
585            <div style="border-radius: 0.3em;"> 
586                <img src="/img/blog/2020/gfx/rottr.jpg"> 
587            </div> 
588        </td>
589        
590        <td class="gfxstudies_gametitle"> Rise of the Tomb Raider </td>
591        
592        <td style="white-space: nowrap;"> 
593          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="http://www.elopezr.com/the-rendering-of-rise-of-the-tomb-raider/" target="_blank">Analysis</a></span>
594        </td>
595        
596        <td class="gfxstudies_author" style="white-space: nowrap;"> 
597          by <a style="white-space: nowrap;" href="http://www.elopezr.com" target="_blank">Emilio López</a> 
598        </td>            
599        
600        <td class="gfxstudies_published"> 2018/12/31 </td>
601        
602    </tr>
603
604    <tr>
605    
606        <td class="gfxstudies_gamerelease"> 2015/12/16 </td>
607        
608        <td>    
609            <div style="border-radius: 0.3em;"> 
610                <img src="/img/blog/2020/gfx/waves2n.jpg"> 
611            </div> 
612        </td>
613        
614        <td class="gfxstudies_gametitle"> Waves 2: Notorious </td>
615        
616        <td style="white-space: nowrap;"> 
617          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://pixelalchemy.dev/posts/a-frame-of-waves-2/" target="_blank">Analysis</a></span>
618        </td>
619        
620        <td class="gfxstudies_author" style="white-space: nowrap;"> 
621          by <a style="white-space: nowrap;" href="https://pixelalchemy.dev" target="_blank">David Maas</a> 
622        </td>            
623        
624        <td class="gfxstudies_published"> 2022/09/21 </td>
625        
626    </tr>
627
628    <tr>
629    
630        <td class="gfxstudies_gamerelease"> 2016/01/26 </td>
631        
632        <td>    
633            <div style="border-radius: 0.3em;"> 
634                <img src="/img/blog/2020/gfx/witness.jpg"> 
635            </div> 
636        </td>
637        
638        <td class="gfxstudies_gametitle"> The Witness </td>
639        
640        <td style="white-space: nowrap;"> 
641          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://blog.thomaspoulet.fr/the-witness-frame-part-1/" target="_blank">Analysis</a></span>
642        </td>
643        
644        <td class="gfxstudies_author" style="white-space: nowrap;"> 
645          by <a style="white-space: nowrap;" href="https://blog.thomaspoulet.fr" target="_blank">Thomas Poulet</a> 
646        </td>            
647        
648        <td class="gfxstudies_published"> 2017/08/21 </td>
649        
650    </tr>
651
652    <tr>
653    
654        <td class="gfxstudies_gamerelease"> 2016/05/13 </td>
655        
656        <td>    
657            <div style="border-radius: 0.3em;"> 
658                <img src="/img/blog/2020/gfx/doom2016.jpg"> 
659            </div> 
660        </td>
661        
662        <td class="gfxstudies_gametitle"> DOOM 2016 </td>
663        
664        <td style="white-space: nowrap;"> 
665          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="http://www.adriancourreges.com/blog/2016/09/09/doom-2016-graphics-study/" target="_blank">Analysis</a></span>
666        </td>
667        
668        <td class="gfxstudies_author" style="white-space: nowrap;"> 
669          by <a style="white-space: nowrap;" href="http://www.adriancourreges.com/" target="_blank">Adrian Courrèges</a> 
670        </td>            
671        
672        <td class="gfxstudies_published"> 2016/09/09 </td>
673        
674    </tr>
675
676    <tr>
677    
678        <td class="gfxstudies_gamerelease"> 2016/05/24 </td>
679        
680        <td>    
681            <div style="border-radius: 0.3em;"> 
682                <img src="/img/blog/2020/gfx/overwatch.jpg"> 
683            </div> 
684        </td>
685        
686        <td class="gfxstudies_gametitle"> Overwatch </td>
687        
688        <td style="white-space: nowrap;"> 
689          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://alain.xyz/blog/frame-analysis-overwatch" target="_blank">Analysis</a></span>
690        </td>
691        
692        <td class="gfxstudies_author" style="white-space: nowrap;"> 
693          by <a style="white-space: nowrap;" href="https://alain.xyz" target="_blank">Alain Galvan</a> 
694        </td>            
695        
696        <td class="gfxstudies_published"> 2020/04/13 </td>
697        
698    </tr>
699
700    <tr>
701    
702        <td class="gfxstudies_gamerelease"> 2016/12/06 </td>
703        
704        <td>    
705            <div style="border-radius: 0.3em;"> 
706                <img src="/img/blog/2020/gfx/stbots.jpg"> 
707            </div> 
708        </td>
709        
710        <td class="gfxstudies_gametitle"> Shadow Tactics:<br/>Blades of the Shogun </td>
711        
712        <td style="white-space: nowrap;"> 
713          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://kosmonautblog.wordpress.com/2017/01/09/shadow-tactics-rendering-breakdown/" target="_blank">Analysis</a></span>
714        </td>
715        
716        <td class="gfxstudies_author" style="white-space: nowrap;"> 
717          by <a style="white-space: nowrap;" href="https://kosmonautblog.wordpress.com" target="_blank">Kosmonaut</a> 
718        </td>            
719        
720        <td class="gfxstudies_published"> 2017/01/09 </td>
721        
722    </tr>
723
724    <tr>
725    
726        <td class="gfxstudies_gamerelease"> 2017/08/01 </td>
727        
728        <td>    
729            <div style="border-radius: 0.3em;"> 
730                <img src="/img/blog/2020/gfx/slimerancher.jpg"> 
731            </div> 
732        </td>
733        
734        <td class="gfxstudies_gametitle"> Slime Rancher </td>
735        
736        <td style="white-space: nowrap;"> 
737          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://pixelalchemy.dev/posts/a-frame-of-slime-rancher/" target="_blank">Analysis</a></span>
738        </td>
739        
740        <td class="gfxstudies_author" style="white-space: nowrap;"> 
741          by <a style="white-space: nowrap;" href="https://pixelalchemy.dev" target="_blank">David Maas</a> 
742        </td>            
743        
744        <td class="gfxstudies_published"> 2022/12/07 </td>
745        
746    </tr>
747
748    <tr>
749    
750        <td class="gfxstudies_gamerelease"> 2018/05/25 </td>
751        
752        <td>    
753            <div style="border-radius: 0.3em;"> 
754                <img src="/img/blog/2020/gfx/detroitbecomehuman.jpg"> 
755            </div> 
756        </td>
757        
758        <td class="gfxstudies_gametitle"> Detroit: Become Human </td>
759        
760        <td style="white-space: nowrap;"> 
761          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://mamoniem.com/behind-the-pretty-frames-detroit-become-human/" target="_blank">Analysis</a></span>
762        </td>
763        
764        <td class="gfxstudies_author" style="white-space: nowrap;"> 
765          by <a style="white-space: nowrap;" href="https://www.mamoniem.com/" target="_blank">M. A. Moniem</a> 
766        </td>            
767        
768        <td class="gfxstudies_published"> 2024/11/27 </td>
769        
770    </tr>
771
772    <tr>
773    
774        <td class="gfxstudies_gamerelease"> 2018/06/12 </td>
775        
776        <td>    
777            <div style="border-radius: 0.3em;"> 
778                <img src="/img/blog/2020/gfx/jwe.jpg"> 
779            </div> 
780        </td>
781        
782        <td class="gfxstudies_gametitle"> Jurassic World Evolution </td>
783        
784        <td style="white-space: nowrap;"> 
785          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="http://www.elopezr.com/the-rendering-of-jurassic-world-evolution/" target="_blank">Analysis</a></span>
786        </td>
787        
788        <td class="gfxstudies_author" style="white-space: nowrap;"> 
789          by <a style="white-space: nowrap;" href="http://www.elopezr.com" target="_blank">Emilio López</a> 
790        </td>            
791        
792        <td class="gfxstudies_published"> 2021/03/12 </td>
793        
794    </tr>
795
796    <tr>
797    
798        <td class="gfxstudies_gamerelease"> 2018/08/01 </td>
799        
800        <td>    
801            <div style="border-radius: 0.3em;"> 
802                <img src="/img/blog/2020/gfx/yakuza0.jpg"> 
803            </div> 
804        </td>
805        
806        <td class="gfxstudies_gametitle"> Yakuza 0 </td>
807        
808        <td style="white-space: nowrap;"> 
809          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://cookieplmonster.github.io/2019/02/24/yakuza-0-fixing-attempts/" target="_blank">Analysis</a></span>
810        </td>
811        
812        <td class="gfxstudies_author" style="white-space: nowrap;"> 
813          by <a style="white-space: nowrap;" href="https://cookieplmonster.github.io/" target="_blank">Silent</a> 
814        </td>            
815        
816        <td class="gfxstudies_published"> 2019/02/24 </td>
817        
818    </tr>
819
820    <tr>
821    
822        <td class="gfxstudies_gamerelease"> 2018/09/14 </td>
823        
824        <td>    
825            <div style="border-radius: 0.3em;"> 
826                <img src="/img/blog/2020/gfx/sottr.jpg"> 
827            </div> 
828        </td>
829        
830        <td class="gfxstudies_gametitle"> Shadow of the Tomb Raider </td>
831        
832        <td style="white-space: nowrap;"> 
833          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="http://morad.in/2019/04/19/under-the-hood-of-shadow-of-the-tomb-raider/" target="_blank">Analysis</a></span>
834        </td>
835        
836        <td class="gfxstudies_author" style="white-space: nowrap;"> 
837          by <a style="white-space: nowrap;" href="http://morad.in" target="_blank">Balázs Török</a> 
838        </td>            
839        
840        <td class="gfxstudies_published"> 2019/04/19 </td>
841        
842    </tr>
843
844    <tr>
845    
846        <td class="gfxstudies_gamerelease"> 2018/10/26 </td>
847        
848        <td>    
849            <div style="border-radius: 0.3em;"> 
850                <img src="/img/blog/2020/gfx/rdr2.jpg"> 
851            </div> 
852        </td>
853        
854        <td class="gfxstudies_gametitle"> Red Dead Redemption 2 </td>
855        
856        <td style="white-space: nowrap;"> 
857          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://imgeself.github.io/posts/2020-06-19-graphics-study-rdr2/" target="_blank">Analysis</a></span>
858        </td>
859        
860        <td class="gfxstudies_author" style="white-space: nowrap;"> 
861          by <a style="white-space: nowrap;" href="https://imgeself.github.io/" target="_blank">Hüseyin</a> 
862        </td>            
863        
864        <td class="gfxstudies_published"> 2020/06/19 </td>
865        
866    </tr>
867
868    <tr>
869    
870        <td class="gfxstudies_gamerelease"> 2018/11/07 </td>
871        
872        <td>    
873            <div style="border-radius: 0.3em;"> 
874                <img src="/img/blog/2020/gfx/ninokuni2.jpg"> 
875            </div> 
876        </td>
877        
878        <td class="gfxstudies_gametitle"> Ni No Kuni 2 </td>
879        
880        <td style="white-space: nowrap;"> 
881          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://blog.thomaspoulet.fr/ninokuni2-frame/" target="_blank">Analysis</a></span>
882        </td>
883        
884        <td class="gfxstudies_author" style="white-space: nowrap;"> 
885          by <a style="white-space: nowrap;" href="https://blog.thomaspoulet.fr" target="_blank">
885Thomas Poulet</a> 
886        </td>            
887        
888        <td class="gfxstudies_published"> 2017/08/21 </td>
889        
890    </tr>
891
892    <tr>
893    
894        <td class="gfxstudies_gamerelease"> 2019/01/25 </td>
895        
896        <td>    
897            <div style="border-radius: 0.3em;"> 
898                <img src="/img/blog/2020/gfx/re2r.jpg"> 
899            </div> 
900        </td>
901        
902        <td class="gfxstudies_gametitle"> Resident Evil 2 (Remake) </td>
903        
904        <td style="white-space: nowrap;"> 
905          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://aschrein.github.io/2019/08/01/re2_breakdown.html" target="_blank">Analysis</a></span>
906        </td>
907        
908        <td class="gfxstudies_author" style="white-space: nowrap;"> 
909          by <a style="white-space: nowrap;" href="https://aschrein.github.io/" target="_blank">Anton Schreiner</a> 
910        </td>            
911        
912        <td class="gfxstudies_published"> 2019/08/01 </td>
913        
914    </tr>
915
916    <tr>
917    
918        <td class="gfxstudies_gamerelease"> 2019/01/25 </td>
919        
920        <td>    
921            <div style="border-radius: 0.3em;"> 
922                <img src="/img/blog/2020/gfx/re2r.jpg"> 
923            </div> 
924        </td>
925        
926        <td class="gfxstudies_gametitle"> Resident Evil 2 (Remake) </td>
927        
928        <td style="white-space: nowrap;"> 
929          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://www.mamoniem.com/behind-the-pretty-frames-resident-evil/" target="_blank">Analysis</a></span>
930        </td>
931        
932        <td class="gfxstudies_author" style="white-space: nowrap;"> 
933          by <a style="white-space: nowrap;" href="https://www.mamoniem.com/" target="_blank">M. A. Moniem</a> 
934        </td>            
935        
936        <td class="gfxstudies_published"> 2022/07/20 </td>
937        
938    </tr>
939
940    <tr>
941    
942        <td class="gfxstudies_gamerelease"> 2019/02/15 </td>
943        
944        <td>    
945            <div style="border-radius: 0.3em;"> 
946                <img src="/img/blog/2020/gfx/metroexodus.jpg"> 
947            </div> 
948        </td>
949        
950        <td class="gfxstudies_gametitle"> Metro Exodus </td>
951        
952        <td style="white-space: nowrap;"> 
953          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="http://morad.in/2019/03/27/observations-about-the-rendering-of-metro-exodus/" target="_blank">Analysis</a></span>
954        </td>
955        
956        <td class="gfxstudies_author" style="white-space: nowrap;"> 
957          by <a style="white-space: nowrap;" href="http://morad.in" target="_blank">Balázs Török</a> 
958        </td>            
959        
960        <td class="gfxstudies_published"> 2019/03/27 </td>
961        
962    </tr>
963
964    <tr>
965    
966        <td class="gfxstudies_gamerelease"> 2019/02/15 </td>
967        
968        <td>    
969            <div style="border-radius: 0.3em;"> 
970                <img src="/img/blog/2020/gfx/metroexodus.jpg"> 
971            </div> 
972        </td>
973        
974        <td class="gfxstudies_gametitle"> Metro Exodus </td>
975        
976        <td style="white-space: nowrap;"> 
977          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://aschrein.github.io/2019/08/11/metro_breakdown.html" target="_blank">Analysis</a></span>
978        </td>
979        
980        <td class="gfxstudies_author" style="white-space: nowrap;"> 
981          by <a style="white-space: nowrap;" href="https://aschrein.github.io/" target="_blank">Anton Schreiner</a> 
982        </td>            
983        
984        <td class="gfxstudies_published"> 2019/08/11 </td>
985        
986    </tr>
987
988    <tr>
989    
990        <td class="gfxstudies_gamerelease"> 2019/04/23 </td>
991        
992        <td>    
993            <div style="border-radius: 0.3em;"> 
994                <img src="/img/blog/2020/gfx/mk11.jpg"> 
995            </div> 
996        </td>
997        
998        <td class="gfxstudies_gametitle"> Mortal Kombat 11 </td>
999        
1000        <td style="white-space: nowrap;"> 
1001          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://alain.xyz/blog/frame-analysis-mk11" target="_blank">Analysis</a></span>
1002        </td>
1003        
1004        <td class="gfxstudies_author" style="white-space: nowrap;"> 
1005          by <a style="white-space: nowrap;" href="https://alain.xyz" target="_blank">Alain Galvan</a> 
1006        </td>            
1007        
1008        <td class="gfxstudies_published"> 2020/04/28 </td>
1009        
1010    </tr>
1011
1012    <tr>
1013    
1014        <td class="gfxstudies_gamerelease"> 2019/05/14 </td>
1015        
1016        <td>    
1017            <div style="border-radius: 0.3em;"> 
1018                <img src="/img/blog/2020/gfx/apti.jpg"> 
1019            </div> 
1020        </td>
1021        
1022        <td class="gfxstudies_gametitle"> A Plague Tale: Innocence </td>
1023        
1024        <td style="white-space: nowrap;"> 
1025          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="http://morad.in/2019/06/16/dissecting-a-plague-tale-innocence/" target="_blank">Analysis</a></span>
1026        </td>
1027        
1028        <td class="gfxstudies_author" style="white-space: nowrap;"> 
1029          by <a style="white-space: nowrap;" href="http://morad.in" target="_blank">Balázs Török</a> 
1030        </td>            
1031        
1032        <td class="gfxstudies_published"> 2019/06/16 </td>
1033        
1034    </tr>
1035
1036    <tr>
1037    
1038        <td class="gfxstudies_gamerelease"> 2019/08/27 </td>
1039        
1040        <td>    
1041            <div style="border-radius: 0.3em;"> 
1042                <img src="/img/blog/2020/gfx/control.jpg"> 
1043            </div> 
1044        </td>
1045        
1046        <td class="gfxstudies_gametitle"> Control </td>
1047        
1048        <td style="white-space: nowrap;"> 
1049          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://alain.xyz/blog/frame-analysis-control" target="_blank">Analysis</a></span>
1050        </td>
1051        
1052        <td class="gfxstudies_author" style="white-space: nowrap;"> 
1053          by <a style="white-space: nowrap;" href="https://alain.xyz" target="_blank">Alain Galvan</a> 
1054        </td>            
1055        
1056        <td class="gfxstudies_published"> 2021/11/06 </td>
1057        
1058    </tr>
1059
1060    <tr>
1061    
1062        <td class="gfxstudies_gamerelease"> 2020/03/20 </td>
1063        
1064        <td>    
1065            <div style="border-radius: 0.3em;"> 
1066                <img src="/img/blog/2020/gfx/doometernal.jpg"> 
1067            </div> 
1068        </td>
1069        
1070        <td class="gfxstudies_gametitle"> DOOM Eternal </td>
1071        
1072        <td style="white-space: nowrap;"> 
1073          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://simoncoenen.com/blog/programming/graphics/DoomEternalStudy.html" target="_blank">Analysis</a></span>
1074        </td>
1075        
1076        <td class="gfxstudies_author" style="white-space: nowrap;"> 
1077          by <a style="white-space: nowrap;" href="https://simoncoenen.com/" target="_blank">Simon Coenen</a> 
1078        </td>            
1079        
1080        <td class="gfxstudies_published"> 2020/08/30 </td>
1081        
1082    </tr>
1083
1084    <tr>
1085    
1086        <td class="gfxstudies_gamerelease"> 2020/04/16 </td>
1087        
1088        <td>    
1089            <div style="border-radius: 0.3em;"> 
1090                <img src="/img/blog/2020/gfx/minecraftrtx.jpg"> 
1091            </div> 
1092        </td>
1093        
1094        <td class="gfxstudies_gametitle"> Minecraft RTX </td>
1095        
1096        <td style="white-space: nowrap;"> 
1097          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://alain.xyz/blog/frame-analysis-minecraftrtx" target="_blank">Analysis</a></span>
1098        </td>
1099        
1100        <td class="gfxstudies_author" style="white-space: nowrap;"> 
1101          by <a style="white-space: nowrap;" href="https://alain.xyz" target="_blank">Alain Galvan</a> 
1102        </td>            
1103        
1104        <td class="gfxstudies_published"> 2020/05/19 </td>
1105        
1106    </tr>
1107
1108    <tr>
1109    
1110        <td class="gfxstudies_gamerelease"> 2020/07/14 </td>
1111        
1112        <td>    
1113            <div style="border-radius: 0.3em;"> 
1114                <img src="/img/blog/2020/gfx/deathstranding.jpg"> 
1115            </div> 
1116        </td>
1117        
1118        <td class="gfxstudies_gametitle"> Death Stranding </td>
1119        
1120        <td style="white-space: nowrap;"> 
1121          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://mamoniem.com/behind-the-pretty-frames-death-stranding/" target="_blank">Analysis</a></span>
1122        </td>
1123        
1124        <td class="gfxstudies_author" style="white-space: nowrap;"> 
1125          by <a style="white-space: nowrap;" href="https://www.mamoniem.com/" target="_blank">M. A. Moniem</a> 
1126        </td>            
1127        
1128        <td class="gfxstudies_published"> 2022/11/30 </td>
1129        
1130    </tr>
1131
1132    <tr>
1133    
1134        <td class="gfxstudies_gamerelease"> 2020/09/25 </td>
1135        
1136        <td>    
1137            <div style="border-radius: 0.3em;"> 
1138                <img src="/img/blog/2020/gfx/mafiadefinitive.jpg"> 
1139            </div> 
1140        </td>
1141        
1142        <td class="gfxstudies_gametitle"> Mafia: Definitive Edition </td>
1143        
1144        <td style="white-space: nowrap;"> 
1145          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://www.elopezr.com/the-rendering-of-mafia-definitive-edition/" target="_blank">Analysis</a></span>
1146        </td>
1147        
1148        <td class="gfxstudies_author" style="white-space: nowrap;"> 
1149          by <a style="white-space: nowrap;" href="http://www.elopezr.com" target="_blank">Emilio López</a> 
1150        </td>            
1151        
1152        <td class="gfxstudies_published"> 2021/08/23 </td>
1153        
1154    </tr>
1155
1156    <tr>
1157    
1158        <td class="gfxstudies_gamerelease"> 2020/12/10 </td>
1159        
1160        <td>    
1161            <div style="border-radius: 0.3em;"> 
1162                <img src="/img/blog/2020/gfx/cyberpunk2077.jpg"> 
1163            </div> 
1164        </td>
1165        
1166        <td class="gfxstudies_gametitle"> Cyberpunk 2077 </td>
1167        
1168        <td style="white-space: nowrap;"> 
1169          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://zhangdoa.com/posts/rendering-analysis-cyberpunk-2077" target="_blank">Analysis</a></span>
1170        </td>
1171        
1172        <td class="gfxstudies_author" style="white-space: nowrap;"> 
1173          by <a style="white-space: nowrap;" href="https://zhangdoa.com/" target="_blank">Hang Zhang</a> 
1174        </td>            
1175        
1176        <td class="gfxstudies_published"> 2020/12/12 </td>
1177        
1178    </tr>
1179
1180    <tr>
1181    
1182        <td class="gfxstudies_gamerelease"> 2020/12/10 </td>
1183        
1184        <td>    
1185            <div style="border-radius: 0.3em;"> 
1186                <img src="/img/blog/2020/gfx/cyberpunk2077.jpg"> 
1187            </div> 
1188        </td>
1189        
1190        <td class="gfxstudies_gametitle"> Cyberpunk 2077 </td>
1191        
1192        <td style="white-space: nowrap;"> 
1193          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://c0de517e.blogspot.com/2020/12/hallucinations-re-rendering-of.html" target="_blank">Analysis</a></span>
1194        </td>
1195        
1196        <td class="gfxstudies_author" style="white-space: nowrap;"> 
1197          by <a style="white-space: nowrap;" href="https://c0de517e.blogspot.com/" target="_blank">Angelo Pesce</a> 
1198        </td>            
1199        
1200        <td class="gfxstudies_published"> 2020/12/17 </td>
1201        
1202    </tr>
1203
1204    <tr>
1205    
1206        <td class="gfxstudies_gamerelease"> 2021/05/21 </td>
1207        
1208        <td>    
1209            <div style="border-radius: 0.3em;"> 
1210                <img src="/img/blog/2020/gfx/knockoutcity.jpg"> 
1211            </div> 
1212        </td>
1213        
1214        <td class="gfxstudies_gametitle"> Knockout City </td>
1215        
1216        <td style="white-space: nowrap;"> 
1217          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://www.velanstudios.com/post/knockout-city-frame-breakdown" target="_blank">Analysis</a></span>
1218        </td>
1219        
1220        <td class="gfxstudies_author" style="white-space: nowrap;"> 
1221          by <a style="white-space: nowrap;" href="https://www.velanstudios.com" target="_blank">Ashley Taylor</a> 
1222        </td>            
1223        
1224        <td class="gfxstudies_published"> 2023/12/15 </td>
1225        
1226    </tr>
1227
1228    <tr>
1229    
1230        <td class="gfxstudies_gamerelease"> 2022/01/14 </td>
1231        
1232        <td>    
1233            <div style="border-radius: 0.3em;"> 
1234                <img src="/img/blog/2020/gfx/gowpc.jpg"> 
1235            </div> 
1236        </td>
1237        
1238        <td class="gfxstudies_gametitle"> God of War (PC) </td>
1239        
1240        <td style="white-space: nowrap;"> 
1241          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://www.mamoniem.com/behind-the-pretty-frames-god-of-war/" target="_blank">Analysis</a></span>
1242        </td>
1243        
1244        <td class="gfxstudies_author" style="white-space: nowrap;"> 
1245          by <a style="white-space: nowrap;" href="https://www.mamoniem.com/" target="_blank">M. A. Moniem</a> 
1246        </td>            
1247        
1248        <td class="gfxstudies_published"> 2022/01/18 </td>
1249        
1250    </tr>
1251
1252    <tr>
1253    
1254        <td class="gfxstudies_gamerelease"> 2022/02/22 </td>
1255        
1256        <td>    
1257            <div style="border-radius: 0.3em;"> 
1258                <img src="/img/blog/2020/gfx/eldenring.jpg"> 
1259            </div> 
1260        </td>
1261        
1262        <td class="gfxstudies_gametitle"> Elden Ring </td>
1263        
1264        <td style="white-space: nowrap;"> 
1265          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://www.mamoniem.com/behind-the-pretty-frames-elden-ring/" target="_blank">Analysis</a></span>
1266        </td>
1267        
1268        <td class="gfxstudies_author" style="white-space: nowrap;"> 
1269          by <a style="white-space: nowrap;" href="https://www.mamoniem.com/" target="_blank">M. A. Moniem</a> 
1270        </td>            
1271        
1272        <td class="gfxstudies_published"> 2022/05/25 </td>
1273        
1274    </tr>
1275
1276    <tr>
1277    
1278        <td class="gfxstudies_gamerelease"> 2022/04/21 </td>
1279        
1280        <td>    
1281            <div style="border-radius: 0.3em;"> 
1282                <img src="/img/blog/2020/gfx/teardown.jpg"> 
1283            </div> 
1284        </td>
1285        
1286        <td class="gfxstudies_gametitle"> Teardown </td>
1287        
1288        <td style="white-space: nowrap;"> 
1289          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://acko.net/blog/teardown-frame-teardown/" target="_blank">Analysis</a></span>
1290        </td>
1291        
1292        <td class="gfxstudies_author" style="white-space: nowrap;"> 
1293          by <a style="white-space: nowrap;" href="https://acko.net/" target="_blank">Steven Wittens</a> 
1294        </td>            
1295        
1296        <td class="gfxstudies_published"> 2023/01/24 </td>
1297        
1298    </tr>
1299
1300    <tr>
1301    
1302        <td class="gfxstudies_gamerelease"> 2022/04/21 </td>
1303        
1304        <td>    
1305            <div style="border-radius: 0.3em;"> 
1306                <img src="/img/blog/2020/gfx/teardown.jpg"> 
1307            </div> 
1308        </td>
1309        
1310        <td class="gfxstudies_gametitle"> Teardown </td>
1311        
1312        <td style="white-space: nowrap;"> 
1313          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://juandiegomontoya.github.io/teardown_breakdown.html" target="_blank">Analysis</a></span>
1314        </td>
1315        
1316        <td class="gfxstudies_author" style="white-space: nowrap;"> 
1317          by <a style="white-space: nowrap;" href="https://juandiegomontoya.github.io/" target="_blank">Jake Ryan</a> 
1318        </td>            
1319        
1320        <td class="gfxstudies_published"> 2023/02/20 </td>
1321        
1322    </tr>
1323
1324    <tr>
1325    
1326        <td class="gfxstudies_gamerelease"> 2023/06/05 </td>
1327        
1328        <td>    
1329            <div style="border-radius: 0.3em;"> 
1330                <img src="/img/blog/2020/gfx/diablo4.jpg"> 
1331            </div> 
1332        </td>
1333        
1334        <td class="gfxstudies_gametitle"> Diablo IV </td>
1335        
1336        <td style="white-space: now
1336rap;"> 
1337          <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>&nbsp;<a href="https://mamoniem.com/behind-the-pretty-frames-diablo-iv/" target="_blank">Analysis</a></span>
1338        </td>
1339        
1340        <td class="gfxstudies_author" style="white-space: nowrap;"> 
1341          by <a style="white-space: nowrap;" href="https://www.mamoniem.com/" target="_blank">M. A. Moniem</a> 
1342        </td>            
1343        
1344        <td class="gfxstudies_published"> 2023/06/28 </td>
1345        
1346    </tr>
1347    
1348        
1349    </tbody>
1350</table>
1351</div>
1352
1353
1354<p>I&rsquo;ll try to maintain the list updated so if I&rsquo;m missing something don&rsquo;t hesitate to reach out.</p>
1355
1356<p>Keep in mind most of this is the fruit of reverse-engineering and some amount of guess-work can be involved.<br/>
1357For those looking for the ground-truth and more explanation, you can hear it straight from the horse&rsquo;s mouth:<br/>
1358studios research division (<a href="https://research.activision.com/">Activision</a>, <a href="https://www.ea.com/seed/publications">EA</a>,
1359<a href="https://medium.com/ready-at-dawn/dev-talks/home">Ready At Dawn</a>&hellip;),
1360Siggraph&rsquo;s <a href="https://advances.realtimerendering.com/">Advances in Real-Time Rendering</a> or
1361<a href="https://www.gdcvault.com/">GDC Vault</a> talks.</p>
1362
1363<p>I also recommend <a href="http://simonschreibt.de/game-art-tricks/">Simon Trümpler&rsquo;s website</a> which presents
1364technical breakdowns of some graphical effects implemented in commercial games.</p>
1365
1366<script>
1367(function(){
1368    
1369    // Returns 1st item inside the DOM hierarchy with the corresponding class
1370    var findClass = function(dom, className) {
1371        if (dom.className && dom.className.split && dom.className.split(' ').indexOf(className) >= 0) return dom;
1372        for (var i = 0; i < dom.childNodes.length; i++) {
1373            var foundChild = findClass(dom.childNodes[i], className);
1374            if (foundChild) return foundChild;
1375        }
1376        return undefined;
1377    };
1378    
1379    var tableBody = document.getElementById("gfxstudies_list");
1380    var studiesArray = [];
1381    for (var i = 0; i < tableBody.children.length; i++) {
1382      var domStudy = tableBody.children[i];
1383      var studyEntry = {
1384          dom: domStudy,
1385          release: findClass(domStudy, "gfxstudies_gamerelease").innerText,
1386          title: findClass(domStudy, "gfxstudies_gametitle").innerText,
1387          author: findClass(domStudy, "gfxstudies_author").innerText,
1388          published: findClass(domStudy, "gfxstudies_published").innerText,
1389      };
1390      studiesArray.push(studyEntry);
1391    }
1392    
1393    function repopulateTable() {
1394        for (var i = 0; i < studiesArray.length; i++) tableBody.appendChild(studiesArray[i].dom);
1395    }
1396    
1397    var sorters = [];
1398    function makeSorter(dom, sortFunction) {
1399        var result = {
1400            isSelected: false,
1401            isAscending: true,
1402            domIndicator: findClass(dom, "column_sort"),
1403        };
1404        result.setSelected = function(selected) {
1405            result.isSelected = selected;
1406            result.domIndicator.style.visibility = selected? "visible" : "hidden";
1407        };
1408        result.updateIcon = function() {
1409            result.domIndicator.innerHTML = result.isAscending? "&#9650;" : "&#9660;";
1410        };
1411        result.doSort = function() {
1412            if (result.isSelected) result.isAscending = !result.isAscending;
1413            result.updateIcon();
1414            studiesArray.sort(sortFunction);
1415            if (!result.isAscending) studiesArray.reverse();
1416            repopulateTable();
1417            
1418        };
1419        result.onClick = function() {
1420            result.doSort();
1421            for (var i = 0; i < sorters.length; i++) sorters[i].setSelected(result == sorters[i]);
1422        };
1423        sorters.push(result);
1424        result.setSelected(false);
1425        result.updateIcon();
1426        
1427        dom.onclick = function(event) {
1428            event && event.preventDefault();
1429            result.onClick();
1430        };
1431        dom.style.cursor = "pointer";
1432        dom.title = "Sort";
1433        dom.classList.add("sortable_header");
1434        
1435        return result;
1436    }
1437    
1438    makeSorter(document.getElementById("gfxstudies_gamerelease"), function(a,b){
1439        var compare = a.release.localeCompare(b.release);
1440        if (compare != 0) return compare;
1441        return a.published.localeCompare(b.published);
1442    }).setSelected(true);
1443    makeSorter(document.getElementById("gfxstudies_gametitle"), function(a,b){
1444        var compare = a.title.localeCompare(b.title);
1445        if (compare != 0) return compare;
1446        return a.release.localeCompare(b.release);
1447    });
1448    makeSorter(document.getElementById("gfxstudies_author"), function(a,b){
1449        var compare = a.author.localeCompare(b.author);
1450        if (compare != 0) return compare;
1451        return a.published.localeCompare(b.published);
1452    });
1453    makeSorter(document.getElementById("gfxstudies_published"), function(a,b){
1454        return a.published.localeCompare(b.published);
1455    });
1456})();
1457
1458</script>
1458
1459
1460
1461
1462</div>
1463  
1464  
1465
1466
1467    </article>
1468  
1469  
1470    <article>
1471      
1472  <header>
1473    
1474      <h1 class="entry-title"><a href="/blog/2018/12/02/ue4-optimized-post-effects/">UE4 Optimized Post-Effects</a></h1>
1475    
1476    
1477      <p class="meta">
1478        
1479
1480
1481
1482
1483
1484
1485
1486
1487  
1488
1489
1490<time datetime="2018-12-02T11:24:00+01:00" pubdate data-updated="true">Dec 2<span>nd</span>, 2018</time>
1491        
1492      </p>
1493    
1494  </header>
1495
1496
1497  <div class="entry-content"><p><img class="left" src="/projects/ue4-postfx/thumbnail.jpg" width="380"/></p>
1498
1499<p>At my day job I get to optimize several games for the <a href="https://en.wikipedia.org/wiki/Nintendo_Switch">Nintendo Switch</a>
1500or the <a href="https://en.wikipedia.org/wiki/Nvidia_Shield_(set-top_box)">NVIDIA Shield</a>,
1501some of them using <a href="https://www.unrealengine.com">Unreal Engine 4</a>.<br/>
1502While UE4 is very powerful and offers a large selection of knobs to balance visual quality
1503and performance some of the post-effects can end up
1504being significantly heavy on a <a href="https://en.wikipedia.org/wiki/Tegra#Tegra_X1">Tegra X1 GPU</a> even at the lowest quality settings.</p>
1505
1506<p>Below is a small collection of customizations/hacks I wrote in order to optimize the runtime cost of certain effects while remaining as close as possible to the original
1507visuals of a vanilla UE4. The idea is to provide a drop-in replacement you can easily integrate into your own game to achieve better performance on a X1. Here I will be mainly writing about:</p>
1508
1509<ul>
1510<li><a href="/blog/2018/12/02/ue4-optimized-post-effects/#ue4_bokehdof"><strong>BokehDOF</strong></a></li>
1511<li><a href="/blog/2018/12/02/ue4-optimized-post-effects/#ue4_ssao"><strong>SSAO</strong></a></li>
1512<li><a href="/blog/2018/12/02/ue4-optimized-post-effects/#ue4_dynres"><strong>Dynamic Resolution</strong></a></li>
1513</ul>
1514
1515
1516<p><a name="ue4_bokehdof"></a></p>
1517
1518<h2 style="font-weight: bold; font-size: 2.5em; background: none; padding-top: 0.3em;">Bokeh <span style="white-space: nowrap;">Depth-of-Field</span></h2>
1519
1520
1521<p><a href="https://en.wikipedia.org/wiki/Depth_of_field">Depth-of-field</a> techniques have seen a lot of changes recently in the latest UE4 versions, some getting deprecated 
1521in favor of the
1522new <a href="https://docs.unrealengine.com/en-US/Engine/Rendering/PostProcessEffects/DepthOfField/CinematicDOFMethods/index.html"><em>DiaphragmDOF</em></a> implementation.
1523Historically UE4 supported 3 different approaches:</p>
1524
1525<div class="table-carousel" style="display: flex; flex-direction: row; width: 100%; margin-bottom: 1em;">
1526
1527        <div style="flex: 1; padding-right: 0.5em;">
1528            
1529            
1530            <div  style="position: relative; margin-bottom:  1.5em ;" >
1531    <div style="margin: auto">
1532        <img src="/img/blog/2018/ue4-postfx/vanilla_nodoftaa.jpg" style="display: block; margin: auto;  "  />
1533    </div> 
1534    
1535    <div class="screenshot-caption"
1536        
1537    >No DOF</div>
1538    
1539</div>
1540
1541
1542
1543
1544
1545
1546        </div>
1547
1548        <div style="flex: 1; padding-right: 0.5em;">
1549            
1550            
1551            <div  style="position: relative; margin-bottom:  1.5em ;" >
1552    <div style="margin: auto">
1553        <img src="/img/blog/2018/ue4-postfx/vanilla_gaussiandof.jpg" style="display: block; margin: auto;  "  />
1554    </div> 
1555    
1556    <div class="screenshot-caption"
1557        
1558    >GaussianDOF</div>
1559    
1560</div>
1561
1562
1563
1564
1565
1566            <div style="margin-top: -1.2em;
1567                font-size: 80%; line-height: 130%;
1568                font-style: italic;
1569                text-align: justify;
1570                padding: 0.5em; padding-top: 0.4em;
1571                box-shadow: inset 0 1px 10px rgba(0,0,0,0.3), 0 1px 0 rgba(255,255,255,0.1), 0 -1px 0 rgba(0,0,0,0.5);
1572                border-radius: 0.4em;
1573                background: #3c3c3c;
1574                ">
1575                Physically incorrect, not very pleasant visually with light fall-off looking wrong. But extremely lightweight and the fastest option available.
1576            </div>
1577        </div>
1578
1579        <div style="flex: 1; padding-right: 0.5em;">
1580            
1581            
1582            <div  style="position: relative; margin-bottom:  1.5em ;" >
1583    <div style="margin: auto">
1584        <img src="/img/blog/2018/ue4-postfx/vanilla_bokehdof.jpg" style="display: block; margin: auto;  "  />
1585    </div> 
1586    
1587    <div class="screenshot-caption"
1588        
1589    >BokehDOF</div>
1590    
1591</div>
1592
1593
1594
1595
1596
1597            <div style="margin-top: -1.2em;
1598                font-size: 80%; line-height: 130%;
1599                font-style: italic;
1600                text-align: justify;
1601                padding: 0.5em; padding-top: 0.4em;
1602                box-shadow: inset 0 1px 10px rgba(0,0,0,0.3), 0 1px 0 rgba(255,255,255,0.1), 0 -1px 0 rgba(0,0,0,0.5);
1603                border-radius: 0.4em;
1604                background: #3c3c3c;
1605                ">
1606            Better physical accuracy, correctly uses a flat kernel unlike Gaussian. Fully artist-driven with custom bokeh sprite, but gets slow at large radius.
1607            </div>
1608        </div>
1609
1610        <div style="flex: 1;">
1611            
1612            
1613            <div  style="position: relative; margin-bottom:  1.5em ;" >
1614    <div style="margin: auto">
1615        <img src="/img/blog/2018/ue4-postfx/vanilla_circledofhigh.jpg" style="display: block; margin: auto;  "  />
1616    </div> 
1617    
1618    <div class="screenshot-caption"
1619        
1620    >CircleDOF</div>
1621    
1622</div>
1623
1624
1625
1626
1627
1628            <div style="margin-top: -1.2em;
1629                font-size: 80%; line-height: 130%;
1630                font-style: italic;
1631                text-align: justify;
1632                padding: 0.5em; padding-top: 0.4em;
1633                box-shadow: inset 0 1px 10px rgba(0,0,0,0.3), 0 1px 0 rgba(255,255,255,0.1), 0 -1px 0 rgba(0,0,0,0.5);
1634                border-radius: 0.4em;
1635                background: #3c3c3c;
1636                ">
1637                Aims for the best physical accuracy relying on lens properties, only disk shape. Can get very expensive and noisy as the bokeh radius increases.
1638            </div>
1639        </div>
1640</div>
1641
1642
1643<p>Here I will be writing about a drop-in replacement for <em>BokehDOF</em> called <em>GatherDOF</em>.</p>
1644
1645<p><em>BokehDOF</em> produces very pleasant visual results but the main issue is its bandwidth cost.<br/>
1646To give some idea of how <em>BokehDOF</em> operates, it basically spawns one bokeh sprite per original pixel of the scene, each sprite size being proportional to
1647the <a href="https://en.wikipedia.org/wiki/Circle_of_confusion">circle-of-confusion</a> value of the pixel it originates from.<br/>
1648<em>(See also the <a href="/blog/2017/12/15/mgs-v-graphics-study/">MGS V graphics study</a> for more in-depth insights, it&rsquo;s using roughly the same method.)</em></p>
1649
1650<div style="text-align: center; margin-bottom: 1.5em;">
1651<img style="padding: 1em; background: black;" src="/img/blog/2018/ue4-postfx/04_bokeh_shape.jpg"/><br/>
1652<span style="font-style: italic;">BokehDOF Sprite</span>
1653</div>
1654
1655
1656<p>For a 1080p scene that means drawing around 2 million quads, blended on the top of each other. As pixels get furthermore out-of-focus
1657the sprite size increases and performance takes a nose-dive with quad overdraw saturating the bandwidth.</p>
1658
1659<p><em>GatherDOF</em> was implemented with the idea of producing a visual result close to <em>BokehDOF</em> but with a different approach: &ldquo;gather&rdquo; neighbor texel values instead of &ldquo;scattering&rdquo; bokeh sprites.
1660The two algorithms are completely different — their cost as well — however the end result is quite similar visually:</p>
1661
1662<div id="03_dof_methods_compare">
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673<div class="slick-margin05">
1674<div  style="position: relative; " >
1675    <div style="margin: auto">
1676        <img src="/img/blog/2018/ue4-postfx/03_nodoftaa.jpg" style="display: block; margin: auto;  "  />
1677    </div> 
1678    
1679    <div class="screenshot-caption"
1680        style="left: 1.5em;"
1681    >No DOF</div>
1682    
1683</div>
1684
1685
1686
1687
1688
1689</div>
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702<div class="slick-margin05">
1703<div  style="position: relative; " >
1704    <div style="margin: auto">
1705        <img src="/img/blog/2018/ue4-postfx/03_bokeh.jpg" style="display: block; margin: auto;  "  />
1706    </div> 
1707    
1708    <div class="screenshot-caption"
1709        style="left: 1.5em;"
1710    >BokehDOF<br>15ms<br><span style="font-size: 70%; font-style: italic;">( TX1@768MHz )</span></div>
1711    
1712</div>
1713
1714
1715
1716
1717
1718</div>
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731<div class="slick-margin05">
1732<div  style="position: relative; " >
1733    <div style="margin: auto">
1734        <img src="/img/blog/2018/ue4-postfx/03_gather.jpg" style="display: block; margin: auto;  "  />
1735    </div> 
1736    
1737    <div class="screenshot-caption"
1738        style="left: 1.5em;"
1739    >GatherDOF<br>2ms<br><span style="font-size: 70%; font-style: italic;">( TX1@768MHz )</span></div>
1740    
1741</div>
1742
1743
1744
1745
1746
1747</div>
1748
1749
1750
1751</div>
1752
1753
1754
1755
1756<script type="text/javascript">
1757        $(document).ready(function(){
1758            $('#03_dof_methods_compare').slick({
1759        autoplay: true,
1760        speed: 600,
1761        autoplaySpeed: 1000,
1762                dots: true,
1763            slidesToShow: 1,
1764            slidesToScroll: 1,
1765        fade: true,
1766        cssEase: 'linear'
1767            });
1768        });
1769</script>
1769
1770
1771
1772
1773
1774</div>
1775  
1776  
1777    <footer>
1778      <a rel="full-article" href="/blog/2018/12/02/ue4-optimized-post-effects/">Read on &rarr;</a>
1779    </footer>
1780  
1781
1782
1783    </article>
1784  
1785  
1786    <article>
1787      
1788  <header>
1789    
1790      <h1 class="entry-title"><a href="/blog/2017/12/15/mgs-v-graphics-study/">Metal Gear Solid V - Graphics Study</a></h1>
1791    
1792    
1793      <p class="meta">
1794        
1795
1796
1797
1798
1799
1800
1801
1802
1803  
1804
1805
1806<time datetime="2017-12-15T19:56:00+01:00" pubdate data-updated="true">Dec 15<span>th</span>, 2017</time>
1807        
1808      </p>
1809    
1810  </header>
1811
1812
1813  <div class="entry-content"><p><img class="right" src="/img/blog/2017/mgsv/logo.jpg" width="420"/></p>
1814
1815<p>The <a href="https://en.wikipedia.org/wiki/Metal_Gear"><em>Metal Gear</em></a> series achieved world-wide recognition
1816when <a href="https://en.wikipedia.org/wiki/Metal_Gear_Solid"><em>Metal&nbsp;Gear&nbsp;Solid</em></a> became a best-seller
1817on the original <a href="https://en.wikipedia.org/wiki/PlayStation_(console)">PlayStation</a> almost two decades ago.
1818The title introduced many players to the genre of &ldquo;tactical espionage action&rdquo;, an expression coined
1819by <a href="https://en.wikipedia.org/wiki/Hideo_Kojima">Hideo&nbsp;Kojima</a> the creator of the franchise.</p>
1820
1821<p>Though in my case the first time I played as <a href="http://metalgear.wikia.com/wiki/Big_Boss"><em>Snake</em></a> wasn&rsquo;t
1822with this game but with the <a href="https://en.wikipedia.org/wiki/Metal_Gear:_Ghost_Babel"><em>Ghost Babel</em></a> spin-off on <a href="https://en.wikipedia.org/wiki/Game_Boy_Color">GBC</a>,
1823a lesser-known but nevertheless excellent title with an impressive depth.</p>
1824
1825<p>The final chapter <a href="https://en.wikipedia.org/wiki/Metal_Gear_Solid_V:_The_Phantom_Pain"><em>Metal Gear Solid V: The Phantom Pain</em></a>
1826was released in 2015 and brings the series to a whole new level of graphics quality thanks to the
1827<a href="https://en.wikipedia.org/wiki/Fox_Engine">Fox Engine</a>
1828developed by <a href="https://en.wikipedia.org/wiki/Kojima_Productions">Kojima Productions</a>.
1829The analysis below is based on the PC version of the game with all the quality knobs set to maximum.
1830Some of the information I present here has already been made public in the GDC 2013 session
1831<a href="https://www.gdcvault.com/play/1018086/Photorealism-Through-the-Eyes-of">&ldquo;Photorealism Through the Eyes of a FOX&rdquo;</a>.</p>
1832
1833<h1>Dissecting a Frame</h1>
1834
1835<p>Here is a frame taken from the very beginning of the game, during the prologue when <em>Snake</em> tries to make his way out of the hospital.
1836<em>Snake</em> is lying on the floor trying to blend in among the other corpses, he&rsquo;s at the bottom of the screen with his naked shoulder.
1837Not the most glamorous scene but it illustrates well the different effects the engine can achieve.</p>
1838
1839<p><img class="center" src="/img/blog/2017/mgsv/99_final.jpg"  ></p>
1840
1841<p>Right in front of <em>Snake</em> two soldiers are standing up, they&rsquo;re looking at some burning silhouette at the end of the hallway.
1842I&rsquo;ll simply refer to that mysterious individual as the &ldquo;Man on Fire&rdquo; not to spoil anything about the story.</p>
1843
1844<p>So let&rsquo;s see how this frame is rendered!</p>
1845
1846<h3>Depth Pre-Pass</h3>
1847
1848<p>This pass renders only the geometry of the terrain underneath the hospital as viewed from the point of view of the player and outputs its depth information to a depth buffer.
1849The terrain mesh is generated from the <a href="https://en.wikipedia.org/wiki/Heightmap">heightmap</a> you can see below:
1850it&rsquo;s a 16-bit floating point texture containing the terrain elevation value (view from the top).
1851The engine divides the heightmap into different tiles, for each tile a draw call is dispatched with a flat grid of 16x16 vertices.
1852The vertex shader reads the heightmap and modifies on-the-fly the vertex position to match the elevation value. The terrain
1853is rasterized in about 150 draw calls.</p>
1854
1855<table class="table-carousel" style="width: 100%;">
1856    <tr style="width: 100%;">
1857        <td style="width: 22%; vertical-align: middle;">
1858            
1859            
1860            <div  style="position: relative; margin-bottom:  1.5em ;" >
1861    <div style="margin: auto">
1862        <img src="/img/blog/2017/mgsv/01_heightmap.jpg" style="display: block; margin: auto;  "  />
1863    </div> 
1864    
1865    <div class="screenshot-caption"
1866        
1867    >Terrain Elevation</div>
1868    
1869</div>
1870
1871
1872
1873
1874
1875        </td>
1876        <td style="width: 18%; text-align: center; vertical-align: middle;">
1877        <img class="center img-nobox" src="/img/arrow-right.png" style="width: 5.5em; margin-bottom: -1em; padding-left: 1em; padding-right: 1em;"/>
1878        <br/>
1879        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
1880        </td>
1881        <td style="width: 60%; padding-left: 2em;">
1882            
1883            
1884            <div id="02_depth_pp">
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895<div class="slick-margin05">
1896<div  style="position: relative; " >
1897    <div style="margin: auto">
1898        <img src="/img/blog/2017/mgsv/02_depth_pp_1.jpg" style="display: block; margin: auto;  "  />
1899    </div> 
1900    
1901    <div class="screenshot-caption"
1902        style="left: 1.5em;"
1903    >Depth Map: 5% </div>
1904    
1905</div>
1906
1907
1908
1909
1910
1911</div>
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924<div class="slick-margin05">
1925<div  style="position: relative; " >
1926    <div style="margin: auto">
1927        <img src="/img/blog/2017/mgsv/02_depth_pp_2.jpg" style="display: block; margin: auto;  "  />
1928    </div> 
1929    
1930    <div class="screenshot-caption"
1931        style="left: 1.5em;"
1932    >Depth Map: 10% </div>
1933    
1934</div>
1935
1936
1937
1938
1939
1940</div>
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953<div class="slick-margin05">
1954<div  style="position: relative; " >
1955    <div style="margin: auto">
1956        <img src="/img/blog/2017/mgsv/02_depth_pp_3.jpg" style="display: block; margin: auto;  "  />
1957    </div> 
1958    
1959    <div class="screenshot-caption"
1960        style="left: 1.5em;"
1961    >Depth Map: 40% </div>
1962    
1963</div>
1964
1965
1966
1967
1968
1969</div>
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982<div class="slick-margin05">
1983<div  style="position: relative; " >
1984    <div style="margin: auto">
1985        <img src="/img/blog/2017/mgsv/02_depth_pp_4.jpg" style="display: block; margin: auto;  "  />
1986    </div> 
1987    
1988    <div class="screenshot-caption"
1989        style="left: 1.5em;"
1990    >Depth Map: 100% </div>
1991    
1992</div>
1993
1994
1995
1996
1997
1998</div>
1999
2000
2001
2002</div>
2003
2004
2005
2006
2007<script type="text/javascript">
2008        $(document).ready(function(){
2009            $('#02_depth_pp').slick({
2010        autoplay: true,
2011        speed: 600,
2012        autoplaySpeed: 1000,
2013                dots: true,
2014            slidesToShow: 1,
2015            slidesToScroll: 1,
2016        fade: true,
2017        cssEase: 'linear'
2018            });
2019        });
2020</script>
2020
2021
2022        </td>
2023    </tr>
2024</table>
2025
2026
2027<p></p>
2028
2029<h3>G-Buffer Generation</h3>
2030
2031<p>MGS V uses a <a href="https://en.wikipedia.org/wiki/Deferred_shading">deferred renderer</a> like many games of its generation,
2032if you already read the <a href="/blog/2015/11/02/gta-v-graphics-study/">GTA V study</a> you will notice several similar elements.
2033So instead of calculating directly the final lighting value of each pixel as the scene is rendered, the engine first
2034stores the properties of each pixels (like albedo colors, normals&hellip;) in several render targets called <abbr title="Geometry Buffer"><em>G-Buffer</em></abbr> and
2035will later
2036combine all this information together.</p>
2037
2038<p>All the following buffers are generated at the same time:</p>
2039
2040<div id="04_gbuffers">
2041
2042
2043<div class="slick-margin05" style="background: #666; padding: 12px 15px 15px 15px; border-radius: 8px;">
2044
2045<div class="caption-frame" style="margin-bottom: 0.4em; width: 30%; min-width: 240px;">
2046G-Buffer Generation: 25%
2047
2048<div class="progressBar" style="height: 2px; background: #444; margin-bottom: 2px; ">
2049<div class="progressBar" style="height: 2px; width: 25%; background: #999; ">&nbsp;</div>
2050</div>
2051
2052</div>
2053<div style="clear: both;">
2054</div>
2055
2056
2057
2058<div style="clear: both;"></div>
2059
2060<table class="table-carousel" style="width: 100%;">
2061    <tr style="width: 100%;">
2062        <td style="width: 50%; vertical-align: middle; padding: 0; padding-right: 0.25em;">
2063            
2064            
2065            
2066            <div  style="position: relative; margin-bottom:  0.5em ;" >
2067    <div style="margin: auto">
2068        <img src="/img/blog/2017/mgsv/04_albedo_1.jpg" style="display: block; margin: auto;  "  />
2069    </div> 
2070    
2071    <div class="screenshot-caption"
2072        
2073    >Albedo</div>
2074    
2075</div>
2076
2077
2078
2079
2080
2081        </td>
2082        
2083        <td style="width: 50%; vertical-align: middle; padding: 0; padding-left: 0.25em;">
2084            
2085            
2086            
2087            <div  style="position: relative; margin-bottom:  0.5em ;" >
2088    <div style="margin: auto">
2089        <img src="/img/blog/2017/mgsv/04_normal_1.jpg" style="display: block; margin: auto;  "  />
2090    </div> 
2091    
2092    <div class="screenshot-caption"
2093        
2094    >Normal</div>
2095    
2096</div>
2097
2098
2099
2100
2101
2102        </td>
2103        
2104    </tr>
2105    <tr style="width: 100%;">
2106        <td style="width: 50%; vertical-align: middle; padding: 0; padding-right: 0.25em;">
2107            
2108            
2109            
2110            <div  style="position: relative; margin-bottom:  0.1em ;" >
2111    <div style="margin: auto">
2112        <img src="/img/blog/2017/mgsv/04_specular_1.jpg" style="display: block; margin: auto;  "  />
2113    </div> 
2114    
2115    <div class="screenshot-caption"
2116        
2117    >Specular</div>
2118    
2119</div>
2120
2121
2122
2123
2124
2125        </td>
2126    
2127        <td style="width: 50%; vertical-align: middle; padding: 0; padding-left: 0.25em;">
2128            
2129            
2130            
2131            <div  style="position: relative; margin-bottom:  0.1em ;" >
2132    <div style="margin: auto">
2133        <img src="/img/blog/2017/mgsv/04_depth_1.jpg" style="display: block; margin: auto;  "  />
2134    </div> 
2135    
2136    <div class="screenshot-caption"
2137        
2138    >Depth</div>
2139    
2140</div>
2141
2142
2143
2144
2145
2146        </td>
2147        
2148    </tr>
2149</table>  
2150
2151
2152</div>
2153
2154
2155
2156
2157<div class="slick-margin05" style="background: #666; padding: 12px 15px 15px 15px; border-radius: 8px;">
2158
2159<div class="caption-frame" style="margin-bottom: 0.4em; width: 30%; min-width: 240px;">
2160G-Buffer Generation: 50%
2161
2162<div class="progressBar" style="height: 2px; background: #444; margin-bottom: 2px; ">
2163<div class="progressBar" style="height: 2px; width: 50%; background: #999; ">&nbsp;</div>
2164</div>
2165
2166</div>
2167<div style="clear: both;">
2168</div>
2169
2170
2171
2172<div style="clear: both;"></div>
2173
2174<table class="table-carousel" style="width: 100%;">
2175    <tr style="width: 100%;">
2176        <td style="width: 50%; vertical-align: middle; padding: 0; padding-right: 0.25em;">
2177            
2178            
2179            
2180            <div  style="position: relative; margin-bottom:  0.5em ;" >
2181    <div style="margin: auto">
2182        <img src="/img/blog/2017/mgsv/04_albedo_2.jpg" style="display: block; margin: auto;  "  />
2183    </div> 
2184    
2185    <div class="screenshot-caption"
2186        
2187    >Albedo</div>
2188    
2189</div>
2190
2191
2192
2193
2194
2195        </td>
2196        
2197        <td style="width: 50%; vertical-align: middle; padding: 0; padding-left: 0.25em;">
2198            
2199            
2200            
2201            <div  style="position: relative; margin-bottom:  0.5em ;" >
2202    <div style="margin: auto">
2203        <img src="/img/blog/2017/mgsv/04_normal_2.jpg" style="display: block; margin: auto;  "  />
2204    </div> 
2205    
2206    <div class="screenshot-caption"
2207        
2208    >Normal</div>
2209    
2210</div>
2211
2212
2213
2214
2215
2216        </td>
2217        
2218    </tr>
2219    <tr style="width: 100%;">
2220        <td style="width: 50%; vertical-align: middle; padding: 0; padding-right: 0.25em;">
2221            
2222            
2223            
2224            <div  style="position: relative; margin-bottom:  0.1em ;" >
2225    <div style="margin: auto">
2226        <img src="/img/blog/2017/mgsv/04_specular_2.jpg" style="display: block; margin: auto;  "  />
2227    </div> 
2228    
2229    <div class="screenshot-caption"
2230        
2231    >Specular</div>
2232    
2233</div>
2234
2235
2236
2237
2238
2239        </td>
2240    
2241        <td style="width: 50%; vertical-align: middle; padding: 0; padding-left: 0.25em;">
2242            
2243            
2244            
2245            <div  style="position: relative; margin-bottom:  0.1em ;" >
2246    <div style="margin: auto">
2247        <img src="/img/blog/2017/mgsv/04_depth_2.jpg" style="display: block; margin: auto;  "  />
2248    </div> 
2249    
2250    <div class="screenshot-caption"
2251        
2252    >Depth</div>
2253    
2254</div>
2255
2256
2257
2258
2259
2260        </td>
2261        
2262    </tr>
2263</table>  
2264
2265
2266</div>
2267
2268
2269
2270
2271<div class="slick-margin05" style="background: #666; padding: 12px 15px 15px 15px; border-radius: 8px;">
2272
2273<div class="caption-frame" style="margin-bottom: 0.4em; width: 30%; min-width: 240px;">
2274G-Buffer Generation: 75%
2275
2276<div class="progressBar" style="height: 2px; background: #444; margin-bottom: 2px; ">
2277<div class="progressBar" style="height: 2px; width: 75%; background: #999; ">&nbsp;</div>
2278</div>
2279
2280</div>
2281<div style="clear: both;">
2282</div>
2283
2284
2285
2286<div style="clear: both;"></div>
2287
2288<table class="table-carousel" style="width: 100%;">
2289    <tr style="width: 100%;">
2290        <td style="width: 50%; vertical-align: middle; padding: 0; padding-right: 0.25em;">
2291            
2292            
2293            
2294            <div  style="position: relative; margin-bottom:  0.5em ;" >
2295    <div style="margin: auto">
2296        <img src="/img/blog/2017/mgsv/04_albedo_3.jpg" style="display: block; margin: auto;  "  />
2297    </div> 
2298    
2299    <div class="screenshot-caption"
2300        
2301    >Albedo</div>
2302    
2303</div>
2304
2305
2306
2307
2308
2309        </td>
2310        
2311        <td style="width: 50%; vertical-align: middle; padding: 0; padding-left: 0.25em;">
2312            
2313            
2314            
2315            <div  style="position: relative; margin-bottom:  0.5em ;" >
2316    <div style="margin: auto">
2317        <img src="/img/blog/2017/mgsv/04_normal_3.jpg" style="display: block; margin: auto;  "  />
2318    </div> 
2319    
2320    <div class="screenshot-caption"
2321        
2322    >Normal</div>
2323    
2324</div>
2325
2326
2327
2328
2329
2330        </td>
2331        
2332    </tr>
2333    <tr style="width: 100%;">
2334        <td style="width: 50%; vertical-align: middle; padding: 0; padding-right: 0.25em;">
2335            
2336            
2337            
2338            <div  style="position: relative; margin-bottom:  0.1em ;" >
2339    <div style="margin: auto">
2340        <img src="/img/blog/2017/mgsv/04_specular_3.jpg" style="display: block; margin: auto;  "  />
2341    </div> 
2342    
2343    <div class="screenshot-caption"
2344        
2345    >Specular</div>
2346    
2347</div>
2348
2349
2350
2351
2352
2353        </td>
2354    
2355        <td style="width: 50%; vertical-align: middle; padding: 0; padding-left: 0.25em;">
2356            
2357            
2358            
2359            <div  style="position: relative; margin-bottom:  0.1em ;" >
2360    <div style="margin: auto">
2361        <img src="/img/blog/2017/mgsv/04_depth_3.jpg" style="display: block; margin: auto;  "  />
2362    </div> 
2363    
2364    <div class="screenshot-caption"
2365        
2366    >Depth</div>
2367    
2368</div>
2369
2370
2371
2372
2373
2374        </td>
2375        
2376    </tr>
2377</table>  
2378
2379
2380</div>
2381
2382
2383
2384
2385<div class="slick-margin05" style="background: #666; padding: 12px 15px 15px 15px; border-radius: 8px;">
2386
2387<div class="caption-frame" style="margin-bottom: 0.4em; width: 30%; min-width: 240px;">
2388G-Buffer Generation: 100%
2389
2390<div class="progressBar" style="height: 2px; background: #444; margin-bottom: 2px; ">
2391<div class="progressBar" style="height: 2px; width: 100%; background: #999; ">&nbsp;</div>
2392</div>
2393
2394</div>
2395<div style="clear: both;">
2396</div>
2397
2398
2399
2400<div style="clear: both;"></div>
2401
2402<table class="table-carousel" style="width: 100%;">
2403    <tr style="width: 100%;">
2404        <td style="width: 50%; vertical-align: middle; padding: 0; padding-right: 0.25em;">
2405            
2406            
2407            
2408            <div  style="position: relative; margin-bottom:  0.5em ;" >
2409    <div style="margin: auto">
2410        <img src="/img/blog/2017/mgsv/04_albedo_4.jpg" style="display: block; margin: auto;  "  />
2411    </div> 
2412    
2413    <div class="screenshot-caption"
2414        
2415    >Albedo</div>
2416    
2417</div>
2418
2419
2420
2421
2422
2423        </td>
2424        
2425        <td style="width: 50%; vertical-align: middle; padding: 0; padding-left: 0.25em;">
2426            
2427            
2428            
2429            <div  style="position: relative; margin-bottom:  0.5em ;" >
2430    <div style="margin: auto">
2431        <img src="/img/blog/2017/mgsv/04_normal_4.jpg" style="display: block; margin: auto;  "  />
2432    </div> 
2433    
2434    <div class="screenshot-caption"
2435        
2436    >Normal</div>
2437    
2438</div>
2439
2440
2441
2442
2443
2444        </td>
2445        
2446    </tr>
2447    <tr style="width: 100%;">
2448        <td style="width: 50%; vertical-align: middle; padding: 0; padding-right: 0.25em;">
2449            
2450            
2451            
2452            <div  style="position: relative; margin-bottom:  0.1em ;" >
2453    <div style="margin: auto">
2454        <img src="/img/blog/2017/mgsv/04_specular_4.jpg" style="display: block; margin: auto;  "  />
2455    </div> 
2456    
2457    <div class="screenshot-caption"
2458        
2459    >Specular</div>
2460    
2461</div>
2462
2463
2464
2465
2466
2467        </td>
2468    
2469        <td style="width: 50%; vertical-align: middle; padding: 0; padding-left: 0.25em;">
2470            
2471            
2472            
2473            <div  style="position: relative; margin-bottom:  0.1em ;" >
2474    <div style="margin: auto">
2475        <img src="/img/blog/2017/mgsv/04_depth_4.jpg" style="display: block; margin: auto;  "  />
2476    </div> 
2477    
2478    <div class="screenshot-caption"
2479        
2480    >Depth</div>
2481    
2482</div>
2483
2484
2485
2486
2487
2488        </td>
2489        
2490    </tr>
2491</table>  
2492
2493
2494</div>
2495
2496
2497
2498</div>
2499
2500
2501
2502
2503<script type="text/javascript">
2504        $(document).ready(function(){
2505            $('#04_gbuffers').slick({
2506        autoplay: true,
2507        speed: 600,
2508        autoplaySpeed: 1000,
2509                dots: true,
2510            slidesToShow: 1,
2511            slidesToScroll: 1,
2512        fade: true,
2513        cssEase: 'linear'
2514            });
2515        });
2516</script>
2516
2517
2518
2519
2520
2521</div>
2522  
2523  
2524    <footer>
2525      <a rel="full-article" href="/blog/2017/12/15/mgs-v-graphics-study/">Read on &rarr;</a>
2526    </footer>
2527  
2528
2529
2530    </article>
2531  
2532  
2533    <article>
2534      
2535  <header>
2536    
2537      <h1 class="entry-title"><a href="/blog/2017/05/09/beware-of-transparent-pixels/">Beware of Transparent Pixels</a></h1>
2538    
2539    
2540      <p class="meta">
2541        
2542
2543
2544
2545
2546
2547
2548
2549
2550  
2551
2552
2553<time datetime="2017-05-09T20:25:00+02:00" pubdate data-updated="true">May 9<span>th</span>, 2017</time>
2554        
2555      </p>
2556    
2557  </header>
2558
2559
2560  <div class="entry-content"><p>If you use sprites with transparency in your game &mdash; and you most likely do for the UI at least &mdash; you&rsquo;ll probably want to pay attention to the fully transparent pixels of your textures (or should I say &ldquo;texels&rdquo;).</p>
2561
2562<p>Even with an alpha of 0, a pixel still has some RGB color value associated with it.<br/>
2563That color shouldn&rsquo;t matter, right? After all if the pixel is completely transparent, who cares about its color&hellip;</p>
2564
2565<p>Well this color does actually matter, getting it wrong leads to artifacts which are present in many games out there.
2566Most of the time the corruption is very subtle and you won&rsquo;t notice it but in some cases it&rsquo;s really standing out.</p>
2567
2568<h1>Corruption Example</h1>
2569
2570<p>Time for a real-world example! Here is the <a href="https://en.wikipedia.org/wiki/XrossMediaBar"><em>XMB</em></a> of my PS3 (home menu), browsing some game demos installed.<br/>
2571At first <a href="https://en.wikipedia.org/wiki/Limbo_(video_game"><em>Limbo</em></a> is selected, I just press &ldquo;Up&rdquo; to move
2572the focus to <a href="https://en.wikipedia.org/wiki/The_Unfinished_Swan"><em>The Unfinished Swan</em></a>
2573(both great games by the way).</p>
2574
2575<div id="a_01_premul">
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586<div class="slick-margin05">
2587<div  style="position: relative; " >
2588    <div style="margin: auto">
2589        <img src="/img/blog/2017/transparentpixels/01_xmb_1.jpg" style="display: block; margin: auto;  "  />
2590    </div> 
2591    
2592    <div class="screenshot-caption"
2593        style="left: 1.5em;"
2594    >Start</div>
2595    
2596</div>
2597
2598
2599
2600
2601
2602</div>
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615<div class="slick-margin05">
2616<div  style="position: relative; " >
2617    <div style="margin: auto">
2618        <img src="/img/blog/2017/transparentpixels/01_xmb_2.jpg" style="display: block; margin: auto;  "  />
2619    </div> 
2620    
2621    <div class="screenshot-caption"
2622        style="left: 1.5em;"
2623    >Press up.<br/><em>Limbo</em> moves down.</div>
2624    
2625</div>
2626
2627
2628
2629
2630
2631</div>
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644<div class="slick-margin05">
2645<div  style="position: relative; " >
2646    <div style="margin: auto">
2647        <img src="/img/blog/2017/transparentpixels/01_xmb_3_glitch.jpg" style="display: block; margin: auto;  "  />
2648    </div> 
2649    
2650    <div class="screenshot-caption"
2651        style="left: 1.5em;"
2652    >White background<br/>fades in.</div>
2653    
2654</div>
2655
2656
2657
2658
2659
2660</div>
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673<div class="slick-margin05">
2674<div  style="position: relative; " >
2675    <div style="margin: auto">
2676        <img src="/img/blog/2017/transparentpixels/01_xmb_4_zoom.jpg" style="display: block; margin: auto;  "  />
2677    </div> 
2678    
2679    <div class="screenshot-caption"
2680        style="left: 1.5em;"
2681    >Artifacts</div>
2682    
2683</div>
2684
2685
2686
2687
2688
2689</div>
2690
2691
2692
2693</div>
2694
2695
2696
2697
2698<script type="text/javascript">
2699        $(document).ready(function(){
2700            $('#a_01_premul').slick({
2701        autoplay: true,
2702        speed: 600,
2703        autoplaySpeed: 1000,
2704                dots: true,
2705            slidesToShow: 1,
2706            slidesToScroll: 1,
2707        fade: true,
2708        cssEase: 'linear'
2709            });
2710        });
2711</script>
2711
2712
2713
2714<p>Do you see what&rsquo;s happening in the <em>Limbo</em> logo area?<br/>
2715<em>The Unfinished Swan</em> white background fades-in and we end up with the <em>Limbo</em> logo &mdash; pure white &mdash; drawn on the top of a background which is also pure white.
2716Everything should be completely white in that area, so why do we have these weird gray pixels?</p>
2717
2718<p>The corruption most likely comes from the <em>Limbo</em> texture using wrong RGB colors for its fully transparent pixels.</p>
2719
2720<h1>Texture Filtering</h1>
2721
2722<p>The artifacts are actually due to the way the GPU filters a texture when it renders a sprite on the screen.
2723Let&rsquo;s see how this all works with a simple example.</p>
2724
2725<p>Here is a tiny 12x12 pixel texture of a red cross: <img class="img-nobox" src="/img/blog/2017/transparentpixels/cross_red.png" style="width: auto;"/></p>
2726
2727<p><img class="left img-nobox" src="/img/blog/2017/transparentpixels/view_cross.png" style="margin-top: 0.3em;"/>
2728On the left is a zoomed view, the checkerboard pattern is just here to emphasize the completely transparent area with an alpha of 0. <br/>
2729You could use this sprite as an icon to display health points in your UI or as a texture for some in-game med-kit model&hellip;
2730(<a href="https://kotaku.com/video-games-arent-allowed-to-use-the-red-cross-symbol-1791265328">No wait! You don&rsquo;t want to do this actually!</a>)</p>
2731
2732<div style="clear: both;"></div>
2733
2734
2735<p>Let&rsquo;s make three versions of this sprite, by changing only the color value of the pixels with an alpha of 0.</p>
2736
2737<table class="table-carousel" style="width: 100%;">
2738<tr style="width: 100%;">
2739    <td style="width: 33%; text-align: center;">
2740        <img class="img-nobox" src="/img/blog/2017/transparentpixels/layer_green.png" style="width: auto;"/> <br/>
2741        <em>
2742        Transparent Area: Green
2743        <br>
2744        Actual Image File:</em>
2745        <img class="img-nobox" src="/img/blog/2017/transparentpixels/cross_green.png" style="width: auto;"/>
2746    </td>
2747    <td style="width: 33%; text-align: center;">
2748        <img class="img-nobox" src="/img/blog/2017/transparentpixels/layer_blue.png" style="width: auto;"/> <br/>
2749        <em>
2750        Transparent Area: Blue
2751        <br>
2752        Actual Image File:</em>
2753        <img class="img-nobox" src="/img/blog/2017/transparentpixels/cross_blue.png" style="width: auto;"/>
2754    </td>
2755    <td style="width: 33%; text-align: center;">
2756        <img class="img-nobox" src="/img/blog/2017/transparentpixels/layer_red.png" style="width: auto;"/> <br/>
2757        <em>
2758        Transparent Area: Red  
2759        <br>
2760        Actual Image File:</em>
2761        <img class="img-nobox" src="/img/blog/2017/transparentpixels/cross_red.png" style="width: auto;"/>
2762    </td>
2763</tr>
2764</table>
2765
2766
2767<p></p>
2768
2769<p>(You can download the image files and do some color picking to confirm the RGB value of the transparent pixels)</p>
2770
2771<p>These 3 sprites look exactly the same on your screen, right?
2772It makes sense: we only modified the color value of the transparent pixels, which end up being invisible anyway.<br/>
2773But let&rsquo;s see what happens when these sprites are in motion. Here is a zoomed view to better see the screen pixels:</p>
2774
2775<div  style="position: relative; margin-bottom:  1.5em ;" >
2776    <div style="margin: auto">
2777        <img src="/img/blog/2017/transparentpixels/cross_anim.gif" style="display: block; margin: auto;  "  />
2778    </div> 
2779    
2780</div>
2781
2782
2783<p>Well that&rsquo;s quite some corruption we have here! Some brown tint for the first sprite, purple tint for the second one.<br/>
2784The 3rd one&hellip; is correct, it&rsquo;s how it&rsquo;s supposed to look.</p>
2785
2786<p>Let&rsquo;s focus on the blue version:</p>
2787
2788<div  style="position: relative; margin-bottom:  1.5em ;" >
2789    <div style="margin: auto">
2790        <img src="/img/blog/2017/transparentpixels/blue_cross_move.gif" style="display: block; margin: auto;  "  />
2791    </div> 
2792    
2793</div>
2794
2795
2796<p>As you can see the issue happens when the texture is not perfectly pixel-aligned with the screen pixels.
2797This can be explained by the <a href="https://en.wikipedia.org/wiki/Bilinear_filtering">bilinear filtering</a>
2798the GPU performs when rendering a sprite on the screen:
2799when sampling a texture, the GPU averages the color values of the closest neighbors of the coordinates requested, both in the vertical and horizontal direction.</p>
2800
2801<p>So if we consider the case where the sprite is misaligned by exactly half a pixel:</p>
2802
2803<p><img class="left" src="/img/blog/2017/transparentpixels/shift.png"  ></p>
2804
2805<p>Each pixel of the screen will sample the sprite texture right in the middle between 2 texels.
2806This is what happens with the pixel you see on the left: it fetches the sprite texture in the middle between a solid red texel and a transparent blue texel.
2807The averaged color is:</p>
2808
2809<p style="text-align: left;">
2810
2811$matht$
28120.5 * [ [\color{#ff2c2c}{1}], [\color{#00c300}{0}], [\color{#2f9fff}{0}], [1] ] 
2813+   
28140.5 * [ [\color{#ff2c2c}{0}], [\color{#00c300}{0}], [\color{#2f9fff}{1}], [0] ]
2815=
2816[ [\color{#ff2c2c}{0.5}], [\color{#00c300}{0}], [\color{#2f9fff}{0.5}], [0.5] ] 
2817$matht$
2818
2819</p>
2820
2821
2822<p>Which is some translucent purple looking like this: <span style="color: #7f007f;">&#9608;</span></p>
2823
2824</div>
2825  
2826  
2827    <footer>
2828      <a rel="full-article" href="/blog/2017/05/09/beware-of-transparent-pixels/">Read on &rarr;</a>
2829    </footer>
2830  
2831
2832
2833    </article>
2834  
2835  
2836    <article>
2837      
2838  <header>
2839    
2840      <h1 class="entry-title"><a href="/blog/2016/09/09/doom-2016-graphics-study/">DOOM (2016) - Graphics Study</a></h1>
2841    
2842    
2843      <p class="meta">
2844        
2845
2846
2847
2848
2849
2850
2851
2852
2853  
2854
2855
2856<time datetime="2016-09-09T18:10:00+02:00" pubdate data-updated="true">Sep 9<span>th</span>, 2016</time>
2857        
2858      </p>
2859    
2860  </header>
2861
2862
2863  <div class="entry-content"><p><img class="left" src="/img/blog/2016/doom2016/shot/../doom_2016_logo.jpg"  ></p>
2864
2865<p><a href="https://en.wikipedia.org/wiki/Doom_(1993_video_game)">DOOM</a> pioneered fundamental changes in game design and mechanics back in 1993, it was a world-wide phenomenon which propelled to fame iconic figures like <a href="https://en.wikipedia.org/wiki/John_Carmack">John Carmack</a> and <a href="https://en.wikipedia.org/wiki/John_Romero">John&nbsp;Romero</a>&hellip;</p>
2866
2867<p>23 years later, <a href="https://en.wikipedia.org/wiki/Id_Software">id Software</a> now belongs to <a href="https://en.wikipedia.org/wiki/ZeniMax_Media">Zenimax</a>, all the original founders are gone but it didn&rsquo;t prevent the team at id from showing all its talent by delivering a great game.</p>
2868
2869<br/>
2870
2871
2872<p>The new <a href="https://en.wikipedia.org/wiki/Doom_(2016_video_game)">DOOM</a> is a perfect addition to the franchise, using the new <a href="https://en.wikipedia.org/wiki/Id_Tech_6">id Tech 6 engine</a> where ex-Crytek <a href="https://twitter.com/idSoftwareTiago">Tiago Sousa</a> now assumes the role of lead renderer programmer after John Carmack&rsquo;s departure.<br/>
2873Historically id Software is known for open-sourcing their engines after a few years, which often leads to <a href="https://www.chocolate-doom.org/wiki/index.php/Chocolate_Doom">nice remakes</a> and <a href="http://fabiensanglard.net/doomIphone/doomClassicRenderer.php">breakdowns</a>.
2874Whether this will stand true with id Tech 6 remains to be seen but we don&rsquo;t necessarily need the source code to appreciate the nice graphics techniques implemented in the engine.</p>
2875
2876<h1>How a Frame is Rendered</h1>
2877
2878<p>We&rsquo;ll examine the scene below where the player attacks a <a href="http://doom.wikia.com/wiki/Gore_nest"><em>Gore Nest</em></a> defended by some <a href="https://doom.fandom.com/wiki/The_Possessed"><em>Possessed</em></a> enemies, right after obtaining the <em>Praetor Suit</em> at the beginning of the game.</p>
2879
2880<p><img class="center" src="/img/blog/2016/doom2016/shot/99_final.jpg"  ></p>
2881
2882<p>Unlike most Windows games released these days, DOOM doesn&rsquo;t use <a href="https://en.wikipedia.org/wiki/Direct3D">Direct3D</a> but offers an <a href="https://en.wikipedia.org/wiki/OpenGL">OpenGL</a> and <a href="https://en.wikipedia.org/wiki/Vulkan_(API)">Vulkan</a> backend.<br/>
2883Vulkan being the new hot thing and <a href="https://twitter.com/baldurk">Baldur Karlsson</a> having recently added support for it in <a href="https://github.com/baldurk/renderdoc">RenderDoc</a>, it was hard resisting picking into DOOM internals.
2884The following observations are based on the game running with Vulkan on a <a href="https://en.wikipedia.org/wiki/GeForce_900_series">GTX 980</a> with all the settings on <em>Ultra</em>, some are guesses others are taken from the <a href="http://advances.realtimerendering.com/s2016/Siggraph2016_idTech6.pdf">Siggraph presentation by Tiago Sousa and Jean Geffroy</a>.</p>
2885
2886<h3>Mega-Texture Update</h3>
2887
2888<p>First step is the <a href="https://en.wikipedia.org/wiki/MegaTexture">Mega-Texture</a> update, a technique already present in <a href="https://en.wikipedia.org/wiki/Id_Tech_5">id Tech 5</a> used in <a href="https://en.wikipedia.org/wiki/Rage_(video_game)">RAGE</a> and now also used in DOOM.  <br/>
2889To give a very basic explanation, the idea is that a few huge textures (16k x 8k in DOOM) are allocated on the GPU memory,
2890each of these being a collection of 128x128 tiles.</p>
2891
2892<div  style="position: relative; margin-bottom:  1.5em ;" >
2893    <div style="margin: auto">
2894        <img src="/img/blog/2016/doom2016/shot/05_megatext_illus.jpg" style="display: block; margin: auto;  "  />
2895    </div> 
2896    
2897    <div class="screenshot-caption"
2898        
2899    >16k x 8k storage with 128 x 128 pages</div>
2900    
2901</div>
2902
2903
2904<p>All these tiles are supposed to represent the ideal set of actual textures at the good mipmap level which will be needed by the pixel shaders later to render the particular scene you&rsquo;re looking at.<br/>
2905When the pixel shader reads from a &ldquo;virtual texture&rdquo; it simply ends up reading from some of these 128x128 physical tiles.<br/>
2906Of course depending on where the player is looking at, this set is going to change: new models will appear on screen, referencing other virtual textures, new tiles must be streamed in, old ones streamed out&hellip;<br/>
2907So at the beginning of a frame, DOOM updates a few tiles through <code>vkCmdCopyBufferToImage</code> to bring some actual texture data into the GPU memory.</p>
2908
2909<p><em>More information about Mega-Textures <a href="http://www.mrelusive.com/publications/papers/Software-Virtual-Textures.pdf">here</a> and
2910<a href="https://web.archive.org/web/20190204083214/http://s09.idav.ucdavis.edu/talks/05-JP_id_Tech_5_Challenges.pdf">here</a>.</em></p>
2911
2912<h3>Shadow Map Atlas</h3>
2913
2914<p>For each light casting a shadow, a unique <a href="https://en.wikipedia.org/wiki/Depth_map">depth map</a> is generated and saved into one tile of a giant 8k x 8k <a href="https://en.wikipedia.org/wiki/Texture_atlas">texture atlas</a>.
2915However not every single depth map is calculated at every frame: DOOM heavily re-uses the result of the previous frame and regenerates only the depth maps which need to be updated.</p>
2916
2917<div id="a_light_depth">
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928<div class="slick-margin05">
2929<div  style="position: relative; " >
2930    <div style="margin: auto">
2931        <img src="/img/blog/2016/doom2016/shot/10_light_depth__zommed_illu_0.png" style="display: block; margin: auto;  "  class="img-nobox"  />
2932    </div> 
2933    
2934    <div class="screenshot-caption"
2935        style="left: 1.5em;"
2936    >8k x 8k Depth Buffer<br/>(Previous Frame)</div>
2937    
2938</div>
2939
2940
2941
2942
2943
2944</div>
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957<div class="slick-margin05">
2958<div  style="position: relative; " >
2959    <div style="margin: auto">
2960        <img src="/img/blog/2016/doom2016/shot/10_light_depth__zommed_illu_1.png" style="display: block; margin: auto;  "  class="img-nobox"  />
2961    </div> 
2962    
2963    <div class="screenshot-caption"
2964        style="left: 1.5em;"
2965    >8k x 8k Depth Buffer<br/>(Current Frame)</div>
2966    
2967</div>
2968
2969
2970
2971
2972
2973</div>
2974
2975
2976
2977</div>
2978
2979
2980
2981
2982<script type="text/javascript">
2983        $(document).ready(function(){
2984            $('#a_light_depth').slick({
2985        autoplay: true,
2986        speed: 600,
2987        autoplaySpeed: 1000,
2988                dots: true,
2989            slidesToShow: 1,
2990            slidesToScroll: 1,
2991        fade: true,
2992        cssEase: 'linear'
2993            });
2994        });
2995</script>
2995
2996
2997
2998<p>When a light is static and casts shadows only on static objects it makes sense to simply keep its depth map as-is instead of doing unnecessary re-calculation.
2999If some enemy is moving under the light though, the depth map must be generated again.<br/>
3000Depth map sizes can vary depending on the light distance from the camera, also re-generated depth maps don&rsquo;t necessarily stay inside the same tile within the atlas.<br/>
3001DOOM has specific optimizations like caching the static portion of a depth map, computing then only the dynamic meshes projection and compositing the results.</p>
3002
3003</div>
3004  
3005  
3006    <footer>
3007      <a rel="full-article" href="/blog/2016/09/09/doom-2016-graphics-study/">Read on &rarr;</a>
3008    </footer>
3009  
3010
3011
3012    </article>
3013  
3014  <div class="pagination">
3015    
3016      <a class="prev" href="/blog/page/2/">&larr; Older</a>
3017    
3018    <a href="/blog/archives/"> <svg class="svg_icon"><use xlink:href="/img/icons.svg#patch"></use></svg>  All Blog Posts</a>
3019    
3020    <br/><br/>
3021    <div style="text-align: center;">
3022<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
3022
3023<!-- AC square 300 250 -->
3024<ins class="adsbygoogle"
3025     style="display:inline-block;width:300px;height:250px"
3026     data-ad-client="ca-pub-4438097360110126"
3027     data-ad-slot="5201554295"></ins>
3028<script>
3029(adsbygoogle = window.adsbygoogle || []).push({});
3030</script>
3030
3031</div>
3032  </div>
3033</div>
3034<aside class="sidebar">
3035  
3036    <section>
3037  <h1>About</h1>
3038  <div style="padding-top: 8px; padding-bottom: 10px;">
3039  <a href="/about/" style="margin: 0; padding: 0; float: left; white-space: normal;" >
3040  <img src="/img/avatar/avatar_opt.svg" class="img-nobox item-rotate" style="width: 68px; margin: -2px 16px 3px 12px;; vertical-align: top;"/>
3041  </a>
3042I&#8217;m Adrian, a software engineer who enjoys playing with game-dev, mobile, web and security. <a href="/about/">More&#8230;</a> 
3043  <div style="clear: both;"></div>
3044  </div>
3045  <div style="padding-bottom: 5px;">
3046  <a title="Twitter" href="https://twitter.com/ado_tan" target="_blank"><div class="socialIcon socialIconTwitter"><div class="socialIconInner">
3047    <svg class="svg_icon"><use xlink:href="/img/icons.svg#twitter"></use></svg>
3048  </div></div></a>
3049  <a title="LinkedIn" href="https://www.linkedin.com/in/adriancourreges" target="_blank"><div class="socialIcon socialIconLinkedIn"><div class="socialIconInner">
3050    <svg class="svg_icon"><use xlink:href="/img/icons.svg#linkedin"></use></svg>
3051  </div></div></a>
3052  <a rel="me" title="Mastodon" href="https://mastodon.social/@ado_tan" target="_blank"><div class="socialIcon socialIconMastodon"><div class="socialIconInner ">
3053    <svg class="svg_icon"><use xlink:href="/img/icons.svg#mastodon"></use></svg>
3054  </div></div></a>
3055  <a title="GitHub" href="https://github.com/acourreges" target="_blank"><div class="socialIcon socialIconGitHub"><div class="socialIconInner ">
3056    <svg class="svg_icon"><use xlink:href="/img/icons.svg#github"></use></svg>
3057  </div></div></a>
3058  <a title="RSS" href="/atom.xml" target="_blank"><div class="socialIcon socialIconRSS"><div class="socialIconInner">
3059    <svg class="svg_icon"><use xlink:href="/img/icons.svg#rss"></use></svg>
3060  </div></div></a>
3061  <a title="Donate" href="https://ko-fi.com/adriancourreges" target="_blank"><div class="socialIcon socialIconTwitter" style="margin-right: 0px;"><div class="socialIconInner" style="width: auto;padding-left: 8px;padding-right: 6px;">
3062   <svg class="svg_icon" style="width: 28px; height: 28px;"><use xlink:href="/img/icons.svg#koficolor"></use></svg><div style="margin-left: 5px;font-weight: bold;letter-spacing: 1px;margin-top:-0.1em;">Tip</div>
3063  </div></div></a>
3064  </div>
3065</section>
3066<section>
3067  <h1>Recent Posts</h1>
3068  <ul id="recent_posts">
3069    
3070      <li class="post">
3071        <a href="/blog/2020/12/29/graphics-studies-compilation/">Graphics Studies Compilation</a>
3072      </li>
3073    
3074      <li class="post">
3075        <a href="/blog/2018/12/02/ue4-optimized-post-effects/">UE4 Optimized Post-Effects</a>
3076      </li>
3077    
3078      <li class="post">
3079        <a href="/blog/2017/12/15/mgs-v-graphics-study/">Metal Gear Solid V - Graphics Study</a>
3080      </li>
3081    
3082      <li class="post">
3083        <a href="/blog/2017/05/09/beware-of-transparent-pixels/">Beware of Transparent Pixels</a>
3084      </li>
3085    
3086      <li class="post">
3087        <a href="/blog/2016/09/09/doom-2016-graphics-study/">DOOM (2016) - Graphics Study</a>
3088      </li>
3089    
3090      <li class="post">
3091        <a href="/blog/2015/11/02/gta-v-graphics-study-part-3/">GTA V - Graphics Study - Part 3</a>
3092      </li>
3093    
3094      <li class="post">
3095        <a href="/blog/2015/11/02/gta-v-graphics-study-part-2/">GTA V - Graphics Study - Part 2</a>
3096      </li>
3097    
3098      <li class="post">
3099        <a href="/blog/2015/11/02/gta-v-graphics-study/">GTA V - Graphics Study</a>
3100      </li>
3101    
3102  </ul>
3103</section>
3104<section>
3105  <h1>Archives</h1>
3106  <ul>
3107  <li class="post">
3108  <a href="/blog/archives/">All Blog Posts List</a>
3109  </li>
3110  </ul>
3111  <ul id="archive">
3112    <li class='post' style='padding: 0 0 0.3em 10px;'><a href='/blog/archives#2020'>2020</a> <span style='font-size: 0.95em'>(1)</span></li><li class='post' style='padding: 0 0 0.3em 10px;'><a href='/blog/archives#2018'>2018</a> <span style='font-size: 0.95em'>(1)</span></li><li class='post' style='padding: 0 0 0.3em 10px;'><a href='/blog/archives#2017'>2017</a> <span style='font-size: 0.95em'>(2)</span></li><li class='post' style='padding: 0 0 0.3em 10px;'><a href='/blog/archives#2016'>2016</a> <span style='font-size: 0.95em'>(1)</span></li><li class='post' style='padding: 0 0 0.3em 10px;'><a href='/blog/archives#2015'>2015</a> <span style='font-size: 0.95em'>(11)</span></li><li class='post' style='padding: 0 0 0.3em 10px;'><a href='/blog/archives#2014'>2014</a> <span style='font-size: 0.95em'>(2)</span></li><li class='post' style='padding: 0 0 0.3em 10px;'><a href='/blog/archives#2013'>2013</a> <span style='font-size: 0.95em'>(1)</span></li><li class='post' style='padding: 0 0 0.3em 10px;'><a href='/blog/archives#2008'>2008</a> <span style='font-size: 0.95em'>(1)</span></li><li class='post' style='padding: 0 0 0.3em 10px;'><a href='/blog/archives#2007'>2007</a> <span style='font-size: 0.95em'>(5)</span></li>
3113  </ul>
3114</section>
3115
3116  
3117</aside>
3118
3119    </div>
3120  </div>
3121  <!-- <footer role="contentinfo"><p>
3122  Copyright &copy; 2025 - Adrian Courrèges - Adrian Courrèges
3123</p>
3124
3125</footer>  -->
3126  
3127  <br/>
3128  
3129
3130<script type="text/javascript">
3131addPageToc()
3132</script>
3132
3133
3134
3135<script type="text/javascript">
3136 
3137      var disqus_shortname = 'adriancourreges';
3138      
3139        
3140        var disqus_script = 'count.js';
3141      
3142lazyLoadDisqus();
3143</script>
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"262bd1773c7a4447bb03b7f5cc8f906d","r":1,"spa":2}' crossorigin="anonymous"></script>
3154
3155</body>
3156</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.