Nous rencontrons des problèmes avec notre lancer de rayons dans DirectX, en particulier avec de graves problèmes de regroupement avec spéculaire. Avec une puissance spéculaire élevée (supérieure à 8), les bandes commencent. Je me demande s'il s'agit d'un problème HDR / LDR ou s'il pourrait être lié à autre chose, comme des normales ou d'autres vecteurs?
MISE À JOUR
Regardez ci-dessous pour les mises à jour.
Voici le code de shader pertinent pour Blinn-Phong sur une sphère:
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 est égal à 8 dans cette image
specPower est égal à 9 dans cette image
Est-ce aussi simple qu'un problème HDR / LDR ou est-ce lié à la précision normale? Je crois avoir déjà rencontré ce problème dans un rendu différé où les normales étaient de faible précision et mal emballées / déballées mais dans ce cas, les normales sont générées à la volée et le tout est rendu directement dans le backbuffer.
Mise à jour 1
Je voudrais ajouter à ce qui précède que les triangles souffrent du même artefact et qu'ils ont leur normale actuellement générée de la manière suivante:
float3 normal = normalize(cross(triangles[bestHit.hitID].vertices[1] - triangles[bestHit.hitID].vertices[0],
triangles[bestHit.hitID].vertices[2] - triangles[bestHit.hitID].vertices[0]));
Je dirais que cela rend encore plus improbable que la normale de la surface soit le problème. L'image suivante montre ce qui se passe lorsque specPower atteint 2048.
spec
directement, et aussi max(dot(normal, h), 0.0f)
. Recherchez ce retour à une valeur 1 dans l'un ou l'autre calcul.
float3 h = normalize( reflect(toLight,normal) );
, etspec = pow(dot(v, h) * 0.5 + 0.5, specPower) * diffuse;