Microfacet BRDF को लागू करने की कोशिश की जा रही है लेकिन मेरे परिणाम चित्र गलत हैं


9

मैं माइक्रोफेट बीआरडीएफ मॉडल को लागू करने की कोशिश कर रहा हूं। मैं सेबेस्टियन लैगार्ड की स्लाइड्स पढ़ रहा हूं । मैंने अपने कोड पर सूत्र लागू किए लेकिन मुझे लगता है कि परिणाम की छवि गलत है।

पीला सामग्री का आधार रंग है। विशिष्ट रंग ठीक से देखने के लिए लाल है।

मेरा कोड:

// Fragment Shader
#version 330 core

in vec3 Position;
in vec2 TexCoord0;
in vec3 Normal;
in vec3 Tangent;
out vec4 FinalColor;

uniform vec3 uCameraPosition; // init value: vec3(0, 0, 5)

#define PI 3.1415926f
#define EPSILON 10e-5f
#define saturate(value) clamp(value, 0.0f, 1.0f);

float BRDF_Lambert(float NdotL)
{
    return NdotL;
}

// Got these BRDF formulas Moving Frostbite to PBR slide by Sebastien Lagarde & Charles de Rousiers 
// http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr_v2.pdf
float BRDF_D_GGX(float NdotH, float Roughness)
{
    float Roughness2 = Roughness * Roughness;
    float f = (NdotH * Roughness2 - NdotH) * NdotH + 1.0f;
    return Roughness2 / (f * f + EPSILON);
}


float BRDF_F_FresnelSchlick(float LdotH, float F0)
{
    float f = F0 + (1.0f - F0) * pow((1.0f - LdotH), 5);
    return f;
}

float BRDF_G_SmithGGXCorrelated(float NdotL, float NdotV, float Roughness)
{
    float Roughness2 = Roughness * Roughness;
    float GV = NdotL * sqrt((-NdotV * Roughness2 + NdotV) * NdotV + Roughness2);
    float GL = NdotV * sqrt((-NdotL * Roughness2 + NdotL) * NdotL + Roughness2);

    return 0.5f / (GV + GL + EPSILON);
}

float BRDF_Specular(float NdotV, float NdotL, float NdotH, float LdotH, float Roughness, float F0)
{
    float D = BRDF_D_GGX(NdotH, Roughness);
    float F = BRDF_F_FresnelSchlick(LdotH, F0);
    float G = BRDF_G_SmithGGXCorrelated(NdotL, NdotV, Roughness);
    return (D * F * G) / PI;
}

void main()
{
    FinalColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);
    vec4 BaseColor = vec4(1.0f, 1.0f, 0.0f, 1.0f);
    vec4 SpecularColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
    vec3 LightDirection = normalize(vec3(0, 4, 4));
    vec3 ViewDirection = normalize(Position - uCameraPosition);
    vec3 HalfVector = normalize(ViewDirection + LightDirection);
    float Roughness = 0.9f; // [0.04 - 0.1f] -> Dielectric, [0.7, 1.0f] -> Metallic

    float RefractiveIndex = 0.27049f; // RI for Gold materials. I got this from http://refractiveindex.info/
    float F0 = pow(((1.0f - RefractiveIndex) / (1.0f + RefractiveIndex)), 2);

    float NdotL = saturate(dot(LightDirection, Normal));
    float NdotV = abs(dot(ViewDirection, Normal)) + EPSILON; // Avoid artifact - Ref: SIGGRAPH14 - Moving Frosbite to PBR
    float LdotH = saturate(dot(LightDirection, HalfVector));
    float NdotH = saturate(dot(Normal, HalfVector));

    float DiffuseFactor = BRDF_Lambert(NdotL);
    float SpecularFactor = BRDF_Specular(NdotV, NdotL, NdotH, LdotH, Roughness, F0);

    FinalColor = BaseColor * DiffuseFactor + SpecularColor * SpecularFactor;
}

गलत परिणाम

संपादित करें

खुरदरापन = 0.2 एफ; यहाँ छवि विवरण दर्ज करें

खुरदरापन = 0.04f; यहाँ छवि विवरण दर्ज करें


1
मैंने कोड में बहुत अधिक विवरण नहीं देखा है, लेकिन छवि ठीक प्रतीत होती है। Fresnel प्रभाव एक लाल अंगूठी के रूप में दिखाई देता है। खुरदरापन इतना अधिक (0.9) के साथ, यह समझ में आता है कि बाकी की छवि ज्यादातर पीले रंग की है (यानी ज्यादातर फैलाना)। यदि आप खुरदरापन कम करते हैं, तो आपको एक लाल स्पेक्युलर हाइलाइट मिल सकता है
रिचीसम्स

@ रिचीम्स मैंने विभिन्न खुरदरापन मूल्यों के लिए नई छवियां जोड़ीं, लेकिन अभी तक लाल चमकदार स्पेक्युलर हाइलाइट नहीं देख सकते हैं।
hmkum

