نموذج انعكاس بلين-فونغ

نموذج بلين-فونغ للانعكاس ، والذي يسمى أيضًا نموذج فونغ المعدل للانعكاس، هو تعديل طوره جيم بلين لنموذج فونغ للانعكاس في عام 1977. [ 1 ]

يُعدّ نموذج بلين-فونغ نموذج تظليل يُستخدم في OpenGL و Direct3D ذي الوظائف الثابتة (قبل Direct3D 10 و OpenGL 3.1)، ويتم تنفيذه على كل رأس أثناء مروره عبر مسار الرسومات ؛ ويتم استكمال قيم البكسل بين الرؤوس بواسطة تظليل غورو افتراضيًا، بدلاً من تظليل فونغ الأكثر تكلفة حسابيًا . [ 2 ]

وصف

متجهات لحساب تظليل فونغ وبلين-فونغ

في تظليل فونغ، يجب إعادة حساب حاصل الضرب النقطي باستمرارRV{\displaystyle R\cdot V}بين المشاهد ( V ) والشعاع المنبعث من مصدر ضوئي ( L ) المنعكس ( R ) على سطح ما.

أما إذا تم حساب متجه في منتصف المسافة بين متجهي المشاهد ومصدر الضوء،

ح=ل+Vل+V{\displaystyle H={\frac {L+V}{\left\|L+V\right\|}}}

RV{\displaystyle R\cdot V}يمكن استبدالها بـشمالح{\displaystyle N\cdot H}، أينشمال{\displaystyle N}يمثل متجه السطح العمودي المعياري . في المعادلة أعلاه،ل{\displaystyle L}وV{\displaystyle V}كلاهما متجهات مُعَيَّرة، وح{\displaystyle H}هو حل للمعادلةV=Pح(-ل)،{\displaystyle V=P_{H}(-L),}أينPح{\displaystyle P_{H}}هي مصفوفة هاوسهولدر التي تعكس نقطة في المستوى الفائق تحتوي على نقطة الأصل ولها متجه عموديح.{\displaystyle H.}

يمثل هذا الضرب القياسي جيب تمام زاوية تساوي نصف الزاوية التي يمثلها الضرب القياسي لفونغ، إذا كانت المتجهات V و L و N و R تقع جميعها في نفس المستوى. وتبقى هذه العلاقة بين الزوايا صحيحة تقريبًا حتى عندما لا تقع المتجهات في نفس المستوى، وخاصةً عندما تكون الزوايا صغيرة. ولذلك، تُسمى الزاوية بين N و H أحيانًا بزاوية المنتصف.

وبالنظر إلى أن الزاوية بين متجه المنتصف والعمودي على السطح من المرجح أن تكون أصغر من الزاوية بين R و V المستخدمة في نموذج فونغ (إلا إذا تم النظر إلى السطح من زاوية شديدة الانحدار، حيث من المرجح أن تكون أكبر)، ولأن فونغ يستخدم(RV)α،{\displaystyle \left(R\cdot V\right)^{\alpha },}يمكن تحديد الأسα>α{\displaystyle \alpha ^{\prime }>\alpha }بحيث(شمالح)α{\displaystyle \left(N\cdot H\right)^{\alpha ^{\prime }}}أقرب إلى التعبير السابق.

بالنسبة للأسطح المضاءة من الأمام (انعكاسات لامعة على الأسطح المواجهة للمشاهد)،α=4α{\displaystyle \alpha ^{\prime }=4\,\alpha }سينتج عن ذلك لمعانٌ لامعٌ يُطابق إلى حدٍ كبيرٍ انعكاسات فونغ المقابلة. مع ذلك، فبينما تكون انعكاسات فونغ دائريةً دائمًا على الأسطح المستوية، تصبح انعكاسات بلين-فونغ بيضاويةً عند النظر إلى السطح من زاوية حادة. يُمكن تشبيه ذلك بحالة انعكاس الشمس في البحر بالقرب من الأفق، أو انعكاس ضوء شارع بعيد على رصيف مبلل، حيث يكون الانعكاس دائمًا أكثر امتدادًا رأسيًا منه أفقيًا. [ 3 ]

مقارنة بصرية: تكون إضاءات بلين-فونغ أكبر من إضاءات فونغ بنفس الأس، ولكن عن طريق خفض الأس، يمكن أن تصبح متساوية تقريبًا.

بالإضافة إلى ذلك، ورغم أنه يمكن اعتباره تقريبًا لنموذج فونغ، إلا أنه ينتج نماذج أكثر دقة لوظائف توزيع الانعكاس ثنائي الاتجاه المحددة تجريبيًا مقارنةً بنموذج فونغ لأنواع عديدة من الأسطح. [ 4 ]

كفاءة

