Como posso usar o pipeline gráfico para renderizar dados volumétricos com base em uma função de densidade?

12

As duas APIs gráficas (OpenGL e DirectX) desenvolvem um pipeline bem definido no qual vários estágios são programáveis. Esses estágios programáveis ​​requerem uma quantidade mínima fixa de dados e devem executar nele um conjunto bem definido de operações e gerar uma saída mínima definida, para que os dados possam ser transmitidos corretamente para o próximo estágio. Parece que esses pipelines foram projetados para trabalhar com apenas uma quantidade limitada de tipos de dados geométricos, que no caso de D3D e OGL são dados de vértice e coordenadas de textura.

Mas, se for dado um caso em que o aplicativo que planejo fazer não use vértices (ou até voxels) para representar seus dados geométricos e não faça exatamente transformações ou projeções ou rasterização ou interpolação ou algo assim, tais limitações das APIs ou o pipeline dificulta as coisas.

Então, existe uma maneira de alterarmos o pipeline de gráficos de maneira que a funcionalidade do que cada estágio faz com os dados e o tipo de dados que é produzido em cada estágio sejam alterados para minha vantagem? Caso contrário, existe uma maneira de usar as funções da API 'bruta' para construir meu próprio pipeline? Caso contrário, mencione por que não é possível.

EDIT : My Application usa funções de densidade para representar geometria. A função tem um valor em cada ponto no espaço. Divido o frustum da câmera em uma grade 3D, cada bloco pode ser projetado como um pixel. Em cada bloco, integro a função de densidade e verifico se seu valor é mais do que um valor necessário. Se sim, presume-se que algo exista nesse bloco e que o pixel correspondente a esse bloco seja renderizado. então, agora no meu renderizador, quero passar a função (que represento com uma string) para o hardware gráfico em vez dos dados de vértice nos buffers de vértice. isso também implica que o shader de vértice não terá vértices para se transformar em espaço de clipe homogêneo e o shader de fragmento não recebe informações de pixel. agora, a maioria das pesquisas e avaliações acontece por pixel.

The Light Spark
fonte
A função função densidade é uma tautologia?
Pharap
@ Sharap, isso foi um erro de digitação. é simplesmente "função divina", que representa a presença de "matéria" no espaço.
The Light Spark
2
Parece que você só quer construir uma superfície isosuperficial, que é um problema bem estudado. Você já viu http.developer.nvidia.com/GPUGems3/gpugems3_ch07.html ou pesquisou em Metaballs, visualização em nuvem de pontos, extração isosuperficial ou renderização de volume? Além disso, que tipo de desempenho você precisa, isso fará uma enorme diferença na escolha da técnica que você procura quando combinada com a complexidade de seus cálculos. Eu acho que você também encontrará que o pixel por pixel causará cintilação quando a câmera se mover, e o sub pixel será necessário.
Patrick Hughes

Respostas:

18

Você pode usar absolutamente a GPU para renderizar dados volumétricos.

Como você deseja avaliar um conjunto de funções por pixel na tela, uma abordagem simples é renderizar um triângulo em tela cheia. Este é apenas um triângulo que cobre a tela inteira (na verdade, cobre mais do que a tela, pois a tela não é triangular, mas as partes fora da tela são descartadas pela GPU). Em seguida, você pode usar o pixel shader (que recebe as coordenadas da tela do pixel que está sombreando) para construir um raio através do seu volume, avaliar funções, o que for necessário.

(Ao contrário das outras respostas, eu não recomendo um sombreador de computação porque parece que você deseja realizar operações por pixel, e um triângulo de tela inteira + sombreador de pixel é geralmente mais eficiente para isso do que um sombreador de computação - embora os shaders de computação certamente também funcionarão.)

O método do triângulo de tela cheia é muito comum em gráficos em tempo real para operações de pós-processamento, portanto, você provavelmente pode encontrar todas as informações necessárias com um pouco de pesquisa.

BTW, pode ser interessante ler Rendering Worlds with Two Triangles de Iñigo Quílez, uma palestra que descreve como renderizar cenas 3D compostas usando funções matemáticas (especificamente, campos de distância) usando a técnica de sombreamento de pixels em tela cheia.

Nathan Reed
fonte
Então, o pixel shader recebe entradas arbitrárias (como strings ou outros tipos de objetos definidos pelo usuário) para que eu possa passar minhas funções?
The Light Spark
Duvido que você queira tentar executar um analisador e / ou idioma em seqüências de funções arbitrárias na GPU, o que seria estranho, pois as GPUs não são realmente de uso geral. Provavelmente, você deseja criar o próprio sombreador dinamicamente em seu código principal e deixar o sistema gráfico compilar e executar o sombreador resultante.
Patrick Hughes
@TheLightSpark Certo, você não passaria as strings para o sombreador (os idiomas de sombreamento nem sequer têm um tipo de string), você gostaria de gerar e compilar código de sombreador para as funções desejadas. Isso pode ser feito em tempo de execução, se necessário.
Nathan Reed
Comecei a ler sua resposta, imaginei um monitor em forma de triângulo;) Ele tem a vantagem de usar apenas um único triângulo em vez de dois que cobrem a tela sem descartar pixels?
danijar
@danijar Sim, há uma pequena vantagem sobre o uso de um quad, porque alguns pixels ao longo da diagonal serão sombreados duas vezes se você usar um quad em tela cheia. Por outro lado, o descarte de pixels fora da tela é gratuito, pois o rasterizador não gerará esses pixels para começar.
Nathan Reed
6

O rastreamento de raio e outras técnicas geralmente são feitas com o Compute Shaders, suportado pelo Direct3D desde o lançamento do D3D11 e pelo OpenGL desde o 4.3 (e mais por meio do uso do OpenCL e de algumas contorções).

Sean Middleditch
fonte
5

Parece muito que você deseja usar um shader de computação da GPU ou utilizar um objeto "Shader Storage Buffer" para ajudar a aumentar o pipeline para atender às suas necessidades. Matemáticos, cientistas e outras pessoas que procuram a GPU para calcular coisas que não se traduzem exatamente em gráficos padrão usam esse tipo de coisa.

Embora o pipeline de gráficos contemporâneos seja muito flexível, os desenvolvedores ainda tendem a tropeçar em algumas restrições. O recurso de sombreadores de computação, no entanto, facilita a vida para não pensar nos estágios do pipeline, como estamos acostumados a pensar no vértice e no fragmento. Não estamos mais restritos pelas entradas e saídas de determinados estágios do pipeline. O recurso Shabo Storage Buffer Object (SSBO), por exemplo, foi introduzido junto com os sombreadores de computação e oferece possibilidades adicionais para a troca de dados entre os estágios do pipeline, além de ser uma entrada e saída flexíveis para sombreadores de computação.

http://community.arm.com/groups/arm-mali-graphics/blog/2014/04/17/get-started-with-compute-shaders

Se isso não apontar a direção certa, você se importaria de expandir o seu conceito que não se encaixa no paradigma vértice / fragmento?

AAorris
fonte
Eu editei minha resposta para incluir o que estou fazendo. O shader de computação parece ser a resposta, mas diga-me se há algo mais que eu possa fazer.
The Light Spark