تظهر الإضاءة المرآوية على الجانبين المواجهين للعين والجانبين الخلفيين للجسم

StackOverflow https://stackoverflow.com//questions/20008089

سؤال

أنا أكتب اختبارًا صغيرًا لتظليل فونج، وأضرب رأسي بجدار من الطوب محاولًا تشغيل المكون المرآوي.يبدو أنه يعمل بشكل صحيح، فيما عدا أنه يتم تطبيق الضوء المرآوي على كل من الجزء الأمامي والخلفي من الجسم.(الكائن نفسه شفاف، مع فرز الوجوه يدويًا على جانب وحدة المعالجة المركزية.)

لاحظ أن المكون المنتشر يعمل بشكل مثالي (يظهر فقط على الجانب المواجه لمصدر الضوء) - وهو ما يبدو أنه يستبعد مشكلة وصول العناصر الطبيعية إلى تظليل الأجزاء، على ما أعتقد.

كما أفهم، فإن المكون المرآوي يتناسب مع جتا الزاوية بين متجه العين ومتجه الضوء المنعكس.

لإبقاء الأمور بسيطة للغاية، يحاول رمز الاختبار الخاص بي القيام بذلك في الفضاء العالمي.يتم ترميز موضع الكاميرا ومتجه الضوء بشكل ثابت (آسف). (0,0,4) و (-0.707, 0, -0.707) على التوالى.وبالتالي فإن ناقلات العين (0,0,4) - fragPosition.

نظرًا لأن مصفوفة النموذج تقوم بالتدوير فقط، فإن تظليل قمة الرأس يقوم ببساطة بتحويل قمة الرأس العادية بواسطة مصفوفة النموذج.(ملحوظة: هذه ليست ممارسة جيدة لأن العديد من أنواع التحويل لا تحافظ على التعامد الطبيعي.عموما للمصفوفة العادية، يجب عليك استخدام التبديل العكسي للجزء العلوي الأيسر 3x3 من مصفوفة النموذج.) لتبسيط الأمور، يعمل تظليل الأجزاء على قناة لونية عائمة واحدة، ويتخطى الأس المرآوي (/ يستخدم الأس 1).

تظليل قمة الرأس:

#version 140

uniform mat4 mvpMtx;
uniform mat4 modelMtx;

in vec3 inVPos;
in vec3 inVNormal;

out vec3 normal_world;
out vec3 fragpos_world;

void main(void) {
  gl_Position = mvpMtx * vec4(inVPos, 1.0);
  normal_world = vec3(modelMtx * vec4(inVNormal, 0.0));
  fragpos_world = vec3(modelMtx * vec4(inVPos, 1.0)); 
}

تظليل الجزء:

#version 140

uniform float
    uLightS,
    uLightD,
    uLightA;

uniform float uObjOpacity;

in vec3 normal_world, fragpos_world;
out vec4 fragOutColour;

void main(void) {

    vec3 vN = normalize(normal_world);
    vec3 vL = vec3(-0.707, 0, -0.707);

    // Diffuse:
    // refl in all directions is proportional to cos(angle between -light vector & normal)
    // i.e. proportional to -l.n
    float df = max(dot(-vL, vN), 0.0);

    // Specular:
    // refl toward eye is proportional to cos(angle between eye & reflected light vectors)
    // i.e. proportional to r.e
    vec3 vE = normalize(vec3(0, 0, 4) - fragpos_world);
    vec3 vR = reflect(vL, vN);
    float sf = max(dot(vR, vE), 0.0);

    float col = uLightA + df*uLightD + sf*uLightS;

    fragOutColour = vec4(col, col, col, uObjOpacity);

}

لا أستطيع العثور على خطأ هنا.هل يمكن لأي شخص أن يشرح سبب ظهور المكون المرآوي في الجزء الخلفي بالإضافة إلى الجانب المواجه للضوء من الجسم؟

تشكرات.

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

المحلول

ستكون مساهمتك المرآوية في الواقع هي نفسها بالنسبة للوجوه الأمامية والخلفية بسبب GLSL reflect غير حساس لعلامة الطبيعي.من هذا المرجع:

reflect(I, N) = I - 2.0 * dot(N, I) * N

لذا فإن قلب علامة N يقدم علامتي ناقص والتي تلغى.بالكلمات ماذا reflect ما يفعله هو عكس علامة مكون I والذي يقع على نفس المحور N.هذا لا يعتمد على الطريقة التي N يواجه.

إذا كنت تريد إزالة المكون المرآوي من وجوهك الخلفية، فأعتقد أنك ستحتاج إلى التحقق بشكل صريح من بياناتك dot(vE,vN).

نصائح أخرى

حاول التغيير

fragpos_world = vec3(modelMtx * vec4(inVPos, 0.0)); 

ل

fragpos_world = vec3(modelMtx * vec4(inVPos, 1.0)); 

لأن http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/#Homogeneous_coerates

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