ستكون خوارزمية بلين-فونغ أسرع من خوارزمية فونغ في حالة اعتبار كل من المشاهد والضوء بعيدين جدًا، كأن يكونا على مسافة قريبة جدًا أو في اللانهاية. ينطبق هذا على الأضواء الموجهة والكاميرات المتعامدة/المتساوية القياس. في هذه الحالة، يكون متجه المنتصف مستقلًا عن الموضع وانحناء السطح، لأنه يعتمد على اتجاه موضع المشاهد واتجاه موضع الضوء، واللذان يتقاربان بشكل منفصل عند هذه المسافة البعيدة، وبالتالي يمكن اعتبار متجه المنتصف ثابتًا في هذه الحالة.ح{\displaystyle H}لذا، يمكن حسابها مرة واحدة لكل مصدر ضوء، ثم استخدامها للإطار بأكمله، أو حتى طالما بقي مصدر الضوء ونقطة الرؤية في نفس الوضع النسبي. لا ينطبق هذا على طريقة فونغ التي تستخدم متجه الانعكاس، والذي يعتمد على انحناء السطح، ويجب إعادة حسابه لكل بكسل في الصورة (أو لكل رأس من رؤوس النموذج في حالة إضاءة الرؤوس). في المشاهد ثلاثية الأبعاد ذات الكاميرات المنظورية، لا يمكن تحقيق هذا التحسين.

نماذج التعليمات البرمجية

نموذج كود لغة التظليل عالية المستوى

هذا المثال في لغة التظليل عالية المستوى هو طريقة لتحديد الضوء المنتشر والضوء المنعكس من ضوء نقطي. يتم تمرير بنية الضوء، وموقع السطح في الفضاء، ومتجه اتجاه الرؤية، والعمودي على السطح. يتم إرجاع بنية الإضاءة؛

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