1
आपकी दूसरी और तीसरी छवियां आपकी मूल छवि की तुलना में सामान्य रूप से (पीले फैल क्षेत्र में) कम लाल दिखाई देती हैं। यह बहुत स्पष्ट नहीं है क्योंकि पीले रंग के एक छोटे से क्षेत्र को जोड़ने से यह एक समान रंग छोड़ देता है (पीले रंग के बजाय नारंगी-पीला)। यदि आप पीले को काफी कम करते हैं तो क्या आपको लाल वितरण का कोई और विवरण दिखाई देता है? पूरी तरह से पीले रंग को छोड़ने से यह पहचानने में मदद मिल सकती है कि क्या गलत हो रहा है।
ट्राइकोप्लाक्स

@trichoplax i ने पीले को कम कर दिया लेकिन फिर से लाल सट्टेबाज को देखने का कोई तरीका नहीं है। मैं सिर्फ लाल अंगूठी (फ्रेस्नेल) प्रभाव देखता हूं। कोई फर्क नहीं पड़ता कि मैं खुरदरापन के लिए क्या मूल्य निर्धारित करता हूं मैं स्पेक्युलर प्रभाव देखता हूं जो एक बिंदु पर केंद्रित था।
हम्कम

2
पहले नॉर्मल वेक्टर का उपयोग करने से पहले उसे सामान्य करें और दूसरे को देखेंडायरेक्शन स्थिति से कैमरे के लिए आउटगोइंग वेक्टर है: uCameraPosition - स्थिति।
xpicox

जवाबों:


3

रिचीसम्स, ट्राइकोप्लाक्स और xpicox द्वारा तय की गई समस्या। उत्तर के लिए आप सभी का धन्यवाद।

मैंने खुरदरापन कम किया, सामग्री का रंग बदला और ViewDirection को उलट दिया और आखिरकार मुझे उचित स्पेक्युलर दिखाई देना शुरू हुआ :)।

फिक्स्ड कोड:

#version 330 core

in vec3 Position;
in vec2 TexCoord0;
in vec3 Normal;
in vec3 Tangent;
out vec4 FinalColor;

uniform vec3 uCameraPosition;

#define PI 3.1415926f
#define EPSILON 10e-5f
#define saturate(value) clamp(value, 0.0f, 1.0f);

float BRDF_Lambert(float NdotL)
{
    return NdotL;
}

// Got these BRDF formulas Moving Frostbite to PBR slide by Sebastien Lagarde & Charles de Rousiers 
// http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr_v2.pdf
float BRDF_D_GGX(float NdotH, float Roughness)
{
    float Roughness2 = Roughness * Roughness;
    float f = (NdotH * Roughness2 - NdotH) * NdotH + 1.0f;
    return Roughness2 / (f * f + EPSILON);
}


float BRDF_F_FresnelSchlick(float LdotH, float F0)
{
    float f = F0 + (1.0f - F0) * pow((1.0f - LdotH), 5);
    return f;
}

float BRDF_G_SmithGGXCorrelated(float NdotL, float NdotV, float Roughness)
{
    float Roughness2 = Roughness * Roughness;
    float GV = NdotL * sqrt((-NdotV * Roughness2 + NdotV) * NdotV + Roughness2);
    float GL = NdotV * sqrt((-NdotL * Roughness2 + NdotL) * NdotL + Roughness2);

    return 0.5f / (GV + GL + EPSILON);
}

float BRDF_Specular(float NdotV, float NdotL, float NdotH, float LdotH, float Roughness, float F0)
{
    float D = BRDF_D_GGX(NdotH, Roughness);
    float F = BRDF_F_FresnelSchlick(LdotH, F0);
    float G = BRDF_G_SmithGGXCorrelated(NdotL, NdotV, Roughness);
    return (D * F * G) / PI;
}

void main()
{
    vec3 normal = normalize(Normal);

    vec4 BaseColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
    vec4 SpecularColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);

    vec3 LightDirection = normalize(vec3(0, 4, 4) - Position);
    vec3 ViewDirection = normalize(uCameraPosition - Position);
    vec3 HalfVector = normalize(ViewDirection + LightDirection);
    float Roughness = 0.04f;

    float RefractiveIndex = 0.24f; // RI for Gold materials. I got this from http://refractiveindex.info/
    float F0 = pow(((1.0f - RefractiveIndex) / (1.0f + RefractiveIndex)), 2);

    float NdotL = saturate(dot(LightDirection, normal));
    float NdotV = abs(dot(ViewDirection, normal)) + EPSILON; // Avoid artifact - Ref: SIGGRAPH14 - Moving Frosbite to PBR
    float LdotH = saturate(dot(LightDirection, HalfVector));
    float NdotH = saturate(dot(normal, HalfVector));

    float DiffuseFactor = BRDF_Lambert(NdotL);
    float SpecularFactor = 0.0f;
    if(DiffuseFactor > 0.0f)
    {
        SpecularFactor = BRDF_Specular(NdotV, NdotL, NdotH, LdotH, Roughness, F0);
    }
    FinalColor = BaseColor * DiffuseFactor + SpecularColor * SpecularFactor;
}

अंतिम छवि:

यहाँ छवि विवरण दर्ज करें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.