Como você gera um número aleatório no HLSL?
Estou perguntando porque quero tentar o rastreamento de raios gpu . Você precisa gerar direções aleatórias em um pixel shader. Então, eu quero randFloat()
, onde o resultado é um número aleatório entre -1 e +1.
Além disso, qual é o problema da instrução hlsl noise ? Os documentos dizem que foi removido do HLSL 2.0 e superior. Por que ?
Eu li sobre uma abordagem em que você preenche uma textura com valores aleatórios e, em seguida, tem uma coordenada de textura em cada vértice que possui um índice nessa textura. Mas isso é por vértice , preciso de uma instrução que eu possa chamar no pixel shader. Além disso, essa abordagem exige "nova propagação" dos cabos de texto por vértice, se você deseja valores diferentes a cada quadro, e isso exige que um buffer de vértice atualize cada quadro (o que pode ser caro!)
Com detalhes, como você pode gerar um número aleatório barato na GPU?
Respostas:
Números pseudo-aleatórios em um pixel shader não são fáceis de obter. Um gerador de número pseudo-aleatório na CPU terá algum estado no qual ele lê e grava em todas as chamadas para a função. Você não pode fazer isso em um pixel shader.
Aqui estão algumas opções:
Use um sombreador de computação em vez de um sombreador de pixels - eles suportam acesso de leitura e gravação a um buffer, para que você possa implementar qualquer PRNG padrão.
Amostra de uma ou mais texturas contendo dados aleatórios, com base em um parâmetro como a posição do espaço na tela. Você também pode fazer algumas matemáticas na posição antes de usá-la para procurar a textura, o que permitirá reutilizá-la se a matemática envolver uma constante de sombreador de chamada aleatória por sorteio.
Encontre alguma função matemática da posição do espaço na tela, que dê resultados 'aleatórios o suficiente'.
Uma rápida pesquisa no Google encontrou esta página com estas funções:
fonte
Aqui está como eu gero números pseudo-aleatórios para meus efeitos de partículas com um sombreador de computação. Não tenho certeza de quão verdadeiramente aleatório é esse código, mas funciona suficientemente bem para os meus propósitos.
A chave para dar a cada kernel da GPU sua própria sequência aleatória é alimentar o shader de computação como uma semente aleatória inicial da CPU. Cada kernel usa essa semente para alternar o gerador de números usando seu ID de thread como uma contagem. A partir daí, cada encadeamento deve ter sua própria semente exclusiva para gerar valores únicos.
fonte