2011-05-06 13 views
14

मैंने सुना है कि मुझे रंगों के बजाय मानक का उपयोग करना चाहिए, क्योंकि रंगों को बहिष्कृत किया गया है। (क्या यह सच है?) सामान्य के पास प्रकाश के प्रतिबिंब के साथ कुछ करना है, लेकिन मुझे स्पष्ट और अंतर्ज्ञानी स्पष्टीकरण नहीं मिल रहा है। सामान्य क्या है?ओपनजीएल में सामान्य क्या है?

उत्तर

17

सामान्य रूप से normal एक यूनिट वेक्टर है जिसका दिशा किसी बिंदु पर सतह पर लंबवत है। इसलिए यह आपको बताता है कि किस दिशा में सतह का सामना करना पड़ रहा है। मानदंडों के लिए मुख्य उपयोग केस प्रकाश गणना है, जहां आपको किसी दिए गए सतह बिंदु पर सामान्य के बीच कोण (या व्यावहारिक रूप से अक्सर कोसाइन) निर्धारित करना होता है और रोशनी या कैमरे की ओर दिशा होती है।

+0

लिंक के लिए धन्यवाद। सामान्य आवश्यकता क्यों है, अगर यह स्पष्ट होना चाहिए कि सतह की दिशा किस दिशा में है? क्या सतह अक्सर लंबवत नहीं होती है, या यह सिर्फ एक गणना है कि ओपनजीएल संभाल नहीं लेना चाहता है? –

+3

भले ही यह स्पष्ट हो कि सतह का सामना करना पड़ रहा है, फिर भी आपको उस जानकारी को प्रकाश गणना करने में सक्षम होने की आवश्यकता है, और मानक केवल ऐसा करने का मानक तरीका है।त्रिकोणीय जाल की साधारण फ्लैट छायांकन के लिए आप आसानी से त्रिभुज शिखर से मानकों की गणना कर सकते हैं। –

+1

