ওপেনজিএল: আমাকে কেন গ্লোনোরমাল দিয়ে একটি সাধারণ সেট করতে হবে?


19

আমি ওপেনগিএলের কয়েকটি বুনিয়াদি শিখছি তবে আমি ভাবছি যে কেন glNormalশীর্ষে অবস্থান নির্ধারণের জন্য একটি কল রয়েছে।

যদি আমি এর মতো একটি সাধারণ ত্রিভুজ তৈরি করি:

glBegin(GL_TRIANGLES);
    glVertex3f(0,0,0);
    glVertex3f(1,0,0);
    glVertex3f(0,1,0);
glEnd();

জ্যামিতিক আদিম ধরণের দ্বারা সাধারণগুলি কী স্পষ্টভাবে সংজ্ঞায়িত করা উচিত নয়? আমি যদি কোনও সাধারণ সেট না করি তবে ওপেনজিএল এটি গণনা করবে?


7
আমি কেবল এটিই উল্লেখ করতে চাই যে এই কোডটি অবহিত স্থির-ফাংশন পাইপলাইন ব্যবহার করছে এবং আধুনিক ওপেনগ্লিতে উভয়ই স্বাভাবিক এবং উল্লম্বগুলি কেবল জেনেরিক ভার্টেক্স গুণাবলী।
বারটেক বানাচিউইচজ

4
তাত্ক্ষণিক মোড ব্যবহার করবেন না। এটি অবমূল্যায়িত হয়েছে। আমি উচ্চতর 3D গ্রাফিক্স প্রোগ্রামিং শিখার প্রস্তাব দিই ।
ডানফোল্ড

3
আমি মনে করি তাত্ক্ষণিক মোডের ব্যবহার সম্পর্কে মন্তব্যটি এখানে সম্পূর্ণ অপ্রাসঙ্গিক। হ্যাঁ, এটি ব্যবহার করা উচিত নয়, তবে তাৎক্ষণিক মোড, ভারটেক্স অ্যারে, ভিবিও, জেনেরিক অ্যাপ্রিবি, স্থিরভাবে প্রাপ্তি বা টোস্টের বিটগুলি নির্বিশেষে প্রশ্নের বিন্দুটি একই থাকে।
ম্যাক্সিমাস মিনিমাস

1
এটি স্বয়ংক্রিয়ভাবে নির্ধারিত হয় না কারণ এটি আলোককে বহুবিবাহ তৈরি করবে (আরও ভাল শব্দের অভাবে)। আমি এর দ্বারা যা বোঝাতে চাইছি তা হল, ত্রিভুজের সমস্ত উলম্বের একই স্বাভাবিক মান থাকবে। সমতল পৃষ্ঠগুলির জন্য আমরা এটি প্রত্যাশা করব, তবে আপনার যদি কোনও ব্যক্তির মুখোমুখি একটি মডেল থাকে তবে মুখের প্রতিটি ত্রিভুজটির আলোকসজ্জার একই মূল্য হবে (বহুভুজগুলি দেখতে এটি খুব সহজ করে তোলে)। আপনার নিজস্ব মানগুলি নির্দিষ্ট করে আপনি জিনিসগুলিকে অনেক বেশি মসৃণ দেখতে পারেন (সাধারণত আপনি বর্তমান বামদিকগুলি সহ সমস্ত ত্রিভুজের সাধারণ মানের গড়পড়তা একটি সাধারণকে আবিষ্কার করেন)।
বেনিয়ামিন ডেঞ্জার জনসন

উত্তর:


30

এর glNormalমধ্যে একাধিকবার কল করা glBegin/Endআপনাকে প্রতি আদিম পরিবর্তে ভার্টেক্স প্রতি সাধারণ সেট করতে দেয়।

glBegin(GL_TRIANGLES);
    glNormal3f(0,0,1);
    glVertex3f(0,0,0);
    glNormal3f(0,0,1);
    glVertex3f(1,0,0);
    glNormal3f(0,0,1);
    glVertex3f(0,1,0);
glEnd();

একাধিক ত্রিভুজ সমন্বিত আরও জটিল জালের জন্য আপনি একটি ভার্টেক্সের স্বাভাবিকটি পার্শ্ববর্তী জ্যামিতির অন্যান্য ত্রিভুজগুলির উপর নির্ভর করে এবং এটি কেবলমাত্র ত্রিভুজের সাথে সম্পর্কিত তার উপর নির্ভর করে না।

এখানে একই জ্যামিতির উদাহরণ রয়েছে:

  • বাম প্রতি পার্ফটেক্স নরমালগুলিতে - তাই মুখের প্রতিটি প্রান্তিকের একটি আলাদা স্বাভাবিক থাকে (এই গোলকের জন্য এটি সমস্ত স্বাভাবিকটি তার কেন্দ্র থেকে বাইরের দিকে নির্দেশ করে) এবং এবং
  • ডান প্রতি মুখের নরমালগুলিতে - প্রতিটি প্রান্তিকটি একই সাধারণ মান পায় (যেহেতু আপনি কেবল এটি একবার নির্দিষ্ট করেছেন, বা কারণ এটি ডিফল্ট স্বাভাবিক মান ব্যবহার করে (0,0,1)):

