نور، منبعهای نور، مدل بازتاب فونگ و سایهزنی چندضلعی
فصل ۵ ــ نورپردازی و سایهزنی
تا اینجا یاد گرفتهایم مدلهای گرافیکی سهبعدی بسازیم و نمایش دهیم. با این حال، اگر یکی از مدلهای قبلی را رندر کنیم ممکن است نتیجه ناامیدکننده باشد: تصویر تخت به نظر میرسد و ماهیت سهبعدی مدل را منتقل نمیکند. دلیل، فرض غیرطبیعی ما بود که هر سطح چنان روشن میشود که برای بیننده فقط یک رنگ یکنواخت دارد. با این فرض، projection قائم یک کره به صورت دایرهای یکنواخت و یک مکعب به صورت ششضلعی تخت دیده میشود. در عکس یک کرهٔ روشنشده، به جای رنگ یکنواخت درجات متعدد روشنایی و رنگ را میبینیم؛ همین تغییرات به تصویر دوبعدی ظاهر سهبعدی میدهند.
آنچه تا اینجا حذف کرده بودیم تعامل میان نور و سطوح مدل است. در این فصل، مدلهای جداگانهای برای منابع نور و متداولترین تعاملهای نور-ماده میسازیم. هدف افزودن Shading به معماری سریع خط لولهای است؛ بنابراین فقط مدلهای نورپردازی محلی را توسعه میدهیم. برخلاف مدلهای Global Lighting، مدل محلی اجازه میدهد Shade یک نقطهٔ سطح مستقل از دیگر سطوح صحنه محاسبه شود. محاسبه فقط به خواص مادهٔ سطح، هندسهٔ محلی سطح و جایگاه/خواص منابع نور وابسته است.
مدلهای نورپردازی رایج در برنامههای OpenGL معرفی میشوند و خواهیم دید یک مدل نورپردازی را میتوان در برنامهٔ کاربردی، Vertex Shader یا Fragment Shader اجرا کرد.
سپس Shading مدلهای چندضلعی را بررسی میکنیم. تقریب بازگشتی یک کره ساخته میشود تا الگوریتمهای Shading آزمایش شوند؛ بعد نحوهٔ تعریف خواص نور و ماده در OpenGL و افزودن آنها به برنامهٔ تقریب کره را بررسی میکنیم. فصل با معرفی کوتاه دو روش مهم Global Lighting ــ Ray Tracing و Radiosity ــ پایان مییابد.
5.1 نور و ماده
در فصلهای ۱ و ۲ اصول اولیهٔ دید رنگی انسان را بیان کردیم و بحث تعامل نور و سطح را تا اینجا به تعویق انداختیم. عمومیترین رویکرد رندر میتواند بر فیزیک بنا شود و با اصولی مانند بقای انرژی معادلات بازتاب نور از سطح را استخراج کند.
از دید فیزیکی، یک سطح میتواند مانند لامپ با گسیل خودبهخودی نور تولید کند یا نور رسیده از سطوح/منابع دیگر را بازتاب دهد. بعضی سطوح هر دو کار را انجام میدهند. رنگی که در یک نقطه از شیء میبینیم نتیجهٔ چندین برهمکنش میان منابع نور و سطوح بازتابنده است و میتوان آن را فرایندی بازگشتی دانست.
شکل 5.1 ــ سطوح بازتابنده. بخشی از نور منبع به سطح A میرسد و پراکنده میشود؛ بخشی از آن به B میرسد، دوباره به A بازتاب مییابد و این فرایند ادامه پیدا میکند. این پراکندگی بازگشتی، اثرهای ظریفی مانند سرایت رنگ میان سطوح مجاور را ایجاد میکند.
از نظر ریاضی حد این فرایند با یک معادلهٔ انتگرالی، معادلهٔ رندرینگ، توصیف میشود که در اصل میتواند Shading همهٔ سطوح صحنه را تعیین کند. اما این معادله عموماً حل تحلیلی ندارد و روشهای عددی آن برای رندر بلادرنگ کافی نیستند. روشهایی مانند Radiosity و Ray Tracing تقریبهای خوبی برای گونههای خاص سطحاند. Ray Tracing میتواند بعضی صحنههای با پیچیدگی متوسط را بلادرنگ رندر کند، اما در معماری کلاسیک خط لولهای هنوز به نرخ عبور Polygonها نمیرسد. بنابراین روی مدل سادهتر بازتاب فونگ تمرکز میکنیم که بین صحت فیزیکی و محاسبهٔ سریع مصالحه ایجاد میکند. روشهای Global در بخش 5.10 و فصل ۱۱ عمیقتر بررسی خواهند شد.
به جای توازن انرژی کلی، پرتوهای نور را از سطوح گسیلکننده یا منابع نور دنبال میکنیم و سپس آنچه هنگام برخورد با سطوح بازتابنده رخ میدهد مدل میکنیم. این رویکرد شبیه Ray Tracing است، اما فعلاً فقط یک تعامل میان منبع و سطح را در نظر میگیریم. مسئله دو بخش مستقل دارد: مدل منابع نور و مدل بازتاب میان ماده و نور.
شکل 5.2 ــ نور و سطوح. از یک منبع نقطهای شروع میکنیم. بیننده فقط نوری را میبیند که مستقیماً یا پس از مسیر و تعاملهای مختلف به چشمش برسد. اگر پرتو مستقیماً از منبع وارد چشم شود رنگ منبع دیده میشود؛ اگر به سطحی برخورد و سپس به چشم برسد، رنگ دیدهشده حاصل تعامل منبع و مادهٔ سطح است.
در گرافیک رایانهای، بیننده را با صفحهٔ projection جایگزین میکنیم.
شکل 5.3 ــ نور، سطوح و تصویربرداری رایانهای. پنجرهٔ برش روی صفحهٔ projection به Screen نگاشت میشود و میتوان آن را شبکهای از ناحیههای متناظر با Pixelها دانست. رنگ منبع نور و سطوح، رنگ یک یا چند Pixel در Frame Buffer را تعیین میکند.
فقط پرتوهایی اهمیت دارند که پس از عبور از مستطیل برش به COP برسند. در صحنههایی که بخش زیادی از تصویر Background است، اکثر پرتوهای خروجی منبع هیچ سهمی در تصویر ندارند؛ این مشاهده در بخش 5.10 مفید خواهد بود.
شکل 5.4 ــ تعامل نور و ماده: (الف) سطح Specular، (ب) سطح Diffuse، (ج) سطح Translucent.
وقتی نور به سطح میرسد، بخشی جذب و بخشی بازتاب میشود. برای سطح کدر، مجموع جذب و بازتاب کل نور فرودی را تشکیل میدهد. سطح نیمهشفاف بخشی از نور را عبور میدهد تا از محل دیگری خارج و با اشیای دیگر تعامل کند. این رفتارها به طول موج وابستهاند. شیئی زیر نور سفید قرمز دیده میشود چون بیشتر نور را جذب و مؤلفههای قرمز را بازتاب میکند. سطح براق به علت صافی و سطح مات به علت زبری چنین دیده میشود. Shading همچنین به جهت سطح وابسته است که با بردار Normal در هر نقطه مشخص میشود.
تعاملها را میتوان به سه گروه تقسیم کرد:
- Specular: بیشتر نور بازتابشده در بازهٔ زاویهای باریکی نزدیک زاویهٔ بازتاب متمرکز است. آینه سطح Specular کامل است: نور بازتابی با قانون برابری زاویهٔ تابش و بازتاب در یک جهت مشخص خارج میشود.
- Diffuse: نور بازتابی در همهٔ جهتها پراکنده میشود. دیوار با رنگ مات و بسیاری از مواد طبیعی نمونهاند. سطح Diffuse کامل نور را در همهٔ جهتها به طور برابر پخش میکند و از همهٔ جهتهای دید تقریباً یکسان است.
- Translucent: بخشی از نور وارد ماده شده و از محل دیگری بیرون میآید. شکست نور در شیشه و آب نمونه است؛ بخشی از نور ممکن است در همان سطح نیز بازتاب شود.
این سه رفتار را در بخش 5.3 مدل میکنیم؛ نخست منابع نور را بررسی میکنیم.
5.2 منابع نور
نور میتواند از سطح با دو فرایند بنیادی خارج شود: گسیل خودبهخودی و بازتاب. معمولاً منبع نور را شیئی میدانیم که به علت انرژی درونی نور گسیل میکند، هرچند خود منبع مانند لامپ میتواند نور محیط را نیز بازتاب دهد. در مدلهای ساده معمولاً مؤلفهٔ گسیل ماده را حذف میکنیم و بعداً میبینیم افزودن آن آسان است.
شکل 5.5 ــ منبع نور. هر نقطهٔ ((x,y,z)) روی سطح منبع میتواند نوری با جهت گسیل ((\theta,\phi)) و شدت وابسته به طول موج (\lambda) تولید کند. بنابراین منبع عمومی با تابع ششمتغیرهٔ
I(x,y,z,\theta,\phi,\lambda)
قابل توصیف است. دو زاویه جهت را مشخص میکنند و هر فرکانس مستقل در نظر گرفته شده است. برای محاسبهٔ سهم کل یک منبع گسترده روی یک سطح باید روی کل سطح منبع انتگرال بگیریم، زاویههای گسیل مؤثر و فاصله تا سطح را نیز در نظر بگیریم. این محاسبه برای منبع توزیعشدهای مانند لامپ دشوار است. در عمل میتوان آن را با Polygonهای ساده یا مجموعهای از Point Sourceها تقریب زد.
چهار نوع اصلی منبع را بررسی میکنیم: Ambient، Point Source، Spotlight و Distant Light. این چهار نوع برای بیشتر صحنههای ساده کافیاند.
شکل 5.6 ــ جمع سهم نقاط مختلف یک منبع.
5.2.1 منابع رنگی
منابع در فرکانسهای مختلف مقدار متفاوتی نور منتشر میکنند و حتی خواص جهتدار آنها میتواند با فرکانس تغییر کند؛ مدل کاملاً فیزیکی پیچیده است. اما نظریهٔ سهرنگی دید انسان میگوید ادراک ما با سه مقدار Tristimulus تقریب زده میشود. بنابراین برای بیشتر کاربردها منبع را با سه مؤلفهٔ قرمز، سبز و آبی مدل میکنیم.
تابع شدت یا Luminance منبع:
I=\begin{bmatrix}I_r\\I_g\\I_b\end{bmatrix}.
هر مؤلفه شدت کانال مستقل متناظر است. مؤلفهٔ قرمز منبع برای محاسبهٔ مؤلفهٔ قرمز تصویر به کار میرود و مشابه آن برای سبز و آبی. چون محاسبات سه کانال ساختار یکسان و مستقل دارند، اغلب فقط یک معادلهٔ اسکالر مینویسیم و آن را برای هر سه کانال تکرار میکنیم.
5.2.2 نور Ambient
در بسیاری از فضاها، منابع و Diffuserها طوری قرار گرفتهاند که روشنایی تقریباً یکنواختی ایجاد کنند. شبیهسازی دقیق آن مستلزم مدلکردن همهٔ منابع گسترده و انتگرالگیری سهم آنها در هر نقطهٔ سطح است که برای رندر بلادرنگ پرهزینه است. به جای آن اثر مطلوب را مستقیماً مدل میکنیم: یک سطح روشنایی یکنواخت در تمام محیط که Ambient Light نام دارد.
شدت Ambient در همهٔ نقاط صحنه یکسان است:
I_a=\begin{bmatrix}I_{ar}\\I_{ag}\\I_{ab}\end{bmatrix}.
هرچند نور ورودی Ambient برای همهٔ نقاط یکسان است، سطوح مختلف میتوانند آن را به مقدار متفاوت بازتاب دهند.
5.2.3 منابع نقطهای
یک Point Source ایدهآل نور را در همهٔ جهتها به طور برابر منتشر میکند. منبع واقع در (p_0) با سه مؤلفهٔ رنگی توصیف میشود:
I(p_0)=\begin{bmatrix}I_r(p_0)\\I_g(p_0)\\I_b(p_0)\end{bmatrix}.
شدت دریافتی از منبع نقطهای با معکوس مربع فاصله متناسب است. در نقطهٔ (p):
i(p,p_0)=\frac{1}{|p-p_0|^2}I(p_0).
شکل 5.7 ــ روشنکردن یک سطح توسط Point Source.
استفادهٔ زیاد از Point Sourceها بیشتر به سادگی محاسبات آنها مربوط است تا شباهت کاملشان به واقعیت. صحنهای با فقط Point Source معمولاً کنتراست زیادی دارد و اشیا یا بسیار روشن یا بسیار تاریک دیده میشوند. منبع فیزیکی با اندازهٔ محدود سایههایی نرمتر میسازد: ناحیهٔ کاملاً تاریک Umbra و ناحیهٔ سایهٔ جزئی Penumbra است.
شکل 5.8 ــ سایههای ایجادشده توسط منبع با اندازهٔ محدود. افزودن Ambient Light یکی از راههای کاهش کنتراست تند Point Source است.
عامل فاصله نیز میتواند رندر Point Source را خشن کند. قانون (1/d^2) از نظر فیزیکی صحیح است، اما در عمل غالباً با عبارت نرمتر
(a+bd+cd^2)^{-1}
جایگزین میشود. ثابتهای (a,b,c) برای کنترل افت شدت انتخاب میشوند. اگر منبع از سطح بسیار دور باشد، تغییر فاصله روی سطح ناچیز و این عامل تقریباً ثابت است.
5.2.4 Spotlight
Spotlight فقط در بازهٔ باریکی از زاویهها نور میفرستد. میتوان آن را از یک Point Source ساخت و تابش را به مخروطی با رأس (p_s)، جهت (l_s) و زاویهٔ بازشدگی (\theta) محدود کرد. اگر (\theta=180^\circ) باشد، Spotlight به Point Source تبدیل میشود.
شکل 5.9 ــ Spotlight.
در مدل واقعیتر، شدت داخل مخروط یکنواخت نیست و معمولاً در مرکز بیشتر است. شدت تابع زاویهٔ (\phi) میان جهت Spotlight و بردار (s) به نقطهٔ سطح است. برای (\phi<\theta) یک انتخاب رایج:
\cos^e\phi
است؛ توان (e) سرعت افت شدت را تعیین میکند.
شکل 5.10 ــ افت شدت Spotlight.
شکل 5.11 ــ اثر توان Spotlight.
Cosineها برای محاسبات نورپردازی مناسباند، زیرا برای دو بردار واحد (u,v):
\cos\theta=u\cdot v,
که فقط سه ضرب و دو جمع لازم دارد.
5.2.5 منابع نور دوردست
بسیاری از محاسبات Shading به جهت از نقطهٔ سطح تا منبع نیاز دارند. برای منبع نزدیک این بردار در هر نقطه باید دوباره محاسبه شود؛ اما اگر منبع بسیار دور باشد، جهت روی کل سطح تقریباً ثابت است، همانند نور خورشید روی اشیای نزدیک به هم.
شکل 5.12 ــ منبع نور موازی. در عمل منبع دوردست مانند projection موازی مدل میشود: به جای مکان منبع، جهت آن ذخیره میشود.
در مختصات همگن، Point Source با مؤلفهٔ چهارم ۱ نمایش داده میشود:
p_0=\begin{bmatrix}x\\y\\z\\1\end{bmatrix},
در حالی که منبع دوردست یک بردار جهت با مؤلفهٔ چهارم صفر است:
p_0=\begin{bmatrix}x\\y\\z\\0\end{bmatrix}.
محاسبات منبع دوردست کارآمدتر است، هرچند ظاهر صحنه با منبع نزدیک متفاوت خواهد بود. مدل ما هر دو نوع را پشتیبانی میکند.
5.3 مدل بازتاب فونگ
به جای مدل کاملاً فیزیکی، مدلی را انتخاب میکنیم که با خط لولهٔ رندر سریع سازگار باشد. مدل بازتاب توسط Phong معرفی و بعدها توسط Blinn اصلاح شد و در عمل مصالحهٔ خوبی میان هزینهٔ محاسباتی و ظاهر واقعگرایانه ایجاد میکند.
شکل 5.13 ــ بردارهای مدل فونگ. برای محاسبهٔ رنگ نقطهٔ (p) روی سطح از چهار بردار استفاده میشود:
- (n): Normal سطح در (p)؛
- (v): جهت از (p) به Viewer/COP؛
- (l): جهت از (p) به منبع نور؛
- (r): جهت بازتاب کامل پرتو ورودی.
برای سطح خمیده هر چهار بردار میتوانند از نقطهای به نقطهٔ دیگر تغییر کنند؛ (r) از (n) و (l) محاسبه میشود.
مدل فونگ سه تعامل Ambient، Diffuse و Specular را پشتیبانی میکند. برای هر منبع میتوان برای هر یک از سه رنگ اصلی، مؤلفههای Ambient/Diffuse/Specular جداگانه داشت. در نتیجه برای منبع (i) نه ضریب داریم که به صورت یک ماتریس روشنایی (3\times3) قابل نمایش است.
L_i=\begin{bmatrix}
L_{ira}&L_{iga}&L_{iba}\L_{ird}&L_{igd}&L_{ibd}\L_{irs}&L_{igs}&L_{ibs}
\end{bmatrix}.
سطر اول Ambient، سطر دوم Diffuse و سطر سوم Specular است. عامل افت فاصله هنوز اعمال نشده است. در کد معمولاً به جای ماتریس از متغیرهایی مانند زیر استفاده میشود:
vec3 light_i_ambient, light_i_diffuse, light_i_specular;
یا
vec4 light_i_ambient, light_i_diffuse, light_i_specular;
فرم چهاربعدی در بحث مواد غیرکدر مفید است.
فرض میکنیم در نقطهٔ مورد نظر میتوان مقدار بازتاب هر مؤلفهٔ نور ورودی را محاسبه کرد. مثلاً برای مؤلفهٔ Diffuse قرمز منبع (i)، ضریب بازتاب (R_{ird}) سهم (R_{ird}L_{ird}) را میدهد. ضریب بازتاب به خواص ماده، جهت سطح، جهت نور و رابطهٔ هندسی Viewer/منبع وابسته است. نه ضریب بازتاب را میتوان در ماتریس
R_i=\begin{bmatrix}
R_{ira}&R_{iga}&R_{iba}\R_{ird}&R_{igd}&R_{ibd}\R_{irs}&R_{igs}&R_{ibs}
\end{bmatrix}
نوشت.
مثلاً شدت قرمز از منبع (i):
I_{ir}=R_{ira}L_{ira}+R_{ird}L_{ird}+R_{irs}L_{irs}
=I_{ira}+I_{ird}+I_{irs}.
شدت کل با جمع سهم همهٔ منابع و در صورت نیاز Ambient سراسری به دست میآید:
I_r=\sum_i(I_{ira}+I_{ird}+I_{irs})+I_{ar}.
چون محاسبات برای هر منبع و هر کانال رنگ ساختار یکسانی دارند، زیرنویسهای منبع و رنگ را حذف میکنیم:
I=I_a+I_d+I_s=L_aR_a+L_dR_d+L_sR_s.
این محاسبه برای هر سه رنگ و هر منبع تکرار میشود و Ambient سراسری در پایان افزوده میشود. در کد نیز میتوان از ساختارهایی مانند
vec4 reflect_i_ambient, reflect_i_diffuse, reflect_i_specular;
استفاده کرد. این خواص برای یک سطح/ماده هستند و مواد مختلف ضرایب متفاوت خواهند داشت.
5.3.1 بازتاب Ambient
شدت Ambient در همهٔ نقاط یک سطح یکسان است. بخشی جذب و بخشی بازتاب میشود. ضریب بازتاب Ambient را (R_a=k_a) مینامیم و چون فقط کسری مثبت از نور بازتاب میشود:
0\le k_a\le1,
و
I_a=k_aL_a.
سطح سه ضریب Ambient مستقل (k_{ar},k_{ag},k_{ab}) دارد. مثلاً کرهای زیر نور Ambient سفید، اگر ضریب آبی کوچک و ضرایب قرمز و سبز بزرگ داشته باشد، زرد دیده میشود.
5.3.2 بازتاب Diffuse
بازتابندهٔ Diffuse کامل نور را به طور برابر در همهٔ جهتها پراکنده میکند، بنابراین ظاهر آن مستقل از جای Viewer است. با این حال مقدار بازتاب به ماده و موقعیت منبع نسبت به سطح وابسته است. سطح Diffuse از نظر میکروسکوپی زبر است؛ پرتوهای با زاویهٔ ورودی نزدیک میتوانند در جهتهای بسیار متفاوت پراکنده شوند.
شکل 5.14 ــ سطح زبر.
سطوح Diffuse کامل را Lambertian مینامند و با قانون Lambert مدل میشوند. سطح صفحهای را زیر نور خورشید در نظر بگیرید: ظهر روشنتر و نزدیک طلوع/غروب تاریکتر است، زیرا فقط مؤلفهٔ عمودی نور در روشنایی مؤثر است.
شکل 5.15 ــ روشنایی سطح Diffuse: (الف) ظهر، (ب) بعدازظهر.
شکل 5.16 ــ سهم عمودی طبق قانون Lambert: با پایینآمدن منبع در آسمان، همان مقدار نور روی مساحت بزرگتری پخش میشود و سطح تاریکتر دیده میشود.
قانون Lambert میگوید:
R_d\propto\cos\theta,
که (\theta) زاویه میان Normal (n) و جهت نور (l) است. اگر هر دو واحد باشند:
\cos\theta=l\cdot n.
با ضریب بازتاب Diffuse (k_d):
I_d=k_d(l\cdot n)L_d.
اگر افت فاصله برای فاصلهٔ (d) لازم باشد:
I_d=\frac{k_d}{a+bd+cd^2}(l\cdot n)L_d.
بردارهای جهت مانند (l) و (n) بارها در Dot Product استفاده میشوند؛ بهتر است تا حد امکان زود Normalize شوند.
اگر منبع زیر افق سطح باشد، (l\cdot n) منفی میشود، در حالی که سهم نور باید صفر باشد. در عمل از
\max(l\cdot n,0)
استفاده میکنیم.
5.3.3 بازتاب Specular
اگر فقط Ambient و Diffuse داشته باشیم، اشیا سهبعدی به نظر میرسند اما همهٔ سطوح مات و گچی خواهند بود. آنچه کم است Highlightهای اجسام براق است. Highlight اغلب رنگی متفاوت از بازتاب Ambient/Diffuse دارد؛ مثلاً توپ پلاستیکی قرمز زیر نور سفید ممکن است Highlight سفید داشته باشد.
شکل 5.17 ــ Highlightهای Specular.
سطح Specular صاف است و هرچه صافتر باشد به آینه نزدیکتر میشود. با افزایش صافی، نور بازتابی در بازهٔ زاویهای باریکتری حول جهت بازتاب کامل متمرکز میشود.
شکل 5.18 ــ سطح Specular. مدل فیزیکی دقیق پیچیده است و الگوی پراکندگی میتواند نامتقارن، وابسته به طول موج و زاویه باشد.
Phong تقریب سادهای پیشنهاد کرد. سطح را برای مؤلفهٔ Diffuse زبر و برای مؤلفهٔ Specular صاف فرض میکنیم. مقدار نوری که Viewer میبیند به زاویهٔ (\phi) میان جهت بازتاب کامل (r) و جهت Viewer یعنی (v) وابسته است:
I_s=k_sL_s\cos^\alpha\phi.
(k_s) در بازهٔ ([0,1]) کسر نور Specular بازتابشده و (\alpha) ضریب براقیت است. با افزایش (\alpha)، Highlight باریکتر و متمرکزتر میشود؛ در حد بینهایت سطح به آینه نزدیک میشود. مقادیر حدود 100 تا 500 برای بسیاری از فلزها و مقادیر کوچکتر از 100 برای Highlightهای پهن مناسباند.
اگر (r) و (v) واحد باشند:
I_s=k_sL_s\max((r\cdot v)^\alpha,0).
با عامل فاصله، مدل Phong کاملتر چنین است:
I=\frac{1}{a+bd+cd^2}
\left[k_dL_d\max(l\cdot n,0)+k_sL_s\max((r\cdot v)^\alpha,0)\right]+k_aL_a.
این رابطه برای هر منبع و هر رنگ اصلی محاسبه میشود.
شکل 5.19 ــ اثر ضریب براقیت (\alpha).
ممکن است نسبتدادن Ambient مستقل به هر منبع یا متفاوتگرفتن مؤلفههای Diffuse و Specular عجیب به نظر برسد. دلیل آن است که معادلهٔ رندرینگ کامل را حل نمیکنیم و برای تقریب اثرهای Global از ترفندهای محلی استفاده میکنیم.
در محیطی با اشیای متعدد، بخشی از نور مستقیماً به سطح میرسد و با Diffuse/Specular مدل میشود؛ بخش زیادی پس از چندین بازتاب از اشیای دیگر به سطح میرسد. میتوان این سهم را با Ambient وابسته به منبع تقریب زد. مقدار مناسب این مؤلفه هم به رنگ منبع و هم رنگ اشیای اتاق وابسته است؛ این یکی از محدودیتهای مدل تقریبی است. تحلیل مشابهی برای نور Diffuse ثانویه وجود دارد. با انتخاب هوشمندانهٔ مؤلفههای Ambient/Diffuse/Specular منبع میتوان برخی اثرهای Global را با محاسبات Local تقلید کرد.
مدل Phong را در فضای شیء توسعه دادیم، اما Shading واقعی پس از model-view و projection رخ میدهد. این تبدیلها میتوانند جملههای Cosine را تغییر دهند. بنابراین برای محاسبهٔ صحیح یا باید روابط فضایی را هنگام عبور رأسها و بردارها از خط لوله حفظ کنیم و اطلاعات اضافی بفرستیم، یا اطلاعات لازم را با تبدیل معکوس از مراحل خط لوله بازیابی کنیم.
5.3.4 مدل فونگ اصلاحشده
در مدل Phong برای Specular باید (r\cdot v) در هر نقطه محاسبه شود. یک تقریب کارآمد از بردار واحدی استفاده میکند که نیمهٔ راه میان بردار Viewer و بردار نور است:
h=\frac{l+v}{|l+v|}.
شکل 5.20 ــ تعیین Halfway Vector. زاویهٔ (\psi) میان (n) و (h) تعریف میشود. وقتی (v,l,n,r) در یک صفحه باشند:
2\psi=\phi.
با جایگزینی (r\cdot v) با (n\cdot h)، نیازی به محاسبهٔ (r) نداریم. چون (\psi<\phi)، اگر همان توان را استفاده کنیم Highlight متفاوت میشود؛ میتوان توان جدیدی انتخاب کرد تا ((n\cdot h)^{e'}) به ((r\cdot v)^e) نزدیک شود.
وقتی از Halfway Vector برای Specular استفاده میکنیم، مدل Blinn-Phong یا Phong اصلاحشده را داریم. این مدل در سامانههای Fixed-Function رایج بود و در Shaderهای نخست ما نیز استفاده خواهد شد. مثال Utah Teapot نشان میدهد فقط با تغییر خواص ماده میتوان ظاهرهایی از سطح مات تا فلز بسیار بازتابنده ایجاد کرد.
5.4 محاسبهٔ بردارها
مدلهای روشنایی و بازتاب به اندازهای عمومیاند که برای سطح تخت یا خمیده، نمای موازی یا پرسپکتیو و منابع/Viewerهای نزدیک یا دور قابل استفادهاند. بخش عمدهٔ هزینهٔ رندر، محاسبهٔ بردارهای لازم و Dot Productهاست. در حالتهای ویژه سادهسازی ممکن است: برای Polygon تخت Normal در همهٔ نقاط ثابت است؛ برای منبع دور جهت نور روی سطح تقریباً ثابت است.
در این بخش محاسبهٔ بردارها را در حالت عمومی بررسی میکنیم. بخش 5.5 به تکنیکهای ویژهٔ اشیای متشکل از Polygonهای تخت میپردازد؛ حالتی مهم چون بیشتر Rendererها، از جمله OpenGL، سطح خمیده را با تعداد زیادی Polygon تخت کوچک تقریب میزنند.
5.4.1 بردارهای Normal
برای سطح صاف، Normal در هر نقطه وجود دارد و جهت محلی سطح را میدهد. نحوهٔ محاسبه به نمایش ریاضی سطح وابسته است.
برای صفحه:
ax+by+cz+d=0.
همان رابطه را میتوان با Normal (n) و نقطهٔ معلوم (p_0) روی صفحه نوشت:
n\cdot(p-p_0)=0.
پس:
n=\begin{bmatrix}a\\b\\c\end{bmatrix},
یا در مختصات همگن:
n=\begin{bmatrix}a\\b\\c\\0\end{bmatrix}.
اگر به جای معادله سه نقطهٔ غیرهمخط (p_0,p_1,p_2) در صفحه داشته باشیم، دو بردار (p_2-p_0) و (p_1-p_0) در صفحهاند و Normal از Cross Product آنها به دست میآید:
n=(p_2-p_0)\times(p_1-p_0).
ترتیب Cross Product مهم است؛ عوضکردن ترتیب جهت Normal را از بیرونرو به داخلرو برمیگرداند و روی نورپردازی اثر دارد. بعضی سامانهها Normal Polygon را خودکار از سه رأس اول میسازند؛ OpenGL این کار را تحمیل نمیکند و این آزادی برای روشهای مختلف Shading مفید است.
برای سطوح خمیده، محاسبهٔ Normal به نوع نمایش سطح بستگی دارد. کرهٔ واحد در مبدأ را با معادلهٔ ضمنی زیر در نظر بگیرید:
f(x,y,z)=x^2+y^2+z^2-1=0.
یا به صورت برداری:
f(p)=p\cdot p-1=0.
Normal همان Gradient است:
n=\begin{bmatrix}\partial f/\partial x\\\partial f/\partial y\\\partial f/\partial z\end{bmatrix}
=\begin{bmatrix}2x\\2y\\2z\end{bmatrix}=2p.
کره را میتوان پارامتری نیز نوشت:
x=x(u,v),\quad y=y(u,v),\quad z=z(u,v).
یک پارامتریسازی برای کره:
x(u,v)=\cos u\sin v,
y(u,v)=\cos u\cos v,
z(u,v)=\sin u,
با (-\pi/2<u<\pi/2) و (-\pi<v<\pi) است.
در نمایش پارامتری، صفحهٔ مماس در (p(u,v)) جهت محلی سطح را میدهد. دو بردار
\frac{\partial p}{\partial u},\qquad \frac{\partial p}{\partial v}
در صفحهٔ مماس هستند و Normal از
n=\frac{\partial p}{\partial u}\times\frac{\partial p}{\partial v}
به دست میآید.
شکل 5.21 ــ صفحهٔ مماس بر کره.
برای کرهٔ بالا نتیجه متناسب با (p) است و پس از Normalize:
n=p.
این نتیجه در بخش 5.9 برای Shading تقریب چندضلعی کره به کار میرود.
در سامانهٔ گرافیکی معمولاً فقط مجموعهای از رأسها داریم و Normal باید از نقاط نزدیک تقریب زده شود. معماری خط لولهای این کار را دشوار میکند، زیرا رأسها یکبهیک پردازش میشوند و ممکن است اطلاعات همسایهها در دسترس نباشد. به همین دلیل محاسبهٔ Normal اغلب به برنامهٔ کاربر سپرده میشود.
در OpenGL معمولاً Normal را به عنوان Vertex Attribute تعریف میکنیم:
typedef normal vec4;
normal n = vec4(nx, ny, nz, 0.0);
و آن را به عنوان Attribute به Vertex Shader میفرستیم.
5.4.2 زاویهٔ بازتاب
پس از محاسبهٔ Normal، با (n) و جهت نور (l) میتوان جهت بازتاب کامل (r) را یافت. آینهٔ ایدهآل از دو شرط پیروی میکند: زاویهٔ تابش با زاویهٔ بازتاب برابر است و پرتو ورودی، پرتو بازتابی و Normal همگی در یک صفحه قرار دارند.
شکل 5.22 ــ آینه.
در سه بعد شرط زاویه به تنهایی کافی نیست و شرط همصفحهبودن نیز لازم است. چون عمدتاً جهت (r) اهمیت دارد، بردارهای (l,n,r) را واحد فرض میکنیم:
|l|=|n|=|r|=1.
اگر (\theta_i=\theta_r)، با Dot Product:
l\cdot n=n\cdot r.
شرط همصفحهبودن اجازه میدهد بنویسیم:
r=\alpha l+\beta n.
با اعمال شروط زاویه و طول واحد و حل ضرایب، به رابطهٔ مهم زیر میرسیم:
r=2(l\cdot n)n-l.
بعضی Shaderها این محاسبه را صریح انجام میدهند؛ در GLSL نیز تابع reflect برای محاسبهٔ بردار بازتاب وجود دارد. تکنیکهایی مانند Environment Mapping از بردار بازتاب دید برای تعیین چیزی که Viewer در یک سطح بسیار صیقلی میبیند استفاده میکنند.
5.5 Shading چندضلعی
اگر Normalها قابل محاسبه باشند، مدل نورپردازی را میتوان در هر نقطهٔ سطح اعمال کرد. اما حتی برای سطوحی با معادلات ساده، محاسبه در همهٔ نقاط پرهزینه است. مدلهای چندضلعی یک مزیت دیگر دارند: برای Polygon تخت میتوان هزینهٔ Shading را به طور چشمگیری کاهش داد. بیشتر سامانهها، از جمله OpenGL، سطوح خمیده را به Polygonهای تخت کوچک تجزیه میکنند.
شکل 5.23 ــ Mesh چندضلعی.
سه روش اصلی Shading را بررسی میکنیم: Flat، Smooth/Gouraud و Phong.
5.5.1 Flat Shading
بردارهای (l,n,v) در سطح عمومی از نقطهای به نقطهٔ دیگر تغییر میکنند. برای Polygon تخت، (n) ثابت است. اگر Viewer دور باشد، (v) نیز در کل Polygon تقریباً ثابت است و اگر منبع نور دور باشد (l) نیز ثابت میماند.
شکل 5.24 ــ منبع و Viewer دوردست. «دوردست» میتواند دقیقاً بینهایت یا صرفاً فاصلهای بسیار بزرگ نسبت به اندازهٔ Polygon باشد.
اگر هر سه بردار ثابت باشند، محاسبهٔ نور فقط یک بار برای هر Polygon انجام میشود و همهٔ نقاط همان Shade را میگیرند. این روش Flat Shading یا Constant Shading نام دارد.
Flat Shading تفاوت Shade بین Polygonهای Mesh را نشان میدهد. اگر Mesh تقریب یک سطح صاف باشد، این تفاوتها معمولاً آزاردهندهاند و ساختار چندضلعی را آشکار میکنند.
شکل 5.25 ــ Flat Shading یک Mesh چندضلعی.
سیستم بینایی انسان به اختلافهای کوچک شدت نور بسیار حساس است؛ پدیدهای به نام Lateral Inhibition. در یک دنبالهٔ پلهای شدت، روشنایی ادراکشده در یک سمت مرز بیشبرآورد و در سمت دیگر کمبرآورد میشود.
شکل 5.26 ــ نمودار پلهای شدت.
شکل 5.27 ــ شدت واقعی و ادراکشده در یک Edge.
نوارهای روشن/تاریک حاصل در مرزها Mach Bands نام دارند. این پدیده از نحوهٔ اتصال Coneهای چشم به عصب بینایی ناشی میشود و عملاً نمیتوان آن را حذف کرد؛ راهحل گرافیکی استفاده از روشهای Shading نرمتر است که جهش بزرگ Shade در Edgeهای Polygon ایجاد نکنند.
5.5.2 Smooth و Gouraud Shading
در مثال مکعب رنگی فصل ۳ دیدیم Rasterizer رنگهای رأس را روی Polygon Interpolate میکند. اگر محاسبهٔ نور در هر رأس با ماده و بردارهای (n,v,l) همان رأس انجام شود، هر رأس رنگ خاص خود را دارد و Rasterizer میتواند Shade هر Fragment را از آن Interpolate کند. اگر منبع دور باشد و Viewer نیز دور یا بازتاب Specular وجود نداشته باشد، این Interpolation ممکن است در یک Polygon به رنگ ثابت منجر شود.
از نظر ریاضی «Normal در رأس» برای Mesh سؤالبرانگیز است، زیرا چند Polygon با Normalهای متفاوت در رأس داخلی به هم میرسند و Normal هندسی در آن نقطه ناپیوسته است. Gouraud پیشنهاد کرد برای دستیابی به Shading نرم، Normal رأس را به صورت میانگین Normalizeشدهٔ Normal Polygonهای مشترک تعریف کنیم.
شکل 5.28 ــ Normalها در نزدیکی یک رأس داخلی. اگر چهار Polygon با Normalهای (n_1,n_2,n_3,n_4) به رأس برسند:
n=\frac{n_1+n_2+n_3+n_4}{|n_1+n_2+n_3+n_4|}.
از دید OpenGL، Gouraud Shading ساده به نظر میرسد: کافی است Normalهای رأس درست تعیین شوند. اما برای یافتن Normalهایی که باید میانگین گرفته شوند، برنامه باید بداند کدام Polygonها یک رأس را به اشتراک میگذارند. لیست خطی رأسها به تنهایی این اطلاعات را ندارد؛ به یک ساختار دادهٔ Mesh شامل دستکم Polygonها، رأسها، Normalها و خواص ماده و مهمتر از همه ارتباط Polygonها با رأسهای مشترک نیاز داریم.
شکل 5.29 ــ ساختار دادهٔ Mesh.
نمونههای تصویری کتاب نشان میدهند در Constant Shading هر Polygon یک Shade منفرد دارد، اما در Gouraud/Smooth، Normal در رأسها تعیین و رنگ رأس محاسبه میشود و OpenGL آن رنگها را روی وجهها Interpolate میکند. همین قابلیت در مکعب رنگی فصلهای ۲ و ۳ نیز دیده میشود: هشت رأس با رنگهای سیاه، سفید، قرمز، سبز، آبی، Cyan، Magenta و زرد تعریف میشوند و رنگ داخل هر وجه به طور خودکار Interpolate میشود.
5.5.3 Phong Shading
حتی نرمی Gouraud Shading ممکن است کاملاً از Mach Band جلوگیری نکند. Phong پیشنهاد کرد به جای Interpolate کردن شدت/رنگ رأسها، Normalها را روی هر Polygon Interpolate کنیم و سپس در هر نقطه محاسبهٔ نور مستقل انجام دهیم.
شکل 5.30 ــ Normalهای Edge. ابتدا Normalهای رأس از Polygonهای مشترک ساخته میشوند.
برای Edge میان رأسهای A و B:
n_C(\alpha)=(1-\alpha)n_A+\alpha n_B.
این کار برای Edgeهای دیگر نیز انجام میشود. سپس Normal نقطهٔ داخلی از دو نقطهٔ متناظر روی Edgeها Interpolate میشود:
n(\alpha,\beta)=(1-\beta)n_C+\beta n_D.
شکل 5.31 ــ Interpolation Normal در Phong Shading.
پس از داشتن Normal در هر نقطه، محاسبهٔ Shading مستقل همان نقطه انجام میشود. معمولاً این فرایند با Rasterization ترکیب میشود. در سختافزارهای قدیمی Phong Shading به علت هزینهٔ Interpolation Normalها عمدتاً Offline بود؛ در معماری Shaderمحور جدید بخش مهمی از این محاسبه میتواند در Fragment Shader انجام شود. ادامهٔ مقایسه و پیادهسازی این روش در مقالهٔ بعد دنبال میشود.