У нас есть некоторые проблемы с трассировкой лучей в DirectX, особенно с некоторыми серьезными проблемами с зеркальным отражением. При высокой зеркальной мощности (выше 8) начинается полосатость. Мне интересно, если это проблема HDR / LDR или это может быть связано с чем-то другим, например с нормальными или другими векторами?
ОБНОВИТЬ
Смотрите ниже для обновлений.
Вот соответствующий код шейдера для Blinn-Phong на сфере:
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 равно 8 на этом изображении
specPower на этом изображении равен 9
Это так же просто, как проблема HDR / LDR, или это как-то связано с нормальной точностью? Я полагаю, что я сталкивался с этой проблемой раньше в отложенном рендере, где нормали были низкой точности и неправильно упакованы / распакованы, но в этом случае нормали генерируются на лету, и все это передается непосредственно в буфер.
Обновление 1
Я хотел бы добавить к вышесказанному, что треугольники страдают от одного и того же артефакта, и их нормаль в настоящее время генерируется следующим образом:
float3 normal = normalize(cross(triangles[bestHit.hitID].vertices[1] - triangles[bestHit.hitID].vertices[0],
triangles[bestHit.hitID].vertices[2] - triangles[bestHit.hitID].vertices[0]));
Я бы сказал, что это делает еще более маловероятным, что нормаль поверхности является проблемой. На следующем изображении показано, что происходит, когда specPower достигает 2048.
spec
непосредственно, а также max(dot(normal, h), 0.0f)
. Ищите этот возврат к значению 1 в любом расчете.
float3 h = normalize( reflect(toLight,normal) );
, иspec = pow(dot(v, h) * 0.5 + 0.5, specPower) * diffuse;