Cobertura - falha no algoritmo - como se livrar de seu uso?


10

Introdução

Muitos dos principais mecanismos de renderização de gráficos vetoriais possuem uma falha algorítmica. Eles renderizam cada forma separadamente e antialias calculando a cobertura de pixels e depois as compõem umas sobre as outras. Sim, é simples, mas as soluções corretas são ainda mais simples.

Isso leva a um problema de conflilação, pois confunde a cobertura pela transparência. A mistura alfa segue uma regra que não representa a situação com precisão, por exemplo, pegue um pixel coberto de 50% que seja vizinho de um pixel que também seja coberto de 50% complementar não termine com 100% de cobertura e termine com 75% de cobertura . A aparência disso depende de como o algoritmo é ajustado e de outros detalhes, mas, em essência, esse é um erro conhecido. Alguém chegou a ter o trabalho de documentar os diferentes erros do mecanismo, além de escrever um artigo mostrando como isso poderia ser feito melhor.

insira a descrição da imagem aqui

Imagem 1 : Amostra totalmente não representativa, de renderização de uma forma feita de triângulos mostrando erro ampliado na linha superior. Fonte SVG

O problema tem uma solução simples e ingênua * apenas uma super amostra sem cálculo de cobertura e filtra a imagem para baixo. Como bônus, você pode usar algoritmos de reconstrução de imagem melhores do que a filtragem de caixas (leia A Pixel não é um quadrado 3 ). Existem até soluções com velocidade comparável às soluções atuais e essas soluções são muito mais fáceis de serem executadas em pipelines de rasterização de hardware (e você raramente vê esse erro na GPU porque foi criada para evitar esse problema).

Isso também não é um problema sem custo. Há muitas pessoas trabalhando no design gráfico que gastam um tempo não trivial tentando contornar esse problema manualmente, garantindo que haja sobreposição aqui e não sobreposição para corrigir o problema que o computador deve fazer por elas. E falhando espetacularmente em muitos casos. Mas seus clientes não se importam porque o erro existe, eles devem corrigi-lo.

Questão

Como o erro se propaga? Como todos estão cometendo o mesmo erro, pode-se concluir que eles usam a mesma fonte para seu algoritmo. O que poderia ter causado os designers escolherem esse algoritmo? Por que apenas os programadores em 3D reconheceram esse erro e até mesmo codificaram sua parte nas APIs e no ensino, enquanto os programadores em 2D não?

Como garantir que esse erro pare de se propagar mais?


Adendo (mas não estou perguntando sobre isso)

* Aparentemente, minha afirmação de que a super amostragem funciona sem falhas é extraordinária e requer provas extraordinárias. Ok, então a chave para o trabalho de super amostragem é que a super amostragem não faz o processamento da cobertura. Em essência, o super amostrador trata cada amostra como uma amostra pontual. Como a amostra pontual não assume a área subjacente, ela não está causando a comparação alfa onde isso não ocorre.

Para que funcione de forma consistente, conforme descrito em uma das respostas. Precisamos fazer para processar as amostras com amostragem inteira para consistência. Isso garante que cada ponto, uma vez transformado em espaço de tela, obtenha exatamente a mesma solução para coordenadas iguais e que nenhuma amostra seja sombreada por uma borda de pixel 2 vezes. Para fazer isso, uma amostra pode não acionar um pixel ou está exatamente ligado, por exemplo, na parte inferior esquerda (por isso, estabelecemos uma regra de que as arestas exatas são processadas em> vs <=). Todas as placas gráficas, exceto uma, funcionam assim. Ele garante que nenhum dado extra precise ser armazenado em cache e nenhum teste extra nas proximidades precisa ser feito. Esta solução é tão estável, mais geral e consistente que as soluções baseadas em cobertura.

O algoritmo é exatamente o mesmo que o original, com um pouco menos de código e um pouco mais de amostras. É, portanto, tão consistente, se não mais, do que o algoritmo baseado em cobertura. Sabemos disso porque usamos esses métodos há muito tempo em praticamente qualquer outro campo de processamento de sinal, além de placas gráficas.

Então, este método tem uma desvantagem? Bem, é um pouco mais lento se você fizer uma suposição ingênua. Teoricamente, possui um comportamento assintótico mais rápido que o rasterizador de cobertura, parecido com um rastreador de raios, ainda está apenas em pé de igualdade nas cenas típicas. Também poderia tornar mais difícil o uso de efeitos baseados em convolução.


Adicionarei fotos para o meu amnendo assim que terminar meu dia de trabalho. Depois de tudo isso é de processamento gráfico que tem uma interpretação visual
joojaa

Respostas:


6

A superamostragem, quando realizada de forma ingênua, é computacionalmente cara, pois se você usar, por exemplo, metade do tamanho de pixel da tela, precisará de quatro vezes a memória e a largura da banda. A Wikipedia menciona isso e também nomeia a supersampling adaptável como uma solução possível. Mas isso começa a tornar o algoritmo muito mais sofisticado, complexo e difícil de implementar.

