सवाल मेरा ओपनजीएल फोंग शेडर एक फ्लैट शेडर की तरह व्यवहार क्यों करता है?


मैं पिछले कुछ हफ्तों के लिए ओपनजीएल सीख रहा हूं और मैंने फोंग शेडर को लागू करने में कुछ परेशानी का सामना किया है। ऐसा लगता है कि मेरे उपयोग के बावजूद वर्टेक्स के बीच कोई इंटरपोलेशन नहीं होता है smooth क्वालीफायर। क्या मुझसे कोई चूक हो रही है? श्रेय देय क्रेडिट देने के लिए, कशेरुक और टुकड़े के टुकड़े के लिए कोड भारी से क्रिप्स करता है ओपनजीएल सुपरबाइबल पांचवें संस्करण। मैं इस किताब की जरूर सिफ़ारिश करूंगा!

वेरटेक्स शेडर:

#version 330
in vec4 vVertex;
in vec3 vNormal;
uniform mat4 mvpMatrix;  // mvp = ModelViewProjection
uniform mat4 mvMatrix; // mv = ModelView
uniform mat3 normalMatrix;
uniform vec3 vLightPosition;
smooth out vec3 vVaryingNormal;
smooth out vec3 vVaryingLightDir;

void main(void) {
 vVaryingNormal = normalMatrix * vNormal;
 vec4 vPosition4 = mvMatrix * vVertex;
 vec3 vPosition3 = vPosition4.xyz / vPosition4.w;
 vVaryingLightDir = normalize(vLightPosition - vPosition3);
 gl_Position = mvpMatrix * vVertex;
}

टुकड़ा शेडर:

#version 330
out vec4 vFragColor;
uniform vec4 ambientColor;
uniform vec4 diffuseColor;
uniform vec4 specularColor;
smooth in vec3 vVaryingNormal;
smooth in vec3 vVaryingLightDir;

void main(void) {
 float diff = max(0.0, dot(normalize(vVaryingNormal), normalize(vVaryingLightDir)));
 vFragColor = diff * diffuseColor;
 vFragColor += ambientColor;
 vec3 vReflection = normalize(reflect(-normalize(vVaryingLightDir),normalize(vVaryingNormal)));
 float spec = max(0.0, dot(normalize(vVaryingNormal), vReflection));

 if(diff != 0) {
   float fSpec = pow(spec, 32.0);
   vFragColor.rgb += vec3(fSpec, fSpec, fSpec);
 }

}

विकिपीडिया से यह (सार्वजनिक डोमेन) छवि दिखाती है कि मुझे किस तरह की छवि मिल रही है और मैं किसके लिए लक्ष्य रख रहा हूं - मुझे "फ्लैट" छवि मिल रही है लेकिन मुझे "फोंग" छवि चाहिए।

किसी भी तरह की सहायता का स्वागत किया जाएगा। धन्यवाद!

संपादित करें: यदि इससे कोई फर्क पड़ता है, तो मैं PyOpenGL 3.0.1 और पायथन 2.6 का उपयोग कर रहा हूं।

EDIT2:

उपाय

यह पता चला कि समस्या मेरी ज्यामिति के साथ थी; कोस सही था। ब्लेंडर मॉडल के साथ इस समस्या को किसी और के लिए, कोस ने बताया कि कर रहा है Edit->Faces->Set Smooth उसने चाल चली। मैंने पाया कि विंग्स 3 डी "बॉक्स से बाहर" काम करता था।


44
2018-01-16 02:20


मूल


वही समाधान मेरे लिए काम किया। आपका बहुत बहुत धन्यवाद। - Vinod


जवाब:


हम्म ... आप सामान्य के रूप में सामान्य interpolating कर रहे हैं varying परिवर्तनीय, इसलिए टुकड़े टुकड़े को सही प्रति-पिक्सेल सामान्य प्राप्त करना चाहिए।

एकमात्र स्पष्टीकरण (मैं इस बारे में सोच सकता हूं) कि आपके बाएं छवि के परिणामस्वरूप आपका परिणाम है किसी दिए गए चेहरे पर हर टुकड़े अंततः एक ही सामान्य प्राप्त करता है। आप इसे एक टुकड़े टुकड़े के साथ पुष्टि कर सकते हैं जैसे:

void main() {
   vFragColor = normalize(vVaryingNormal);
}

यदि यह मामला है, सवाल बनी हुई है: क्यों? कशेरुक शेडर ठीक दिखता है।

तो शायद आपके में कुछ गड़बड़ है ज्यामिति? आप जिस डेटा को शेडर को भेजते हैं वह क्या है? क्या आप वाकई प्रति-चरणीय मानदंडों के अनुसार प्रति-चरणीय मानदंडों की सही गणना नहीं कर चुके हैं?

normals

नारंगी रेखाएं विकर्ण चेहरे के मानक हैं, लाल रेखाएं क्षैतिज चेहरे के मानक हैं।