अधिक यथार्थवादी छायांकन के लिए, मानक अक्सर आसानी से भिन्न होते हैं। यह अक्सर सतह के मानदंडों को इंटरपोल करके हासिल किया जाता है, या तो चेहरा मानक या कशेरुक मानदंडों के बीच अंतरण करके। फेस मानक प्राप्त करना आसान है (जैसे फ्लैट छायांकित मामले), लेकिन इंटरपोलेट करना मुश्किल है। वेरटेक्स मानदंडों को अलग करना आसान है (देखें [फोंग छायांकन] (http://en.wikipedia.org/wiki/Phong_shading)) लेकिन जाल के लिए गणना करना इतना आसान नहीं है। यही कारण है कि वर्टेक्स मानक अक्सर पहले गणना की जाती है और जाल के साथ आपूर्ति की जाती है। –

3

मानक और रंग समेत कई चीजें अब बहिष्कृत की गई हैं। इसका मतलब है कि आपको उन्हें स्वयं लागू करना है। आदर्श के साथ आप अपनी वस्तुओं को छाया कर सकते हैं। गणना करने के लिए आप पर निर्भर है लेकिन उदाहरण पर बहुत सारे ट्यूटोरियल हैं गौराउड/फोंग छायांकन।

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

+0

यह जानकारी मुझे लगता है कर लिया है की सबसे अधिक पसंद है, मुझे एक कहता हैकिस मानक के लिए उपयोग किया जाता है, इसके बारे में थोड़ा और, लेकिन मुझे अभी भी यकीन नहीं है कि सामान्य * क्या है *। मुझे यह जानकर आश्चर्य हुआ कि उन्हें बहिष्कृत कर दिया गया है, लेकिन मुझे कोई जानकारी नहीं होगी कि क्यों, या मैं उन्हें कैसे लागू करूंगा, क्योंकि मुझे यकीन नहीं है कि वे क्या हैं। –

+3

कागज का एक टुकड़ा लो और एक रेखा खींचें। फिर दूसरी पंक्ति खींचें जो पहले के लिए लंबवत है। दूसरी पंक्ति पहली सामान्य है। अब कल्पना करें कि पहली पंक्ति एक त्रिकोण की सतह है। पहली पंक्ति के किनारों को शिखर हैं। – SurvivalMachine

+4

सामान्य इकाई-लंबाई वाले वैक्टर हैं। तो एक सामान्य (1, 0, 0) दाएं को इंगित करता है। जब आप प्रस्तुत करने के लिए कोने भेजते हैं, तो आप मानक भी भेज सकते हैं। फिर आप शेडर में प्रकाश गणना करते हैं। – SurvivalMachine

3

glNormal न्यूनतम उदाहरण

glNormal एक पदावनत ओपन 2 विधि है, लेकिन यह समझते हैं, तो चलो इस पर गौर करने देने के लिए सरल है। आधुनिक शेडर विकल्प पर चर्चा की गई है।

यह उदाहरण कुछ विवरण बताता है कि कैसे glNormal फैलाने वाली बिजली के साथ काम करता है।

display फ़ंक्शन की टिप्पणियां बताती हैं कि प्रत्येक त्रिभुज का अर्थ क्या है।

enter image description here

#include <stdlib.h> 

#include <GL/gl.h> 
#include <GL/glu.h> 
#include <GL/glut.h> 

/* Triangle on the x-y plane. */ 
static void draw_triangle() { 
    glBegin(GL_TRIANGLES); 
    glVertex3f(0.0f, 1.0f, 0.0f); 
    glVertex3f(-1.0f, -1.0f, 0.0f); 
    glVertex3f(1.0f, -1.0f, 0.0f); 
    glEnd(); 
} 

/* A triangle tilted 45 degrees manually. */ 
static void draw_triangle_45() { 
    glBegin(GL_TRIANGLES); 
    glVertex3f(0.0f, 1.0f, -1.0f); 
    glVertex3f(-1.0f, -1.0f, 0.0f); 
    glVertex3f(1.0f, -1.0f, 0.0f); 
    glEnd(); 
} 

static void display(void) { 
    glColor3f(1.0f, 0.0f, 0.0f); 
    glClear(GL_COLOR_BUFFER_BIT); 
    glPushMatrix(); 

    /* 
    Triangle perpendicular to the light. 
    0,0,1 also happens to be the default normal if we hadn't specified one. 
    */ 
    glNormal3f(0.0f, 0.0f, 1.0f); 
    draw_triangle(); 

    /* 
    This triangle is as bright as the previous one. 
    This is not photorealistic, where it should be less bright. 
    */ 
    glTranslatef(2.0f, 0.0f, 0.0f); 
    draw_triangle_45(); 

    /* 
    Same as previous triangle, but with the normal set 
    to the photorealistic value of 45, making it less bright. 

    Note that the norm of this normal vector is not 1, 
    but we are fine since we are using `glEnable(GL_NORMALIZE)`. 
    */ 
    glTranslatef(2.0f, 0.0f, 0.0f); 
    glNormal3f(0.0f, 1.0f, 1.0f); 
    draw_triangle_45(); 

    /* 
    This triangle is rotated 45 degrees with a glRotate. 
    It should be as bright as the previous one, 
    even though we set the normal to 0,0,1. 
    So glRotate also affects the normal! 
    */ 
    glTranslatef(2.0f, 0.0f, 0.0f); 
    glNormal3f(0.0, 0.0, 1.0); 
    glRotatef(45.0, -1.0, 0.0, 0.0); 
    draw_triangle(); 

    glPopMatrix(); 
    glFlush(); 
} 

static void init(void) { 
    GLfloat light0_diffuse[] = {1.0, 1.0, 1.0, 1.0}; 
    /* Plane wave coming from +z infinity. */ 
    GLfloat light0_position[] = {0.0, 0.0, 1.0, 0.0}; 
    glClearColor(0.0, 0.0, 0.0, 0.0); 
    glShadeModel(GL_SMOOTH); 
    glLightfv(GL_LIGHT0, GL_POSITION, light0_position); 
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse); 
    glEnable(GL_LIGHTING); 
    glEnable(GL_LIGHT0); 
    glColorMaterial(GL_FRONT, GL_DIFFUSE); 
    glEnable(GL_COLOR_MATERIAL); 
    glEnable(GL_NORMALIZE); 
} 

static void reshape(int w, int h) { 
    glViewport(0, 0, w, h); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glOrtho(-1.0, 7.0, -1.0, 1.0, -1.5, 1.5); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
} 

int main(int argc, char** argv) { 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); 
    glutInitWindowSize(800, 200); 
    glutInitWindowPosition(100, 100); 
    glutCreateWindow(argv[0]); 
    init(); 
    glutDisplayFunc(display); 
    glutReshapeFunc(reshape); 
    glutMainLoop(); 
    return EXIT_SUCCESS; 
} 

