2016-04-08 9 views
2

Я пытаюсь реализовать физический рендеринг (PBR) в нашем проекте (мы запустили небольшой игровой движок для академических и учебных целей), и я не могу понять, что это правильный способ расчета зеркального и диффузного вклада на основе металлического материала и шероховатость.Как рассчитать зеркальный вклад в PBR?

Мы не используем сторонние библиотеки/механизмы для рендеринга, все написано в OpenGL 3.3.

Сейчас у меня есть это (я положу полный код ниже):

// Calculate contribution based on metallicity 
vec3 diffuseColor = baseColor - baseColor * metallic; 
vec3 specularColor = mix(vec3(0.00), baseColor, metallic); 

Но я нахожусь под впечатлением, что зеркальная термин должен быть зависит от шероховатости каким-то образом. Я решил изменить его на это:

vec3 specularColor = mix(vec3(0.00), baseColor, roughness); 

Но опять же, я не уверен. Каков правильный способ сделать это? Есть ли даже правильный путь или я должен использовать метод «проб и ошибок», пока не получу удовлетворительный результат?

Вот полный код GLSL:

// Calculates specular intensity according to the Cook - Torrance model 
float CalcCookTorSpec(vec3 normal, vec3 lightDir, vec3 viewDir, float roughness, float F0) 
{ 
    // Calculate intermediary values 
    vec3 halfVector = normalize(lightDir + viewDir); 
    float NdotL = max(dot(normal, lightDir), 0.0); 
    float NdotH = max(dot(normal, halfVector), 0.0); 
    float NdotV = max(dot(normal, viewDir), 0.0); // Note: this could also be NdotL, which is the same value 
    float VdotH = max(dot(viewDir, halfVector), 0.0); 

    float specular = 0.0; 
    if(NdotL > 0.0) 
    { 
     float G = GeometricalAttenuation(NdotH, NdotV, VdotH, NdotL); 
     float D = BeckmannDistribution(roughness, NdotH); 
     float F = Fresnel(F0, VdotH); 

     specular = (D * F * G)/(NdotV * NdotL * 4); 
    } 
    return specular; 
} 

vec3 CalcLight(vec3 lightColor, vec3 normal, vec3 lightDir, vec3 viewDir, Material material, float shadowFactor) 
{ 
    // Helper variables 
    vec3 baseColor = material.diffuse; 
    vec3 specColor = material.specular; 
    vec3 emissive = material.emissive; 
    float roughness = material.roughness; 
    float fresnel = material.fresnel; 
    float metallic = material.metallic; 

    // Calculate contribution based on metallicity 
    vec3 diffuseColor = baseColor - baseColor * metallic; 
    vec3 specularColor = mix(vec3(0.00), baseColor, metallic); 

    // Lambertian reflectance 
    float Kd = DiffuseLambert(normal, lightDir); 

    // Specular shading (Cook-Torrance model) 
    float Ks = CalcCookTorSpec(normal, lightDir, viewDir, roughness, fresnel); 

    // Combine results 
    vec3 diffuse = diffuseColor * Kd; 
    vec3 specular = specularColor * Ks; 
    vec3 result = lightColor * (emissive + diffuse + specular); 
    return result * (1.0 - shadowFactor); 
} 

ответ

1

Что вы ищете двунаправленная функция распределения коэффициента отражения (ДФО) для материала. В вашем коде вы ссылаетесь на «модель Кука-Торранса», которая является общей и эффективной (но также вычислительно дорогой) BRDF. Похоже, вы могли бы получать идеи от модели «металлик/шероховатость» и «зеркальной/глянцевой» модели. Это огромная тема, но понимание двух может помочь.

В любом случае, в модели с затенением на физическом уровне BRDF должен сохранять энергию. Поэтому вклад диффузного + зеркальный не должен превышать 1 или:

Kd = 1 - Ks 

Физической точность ваших шейдеров зависят от вычислений вы выполняете от свойств материала, но в вашем случае вы можете включить металлическую терму в BRDF так:

BRDF = (1-m)*diffuse + m*specular 

здесь вы можете отрегулировать освещение и т.д.

- Metalness/Шероховатость шейдерных происхождение

Disney придумал метод шейдера, который был более реалистичным. UnrealEngine4 реализовал эту модель-иш, и теперь есть много путаницы вокруг терминологии и технологического процесса текстур.

UE4 BRDF code - signup required

Disney's BRDF

Basic Background

+0

Да, но все-таки, как я должен смешаться диффузного вклад Lambert с зеркальными из CookTorrance, основанного на грубости материала и металличности? – TheCrafter

+0

Я отредактировал ответ, чтобы надеяться предоставить лучшую информацию. – adon

+0

Я думаю, что я начинаю это делать. Что вы имеете в виду, когда говорите: «Кажется, вы можете получать идеи от модели« металлик/шероховатость »и« зеркальной/глянцевой »модели». ? – TheCrafter