বামদিকে প্রতি-ভার্টেক্স নরমালস, ডানদিকে প্রতি মুখের নরমালগুলি

ডিফল্ট শেড মডেল ( GL_SMOOTH) মুখের প্রান্তগুলিকে স্বাভাবিকের মুখ জুড়ে ইন্টারপোল্ট করে তোলে। প্রতি-ভার্টেক্সের স্বাভাবিকের জন্য এটি মসৃণ ছায়াযুক্ত গোলকের ক্ষেত্রে তৈরি হয় তবে প্রতি মুখের নরমালগুলির জন্য আপনি বৈশিষ্ট্যযুক্ত চেহারার চেহারাটি শেষ করেন।


4

না, জিএল আপনার জন্য কোনও আদর্শ গণনা করে না। এটি কী হতে হবে তা জানতে পারে না। আপনার আদিমগুলি রাস্টারাইজেশনের বাইরে (এবং কয়েকটি অন্যান্য স্থানের) অর্থ নয়। কোন মুখগুলি (ত্রিভুজগুলি) কোন ভার্টেক্স ভাগ করে তা জিএল জানেন না (বিভিন্ন ডেটা স্ট্রাকচার ব্যবহার না করে রানটাইমের সময় এটি গণনা খুব ব্যয়বহুল)।

সাধারণ শিখরেখাগুলি খুঁজে বের করতে এবং নরমাল গণনা করতে আপনার একটি জালের "ত্রিভুজ স্যুপ" প্রিপ্রোসেস করতে হবে। গেমটি গতির জন্য চালানোর আগে এটি করা উচিত।

শক্ত প্রান্তের মতো কেসও রয়েছে যেখানে জ্যামিতিকভাবে কোণে একটি ভাগ করা শীর্ষস্থান রয়েছে তবে আপনি পৃথক নরমাল চান যাতে এটি সঠিকভাবে আলোকিত হয়। জিএল / ডি 3 ডি রেন্ডারিং মডেলটিতে আপনার জন্য পৃথক দুটি স্বাভাবিক বিশিষ্ট (একই অবস্থানে) প্রয়োজন, প্রতিটি পৃথক স্বাভাবিক রয়েছে।

আপনার ইউভি এবং টেক্সচার ম্যাপিংয়ের জন্যও এগুলি দরকার।


3

সংক্ষিপ্ত উত্তর আপনি আসলে না যে আছে এ সব একটি স্বাভাবিক সেট করতে। সাধারণ ভেক্টরগুলি কেবল তখনই ব্যবহার করা হয় যদি আপনি ওপেনএল লাইটিং করছেন (বা সম্ভবত তাদের উপর নির্ভর করে এমন কোনও গণনা) তবে আপনি যদি এটি প্রযোজ্য না হন (বা আপনি যদি আলোকপাতের জন্য অন্য কোনও পদ্ধতি ব্যবহার করেন, যেমন লাইটম্যাপস ) তারপরে আপনি বেশ আনন্দের সাথে সমস্ত glNormal কল বাদ দিতে পারেন।

সুতরাং আসুন ধরে নেওয়া যাক আপনি এমন কিছু করছেন যেখানে গ্লোনোরমাল নির্দিষ্ট করে বোঝানো যায় এবং এটি আরও কিছু দেখুন।

glNormal প্রতি-আদিম বা প্রতি-ভার্টেক্স নির্দিষ্ট করা যেতে পারে। প্রতি-আদিম নরমালগুলির সাথে এর অর্থ হ'ল আদিম মুখের প্রতিটি ভার্টেক্সের জন্য সমস্ত নরমাল একই দিকে। কখনও কখনও এটি আপনি চান তবে কখনও কখনও তা হয় না - যেখানে প্রতি-ভার্টেক্স নরমালগুলি কার্যকর হয় তা হ'ল তারা প্রতিটি ভার্টেক্সকে তার নিজের মুখোমুখি হওয়ার অনুমতি দেয়।

একটি গোলকের ক্লাসিক উদাহরণ নিন। যদি একটি গোলকের প্রতিটি ত্রিভুজটির একই স্বাভাবিক থাকে তবে শেষের ফলাফলটি বেশ কার্যকর হবে। এটি সম্ভবত আপনি যা চান তা নয়, পরিবর্তে আপনি একটি মসৃণ ছায়া চান। সুতরাং আপনি যা করেন তা হ'ল প্রতিটি ত্রিভুজের জন্য সাধারণ যেটি একটি সাধারণ ভার্টেক্স ভাগ করে তোলে এবং একটি মসৃণ ছায়াযুক্ত ফলাফল পান।


2