थ्योरी

ओपन 2 में प्रत्येक शीर्ष यह ही है जुड़े सामान्य वेक्टर है।

सामान्य वेक्टर निर्धारित करता है कि वर्टेक्स कितना उज्ज्वल है, जिसका उपयोग यह निर्धारित करने के लिए किया जाता है कि त्रिकोण कितना उज्ज्वल है।

ओपनजीएल 2 ने Phong reflection model का उपयोग किया, जिसमें प्रकाश को तीन घटकों में विभाजित किया गया है: परिवेश, फैलाव और specular। उन में से, फैलाना और specular घटक सामान्य से प्रभावित होते हैं: यदि specular प्रकाश सतह पर पड़ती

  • अगर फैलाना प्रकाश सतह करने के लिए खड़ा है, यह बनाता है उज्जवल है, चाहे पर्यवेक्षक
  • है , और सही पर्यवेक्षक की आंख में होने वाले बाउंस, brigher

glNormal वर्तमान सामान्य वेक्टर है, जो सभी निम्नलिखित vertexes के लिए प्रयोग किया जाता है सेट उस बिंदु बन जाता है।

हम सभी glNormal0,0,1 से पहले सामान्य के लिए प्रारंभिक मान सामान्य है।

सामान्य वैक्टर में मानक 1 होना चाहिए, या अन्य रंग बदल सकते हैं! glScale भी मानक की लंबाई बदलता है! glEnable(GL_NORMALIZE); ओपनजीएल स्वचालित रूप से हमारे मानदंड को हमारे लिए 1 पर सेट करता है। This GIF उस सुंदरता को दिखाता है।

यह उपयोगी क्यों है vertexes प्रति चेहरे नीचे

दोनों क्षेत्रों बहुभुज की समान संख्या के बजाय normals है। कशेरुक पर आदर्श के साथ एक बहुत चिकना दिखता है।

enter image description here

ओपन 4 टुकड़ा shaders

नए ओपन एपीआई में, आप डेटा की एक मनमाना हिस्सा के रूप में GPU के लिए सामान्य दिशा डेटा पास: GPU पता नहीं है कि यह normals का प्रतिनिधित्व करता है ।

फिर आप एक हाथ से लिखे गए टुकड़े शेडर लिखते हैं, जो एक मनमाना प्रोग्राम है जो GPU में चलता है, जो आपके द्वारा पारित सामान्य डेटा को पढ़ता है, और जो भी बिजली एल्गोरिदम आप चाहते हैं उसे लागू करता है। यदि आप कुछ डॉट उत्पादों की मैन्युअल रूप से गणना करके इसे महसूस करते हैं तो आप फोंग को कुशलतापूर्वक कार्यान्वित कर सकते हैं।

यह आपको एल्गोरिदम डिज़ाइन को बदलने के लिए पूर्ण लचीलापन देता है, जो आधुनिक जीपीयू की एक प्रमुख विशेषताएं है। देखें: https://stackoverflow.com/a/36211337/895245

इसका उदाहरण किसी भी "आधुनिक" ओपनजीएल 4 ट्यूटोरियल में पाया जा सकता है, उदाहरण के लिए https://github.com/opengl-tutorials/ogl/blob/a9fe43fedef827240ce17c1c0f07e83e2680909a/tutorial08_basic_shading/StandardShading.fragmentshader#L42

ग्रंथ सूची

+0

अच्छा स्पष्टीकरण, हालांकि glnormal पुराने ओपनजीएल कार्यान्वयन का हिस्सा है और इससे बचा जाना चाहिए। – Matth

+1

@MaththUnderpants प्रतिक्रिया के लिए धन्यवाद, अब इसे करने का बेहतर तरीका क्या है? –

+0

यह कशेरुक शेडर का उपयोग करके और फिर खंड टुकड़े को डेटा पास कर रहा है। मैं सलाह देता हूं कि आप इस भयानक ट्यूटोरियल पर पढ़ लें: www.learnopengl.com – Matth

संबंधित मुद्दे