1 pontos por GN⁺ 2024-12-19 | 1 comentários | Compartilhar no WhatsApp
  • Textura XOR é uma textura procedural simples criada aplicando XOR às coordenadas x e y de cada pixel, útil para testar rapidamente um mapeador de texturas sem usar arquivos de imagem
  • Em C++, o valor x ^ y é produzido com o operador ^, e ao inseri-lo em RGB surge um padrão em tons de cinza; o XOR retorna 1 apenas quando os dois bits são diferentes
  • O tamanho da textura fica mais bonito quando é uma potência de 2, e em tamanhos menores que 256 a faixa de valores é estreita, deixando a imagem escura, o que pode ser corrigido multiplicando os valores de cor
  • Texturas XOR maiores que 256 não ganham qualidade por ficarem limitadas à faixa de cores 0~255 de canais de 8 bits; para tamanhos maiores é preciso dividir os valores ou usar canais com mais bits
  • Aplicando & e | da mesma forma baseada em coordenadas, também é possível criar texturas AND e OR; AND é mais escura, OR é mais clara, e a soma de XOR com AND resulta em OR

Onde a textura XOR pode ser útil

  • Textura XOR é uma textura procedural muito fácil de gerar e visualmente até convincente
  • Em demos ou intro releases ela já foi usada demais e não é uma boa escolha; em jogos, também tem pouca utilidade prática, a menos que seja para algo como pisos chamativos
  • É possível verificar rapidamente se um novo mapeador de texturas está funcionando sem carregar arquivos de imagem nem escrever código complexo de geração

Criando um padrão com XOR de coordenadas

  • A ideia básica é aplicar XOR entre a coordenada x e a coordenada y do pixel atual
  • Em C++, o operador de XOR é ^
  • O código de exemplo calcula o valor para todos os pixels de uma tela 256×256
    • Uint8 c = x ^ y
    • Define uma cor em tons de cinza com ColorRGB(c, c, c)
  • O resultado é exibido como um padrão XOR formado pela combinação dos padrões de bits das coordenadas

Restrições de tamanho e faixa de cores

  • O tamanho da textura fica mais agradável quando é uma potência de 2
  • Os valores dos componentes de cor vão de 0 a 255
  • O valor máximo de cor produzido pela operação XOR é igual à dimensão da textura quando o tamanho da textura é uma potência de 2
    • Um padrão como 64, por ser menor que 256, parece escuro demais
    • Multiplicar os valores de cor por 4 pode recuperar o brilho
  • Em tamanhos maiores que 256, como 512, é preciso limitar a cor para que ela não ultrapasse 256
    • Dá para usar operação de resto por 256, mas então deixa de ser um padrão XOR real
    • Dividir por 2 é uma opção melhor
  • Em canais de 8 bits, não há valores de cor distinguíveis suficientes para melhorar a qualidade de texturas XOR maiores que 256×256
  • Em modos de cor com mais bits por canal, o limite para texturas grandes pode ser diferente

Funcionamento em bits da operação XOR

  • XOR opera sobre cada par de bits correspondentes na representação binária de dois inteiros
  • Exclusive OR retorna 1 quando os dois bits são diferentes e 0 quando são iguais
  • A tabela verdade é a seguinte
    • 0 XOR 0 = 0
    • 0 XOR 1 = 1
    • 1 XOR 0 = 1
    • 1 XOR 1 = 0
  • Por exemplo, 5 XOR 13 = 8
    • Em binário, 0101 XOR 1101 = 1000

Variações de cor

  • O valor de XOR pode ser aplicado não só em tons de cinza, mas também de formas diferentes em cada canal RGB
  • No exemplo, a cor é montada usando c = x ^ y
    • r = 255 - c
    • g = c
    • b = c % 128
  • Também é possível usar o valor XOR como hue de uma cor HSV e passá-lo para a função HSVtoRGB
    • No exemplo, ColorHSV(c, 255, 255) é convertido por HSVtoRGB e usado como cor do pixel

Texturas AND e OR

  • Também é possível criar texturas semelhantes baseadas em coordenadas usando operadores AND e OR no lugar de XOR
  • Em C++, o operador AND é & e o operador OR é |
  • AND retorna 1 apenas quando os dois bits são 1
    • 0 AND 0 = 0
    • 0 AND 1 = 0
    • 1 AND 0 = 0
    • 1 AND 1 = 1
  • OR retorna 1 quando um dos dois bits ou ambos são 1
    • 0 OR 0 = 0
    • 0 OR 1 = 1
    • 1 OR 0 = 1
    • 1 OR 1 = 1
  • A textura AND é mais escura porque só há um caso em que retorna 1, enquanto a textura OR é mais clara porque retorna 1 em mais casos
  • A soma da textura XOR com a textura AND resulta em uma textura OR

