Estamos tendo alguns problemas com o nosso traçado de raios no DirectX, especialmente com alguns problemas sérios de faixas com o especular. Com alta potência especular (acima de 8), começa a formação de faixas. Gostaria de saber se este é um problema de HDR / LDR ou pode estar relacionado a outra coisa, como normais ou outros vetores?
ATUALIZAR
Veja abaixo as atualizações.
Aqui está o código de sombreamento relevante para Blinn-Phong em uma esfera:
float3 hitPoint = thisRay.origin + thisRay.direction * bestHit.hitT;
float3 normal = normalize(hitPoint - spheres[bestHit.hitID].center);
float3 toLight = pointLights[0].position.xyz - hitPoint;
float d = length(toLight);
toLight = normalize(toLight);
float diffuse = max(dot(normal, toLight), 0.0f);
float3 v = normalize(thisRay.origin - hitPoint);
float3 h = normalize(v + toLight);
float spec = 0;
if (diffuse > 0)
spec = pow(max(dot(normal, h), 0.0f), specPower) * diffuse;
output[threadID.xy] = spheres[bestHit.hitID].colour * diffuse + spheres[bestHit.hitID].specColour * spec;
specPower é igual a 8 nesta imagem
specPower é igual a 9 nesta imagem
Isso é tão simples quanto um problema de HDR / LDR ou está de alguma forma relacionado à precisão normal? Acredito que já encontrei esse problema antes em um renderizador diferido, onde os normais eram de baixa precisão e embalados / descompactados incorretamente, mas, neste caso, os normais são gerados em tempo real e tudo é renderizado diretamente no backbuffer.
Atualização 1
Gostaria de acrescentar que os triângulos sofrem o mesmo artefato e que eles têm seu normal gerado atualmente da seguinte maneira:
float3 normal = normalize(cross(triangles[bestHit.hitID].vertices[1] - triangles[bestHit.hitID].vertices[0],
triangles[bestHit.hitID].vertices[2] - triangles[bestHit.hitID].vertices[0]));
Eu diria que isso torna ainda mais improvável que o normal da superfície seja o problema. A imagem a seguir mostra o que acontece quando o specPower chega a 2048.
fonte
float3 h = normalize( reflect(toLight,normal) );
, espec = pow(dot(v, h) * 0.5 + 0.5, specPower) * diffuse;
spec
diretamente, e tambémmax(dot(normal, h), 0.0f)
. Procure esse retorno para um valor 1 em qualquer cálculo.Respostas:
Parece um problema com a implementação da função pow nesta GPU específica.
Ao suspeitar de um bug em uma função matemática, substitua a função matemática por seu equivalente, por exemplo, substitua:
Com o bug aparecendo em specPower = 9.0, codifique-o para
Ou
Se o problema desaparecer, isso significa que provavelmente há um bug de fluxo insuficiente na função pow em relação ao expoente nesta GPU ou driver.
O que você pode fazer como uma solução alternativa, assumindo que o cálculo do fragment shader seja feito internamente com flutuações de 16 bits. Se eu calcular isso direito, você deve fazer
Pode ser 32768 ou 8192: posso estar um pouco desligado ou a GPU pode estar usando mais ou menos precisão. para pow (x, 9.0), a fixação seria pow (max (temp, 0.3401975), 9.0) Os valores de X abaixo disso estariam abaixo do intervalo de expoentes (+15 a -14) dos pontos flutuantes IEEE de 16 bits (novamente, assumindo que é isso que a GPU usa.)
do código rosetta ( http://rosettacode.org/wiki/Nth_root#C.2B.2B )
Você precisará calcular isso na CPU e alimentar o valor de maneira uniforme: a GPU provavelmente terá o mesmo problema de precisão se você calcular isso corretamente no shader.
Se você puder confirmar isso, tente entrar em contato com a equipe de drivers da GPU com um código-fonte de sombreador de amostra que replique o problema e forneça a versão exata do driver, o SO e a revisão do modelo da GPU, um executável pode ajudar, mas não o envia conforme seu email fique preso no verificador de vírus / spam. Basta criar uma e manter uma cópia, caso elas solicitem um executável de amostra pré-criado. Como cortesia, dê a eles a chance de corrigi-lo antes de nomeá-lo publicamente. Poderia ser simplesmente um bug de otimização no compilador de shader que só acontece com o shader específico. Pode demorar um pouco (meses) para entrar em contato com eles, esses caras geralmente têm falta de pessoal.
fonte