E acho que esse é o motivo pelo qual você está procurando: se você deseja um algoritmo que não precise de muito mais memória e tempo de execução, as coisas estão ficando muito mais complicadas do que na ingênua abordagem de "transparência".


Na verdade, você não precisa armazenar as amostras, tudo o que você precisa fazer é armazenar a configuração de rasterização. O método baseado em cobertura também não os armazena, portanto, isso não representa um retrocesso. O método ingênuo é apresentado apenas porque é fácil de entender, você pode facilmente fazer amostragens baseadas em prioridades. Além disso, se você deseja mover suas soluções baseadas em cobertura para a GPU, precisará fazer muito trabalho extra e será incompatível com seu modelo.
Joojaa 28/09/16

@joojaa: você pode descrever o que você quer dizer com "armazenando a configuração de rasterização" ou fornecer um link onde a abordagem é explicada de uma maneira que não é necessário pesquisar um artigo científico de> 20 páginas?
Doc Brown

Cada pixel é independente um do outro, portanto, você só precisa salvar as amostras enquanto estiver fazendo o pixel. É possível descartá-las com segurança depois disso. Se você quiser usar um marcador de ordem superior, poderá armazenar apenas uma exibição limitada. Então, tudo que você realmente precisa fazer é alocar memória para o seu núcleo de processamento, então talvez (16-256 bytes por thread)
joojaa

oh pena que nem sequer necessidade de armazenar as amostras se youy fazer caixa de filtragem você pode apenas usar a fórmula para mover / corrida média, que não precisa de você para armazenar amostras individuais
joojaa

@joojaa: Eu não entendi - você não precisa calcular as amostras primeiro de todas as formas relacionadas , talvez centenas ou milhares, e depois filtrar para a exibição raster?
Doc Brown

6

A superamostragem não resolverá o problema em geral: apenas o tornará menos perceptível. Com pixels com metade do tamanho, o problema será metade do visível, mas não desaparecerá.

O ponto arquitetônico por trás desses projetos é que queremos que o comando "renderize o triângulo ABC" tenha um significado definido. Não queremos que seja ambíguo, exceto quando considerado como parte de uma coleção de comandos de desenho - por exemplo, ter um significado quando "tornar triângulo BCD" também estiver na coleção (com a mesma ou uma cor diferente) e outro significado quando não é.

Considerando, por exemplo, mil triângulos, até encontrar todos os triângulos que compartilham um lado ou parte de um lado com o ABC é computacionalmente pesado (lembrando que é necessário refazer mil vezes). Também existem muitos outros problemas práticos: notavelmente, todas as solicitações de renderização originais precisam ser mantidas, mesmo que tenham sido extraídas há muito tempo, caso precisem ser reavaliadas por causa de uma nova solicitação adicional.

A linha inferior é que uma solução perfeitamente consistente não é praticável. Resta a pergunta: devemos tentar melhorar a situação atual quando pudermos? Em geral, a resposta para essa pergunta é Não. Uma implementação perfeitamente consistente de um modelo é sempre melhor, mesmo que o próprio modelo tenha as limitações que você ilustrou. A alternativa seria uma implementação que às vezes se sai melhor e às vezes não, sem que o programador saiba qual desses dois se manterá em qualquer caso específico. Além disso, pode pular de "faz melhor" para "não faz melhor" como resultado de pequenas alterações feitas pelo programador - ou mesmo como resultado de outras que estão fora do controle do programador. A previsibilidade, em um contexto de programação, está longe,


Este é um problema do cálculo da cobertura, se minha superamostragem NÃO fizer o cálculo da cobertura, ela não terá problemas, pois convergirá para a resposta real e não apenas diminuirá o problema. Você precisa de algum código para provar isso? É assim que a sua placa gráfica funciona e não obtém esse problema. Caso contrário, todos os jogos que você exibir exibirão o problema. Não estou comprando esta resposta, pois ela se baseia em lógica falsa.
Joojaa 26/09/16

Os jogos do @joojaa não fazem anti-aliasing ou usam super-amostragem para anti-aliasing, o que fornece tipicamente quatro níveis de anti-aliasing. Isso não é bom o suficiente para gráficos de qualidade de apresentação em que você deseja cerca de 64 níveis de anti-aliasing. Portanto, os jogos trocam um problema por outro.
Pete Kirkham

O @PeteKirkham depende da sua configuração. Algumas gamas permitem especificar valores de amostra. De qualquer forma, você não precisa de mais de 16 amostras para produzir o nível de apresentação AA se você usar um filtro de ordem superior ao filtro de caixa. Observe que a imagem sem erro no meu exemplo é feita por superamostragem dentro do reasterizer de hardware.
Joojaa 28/09/16
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.