Conclusão e usos de exemplo

  • A textura XOR é fácil de criar e útil para testar se um renderizador de texturas está funcionando
  • Não é adequada para trabalhos artísticos nem para aplicações como jogos
  • Também pode ser usada como textura 3D no formato x ^ y ^ z; no exemplo, ela serve para verificar se um renderizador de textura de planeta está funcionando corretamente

1 comentários

 
GN⁺ 2024-12-19
Opiniões no Hacker News
  • No ensino fundamental II, eu tinha mexido um pouco com programação, mas só sabia criar aplicações CLI simples que rodavam no terminal. Um dia, encontrei o Lode's Computer Graphics Tutorial e tive meu primeiro contato com exemplos fáceis que abriam uma janela e desenhavam gráficos na tela
    Graças a isso, consegui recriar jogos retrô como Pacman, Snake e Space Invaders, e passei a fazer coisas que seriam impossíveis usando apenas o terminal
    Vejo esse site como o que me levou a começar uma carreira em desenvolvimento de software ainda bem jovem. Na época, eu praticamente tinha decorado as páginas e exemplos de https://lodev.org/cgtutor/, e algumas partes da matemática eu não entendia nem um pouco
  • Há algum tempo, criei um pequeno programa em assembly x86 que gerava imagens com uma técnica parecida, mas as cores eram de 1 bit
    Em vez de x ^ y, usei parity(x ^ y): se houvesse um número par de bits 1, pintava com uma cor; se fosse ímpar, com outra. Visualmente era interessante, porque parecia um ladrilhamento quase repetitivo, mas que nunca se repetia completamente
    Fuçando arquivos antigos, vi que escrevi isso em fasm em 2019 e que ele gerava arquivos XPM2; para visualizar, era preciso converter manualmente para XPM3. A imagem resultante está aqui: https://i.postimg.cc/FsFhXSHG/xortiles.png
    Se alguém quiser, posso publicar o código, mas não sei se haveria tanto interesse assim
  • Isso me lembra as texturas de distância de Hamming: https://chalkdustmagazine.com/features/the-hidden-harmonies-...
  • Um fato curioso: cada ponto de uma textura XOR é o menor inteiro que não apareceu acima dele nem à esquerda dele
    Jogo aqui discretamente meu blog e saio de fininho: https://nicknash.me/2012/10/26/happy-halloween/
    • A linha que começa com 5 na matriz de exemplo está errada; deveria ser assim
      5 4 7 6 1 0 3 2
  • Se você animar uma função como color = (y == (x ^ t)), variando o valor de t, o efeito é parecido; isso é chamado de munching squares
    Originalmente, foi escrito para o PDP-1 no início dos anos 1960, e já vi uma demonstração dele no PDP-1 do Computer History Museum
    O display do PDP-1 só consegue desenhar pontos e não usa um framebuffer bitmap, então eu sempre me perguntei como aquela textura XOR característica era gerada
    Acontece que ele aproveitava a longa persistência do fósforo da tela, com o brilho de cada ponto diminuindo ao longo do tempo
    O CHM tem um vídeo em execução, mas ele não captura muito bem o efeito de persistência do fósforo: https://www.computerhistory.org/collections/catalog/10266415...
    Um vídeo rodando no MAME mostra em alguma medida como a persistência do fósforo cria a textura XOR: https://youtu.be/AxJzUiaQ7xM?si=X9K47c4WyD6AisUp
  • Há um site com milhares de exemplos desse tipo: https://www.dwitter.net/
    Dwitter é como um Twitter para exemplos de JavaScript de uma linha usando canvas, e os usuários precisam fazer suas obras caberem em 140 bytes
  • Já fiz uma colcha usando essa textura
    Usei a mesma escala de cores em arco-íris de uma das imagens perto do fim do site, então ela ficou bem parecida, e hoje a mantenho pendurada na parede como uma peça decorativa de 6 pés × 6 pés
  • É um site bem legal. Recomendo subir um nível e dar uma olhada nas outras páginas também
    Embora seja material de 20 anos atrás, especialmente se você trabalha com shaders, ainda há muita coisa útil em vários pontos
  • Recentemente brinquei com esse padrão em J, e dá para expressá-lo assim
    ~:\"1/~&.#:i.2^8
    Dá para ver aqui: https://jsoftware.github.io/j-playground/bin/html2/#base64=b...
  • Acabei de ler https://news.ycombinator.com/item?id=42414817 e acho que dá para dizer que a textura XOR também foi descoberta por acaso