سؤال

أنا جديد على OpenGL ES وأتطور في Objective-C لـ iPhone.

ما أحاول أن أفهمه هو كيف يتم وضع الضوء في بلدي الحفر. هكذا أفعل ذلك:

أقوم بإنشاء مربع وأضعه على أنه "أرضية" في حريري. أنا أضع الضوء ، أعلاه مباشرة ، في منتصف الأرض وأوجه اتجاه الضوء لأسفل. الآن ، أتوقع أن تكون دائرة الضوء على الأرض في الوسط. لكن الأمر ليس كذلك ، فهذا أكثر من الظهر (Futher Away). كيف ذلك؟

near = 8.0
far = 28
light position = {0.0, 0.0, -10.0}
light direction = {0.0, -1.0, 0.0}

Floor coordinates = {-0.3153, -0.473, -20.0},
{-0.3153, -0.473, 0.0},
{0.3153, -0.473, -20.0},
{0.3153, -0.473, 0.0},

ألا ينبغي أن يجعل هذا معًا دائرة الضوء في منتصف الأرض ولا يتم وضعها إلى الوراء قليلاً؟

هذا هو رمزتي المهمة:

إعداد العرض:

 -(void)setupView:(TDRoomView*)view
    {


    const GLfloat zNear = 8, zFar = 28, fieldOfView = 5; 

 GLfloat size; 
 glEnable(GL_DEPTH_TEST);
 glMatrixMode(GL_PROJECTION); 
 size = zNear * tanf(DEGREES_TO_RADIANS(fieldOfView) / 2.0); 
 NSLog(@"tanf(DEGREES_TO_RADIANS(fieldOfView)/2.0); %f ", tanf(DEGREES_TO_RADIANS(fieldOfView)/2.0));

 CGRect rect = view.bounds; 
 glFrustumf(-size, size, -size / (rect.size.width / rect.size.height), size / 
      (rect.size.width / rect.size.height), zNear, zFar);  
 glViewport(-size, size, rect.size.width, rect.size.height);  
 glMatrixMode(GL_MODELVIEW);
    glShadeModel(GL_SMOOTH);
 glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_LIGHTING);

    glEnable(GL_LIGHT0);

 static const Color3D light0Ambient[] = {{1.0, 1.0, 1.0, 1.0}};
 glLightfv(GL_LIGHT0, GL_AMBIENT, (const GLfloat *)light0Ambient);

    static const Color3D light0Diffuse[] = {{0.5, 0.5, 0.5, 1.0}};
 glLightfv(GL_LIGHT0, GL_DIFFUSE, (const GLfloat *)light0Diffuse);

    static const Color3D light0Specular[] = {{0.5, 0.5, 0.5, 1.0}};
    glLightfv(GL_LIGHT0, GL_SPECULAR, (const GLfloat *)light0Specular);

    static const Vertex3D light0Position[] = {{0.0, 0.473, -10.0}};
 glLightfv(GL_LIGHT0, GL_POSITION, (const GLfloat *)light0Position); 

 static const Vertex3D lightVector= {0.0, -1.0, 0.0};

    glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, (GLfloat *)&lightVector);

    glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 85);

 glLoadIdentity(); 
 glClearColor(0.0f, 0.0f, 1.0f, 1.0f); 

    }

