PBR GGX зеркальный ненасыщенный цвет
Я пытаюсь реализовать PBR рендерер. Мое зеркальное выделение имеет ненасыщенный цвет (особенно в углах скольжения) и ускользает от моей сферы, ограничивающей объем света. Почему это происходит?
Функция, которую я использую для вычисления GGX specular:
vec3 shadingSpecularGGX(vec3 N, vec3 V, vec3 L, float roughness, vec3 F0)
{
vec3 H = normalize(V + L);
float dotLH = max(dot(L, H), 0.0);
float dotNH = max(dot(N, H), 0.0);
float dotNL = max(dot(N, L), 0.0);
float dotNV = max(dot(N, V), 0.0);
float alpha = roughness * roughness;
// D (GGX normal distribution)
float alphaSqr = alpha * alpha;
float denom = dotNH * dotNH * (alphaSqr - 1.0) + 1.0;
float D = alphaSqr / (denom * denom);
// no pi because BRDF -> lighting
// F (Fresnel term)
float F_a = 1.0;
float F_b = pow(1.0 - dotLH, 5); // manually?
vec3 F = mix(vec3(F_b), vec3(F_a), F0);
// G (remapped hotness, see Unreal Shading)
float k = (alpha + 2 * roughness + 1) / 8.0;
float G = dotNL / (mix(dotNL, 1, k) * mix(dotNV, 1, k));
return D * F * G / 4.0;
}
И затем я объединяю его с диффузным термином Ламберта:
float lambert = max(0.0, dot(lightDir, normal));
vec3 diffuse = albedo * (1 - metallic);
vec3 specular = mix(vec3(0.04), albedo, metallic) * light.color;
float distance = length(light.position - worldPos);
float attenuation = clamp(1.0 / (distance * distance * light.atten.quadratic + distance * light.atten.linear + light.atten.constant), 0.0, 1.0);
gl_FragColor.rgb = (diffuse * lambert * light.color * light.intensity) + shadingSpecularGGX(normal, viewDir, lightDir, roughness, specular) * light.intensity;
gl_FragColor.rgb *= attenuation;
gl_FragColor.a = 1.0;
Зеркальная подсветка имеет цвета при просмотре сверху, но когда камера приближается к земле, цвета начинают размываться.
Это правильное поведение? Потому что, глядя на фотографии мокрого асфальта, цвета отражений, похоже, сохраняются.
Мне удалось получить цветные отражения, изменив F0
цвет к light.color
vec3 specular = mix(light.color, albedo * light.color, metallic);
https://i.imgur.com/hIdvAH6.png
но я прочитал, что значение F0 должно быть для неметаллов около 0,04, и мое зеркальное отражение ускользает от моей ограничивающей сферы.