Implementação de textura de imagem perturbada da linguagem renderman

8

Estou tentando implementar (em C #) um algoritmo de perturbação de imagem apresentado no livro "Texturização e modelagem - K. Perlin et al" (página 91, se houver), o que distorce uma imagem. O código a seguir está no idioma Renderman: O acesso à textura

Ct = texture("example.tx", s, t);

é substituído por

point Psh;
float ss, tt;
Psh = transform("shader", P);
ss = s + 0.2 * snoise(Psh);
tt = t + 0.2 * snoise(Psh+(l.5,6.7,3.4));
Ct = texture("example.tx", ss, tt);

transformando a imagem da esquerda para a direita. insira a descrição da imagem aqui

Pelo que eu subestimo, em vez de acessar as coordenadas , acessamos leves coordenadas perturbadas e as exibimos no local , criando assim uma imagem que parece levemente perturbada .(s,t)[0,1](ss,tt)(s,t)

snoise(x) é definido como , mapeando o ruído de a e, na documentação do RenderMan, o que P é um ponto, retorna um valor baseado em algum ruído (provavelmente perlin ou treliça). ( http://renderman.pixar.com/resources/current/RenderMan/noiseFunctions.html )(noise(x)2)1[0,1][1,1]noise(P)

O que não entendo é o que a função de transformação faz, que deveria mapear o ponto P 3D no espaço "shader" e como ela pode ser implementada. Além disso, não tenho certeza se o ruído (x) retorna um ponto 3d, um ponto flutuante (faria mais sentido) e se eu posso usar uma implementação 2D simples do ruído do Perlin para alcançar o mesmo efeito desejado.

simog
fonte

Respostas:

6

Como você supôs, a transform()função transforma pontos de um espaço coordenado para outro. (Existem também vtransform()entransform() para transformar vetores de direção e vetores normais, respectivamente.) O argumento string nomeia o espaço de coordenadas para transformar.

O Renderman Shading Guidelines tem a dizer sobre isso:

No início da execução do sombreador, todas as variáveis ​​de ponto, vetor, normal e matriz são expressas no sistema de coordenadas "atual". Exatamente qual sistema de coordenadas é "atual" depende da implementação. Ocorre que "atual" é "câmera" para o PRMan *, mas você nunca deve contar com esse comportamento - é perfeitamente possível que outros renderizadores compatíveis com RenderMan (incluindo futuros renderizadores da Pixar) possam usar algum outro espaço (como "mundo") como espaço "atual".

Ele continua dando um caso como esse como exemplo. A maioria dos cálculos de iluminação deve ser feita no espaço da câmera, mas a avaliação de uma função de ruído deve estar no sistema de coordenadas do objeto, porque você deseja que o ruído permaneça o mesmo que o objeto se move pelo espaço no mundo.

Na sua implementação de C #, você também precisará transformar o ponto que está sendo sombreado do espaço da câmera no sistema de coordenadas do objeto. Talvez você já tenha feito isso antes de calcular as coordenadas de textura. Caso contrário, será necessário multiplicar pela matriz de transformação do objeto. Lembre-se de que o único uso desse ponto transformado é como uma entrada (como uma semente) para o gerador de ruído Perlin. Ele define o domínio em que o ruído varia: o espaço mundial coordena.

No RSL, a noise()função pode retornar qualquer tipo que você desejar: a float, a color, a pointou a vector. À medida que você o adiciona a outro float( uou v), você obtém um floatneste código. Realmente, as duas noise()chamadas, adicionadas se t, estão agindo para gerar um único vetor de ruído 2D. No seu próprio código, se você estiver usando um vetor 2D para armazenar suas coordenadas de textura, poderá usar uma única função de ruído que retorne um vetor 2D, para obter o mesmo efeito em uma linha de código.


Se você estiver interessado em criar um bom gerador de ruído, o Shadertoy possui muitos shaders de ruído com diferentes variantes do ruído Perlin com propriedades diferentes (isotrópicas ou não, suavidade configurável e largura de banda) e vale a pena procurar inspiração e dicas de implementação .

Dan Hulme
fonte