والرسم:

     -(void)drawView:(TDRoomView*)view
    {

        static const Vertex3D vertices[]= {
  {-0.3153, -0.473, -20.0},
  {-0.3153, -0.473, 0.0},
  {0.3153, -0.473, -20.0},
  {0.3153, -0.473, 0.0},
  {-0.1, -0.25, -3.0},
  {0.0, 0.0, -10.0},
  {0.1, -0.25, -3.0}
 };

 static const Color3D colors[] = {
  {0.7, 0.7, 0.7, 1.0},
  {0.7, 0.7, 0.7, 1.0},
  {0.7, 0.7, 0.7, 1.0},
  {0.7, 0.7, 0.7, 1.0},
  {1.0, 0.0, 0.0, 1.0},
  {0.0, 1.0, 0.0, 1.0},
  {0.0, 0.0, 1.0, 1.0}
       };


 static const GLubyte roomFaces[] = {
  0, 1, 2,
  1, 2, 3};


        static const Vector3D normals[] = {
  {0.000000, 1.000000, 0.000000},
  {0.000000, 1.000000, 0.000000},
  {0.000000, 1.000000, 0.000000},
  {0.000000, 1.000000, 0.000000},
  {0.000000, 1.000000, 0.000000},
  {0.000000, 1.000000, 0.000000},
  {0.000000, 1.000000, 0.000000}
 };

    glLoadIdentity();

    glClearColor(0.7, 0.7, 0.7, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnableClientState(GL_VERTEX_ARRAY);
 glEnableClientState(GL_COLOR_ARRAY);
 glEnableClientState(GL_NORMAL_ARRAY);

        glVertexPointer(3, GL_FLOAT, 0, vertices);
 glColorPointer(4, GL_FLOAT, 0, colors);
 glNormalPointer(GL_FLOAT, 0, normals);
 glDrawElements(GL_TRIANGLE_STRIP, 8, GL_UNSIGNED_BYTE, roomFaces);

        glDisableClientState(GL_NORMAL_ARRAY);
 glDisableClientState(GL_VERTEX_ARRAY);
 glDisableClientState(GL_COLOR_ARRAY); }

أيضا ، أنا إعادة تغيير

static const Vertex3D light0Position[] = {{0.0, 0.473, -10.0}};

إلى

static const Vertex3D light0Position[] = {{0.0, 0.473, -8.0}}; 

يتحول البورد إلى الظلام ، ولا يضيء الضوء عليه. لماذا ، أنا فقط نقلت الضوء على خطوتين أقرب ...؟ تحدث نفس الأشياء إذا قمت بنقلها خطوتين بعيدًا مثل هذا:

static const Vertex3D light0Position[] = {{0.0, 0.473, -12.0}};

أي مساعدة من أجل "إلقاء ضوء سوم" على مشكلتي موضع تقدير كبير! (لا يمكن أن تساعدها ... ؛))

شكرا مقدما!

هل كانت مفيدة؟

المحلول

أقترح عليك القيام بشبكة أكبر مع المزيد من القمم ، ويفضل أن يكون n من المربعات n. حاول ألا تكون مثلثات طويلة جدًا. هذا سيجعل من السهل معرفة أين يبدو الضوء كما يتم حساب الضوء لكل قمة وليس لكل بكسل للسطح.

http://www.opengl.org/resources/features/kilgardtechniques/oglpitfall/

2. الفسيفساء الضعيف يؤلم الإضاءة

تتم حسابات إضاءة OpenGL لكل فرد. هذا يعني أن حسابات التظليل الناتجة عن مصادر الضوء التي تتفاعل مع المادة السطحية لكائن ثلاثي الأبعاد يتم حسابها فقط في رؤوس الكائن. عادةً ما يتداخل OpenGL أو ظلال ناعمة بين ألوان قمة الرأس. تعمل إضاءة Pertex الخاصة بـ OpenGL بشكل جيد باستثناء عندما يتم فقدان تأثير الإضاءة مثل تسليط الضوء على المحاربة أو الأضواء أو عدم وضوح لأن التأثير لا يتم أخذ عينات منه بشكل كافٍ بواسطة رؤوس الكائن. يحدث مثل هذا النوع من التأثيرات من آثار الإضاءة عندما يتم تصميم الكائنات بشكل خشن لاستخدام الحد الأدنى من القمم.

:

غالبًا ما يتم إغراء مبرمجي Novice OpenGL لتمكين وظائف الأضواء من OpenGL وتسليط الضوء على جدار على غرار بمضلع ضخم واحد. لسوء الحظ ، لن يظهر نمط الأضواء الحاد كما المقصود المبتدئ ؛ ربما لن ترى أي تأثير على الإطلاق. المشكلة هي أن قطع الأضواء يعني أن الزوايا القصوى للجدار حيث يتم تحديد القمم لا تحصل على أي مساهمة من الأضواء ولأن هذه هي القمم الوحيدة التي يمتلكها الجدار ، فلن يكون هناك نمط تسليط الضوء على الحائط.

نصائح أخرى

GL_POSITION تم تحديده في إحداثيات متجانسة ، مما يعني أنه يتطلب أربع قيم ، وليس ثلاث قيم. تحتاج إلى تحديد ث = 1.0 لمصدر الضوء الخاص بك ، ولكن الخاص بك ث المكون بدلاً من ذلك يأتي من كل ما يحدث بجوار light0Position في الذاكرة.

(جزء من سبب ذلك GL_POSITION هو في إحداثيات متجانسة هو السماح لك بتحديد المصابيح الاتجاهية عن طريق تحديد موضع مع ث = 0.0.)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top