struct Lighting { float3 Diffuse ; float3 Specular ; };struct PointLight { float3 position ; float3 diffuseColor ; float diffusePower ; float3 specularColor ; float specularPower ; };دالة `GetPointLight` للإضاءة ( نقطة الضوء ، موضع ثلاثي الأبعاد ، اتجاه العرض ، متجه عادي ) { الإضاءة خارجة ؛ إذا كانت قوة الانتشار للضوء أكبر من صفر ، { اتجاه الضوء = موضع الضوء - موضع ثلاثي الأبعاد ؛ // الموضع ثلاثي الأبعاد في فضاء السطح؛ المسافة = طول اتجاه الضوء ؛ اتجاه الضوء = اتجاه الضوء / المسافة ؛ // = تطبيع(اتجاه الضوء)؛ المسافة = المسافة * المسافة ؛// شدة الضوء المنتشر. يتم تشبعها للحفاظ على القيمة ضمن النطاق 0-1. float NdotL = dot ( normal , lightDir ); float diffuseIntensity = saturate ( NdotL );// حساب الإضاءة المنتشرة مع مراعاة لون الضوء وقوته وتوهينه . OUT.Diffuse = diffuseIntensity * light.diffuseColor * light.diffusePower / distance ;// احسب نصف المتجه بين متجه الضوء ومتجه الرؤية. float3 H = normalize ( lightDir + viewDir );// شدة الضوء الانعكاسي float NdotH = dot ( normal , H ); float specularIntensity = pow ( saturate ( NdotH ), specularHardness );// اجمع عوامل الضوء الانعكاسي OUT . Specular = specularIntensity * light.specularColor * light.specularPower / distance ; } return OUT ; }

نموذج كود لغة تظليل OpenGL

يتكون هذا المثال في لغة تظليل OpenGL من ملفي كود، أو مُظلِّلَين . الأول هو ما يُسمى مُظلِّل الرؤوس، ويُطبِّق تظليل فونغ ، الذي يُستخدم لاستكمال متجه السطح العمودي بين الرؤوس. أما المُظلِّل الثاني فهو ما يُسمى مُظلِّل الأجزاء، ويُطبِّق نموذج تظليل بلين-فونغ لتحديد الضوء المنتشر واللامع من مصدر ضوء نقطي.

مُظلل الرؤوس

يقوم هذا البرنامج المُظلل للرؤوس بتنفيذ تظليل فونغ :

السمة vec3 inputPosition ؛ السمة vec3 inputNormal ؛إسقاط موحد من نوع mat4 ، عرض النموذج ، مصفوفة عادية ؛تغيير متجه ثلاثي الأبعاد normalInterp ؛ تغيير متجه ثلاثي الأبعاد vertPos ؛void main () { gl_Position = projection * modelview * vec4 ( inputPosition , 1.0 ); // modelview عبارة عن تحويل خطي، لذا يجب أن تكون قيمة w هي 1.0 vec4 vertPos4 = modelview * vec4 ( inputPosition , 1.0 ); vertPos = vec3 ( vertPos4 ). xyz ; normalInterp = vec3 ( normalMat * vec4 ( inputNormal , 0.0 )); }

تظليل الأجزاء

يقوم هذا المظلل الجزئي بتنفيذ نموذج تظليل بلين-فونغ [ 5 ] وتصحيح جاما :

نوع البيانات الدقيق ذو الدقة المتوسطة (float في vec3 normalInterp ؛ في vec3 vertPos ؛الوضع الموحد للأعداد الصحيحة ؛const vec3 lightPos = vec3 ( 1.0 , 1.0 , 1.0 ); const vec3 lightColor = vec3 ( 1.0 , 1.0 , 1.0 ); const float lightPower = 40.0 ; const vec3 ambientColor = vec3 ( 0.1 , 0.0 , 0.0 ); const vec3 diffuseColor = vec3 ( 0.5 , 0.0 , 0.0 ); const vec3 specColor = vec3 ( 1.0 , 1.0 , 1.0 ); const float shininess = 16.0 ; const float screenGamma = 2.2 ; // نفترض أن الشاشة معايرة وفقًا لمساحة ألوان sRGBvoid main () {vec3 normal = normalize ( normalInterp ); vec3 lightDir = lightPos - vertPos ; float distance = dot ( lightDir , lightDir ); lightDir = normalize ( lightDir );float lambertian = max ( dot ( lightDir , normal ), 0.0 ); float specular = 0.0 ;إذا كانت قيمة لامبرتيان أكبر من 0.0 {vec3 viewDir = normalize ( - vertPos );// هذا هو vec3 blinn phong halfDir = normalize ( lightDir + viewDir ); float specAngle = max ( dot ( halfDir , normal ), 0.0 ); specular = pow ( specAngle , shininess ); // هذا هو phong (للمقارنة) if ( mode == 2 ) { vec3 reflectDir = reflect ( - lightDir , normal ); specAngle = max ( dot ( reflectDir , viewDir ), 0.0 ); // لاحظ أن الأس مختلف هنا specular = pow ( specAngle , shininess / 4.0 ); } } vec3 colorLinear = ambientColor + diffuseColor * lambertian * lightColor * lightPower / distance + specColor * specular * lightColor * lightPower / distance ; // تطبيق تصحيح غاما (بافتراض أن ambientColor و diffuseColor و specColor قد تم تحويلها إلى قيم خطية، أي لا تحتوي على تصحيح غاما) vec3 colorGammaCorrected = pow ( colorLinear , vec3 ( 1.0 / screenGamma )); // استخدام اللون المصحح غاما في الجزء gl_FragColor = vec4 ( colorGammaCorrected , 1.0 ); }

لا يُفترض تصحيح غاما للألوان ambientColor و diffuseColor و specColor . إذا كانت هذه الألوان مُستخرجة من ملفات صور مُصحّحة غاما ( مثل JPEG و PNG )، فيجب تحويلها إلى قيم خطية قبل التعامل معها، وذلك عن طريق تغيير مقياس قيم القنوات إلى النطاق [0، 1] ورفعها إلى قيمة غاما للصورة، والتي يُمكن افتراض أنها تُساوي 2.2 تقريبًا للصور في فضاء ألوان sRGB (مع العلم أن العلاقة الأسية البسيطة لهذا الفضاء اللوني تحديدًا تُعدّ تقريبًا للتحويل الفعلي). تتمتع واجهات برمجة تطبيقات الرسومات الحديثة بالقدرة على إجراء تصحيح غاما هذا تلقائيًا عند أخذ عينات من نسيج أو الكتابة إلى مخزن الإطارات . [ 6 ]

انظر أيضاً

مراجع

  1. جيمس ف. بلين (1977). "نماذج انعكاس الضوء للصور المُصنّعة حاسوبيًا". وقائع المؤتمر السنوي الرابع حول رسومات الحاسوب والتقنيات التفاعلية . الصفحات 192-198 . CiteSeerX 10.1.1.131.7741 . doi : 10.1145/563858.563893 . ISBN   9781450373555. S2CID 8043767 . 
  2. شراينر، ديف؛ مجموعة عمل كرونوس OpenGL ARB (2010). "رياضيات الإضاءة". دليل برمجة OpenGL : الدليل الرسمي لتعلم OpenGL، الإصدار 3.0 و3.1 ( الطبعة السابعة). بيرسون للتعليم، الصفحات 240-245 . ISBN    978-0-321-55262-4.
  3. كروس، كريستوفر (2014)، نموذج الموجة ونموذج المركبة المائية لمحاكاة حالة البحر ، جامعة لينشوبينغ ، ص 97 
  4. نغان، آدي؛ دوراند، فريدو؛ ماتوسيك، فويتش (2004). "التحقق التجريبي من نماذج BRDF التحليلية" . ACM SIGGRAPH 2004 Sketches on - SIGGRAPH '04 . ACM Press. ص 90. doi : 10.1145/1186223.1186336 . ISBN  1-59593-836-2S2CID 9259363. تم الاطلاع عليه بتاريخ 23 أبريل 2019 . 
  5. "مثال WebGL: تظليل فونغ / بلين فونغ" . www.mathematik.uni-marburg.de . تاريخ الاسترجاع: 13 سبتمبر 2019 .
  6. إطار العرض khronos.org