Neste artigo vamos tentar explicar os motivos de algumas das limitações que tem causado problemas aos programadores da Xbox One, bem como referir o que se tem feito para superar as mesmas.
O tempo
Para um sistema informático o tempo é tudo. Para que haja um débito de dados há uma sequência de operações de processamento que envolvem leitura, cálculo e escrita de dados que necessitam de gastar tempo. E quanto menos tempo um sistema gastar com eles, mais poderoso ele é.
Assim, para que um sistema debite 30 fps, ele necessita de fazer todo o ciclo de processamento com as referidas leituras, cálculos e escritas de dados em 33,33 ms. Mas para 60 fps, esses dados necessitam de ser processados em metade desse tempo, ou seja 16,66 ms.
Para se cumprir com estes parâmetros, todos os componentes intervenientes necessitam de responder nas vezes que forem solicitados em tempos que somados cumpram com os valores acima referidos.
1 – Qual a importância da eSRAM
Esta é a pergunta que é necessária pois tudo o resto acaba por passar por aqui.
No que toca à transferência de dados o tempo é normalmente referido de uma outra forma. A largura de banda.
Referir uma largura de banda não implica referir apenas a quantidade de dados que um sistema é capaz de mover por segundo, mas implica igualmente referir o tempo gasto para mover esses dados.
Como exemplo, imaginemos dois sistemas, um capaz de transferir 50 GB/s e outro 100 GB/s. E vamos mover 100 GB!
Como se percebe o primeiro sistema requer 2 segundos, e o segundo requer apenas 1 segundo. Ou seja o segundo sistema ao ter o dobro da largura de banda entrega os dados em metade do tempo. E isso é verdade estejamos perante 100 GB ou perante 1 KB. Qualquer quantidade de dados movida pelo segundo sistema demorará metade do tempo a chegar do que demora no primeiro.
Para percebermos assim a real importância da eSRAM na Xbox One teremos de falar em larguras de banda. Mas não nos valores tradicionalmente conhecidos, mas sim em larguras de banda reais.
De acordo com os dados oficiais da Microsoft dados em entrevista à Digital Foundry, a DDR3 da Xbox One possui uma eficiência que ronda os 70 a 80%, o que lhe permite uma largura de banda real entre os 50 a 55 GB/s. Vamos trabalhar com um valor intermédio de 52,5 GB/s.
Da mesma forma, a Microsoft refere na mesma entrevista que a eSRAM possui 109 GB/s em escrita e/ou leitura, sendo que caso faça as duas em simultâneo o valor máximo realista que a Microsoft reconhece na mesma entrevista ter sido atingido até agora é algo entre 140 e 150 GB/s (vamos usar 145 GB/s).
Analisemos a arquitectura da Xbox nos slides oficiais apresentados pela Microsoft na Hot Chips.
Como vemos o CPU possui uma largura de banda coerente de 30 GB/s. E retirada da largura de banda da DDR3!
Apesar de muito dificilmente o CPU manter este canal constantemente ocupado, a verdade é que, mesmo que pontualmente, o poderá encher. Isso quer dizer que dos 52,5 GB/s que efectivamente temos, se subtrairmos estes 30 obtemos a largura de banda da DDR3 que podemos garantir a 100% do tempo para o GPU. E que é de apenas 22,5 GB/s.
Ora comparativamente à largura de banda de 145 GB/s da eSRAM, este é um valor 6,444444 vezes inferior, o que como vimos corresponde a ser igualmente 6,444444 vezes mais lento a responder. E esse é um valor bastante significativo.
Por aqui se compreende que para se conseguir boas performances e reduzir o tempo de processamento, o uso da eSRAM é obrigatório. Sem ela as performances da consola não conseguem ser obtidas na sua totalidade.
Infelizmente, como todos sabemos, esta memória é de apenas 32 MB e é por ela que toda a informação gráfica contida nos 8 GB deveria idealmente passar.
Mas dado que tal não é possível, a escolha das componentes mais críticas ao processamento para serem colocadas nesta memória é absolutamente essencial. E diga-se que tal até tem decorrido bastante bem uma vez que com mais frame ou menos frame, com mais ou menos diferença de resolução, as performances da Xbox One não tem sofrido assim tanto e a consola até acompanha o que a da concorrência faz, o que mostra que a gestão da memória até se tem revelado bastante adequada.
2 – É ou não possível meter-se um frame buffer 1080p nos 32 MB de eSRAM?
A Microsoft diz que sim, e que 32 MB é suficiente para um framebuffer de 32 MB, mas como já vimos, a eSRAM é super importante e como tal a escolha do que lá é colocado é crítico para as performances. A colocação do frame buffer nessa memória ou na DDR3 é por isso uma escolha dos programadores que pesarão as vantagens e desvantagens para cada caso.
No entanto vamos ver os nossos resultados. Esquecendo que precisamos de manter memória livre para os processos de cálculo, shading, Buffers de iluminação, Stencil, e outras situações, vamos de forma simplificada apenas ver que frame buffers cabem em 32 MB. Note-se não sou programador, pelo que abordo a situação apenas pela componente teórica e mais conhecida num calculo de um framebuffer, tal como usado sem limitações, não se pretendendo afirmar que não possam existir optimização que reduzam as suas dimensões, ou que não existam situações adicionais que o possam aumentar.
Porém antes de o fazermos vamos recomendar que leiam este nosso artigo sobre o Anti Aliasing, especialmente a parte sobre o MSAA e o Super Sampling para que percebam o exemplo que daremos de seguida, bem como este nosso artigo sobre o Screen Tearing, este último absolutamente essencial para a compreensão do que se segue, de forma a perceberem o problema que leva à necessidade de buffers video adicionais e à necessidade de se recorrer a um Double ou um Triple Buffering.
Nesse último artigo do Screen Tearing usamos o termo frame buffer para designar o buffer onde o monitor vai ler a informação a apresentar. No entanto, esse não é efectivamente o frame buffer total, pelo que essa designação, para este novo artigo, se revela enganadora. Vamos por isso designar esse frame buffer parcial pelo seu real nome, ou seja, o Front Buffer.
Assim, nos exemplos dados teremos um Front Buffer onde a informação vídeo final é guardada, e dois back-buffers para a implementação do Triple Buffering necessário para evitar o Screen Tearing quando a placa gráfica debita menos FPS do que a taxa de refrescamento do ecrã.
Vamos igualmente referir outra situação necessária contabilizar para o Frame Buffer, o calculo do Depth Buffer, ou buffer de profundidade, e que é usado na geometria 3D onde na realidade o universo possui 3 dimensões e normalmente designado por Z-Buffer.
Com os conceitos dos dois artigos anteriores e exclusivos da PCManias assimilados, antes de passarmos aos cálculos, vamos referir os tipos de frame buffers existentes:
Formatos de Frame buffer
RGBA8 = Neste tipo de buffer vamos ter 8 bits de cor para os Vermelhos, 8 bits de cor para o Verde, 8 bits de cor para o Azul, e 8 bits para o canal alpha de transparência, o que perfaz uma profundidade de cor total de 32 bits por pixel
FP10 = Neste modo sacrificamos um pouco o canal alpha, atribuindo-se 10 bits de cor a cada um dos componentes do RGB, e apenas 2 bits ao canal alpha. Neste caso continuamos com uma profundidade de cor de 32 bits por pixel
FP16 = Neste modo de cor mais complexo temos 16 bits de cor para cada um dos componentes, o que implica uma profundidade de cor de 64 bits por pixel.
NAO32 = Profundidade de cor de 32 bits por pixel
Vamos assumir que a profundidade de cor do Framebuffer é um dos dois primeiros modos (são os mais comuns, especialmente o primeiro).
Assim, para o cálculo de um Frame buffer total teremos de somar a memória gasta pelos seguintes componentes:
Frame Buffer = Back-Buffer(s) + Z-Buffer + Front-Buffer
Como referido, e aceitando que o jogo possui FPS não bloqueados e oscilantes abaixo da taxa de refrescamento do ecrã, vamos precisar de Triple Buffering, ou seja, um Front Buffer e dois Back Buffers.
Back-Buffer(s) = Pixels * Profundidade do Full Scene Anti Aliasing * Profundidade de cor de cálculo (vamos usar dois backbuffers para evitar o Screen Tearing em fps soltos e variáveis acima e abaixo da taxa de refrescamento do ecrã).
Z-Buffer = Pixels * Profundidade do Full Scene Anti Aliasing * Profundidade do Z (normalmente 32-bits)
Front-Buffer(s), ou o buffer video que é apresentado ao utilizador = Pixels * Profundidade de cor de apresentação.
Assim, em uma imagem 32 Bits, quer de apresentação, quer de cálculo, e com um 2xMSAA que requer o uso do dobro da resolução, teríamos:
1080p, 32 bits cor, 2xMSAA
Front Buffer = 1920*1080*32 bits/8bytes = 8294400 bytes ou 8,1 MB.
Z-Buffer = 1920*1080*2*32/8 = 16588800 bytes ou 16,2 MB
Back Buffers = 1920*1080*2*(32/8+32/8)= 33177600 bytes ou 32,4 MB
Frame Buffer = 8,1+16,2+32,4 = 56,7 MB > 32 MB. – KO
900p, 32 bits cor, 2xMSAA
Front Buffer = 1600*900*32 bits/8bytes = 5760000 bytes ou 5,625 MB.
Z-Buffer = 1600*900*2*32/8 = 11520000 bytes ou 11,250 MB.
Back Buffers = 1600*900*2*(32/8+32/8)= 23040000 bytes ou 22,5 MB.
Frame Buffer = 5,625+11,250+22,5 = 39.375 MB > 32 MB. – KO
720p, 32 bits cor, 2xMSAA
Front Buffer = 1280*720*32 bits/8bytes = 3686400 bytes ou 3,6 MB.
Z-Buffer = 1280*720*2*32/8 = 7372800 bytes ou 7,2 MB.
Back Buffers = 1280*720*2*(32/8+32/8)= 14745600 bytes ou 14,4 MB.
Frame Buffer = 3,6+7,2+14,4 = 25,2MB < 32 MB. – OK
Como vemos, com as características acima referidas, caso todo o framebuffer fosse colocado na eSRAM, apenas poderíamos optar por 720p.
No entanto, o que temos em cima não é uma condição obrigatória. Por exemplo, vamos repetir as contas usando um método de anti aliasing pós processamento em vez do MSAA.
1080p, 32 bits cor, FXAA
Front Buffer = 1920*1080*32 bits/8bytes = 8294400 bytes ou 8,1 MB.
Z-Buffer = 1920*1080*32/8 = 8294400 bytes ou 8,1 MB
Back Buffers = 1920*1080*(32/8+32/8)= 16588800 bytes ou 16.2 MB
Frame Buffer = 8,1+16,2+8,1 = 32,4 MB > 32 MB. – KO
900p, 32 bits cor, FXAA
Front Buffer = 1600*900*32 bits/8bytes = 5760000 bytes ou 5,625 MB.
Z-Buffer = 1600*900*32/8 = 5760000 bytes ou 5,625 MB.
Back Buffers = 1600*900*(32/8+32/8)=11520000 bytes ou 11,250 MB.
Frame Buffer = 5,625+5,635+11,250 = 22,5 MB < 32 MB. – OK
Parece assim que os 1080p estão difíceis. E isto apesar de já andarmos lá perto.
No entanto ainda há mais que pode ser feito. Eis alguns exemplos:
Como já vimos no artigo do Screen Tearing, quanto temos Back Buffers, a escrita da placa gráfica é feita para estes, sendo depois os dados lidos e copiados para o Front Buffer quando o frame está completo.
Isso quer dizer que o Front Buffer é apenas um buffer onde se escreve e lê uma única vez, ao contrário dos back buffers que estão a ser trabalhados pela gráfica. Daí que a sua passagem para a DDR3 é uma possibilidade desde que os tempos gastos a mais na escrita e leitura do monitor não afectem os tempos de entrega dos fotogramas. No entanto dado que estamos a falar de uma quantidade pequena de dados, o tempo acrescido é muito, muito reduzido.
Seja como for, esta situação é apenas referida como explicação de uma solução, mas aqui estamos a fugir à questão que nos trouxe aqui e que é se o frame buffer cabe ou não nos 32 MB, uma vez que estamos a retirar parte dele para a DDR3, e como referido, aqui apenas íamos ver se ele cabia ou não em 32 MB tal como a Microsoft afirma.
Daí que a outra solução que vamos falar seja mais adequada à resposta que pretendemos obter. E já falamos nela no artigo so Screen Tearing: o uso de fotogramas fixos.
Se o jogo tiver sido pensado para 30 ou 60 fps fixos podemos fixar o refresh rate em valor idêntico aos FPS e dispensar o uso de qualquer Back Buffers. Alternativamente pode-se tentar manter a performance sempre acima dos 30/60 fps usando um refrescamento adequado e usando apenas um Back Buffer para compensar uma taxa de fps superior ao refrescamento (um caso pior pois requer mais performance), descendo as necessidades de memória. Note-se porém que qualquer dos casos desperdiçamos parte da capacidade de cálculo do sistema, motivo pelo qual fotogramas fixos ou estáveis não são uma metodologia muito usada.
Neste último caso dos 1080p, se não precisássemos de qualquer dos back buffers a utilização passaria para 8,1 MB+16,2 MB = 24,2 MB. E a memória tornava-se suficiente.
Naturalmente que na prática a solução é mais complexa e se possível, para além de outras soluções que possam ser metidas ao barulho, misturam-se estas tentando dispensar um (o mais comum com fps sempre acima do refrescamento) ou mesmo os dois back buffers (fps fixos) e o front buffer passa para a DDR3 de forma a libertar a maior parte de eSRAM possível. E até há casos onde todo o framebuffer é movido por haver outras componentes que se revelam mais importantes.
O que se pretende que se perceba aqui são várias coisas.
1º – Há soluções.
2º – Nenhuma das soluções é perfeita e podem obrigar a sacrifícios (como a descida da qualidade do anti aliasing, ou corte de efeitos gráficos (quer totalmente, quer na qualidade) para libertar memória)
3º – Requer planeamento, trabalho e experimentação para ver o que é melhor.
3 – Porque motivo alguns jogos ganharam com a libertação da reserva dos 10% do Kinect e outros não?
A resposta a esta questão poderá já ser óbvia. Tudo depende do factor que limitava o jogo. Se era uma questão relacionada com a eSRAM, a libertação da reserva não altera qualquer realidade. Mas se era uma questão relacionada com performance geral, 10% poderão permitir dar o salto. Eis exemplos.
Vamos ver exemplos: Destiny por exemplo, será um jogo 1080p estudado para garantir 30 fps a 30 Hz, em ambas as consolas, aparentemente com fps fixos, i.e com cada frame a ser calculado a cada 33,33 ms, e uma vez que usa um FXAA e não um 2xMSAA, como já vimos, a utilização de máxima de memória para o framebuffer (caso este esteja totalmente na eSRAM) é de apenas 16,2 MB , dando espaço para outros processamentos em paralelo. Isso leva a crer que este não era um jogo de forma alguma limitada pela eSRAM, mas sim pela performance global da consola que já andaria já perto dos 1080p 30 fps, mas sem os conseguir manter estáveis.
Ora caso os FPS não fossem estáveis, para se manter os 1080p tinhamos de acrescentar back buffer para evitar os problemas de screen tearing, e dado que isso iria criar problemas não existentes até então, o mais lógico seria descer a resolução para os 900p onde a performance era suficiente para os 30 fps bloqueados.
Ou seja, estamos aparentemente perante um caso de um jogo que não estava preso por questões de limitações da eSRAM, mas sim por uma pequena margem de performance que se conseguiu superar.
Diablo 3 é outro dos casos onde aparentemente teremos os fps bloqueados e tambem aparenta não ter limitações da eSRAM pelo que estaria exactamente na mesma situação, pelo que com a libertação da reserva destinada ao Kinect pode-se passar definitivamente para os 1080p 60 fps (No PC Diablo 3 corre a 50 fps a 1920*1200 em uma ATI 7750, sendo pouco dependente do CPU).
Fica assim claro que para 1080p na XBox One há efectivamente casos onde não temos limitações de memória, mas apenas, como é normal em qualquer sistema, na performance global. Mas isso é algo mais comum em casos em que temos um motor capaz de criar um número de FPS fixos nessa resolução ou então estes são bloqueados superiormente de forma a se garantir pelo menos 90% do tempo nesse limite superior usando apenas um Double Buffer (mesmo que correndo o risco de algum “tearing” nos restantes 10%).
Actualmente vários jogos na Xbox One possuem fps bloqueados não tendo assim limitações na eSRAM que coloquem problemas de performance a 1080p, como é o caso de Forza 5 e de Wolfenstein: The New Order.
4 – Porque motivo alguns jogos tem resoluções estranhas como 792 p?
O Deferred rendering é uma alternativa ao método tradicional de render cenas 3D. Na metodologia clássica cada objecto é rendido e é-lhe aplicado um passagem de luz. Isso quer dizer que se um objecto for afectado por 6 luzes, ele tem de ser rendido 6 vezes, uma para cada luz de forma a acumular os efeitos.
Mas o Deferred Rendering toma outra aproximação. Todos os objectos rendem a sua informação de luz e cria-se uma textura chamada de G-Buffer que inclui todos os dados necessários para o cálculo da cor final. Depois as luzes são rendidas como geometria (cones para focos, esferas para luzes omnidireccionais, etc) e usam o G-buffer para calcular a contribuição de luz para esse pixel.
O motivo para o uso de Deferred Rendering é a performance que se revela superior quando há muitos objectos e/ou luzes e o render target mais acedido nesta metodologia é exactamente o G-Buffer que, devido à baixa performance da DDR3, necessita de estar colocado na eSRAM.
Infelizmente esta é uma metodologia que requer memória, e como tal aparecem jogos como TitanFall ou Watch Dogs a usar resoluções estranhas como 792p.
Titanfall é um jogo usa um método de “Deferred Rendering” simplificado, o “Deferred Shading”, mas não usa a versão mais complexa denominada de “Deferred Lighting”. Ora o uso de um “Deferred Shading” implica o uso de um G-Buffer de 20 bytes por pixel ao qual se acrescenta um “radiance target” de mais 8 bytes. É um total de 28 bytes por pixel.
Assim sendo é uma questão de se fazer as contas e ver que resolução caberia nos 32 MB.
Passando os MegaBytes a Bytes temos:
32 MB*1024*1024=33554432 bytes
Ora se dividirmos esse valor por 1920*1080 (1080p), com esta memória teríamos disponíveis 16,18 bytes por pixel. Ou seja, os 32 MB não chegam!
A 900p o valor seria de 23,3, ou seja a memória não chega igualmente.
A 720p teriamos 36,4 Bytes, ou seja, o G-Buffer cabe perfeitamente na RAM.
Pensando em subir um pouco mais na resolução mantendo a proporção largura/altura da resolução em 1,777777777777778, vemos que nem todas elas nos servem por não apresentarem valores inteiros. No entanto eis que chegamos a um valor que obedece a essa proporção e se adequa à necessidade de memória: A 792p a memória disponível é de 30,01 Bytes por pixel, o que significa que a memória está basicamente usada na sua totalidade, e o melhor possível.
Este é o motivo pelo qual aparecem jogos a 792p.
Watch Dogs usa exactamente o mesmo tipo de Deferred Shading, razão pela qual a resolução é exactamente a mesma.
Curiosamente esta é a técnica igualmente usada em Ryse: Son of Rome, mas como podemos ver neste PDF a Crytek utilizou várias metodologias que reduzem o uso de memória neste tipo de rendering, conseguindo assim chegar aos 900p. Esta é uma situação igualmente descrita neste documento que refere que nas consolas mais flexíveis (o que é o caso) algumas variações da técnica permitem descer o uso da memória para algo entre os 20 e os 24 bytes por pixel, o que apesar de ser insuficiente para a Xbox One atingir os 1080p, permite efectivamente os 900p.
No entanto, Ryse foi mais longe que a metodologia tradicional, usando um G-Buffer minimalista (pag. 12) com diminuição da qualidade do processamento do pixel, e com este método é possível chegar-se aos 1080p (como a Crytek deixa perceber no PDF na pag. 42). Mas naturalmente, dado que as perdas na qualidade ultrapassavam as benesses da resolução, essa foi uma hipótese fora de questão, pelo que a escolha ficou-se pelo que a Crytek chamou de “Sweet Spot” ou “ponto doce”, os 900p. E o resultado, como todos sabemos, foi excelente.
Naturalmente todas estas explicações baseiam-se no principio que não há limitações de performance no sistema (seja ela global, ou pontual). Pois por exemplo, a PS4, mesmo não tendo problemas com o limite de memória, usando o mesmo tipo de programação que a Xbox, não conseguiu mais que 900p em Watch Dogs, mas aqui o problema deveu-se ao facto de o jogo ser compatível com as consolas de anterior geração que impediu o uso de técnicas mais avançadas e não suportadas pelo hardware mais antigo.
Acréscimo
Tenho andado a falar com este assunto em um fórum frequentado por programadores, sendo que recebi a seguinte resposta de Sebastian Aaltonen, o programador gráfico principal da RedLynx, responsável por Trials Evolution e Trials Fusion que nos falou sobre a dimensão mínima de um G-Buffer bem como nos deu a conhecer novas técnicas acabadas de aparecer.
Deixo-vos a resposta dele. Avisa-se desde já que pela complexidade da resposta, e dado que opto por colocar estes dados como mera informação e não como parte integrante e necessária do artigo, optei igualmente por não a traduzir, sendo que é preciso um pouco de conhecimentos para a entender:
The tightest G-buffer layout is 12 bytes per pixel. That is two ARGB8 render targets plus a 32 bit per pixel depth+stencil buffer.
You store albedo.rgb and roughness to the first ARGB8 render target, and specular (grayscale) and normal.xyz to the second render target. You can store the normal with only two channels if you use some encoding scheme, but 8+8 bits provides slightly too bad quality for my taste. This way you free one 8 bit channel for some other use.
Chroma subsampling also frees one extra 8 bit channel per pixel (Cr and Cb are stored for every other pixel). We don’t use this, because we have a third g-buffer layer on next gen consoles (total of 16 bytes per pixel).
In our case (Trials Evolution & Trials Fusion) we use 10-10-10-2 format (instead of ARGB8) as the second render target format. This gives 10+10 bits for the normal vector (four times the precision compared to 8 bit). We encode our normals with Lambert azimuthal equal-area projection. It’s costs only a few ALU instructions to encode and decode. Roughness is stored to the third component with 10 bits precision (we use 2^x roughness for our physically based formula, so all the extra precision is welcome). The remainig 2 bit channel is used to store the selected lighting formula (four different formulas are supported).
If you use traditional (pixel shader based) deferred rendering. You also need to have a (HDR) lighting buffer in the memory at the same time as the g-buffer, as the lighting shader reads the g-buffer and writes to the lighting buffer. This consumes extra 8 bytes per pixel (ARGB16F). However with modern compute shader based lighting, you can do the lighting “in-place”, meaning that you first read the g-buffer to the GPU local memory (LDS), do the lighting there, and output the result on top of the existing g-buffer. This way you can do pretty robust deferred rendering with just 16 bytes per pixel (eight 8 bit channels, three 10 bit channels, one 2 bit channel, 24 bit depth, 8 bit stencil).
Obviously on modern GPUs (full rate 64 bpp ROPs) you pack the two ARGB8 render targets to a single ARGB16 render target (to double the fill rate). This also makes it easier to write the output 16 bit float values on top of the existing buffer (no need to split the float values to 8 bit upper and lower parts).
There’s also exist new deferred rendering techniques that do not store the color/material data to the g-buffer at all. By using a technique like this, you can fit even an 8xMSAA g-buffer to a very tight space. It’s going to be interesting to see that kind of innovations all the big studios have came up with when the second wave of next gen games are launched. During the last generation we got a lot of new innovations: HDR lighting (including tone mapping and color grading), deferred shading (many variations), cascaded shadow mapping (and SDSM), variance based shadow filtering, post process antialiasing (many variations), physically based rendering, specular antialiasing (Toksvig and LEAN/CLEAN mapping) and many other new innovations that we almost universally adapted by all studios.
Mediante esta resposta questionamos se a equipa tinha conseguido chegar aos 16 bytes por pixel, porque (de acordo com algumas publicações), a ideia original era os 1080p para ambas as consola, e com 16 bytes por pixel, caso não fosse necessária eSRAM para mais, poderiam ter atingido os 1080p. Questionamos igualmente se o DirectX 12 poderia ajudar com a situação, algo que não foi respondido.
O que penso ser de reter é que a resposta explica que um dos motivos pelos quais não se atingiu os 1080p foi a necessidade de outros buffers na eSRAM (um Buffer HDR e um Stencil Buffer), bem como a compatibilidade necessária no código para com a XBox 360 e os PCs DirectX 10 que limita a versatilidade no uso do GPU e consequentemente o uso de compute shaders.
A resposta total foi:
We didn’t target 1080p. We targeted locked 60 fps (meaning that the game runs most of the time at 70-80 fps and dips down to 60 fps when heavily stressed). During most of our development time, we were 720p on both next gen platforms. Stable 60 fps was very important for our level designers during the development (the game is basically a physics based reaction game). Like I said in my Digital Foundry interview, at the end of the project we upgraded the resolutions as we finalized our engine optimizations. We were very happy to achieve 900p on Xbox One and 1080p on PS4. We didn’t need to do any shader quality trade-offs on either platforms.
We weren’t 16 bytes per pixel, because Trials Fusion was a cross generation game, and we had to support Xbox 360 and DirectX 10 PCs as well, so we still used pixel shader based lighting (tiled deferred lighting, but with CPU based vectorized light binning instead of a GPU based compute shader binning). Basically the tiling algorithm was directly ported from Xbox 360 to PC and other platforms. So we had a separate (HDR) lighting buffer, and that used some extra memory. We also had a 1 byte per pixel stencil buffer.