Atualmente, estou desenvolvendo um mecanismo de jogo que utiliza campos de distância assinados como uma técnica de renderização para exibir geometria processual suave (gerada com primitivas simples como as do seu link no momento, procurando implementar os fractais Julia e IFS no futuro). Como meu mecanismo está focado na geração de procedimentos e deve definir figuras de maneira a torná-las amigáveis aos marcadores de raios, acho que estou em um bom lugar para responder a essa pergunta: P.
Em relação ao streaming, a solução simples é usar um tipo de buffer de algum tipo e jogá-lo na GPU quando você quiser fazer a marcação de raios. Cada elemento do buffer é um tipo complexo (por exemplo, uma estrutura em C / C ++), e cada tipo contém elementos que definem qual função você deve usar para representá-lo, sua posição, rotação, escala, etc. e uma cor média. O processo simplifica até:
- Escolha sua cena em um subconjunto gerenciável (observe que a seleção de frustum e a seleção de oclusão são parcialmente realizadas automaticamente pelo algoritmo de marcação de raios)
- Passe o subconjunto para o buffer de entrada de renderização
- Passe o buffer para a GPU, se ainda não estiver lá, e depois renderize sua cena com a marcha tradicional tradicional. Você precisará executar algum tipo de pesquisa por etapa para avaliar qual item do buffer de entrada é o mais próximo de cada raio para cada iteração do marcador de raios e aplicar transformações nos raios (nesse caso, você precisará inverter as rotações das figuras antes que elas atinjam a GPU) ou as próprias funções de distância (mover a origem da função para alterações de posição, ajustando, por exemplo, comprimentos laterais cúbicos para alterações de escala, etc.) A abordagem mais simples é modificar os raios antes você os passa para a função de distância do núcleo real.
Em relação às cores das figuras, lembre-se de que os sombreadores permitem definir tipos complexos e primitivos;). Isso permite que você jogue tudo em uma estrutura no estilo C e passe essas estruturas de volta da sua função de distância.
No meu mecanismo, cada estrutura contém uma distância, uma cor e um ID que o vincula à definição de figura correspondente no buffer de entrada. Cada ID é deduzido do contexto circundante da função de distância relevante (como minha função de mapeamento percorre o buffer de entrada para encontrar a figura mais próxima de cada raio para cada etapa, posso tratar com segurança o valor do contador de loop quando cada SDF é chamado como o ID da figura para essa função), enquanto os valores de distância são definidos usando um SDF principal arbitrário (por exemplo,point - figure.pos
para uma esfera) e as cores são definidas a partir da cor média do elemento apropriado no buffer de figuras (por isso, é útil manter os IDs das figuras por aí) ou através de uma cor de procedimento ponderada em relação à média armazenada (um exemplo pode estar ocorrendo uma contagem de iteração para algum ponto no Mandelbulb, mapeando sua "cor média" do espaço de cores FP para o espaço de cores inteiro e, em seguida, usando a cor mapeada como uma paleta, usando XOR para a contagem de iterações).
Texturas procedurais são outra abordagem, mas eu nunca as usei. O iq fez muita pesquisa nessa área e publicou algumas demonstrações interessantes em Shadertoy, de modo que essa pode ser uma maneira de reunir algumas informações extras.
Independentemente de sua cor é estático para cada figura, processualmente gerado, ou magicamente amostrados de uma textura processual, a lógica básica é a mesma: Figuras abstratas em algum tipo de tipo complexo intermediário (por exemplo, um struct), armazenar tanto distância locais e locais color em uma instância desse tipo, depois passe o tipo complexo como um valor de retorno da sua função de distância. Dependendo da sua implementação, a cor de saída pode passar diretamente para a tela ou seguir o ponto de colisão no seu código de iluminação.
Não sei se o exposto foi claro o suficiente ou não, então não se preocupe em perguntar se algo não faz sentido. Eu realmente não posso fornecer nenhum exemplo de código GLSL / pixel-shading, pois estou trabalhando com HLSL e computar sombreamento, mas estou feliz em tentar revisar qualquer coisa que não tenha escrito corretamente em primeiro lugar :).