Estou tentando entender o que é HDR e como ele funciona.
Entendo os conceitos básicos e tenho uma pequena idéia de como ele é implementado com o D3D / hlsl.
No entanto, ainda está muito nublado.
Digamos que eu esteja renderizando uma esfera com uma textura da Terra e uma pequena lista de vértices para atuar como estrelas, como eu renderizaria isso em HDR?
Aqui estão algumas coisas sobre as quais estou confuso:
Acho que não posso usar nenhum formato básico de imagem para a textura, pois os valores seriam limitados a [0, 255] e fixados a [0, 1] em um shader. O mesmo vale para o buffer de volta, entendo que o formato precisa ser um formato de ponto flutuante?
Quais são as outras etapas envolvidas? Certamente deve haver mais do que apenas usar formatos de ponto flutuante para renderizar em um destino de renderização e aplicar alguma floração como um processo posterior? (considerando que a saída será 8bpp de qualquer maneira)
Basicamente, quais são as etapas para o HDR? Como funciona ? Parece que não consigo encontrar bons papéis / artigos que descrevam o processo, além deste , mas ele parece deslizar um pouco sobre o básico, por isso é confuso.
Tecnicamente, HDR significa apenas o uso de uma faixa maior de valores possíveis para seus gráficos. Normalmente, você está restrito a 256 valores discretos para os canais vermelho, verde e azul, o que significa que se você tiver 2 itens, um com o dobro da luminosidade do outro e um terceiro com 10.000 vezes mais brilho que o primeiro, não haverá maneira como você pode representar todos os 3 na mesma cena corretamente - ou você torna o objeto brilhante apenas 256x mais brilhante que o primeiro, ou torna ambos os objetos opacos completamente pretos (perdendo o contraste entre eles) e o objeto brilhante é infinitamente mais brilhante do que os dois.
Isso é fácil de corrigir usando valores de ponto flutuante para os valores vermelho / verde / azul - mas agora você tem o problema de como exibi-lo em um dispositivo gráfico que lida com apenas um número fixo de valores discretos por canal (por exemplo, 256) . Portanto, a segunda parte do problema é como mapear seus valores de ponto flutuante de volta ao intervalo limitado. A solução trivial é dimensionar todos os valores proporcionalmente para um intervalo discreto, mas isso significa que 1 pixel muito brilhante pode deixar o restante da tela preto, etc. Às vezes é isso que você deseja, às vezes não é - veja o mapeamento de tons do CiscoIPPhone link para exemplos de como você pode abordar isso.
Geralmente, não são suas texturas que precisam ser armazenadas em um novo formato - é quando a iluminação é aplicada a elas que você precisa acomodar valores maiores. Obviamente, no entanto, se você tiver fontes de luz cozidas em uma textura - por exemplo, um fundo estrelado - você pode querer um formato de resolução mais alta lá. Ou apenas faça com que o shader dimensione os valores desses materiais quando chegar a hora de renderizá-los.
fonte
Os computadores tradicionalmente representavam cada pixel na tela como apenas 24 bits na memória: 8 para vermelho, 8 para verde e 8 para azul. Isso é quase o suficiente para que um ser humano não notaria se você adicionasse mais, e o byte de 8 bits é muito conveniente para microprocessadores, então foi isso que aconteceu.
Enquanto 8 bits é quase precisão suficiente para exibir uma imagem, definitivamente não é precisão suficiente para calcular uma imagem. Em vários pontos ao calcular uma imagem, são necessários pelo menos 32 bits de precisão.
É por isso que os sombreadores de pixel calculam as cores com precisão de 32 bits, mesmo quando você está renderizando para uma imagem de precisão de 8 bits. Caso contrário, você não poderia, por exemplo, dividir um valor por 1000 e depois multiplicá-lo por 1000, porque dividir qualquer valor de 8 bits por 1000 resulta em zero.
Houve uma tendência nos gráficos 3D em tempo real de manter todos os gráficos com precisão> 8 bits até o último momento possível; nesse momento, os> 8 bits de vermelho são reduzidos para 8 bits e assim por diante para verde e azul.
HDR refere-se ao ato de renderizar imagens com precisão superior a 8 bits. Nos videogames de TV contemporâneos, a precisão de 16 bits é a norma, e isso pode ser "suficiente" nos videogames nos próximos anos.
fonte
Um aspecto que considero essencial para o HDR é a aplicação correta do monitor gama.
O monitor que você está vendo produz luz em função dos pixels de entrada. Você pode esperar que um pixel com valor 255 produza (aproximadamente) 255 vezes mais luz que um pixel com valor 1. Esse não é o caso. Com uma gama de monitores padrão de 2,3, é 255 ^ 2,3 vezes mais brilhante, ou cerca de 340000!
Todo mundo que produz conteúdo (mantenedores de câmera) sabe disso ou (se você é um designer) você implicitamente compensa.
Tudo bem se você renderizar bitmaps (bem, na maioria das vezes), mas se você usá-los como texturas em uma cena 3D, é uma história diferente. Se você deseja modelar a interação com a luz corretamente, use cálculos lineares de luz em todo o pipeline de renderização. Isso significa
corrigindo suas texturas para gama
renderize tudo com luz linear (onde você precisa de muita precisão devido à alta faixa dinâmica de luz),
aplique a transformação gama inversa do monitor como a última coisa antes de colocar a imagem na tela.
Quando você faz essa alteração em uma cena existente, com obras de arte, luzes etc., provavelmente precisará corrigir muitas intensidades e texturas de luz, porque elas foram escolhidas para ficar bonitas ao renderizar com luz não linear. Portanto, não é um recurso que você pode simplesmente "ativar" e esperar que tudo fique melhor assim.
fonte