ন্যূনতম উদাহরণ যা কীভাবে glNormalছড়িয়ে পড়া বাজ নিয়ে কাজ করে তার কিছু বিশদ চিত্রিত করে।

displayফাংশনের মন্তব্যগুলি প্রতিটি ত্রিভুজটির অর্থ কী তা ব্যাখ্যা করে।

এখানে চিত্র বর্ণনা লিখুন

#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;
}

তত্ত্ব

ওপেনজিএলে প্রতিটি ভার্টেক্সের নিজস্ব সম্পর্কিত সাধারণ ভেক্টর রয়েছে।

সাধারণ ভেক্টরটি নির্ধারণ করে যে ভার্টেক্সটি কতটা উজ্জ্বল, যা ত্রিভুজটি কতটা উজ্জ্বল তা নির্ধারণের জন্য ব্যবহৃত হয়।

যখন কোনও পৃষ্ঠ আলোর জন্য লম্ব হয় তখন এটি সমান্তরাল পৃষ্ঠের চেয়ে উজ্জ্বল থাকে।

glNormal বর্তমানের সাধারণ ভেক্টর সেট করে যা নীচের সমস্ত ভার্টেক্সগুলির জন্য ব্যবহৃত হয়।

স্বাভাবিক জন্য প্রারম্ভিক মান আগে আমরা সব glNormalহয় 0,0,1

সাধারণ ভেক্টরগুলির অবশ্যই আদর্শ 1 থাকতে হবে , অন্যথায় রঙ পরিবর্তন হয়! glScaleস্বাভাবিকের দৈর্ঘ্যও বদলে দেয়! glEnable(GL_NORMALIZE);ওপেনজিএল আমাদের জন্য স্বয়ংক্রিয়ভাবে তাদের আদর্শ 1 এ সেট করে। এই জিআইএফ এটি সুন্দরভাবে চিত্রিত করে।

বিবলিওগ্রাফি:


উত্তম উত্তর, তবে কেন একটি পুরানো প্রশ্ন এবং একটি পুরানো প্রযুক্তিতে কেন মনোযোগ কেন?
ভায়ল্যানকোর্ট

ধন্যবাদ আলেকজান্দ্রেভেল্যানকোর্ট! পুরানো প্রশ্ন: কেন নয় :-) পুরাতন প্রযুক্তি: আজ এর চেয়ে ভাল উপায় কী?
সিরো সান্তিলি :4 改造 中心 法轮功 六四 事件

আমি মনে করি আধুনিক ওপেনজিএল glNormal নির্দিষ্ট করার পরিবর্তে বাফার অবজেক্ট ব্যবহার করে।
ভ্যালেনকোর্ট

1
প্রকৃতপক্ষে, গ্লোনোরমাল এবং গ্লোভার্টেক্স এবং এর মতো আধুনিক ওপেনলিতে চলে গেছে, এবং এর কিছু সময় আগে তাকে অবহেলা করা হয়েছিল ... এই প্রশ্নটি মূলত জিজ্ঞাসা করার পরেও তারা বাস্তবে অবহেলিত ছিল।

0

কোডার-নির্ভর কিছু বৈশিষ্ট্য বাস্তবায়নের জন্য আপনার গ্লোনোরমাল প্রয়োজন। উদাহরণস্বরূপ আপনি হার্ড এজগুলি সংরক্ষণ করতে পারেন নরমাল ডাট তৈরি করতে।


4
সম্ভবত আপনি নিজের উত্তরটি কিছুটা উন্নত করতে চাইবেন।
বার্তেক বনচেউইচজ 8'13

1
আপনি যদি আমার উত্তরটি উন্নত করতে চান তবে আপনার দুর্বল দাগগুলি চিহ্নিত করতে হবে। যদিও আমি এটিতে বিস্তারিত বলতে পারি। এক্সব্ল্যাক্স যেমন ভাবতেন, প্রতিটি সাধারণকে একইভাবে গণনা করা উচিত। প্রতিটি পিক্সেল বনাম প্রতিটি পিক্সেলের জন্য ইন্টারপোল্টেড নরমালগুলির মধ্যে পার্থক্য থাকা সত্ত্বেও। আসুন বিষয়টিকে আরও কিছুটা বিবেচনা করুন।
এবি।

1
কখনও কখনও আপনি কঠোর প্রান্ত বজায় রাখতে এবং এটি আরও স্বতন্ত্র করে তুলতে পারেন wish এখানে কয়েকটি নমুনা চিত্র রয়েছে: টাইটান.সি.ইউজএন.এক.জা . / ওপেনগল / ওপেনগ্ল- ডি 5 / ট্রেন্ট.সগি / ওপেনগল/… পিএস। দু'বার পোস্ট করার জন্য দুঃখিত আমি এসই ইন্টারফেসে নতুন
এবি।

একটি "সম্পাদনা" বোতাম আছে।
বারটেক বানাচিউইচজ

1
আপনি 5 মিনিটের পরে সম্পাদনা করতে পারবেন না
এবি।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.