Ao reduzir a profundidade de cor e o pontilhamento com um ruído de 2 bits (com n =] 0,5,1,5 [e saída = piso (entrada * (2 ^ bits-1) + n)), as extremidades do intervalo de valores (entradas 0.0 e 1.0 ) são barulhentos. Seria desejável que eles fossem de cor sólida.
Exemplo: https://www.shadertoy.com/view/llsfz4
(acima, é uma captura de tela do shadertoy, representando um gradiente e as duas extremidades, que devem ser brancas e pretas sólidas, respectivamente, mas barulhentas)
Obviamente, o problema pode ser resolvido apenas compactando a faixa de valores para que as extremidades sejam sempre arredondadas para valores únicos. Isso parece um pouco complicado, e eu estou querendo saber se há uma maneira de implementar isso "corretamente"?
image-processing
noise
hotmultimedia
fonte
fonte
Respostas:
TL; DR: 2 * 1LSB pontilhado triangular-pdf quebra nas bordas em 0 e 1 devido ao aperto. Uma solução é ler um pontilhado uniforme de 1bit nessas bordas.
Estou adicionando uma segunda resposta, visto que isso ficou um pouco mais complicado do que eu pensava inicialmente. Parece que esse problema foi "TODO: precisa de aperto?" no meu código desde que mudei do pontilhamento normalizado para o triangular ... em 2012. É bom finalmente vê-lo :) Código completo para soluções / imagens usadas em todo o post: https://www.shadertoy.com/view/llXfzS
Primeiro de tudo, aqui está o problema que estamos vendo, ao quantificar um sinal para 3 bits com o pontilhamento triangular-pdf de 2 * 1LSB:
- essencialmente o que a hotmultimedia mostrou.
Aumentando o contraste, o efeito descrito na pergunta se torna aparente: o resultado não é em média preto / branco nas bordas (e na verdade se estende muito além de 0/1 antes de fazê-lo).
Olhar para um gráfico fornece um pouco mais de insight:
(as linhas cinza marcam 0/1, também em cinza é o sinal que estamos tentando emitir, a linha amarela é a média da saída pontilhada / quantizada, o vermelho é o erro (média do sinal)).
Curiosamente, a saída média não é apenas 0/1 nos limites, mas também não é linear (provavelmente devido ao pdf triangular do ruído). Observando a extremidade inferior, faz sentido intuitivo o motivo pelo qual a saída diverge: Como o sinal pontilhado começa a incluir valores negativos, a fixação na saída altera o valor das partes pontilhadas inferiores da saída (ou seja, os valores negativos). aumentando o valor da média. Uma ilustração parece estar em ordem (pontilhado 2LSB uniforme e simétrico, média ainda em amarelo):
Agora, se apenas usarmos um pontilhamento 1LSB normalizado, não haverá problemas nos casos de bordas, mas é claro que perderemos as boas propriedades do pontilhamento triangular (veja, por exemplo, esta apresentação ).
Uma solução (pragmática, empírica) (hack), então, é reverter para [-0,5; 0,5 [pontilhamento uniforme para o edgecase:
Que corrige as bordas, mantendo intacto o pontilhamento triangular para o intervalo restante:
Portanto, para não responder à sua pergunta: não sei se existe uma solução matematicamente mais sólida e estou igualmente interessado em saber o que os Masters of Past fizeram :) Até então, pelo menos, temos esse truque horrível para manter nosso código funcionando.
EDIT
Provavelmente, eu deveria abordar a sugestão de solução alternativa apresentada em The Question, simplesmente comprimindo o sinal. Como a média não é linear nas edgecases, a simples compactação do sinal de entrada não produz um resultado perfeito - embora conserte os pontos finais:
Referências
fonte
dithertri
e emdithernorm
vez de um independente. Depois de trabalhar com toda a matemática e cancelar todos os termos, você descobrirá que não está lendo nada! Em vez disso, o código age como um ponto de corte rígidov < 0.5 / depth || v > 1 - 0.5/depth
, alternando instantaneamente para a distribuição uniforme lá. Não que isso afaste o belo pontilhamento que você tem, é apenas desnecessariamente complicado. Corrigir o bug é realmente ruim, você vai acabar com uma pontada pior. Basta usar um ponto de corte rígido.Não sei se posso responder totalmente à sua pergunta, mas acrescentarei algumas idéias e talvez possamos chegar a uma resposta juntos :)
Primeiro, a base da pergunta não é clara para mim: por que você considera desejável ter um preto / branco limpo quando todas as outras cores apresentam ruído? O resultado ideal após o pontilhamento é o sinal original com ruído totalmente uniforme. Se preto e branco forem diferentes, seu ruído ficará dependente do sinal (o que pode ser bom, pois acontece onde as cores são fixadas de qualquer maneira).
Dito isto, há situações em que o ruído nos brancos ou nos negros representa um problema (não conheço casos de uso que exijam que o preto e o branco sejam simultaneamente "limpos"): Ao renderizar uma partícula combinada aditivamente como um quad com como uma textura, você não deseja adicionar ruído em todo o quad, pois isso também seria mostrado fora da textura. Uma solução é compensar o ruído, em vez de adicionar [-0,5; 1,5 [você adiciona [-2,0; 0,0 [(isto é, subtrai 2 bits de ruído). Essa é uma solução bastante empírica, mas não estou ciente de uma abordagem mais correta. Pensando nisso, você provavelmente também quer aumentar seu sinal para compensar a intensidade perdida ...
De alguma forma relacionado, Timothy Lottes fez uma palestra do GDC sobre moldar o ruído nas partes do espectro onde é mais necessário, reduzindo o ruído na extremidade brilhante do espectro: http://32ipi028l5q82yhj72224m8j-wpengine.netdna-ssl.com/wp- content / uploads / 2016/03 / GdcVdrLottes.pdf
fonte
Simplifiquei a ideia de Mikkel Gjoel de pontilhar com ruído triangular para uma função simples que precisa apenas de uma única chamada RNG. Eu retirei todos os bits desnecessários para que fique bem legível e compreensível o que está acontecendo:
Para a idéia e o contexto, encaminhá-lo-ei à resposta de Mikkel Gjoel.
fonte
Eu segui os links para esta excelente pergunta, juntamente com o exemplo shadertoy.
Tenho algumas perguntas sobre a solução sugerida:
Ótimo trabalho! Quero ver que entendi sua linha de pensamento corretamente. Obrigado!
fonte