यदि आपका डेटा उपर्युक्त छवि जैसा दिखता है, तो सही शेडर के साथ भी आपको फ्लैट छायांकन मिल जाएगी। सुनिश्चित करें कि आपके पास निचले छवि पर सही प्रति-वर्टेक्स मानक हैं। (वे एक क्षेत्र के लिए गणना करने के लिए वास्तव में सरल हैं।)


48
2018-01-16 14:00



बस यह इंगित करना चाहते हैं कि @ कोस का अर्थ "क्षेत्र के लिए गणना करने के लिए वास्तव में सरल" है: उत्पत्ति पर यूनिट त्रिज्या क्षेत्र के मामले में सामान्य वर्टेक्स स्थिति के समान होता है। - datenwolf
मैंने आपके कोड स्निपेट की कोशिश की और कोई रंग इंटरपोलेशन नहीं था, इसलिए मुझे लगता है कि इसका मतलब है कि यह ज्यामिति के साथ एक समस्या है। मैं जिस क्षेत्र का उपयोग कर रहा हूं वह वास्तव में ब्लेंडर से वेवफ़्रंट ओबीजे फ़ाइल प्रारूप में निर्यात किया गया था। मानक ब्लेंडर में सही दिखाई देते हैं, लेकिन क्या यह सुनिश्चित करने के लिए कुछ ऐसा है जो वे ठीक से बाहर आते हैं? - Jonba
हम्म ... यह अजीब बात है। क्या तुमने किया Edit->Faces->Set Smooth निर्यात से पहले ब्लेंडर में? - Kos
यह पूरी तरह से काम किया! मैंने यह भी पाया कि विंग्स 3 डी सामान्य मानकों को निर्यात करने लगता है जो किसी भी चिकनाई को निर्दिष्ट किए बिना अच्छी तरह से खेलते हैं। - Jonba
खैर, कभी-कभी आप एक परिणाम चाहते हैं, कभी-कभी आप दूसरे को चाहते हैं- यह जानना अच्छा है कि आप इसे कहां नियंत्रित कर सकते हैं। लेकिन मुझे नहीं पता कि यह ब्लेंडर में चिकनी क्यों दिखाई देगा से पहले आप इसे सेट करेंगे? - Kos


इस उत्तर के अतिरिक्त, यहां एक साधारण ज्यामिति शेडर है जो आपको अपने आदर्शों को देखने देगा। अपने विशेषता स्थानों और आप अपनी matrices कैसे भेजते हैं, के आधार पर आवश्यक वर्टेक्स शेडर को संशोधित करें।

लेकिन सबसे पहले, परिणाम के उदाहरण के रूप में हमारे दोस्त स्टैनफोर्ड बनी से एक विशाल बनी सिर की एक तस्वीर!

normals for the Stanford bunny

प्रमुख चेतावनी: ध्यान दें कि मैं उचित सामान्य मैट्रिक्स के बजाय मॉडलव्यू मैट्रिक्स के साथ मानकों को बदलने के साथ दूर हो जाता हूं। यदि आपके मॉडलव्यू में गैर वर्दी स्केलिंग है तो यह सही तरीके से काम नहीं करेगा। साथ ही, आपके मानदंडों की लंबाई सही नहीं होगी, लेकिन यदि आप उनकी दिशा जांचना चाहते हैं तो यह मामूली बात है।

Vertex शेडर:

#version 330

layout(location = 0) in vec4 position;
layout(location = 1) in vec4 normal;
layout(location = 2) in mat4 mv;

out Data
{
    vec4 position;
    vec4 normal;
    vec4 color;
    mat4 mvp;
} vdata;

uniform mat4 projection;

void main()
{
    vdata.mvp = projection * mv;
    vdata.position = position;
    vdata.normal = normal;
}

ज्यामिति शेडर:

#version 330
layout(triangles) in;
layout(line_strip, max_vertices = 6) out;

in Data
{
    vec4 position;
    vec4 normal;
    vec4 color;
    mat4 mvp;
} vdata[3];

out Data
{
    vec4 color;
} gdata;

void main()
{
    const vec4 green = vec4(0.0f, 1.0f, 0.0f, 1.0f);
    const vec4 blue = vec4(0.0f, 0.0f, 1.0f, 1.0f);

    for (int i = 0; i < 3; i++)
    {
        gl_Position = vdata[i].mvp * vdata[i].position;
        gdata.color = green;
        EmitVertex();

        gl_Position = vdata[i].mvp * (vdata[i].position + vdata[i].normal);
        gdata.color = blue;
        EmitVertex();

        EndPrimitive();
    }
}

टुकड़ा शेडर:

#version 330

in Data
{
    vec4 color;
} gdata;

out vec4 outputColor;

void main()
{
    outputColor = gdata.color;
}

64
2018-02-28 14:18



कितना मजेदार था वो! - Kos