عکس های بالا بطور گوناگون ساخته شده اند. مورد اول توسط ون گوگ با استفاده از لایه های رنگ ساخته شده . ساعت ها وقتش را گرفته. تصویر دومی در عرض ثانیه ای با ترکیب چهار ماتریس تولید شده: یکی برای فیروزه ای دیگری سرخابی، دیگری زرد و در آخر سیاه . تفاومت اصلی این است که تصویر دومی به صورت همزمان(غیر سریالی) تولید میشود (یعنی مرحله به مرحله نیست و همه در یک زمان تولید میشود).
این کتاب در مورد روش محاسباتی که انقلابی بر پا کرد, *fragment shaders* است. این روش تولید تصاویر دیجیتالی را به سطح دیگری برد. میتوان آن را مانند پرس گوتنبرگ برای گرافیک تصور کرد.
این کتاب در مورد روش محاسباتی *fragment shaders* است که انقلابی بر پا کرد. این روش تولید تصاویر دیجیتالی را به سطح دیگری برد. میتوان آن را مانند پرس گوتنبرگ برای گرافیک تصور کرد.
![Gutenberg's press](gutenpress.jpg)
@ -18,7 +18,7 @@
این کتاب برای کد نویسان خلاق، توسعه دهنده های بازی و کسانی که با برنامه نویسی آشنا هستند و و دانش اولیه از جبر خطی و مثلثات دارند مناسب است, و کسانی که میخواهند سطح کار خود را یک مرحله از نظر گرافیکی و هیجان انگیز بودن بالا بببرند. (اگر میخواهید کد نویسی یاد بگیرید, پیشنهاد میکنم با [Processing](https://processing.org/) شروع کنید و وقتی با کار کردن با آن اشنا شدید، برگردید)
این کتاب به شما نحوه استفاده و ادغام شیدر ها در پروژه هارا یاد میدهد,برای افزایش کارایی و گرافیک آن ها. چون GLSL (OpenGL Shading Language) روی پلتفرم های مختلفی اجرا میشوند, هرآنچه در اینجا یاد بگیرید رو هر محیطی که از OpenGl استفاده میکند میتوانید اجرا کنید . به عبارت دیگر, با استفاده از دانش خود میتوانید از محیط های مقابل استفاده کنید: [Processing](https://processing.org/) sketches, [openFrameworks](http://openframeworks.cc/) applications, [Cinder](http://libcinder.org/) interactive installations, [Three.js](http://threejs.org/) websites or iOS/Android games.
این کتاب به شما نحوه استفاده و ادغام شیدر ها در پروژه هارا یاد میدهد. چون GLSL (OpenGL Shading Language) روی پلتفرم های مختلفی اجرا میشوند, هرآنچه در اینجا یاد بگیرید رو هر محیطی که از OpenGl استفاده میکند میتوانید اجرا کنید . به عبارت دیگر, با استفاده از دانش خود میتوانید از محیط های مقابل استفاده کنید: [Processing](https://processing.org/) sketches, [openFrameworks](http://openframeworks.cc/) applications, [Cinder](http://libcinder.org/) interactive installations, [Three.js](http://threejs.org/) websites یا iOS/Android games.
اگر تجربه نقاشی در کامپیوتر را داشته باشید میدانید که در این فرایند، دایره، مستطیل و خط هارا یکی پس از دیگری میکشید تا شکل مورد نظر خود را نهایی کنید، این فرایند شبیه نوشتن کتاب است، در واقع این کار ها مجموعه ای از دستور العمل ها هستند که وظایف را یکی پس از دیگری انجام میدهند.
شیدر ها هم مجموعه ای از دستورالعمل ها هستند، اما دستورالمل هایی که به یکباره برای هر پیکسل روی صفحه اجرا میشود. این بدان معناست، کدی که مینویسید بسته به موقعیت پیکسل روی صفحه نمایش باید رفتار متفاوتی انجام دهد. برنامه شما مانند تابعی کار میکند که موقعیت را دریافت میکند و یک رنگ را بر میگرداند، زمانی که کد شما کامپایل میشود، این عملیات بسیار سریع انجام میشود.
شیدر ها هم مجموعه ای از دستورالعمل ها هستند، اما دستورالعمل هایی که به یکباره برای هر پیکسل روی صفحه اجرا میشود. این بدان معناست، کدی که مینویسید بسته به موقعیت پیکسل روی صفحه نمایش باید رفتار متفاوتی انجام دهد. برنامه شما مانند تابعی کار میکند که موقعیت را دریافت میکند و یک رنگ را بر میگرداند، زمانی که کد شما کامپایل میشود، این عملیات بسیار سریع انجام میشود.
![Chinese movable type](typepress.jpg)
@ -21,14 +21,14 @@
بازی های ویدئویی و سایر برنامه های گرافیکی به پردازش بیشتری نسبت به برنامه های معمول نیاز دارند. به دلیل محتویات زیاد، آن ها باید باید مقادیر زیادی عملیات پیکسل به پیکسل انجام دهند. هر یک از پیکسل ها باید محاسبه شوند، همچنین در بازی های سه بعدی باید عملیات های بیشتری مثل محاسبات هندسی و پرسپکتیو هم انجام شود.
بیاید به استعاره خود در مورد لوله ها و تسک ها برگردیم، هر پیکسل رو صفحه نمایش یک تسک کوچک و ساده را نشان میدهد، به طور جداگانه تسک هر پیکسل برای CPU مسئله ای نیست. اما اینکه این تسک های کوچک باید برای هر پیکسل انجام شود برای CPU مشکل ساز است. این یعنی در صفحات قدیمی 800x600 باید 480,000 پیکسل در هر فریم پردازش شود که به معنی 14,400,000 محاسبه در ثانیه است! بله این مقدار به قدری بزرگ هست که یک ریزپردازنه را سرریز کند. در یک نمایشگر مدرن 2880x1800 با نرخ 60 فریم بر ثانیه، این محاسبات به 311,040,000 محاسبه در ثانیه میرسد. چگونه مهندسان گرافیک این مشکل را حل میکنند؟
بیایید به استعاره خود در مورد لوله ها و تسک ها برگردیم، هر پیکسل رو صفحه نمایش یک تسک کوچک و ساده را نشان میدهد، به طور جداگانه تسک هر پیکسل برای CPU مسئله ای نیست. اما اینکه این تسک های کوچک باید برای هر پیکسل انجام شود برای CPU مشکل ساز است. این یعنی در صفحات قدیمی 800x600 باید 480,000 پیکسل در هر فریم پردازش شود که به معنی 14,400,000 محاسبه در ثانیه است! بله این مقدار به قدری بزرگ هست که یک ریزپردازنه را سرریز کند. در یک نمایشگر مدرن 2880x1800 با نرخ 60 فریم بر ثانیه، این محاسبات به 311,040,000 محاسبه در ثانیه میرسد. چگونه مهندسان گرافیک این مشکل را حل میکنند؟
![](03.jpeg)
این زمانی است که پردازش موازی به یک راه حل خوب تبدیل میشود، منطقی است که به جای داشتن چند ریز پردازنده بزرگ یا قدرتمند(لوله)، ریزپردازنده های کوچکتری و بیشتری به صورت موازی کار کنند.واحد پردازنده گرافیکی(GPU) همین طور عمل میکند.
![GPU](04.jpeg)
ریز پردازنده های کوچک را مانند جدولی از لوله ها وداده های هر پیکسل را مانند یک توپ تصور کنید، 14,400,000 توپ میتواند هر لوله های را مسدود کند، اما میتوان یک جدول از 800x600 لوله کوچک را که 30 موج 480,000 تایی پیکسل در ثانیه دریافت میکند را به راحتی کنترل کرد. در وضوح بالاتر هم به همین صورت عمل میکند. هرچه سخت افزار های موازی بیشتری داشته باشید، به همان نسبت جریان بیشتری را میتوانید مدیریت کنید.
ریز پردازنده های کوچک را مانند جدولی از لوله ها وداده های هر پیکسل را مانند یک توپ تصور کنید، 14,400,000 توپ میتواند هر لوله ای را مسدود کند، اما میتوان یک جدول از 800x600 لوله کوچک را که 30 موج 480,000 تایی پیکسل در ثانیه دریافت میکند را به راحتی کنترل کرد. در وضوح بالاتر هم به همین صورت عمل میکند. هرچه سخت افزار های موازی بیشتری داشته باشید، به همان نسبت جریان بیشتری را میتوانید مدیریت کنید.
از دیگر قدرت های فوق العاده GPU عملکرد های ویژه ریاضی آن است که از طریق سخت افزار سریع تر میشود، یعنی این عملیات ریاضی به جای استفاده از نرم افزار مستقیما توسط میکرو تراشه حل میشوند، به عبارتی عملکرد های مثلثاتی و ماتریسی به سرعت الکتریسیته میتوانند سریع باشند.
5. یکی از دیگر ویژگی های مشابه C مثال بالا وجود ماکرو ها هستند. با استفاده از آنان میتوان متغیر های جهانی را تعریف کرد و یا برخی عملیات شرطی اساسی را انجام داد(ifdef and #endif#). تمام دستورات کلان(ماکرو) با هشتگ شروع میشوند. ماکرو ها قبل از کامپایل اجرا میشوند، شرایط را بررسی میکند(ifdef and #endif#) و ارجاعات به defines# را کپی میکند. مثلا در مثال بالا ما خط 2 را در صورت تعریف GL_ES وارد میکنیم. که معمولا در هنگام کامپایل این کد در تلفن های همراه و مرورگر ها اتفاق میافتد.
6. شناور ها(float) در شیدر ها حیاتی هستند، بنابراین سطح دقت بسیار مهم است. دقت پایین تر به معنای رندر سریع تر است، همچنین کیفیت کمتر. میتوانید مثل من خط دو مثال بالا متغیر ها را شناور با دقت متوسط درنظر بگیرید(precision mediump float)، همچنین میتوانید متغیر شناور با دقت پایین(precision lowp float) یا بالا(precision highp float)هم در نظر بگیرید.
6. شناور ها(float) در شیدر ها حیاتی هستند، بنابراین سطح دقت بسیار مهم است. دقت پایین تر به معنای رندر سریع تر است، همچنین کیفیت کمتر. میتوانید مثل من خط دو مثال بالا متغیر های شناور را با دقت متوسط درنظر بگیرید(precision mediump float)، همچنین میتوانید متغیر شناور با دقت پایین(precision lowp float) یا بالا(precision highp float)هم میتوان در نظر گرفت.
7. آخرین و شاید مهمترین نکته در مثال بالا اینکه در GLSL تضمین نمیشود که متغیر ها به طور خودکار تغییر نوع داده(casting) رویشان اعمال شود. این به چه معناست؟ تولید کنندگان رویکرد های مختلفی برای سرعت بخشیدن روند پردازش کارت های گرافیکی دارند، و مجبورند حداقل مشخصات را تضمین کنند. کستینگ ازین رویکرد ها نیست. در مثال بالا vect4 دارای نقطه شناور است و برای آن انتظار میرود که به متغیر های شناور انتساب شود. اگر میخواهید کد سازگار خوبی ایجاد کنید و ساعت ها وقت صرف دیبگ کردن آن نکنید، عادت کنید در float ها از نقطه(.) استفاده کنید.
@ -50,4 +50,4 @@ vec4 red(){
vec4 color = vec4(vec3(1.0,0.0,1.0),1.0);
```
اگرچه این مثال خیلی هیجان انگیز نیست، اما ابتدایی ترین مثال است. ما تمام پیکسل های داخل کنوس(canvas) را به یک رنگ تغییر میدهیم. در فصل بعد نحوه تغییر رنگ پیکسل را با استفاده از دو نوع ورودی دیگر میبینیم. فضا(محل و مختصات پیکسل روی صفحه) و زمان(مقدار زمان از لحظه بارگیری صفحه بر حسب ثانیه).
اگرچه این مثال خیلی هیجان انگیز نیست، اما ابتدایی ترین مثال است. ما تمام پیکسل های داخل کنوس(canvas) را به یک رنگ تغییر دادیم. در فصل بعد نحوه تغییر رنگ پیکسل را با استفاده از دو نوع ورودی دیگر میبینیم. فضا(محل و مختصات پیکسل روی صفحه) و زمان(مقدار زمان از لحظه بارگیری صفحه بر حسب ثانیه).
@ -30,7 +30,7 @@ uniform float iTime; // shader playback time (in seconds)
همانطور که میبینید GLSL سورپرایز های بیشتری دارد. GPU دارای عملکرد های زاویه شتاب همچنین توابع نمایی و مثلثاتی هست. برخی ازین توابع عبارتند از: [`sin()`](../glossary/?search=sin), [`cos()`](../glossary/?search=cos), [`tan()`](../glossary/?search=tan), [`asin()`](../glossary/?search=asin), [`acos()`](../glossary/?search=acos), [`atan()`](../glossary/?search=atan), [`pow()`](../glossary/?search=pow), [`exp()`](../glossary/?search=exp), [`log()`](../glossary/?search=log), [`sqrt()`](../glossary/?search=sqrt), [`abs()`](../glossary/?search=abs), [`sign()`](../glossary/?search=sign), [`floor()`](../glossary/?search=floor), [`ceil()`](../glossary/?search=ceil), [`fract()`](../glossary/?search=fract), [`mod()`](../glossary/?search=mod), [`min()`](../glossary/?search=min), [`max()`](../glossary/?search=max) و [`clamp()`](../glossary/?search=clamp).
اکنون زمان آن است که دوباره با کد با بازی کنیم.
اکنون زمان آن است که دوباره با کد بازی کنیم.
* فرکانس را کم کنید تا زمانی که تغییر رنگ نامحسوس شود.
@ -46,7 +46,7 @@ uniform float iTime; // shader playback time (in seconds)
در مثال بالا ما با تقسیم gl_FragCoord بر u_resolution مختصات نرمالایز شده(بین 0 و 1) را در st ذخیره میکنیم. با این کار به راحتی میتوان مقادیر x را به قرمز و مقادیر y را به سبز مپ کرد.
در شیدر نویسی ما منابع زیادی برای دیباگ کردن نداریم، خواهید فهمید که گاهی اوقات کد نویسی در GLSL مانند قراردادن کشتی در داخل بطری است. به همان اندازه سخت زیبا و خوشایند.
در شیدر نویسی منابع زیادی برای دیباگ کردن نداریم، خواهید فهمید که گاهی اوقات کد نویسی در GLSL مانند قراردادن کشتی در داخل بطری است. به همان اندازه سخت زیبا و خوشایند.
ساخته شده توسط [Ben Fry](http://benfry.com/) و [Casey Reas](http://reas.com/) in 2001, [Processing](https://processing.org/) یک محیط فوق العاده ساده و قدرتمند است که میتوانید در آن اولین قدم های کد زنی خود را بردارید. (حداقل برای من اینگونه بود). [Andres Colubri](https://codeanticode.wordpress.com/) بروزرسانی های مهمی به OpenGl و پردازش ویدئو آن اضافه کرده است, که استفاده از شیدر های GLSL را در این محیط دوستانه بسیار آسان میکند. این برنامه به دنبال فایل `"shader.frag"` در پوشه `data` داخل `sketch` میگردد. مطمئن شوید که نمونه هایی که از اینجا در آن پوشه کپی میکنید، تغییر نام دهید.
[Processing](https://processing.org/) ساخته شده توسط [Ben Fry](http://benfry.com/) و [Casey Reas](http://reas.com/) , یک محیط فوق العاده ساده و قدرتمند است که میتوانید در آن اولین قدم های کد زنی خود را بردارید. (حداقل برای من اینگونه بود). [Andres Colubri](https://codeanticode.wordpress.com/) بروزرسانی های مهمی به OpenGl و پردازش ویدئو آن اضافه کرده است, که استفاده از شیدر های GLSL را در این محیط دوستانه بسیار آسان میکند. این برنامه به دنبال فایل `"shader.frag"` در پوشه `data` داخل `sketch` میگردد. مطمئن شوید که نمونه هایی که از اینجا در آن پوشه کپی میکنید، تغییر نام دهید.
![William Turner - The Fighting Temeraire (1838)](turner.jpg)
* گرادیانی شبیه غروب خورشید ویلیام ترنر بسازید
* گرادیانی شبیه غروب خورشید ویلیام ترنر بسازید.
* با استفاده از `u_time` انتقال بین طلوع و غروب را متحرک کنید..
* با استفاده از `u_time` انتقال بین طلوع و غروب را متحرک کنید.
* آیا با استفاده از آنچه تا کنون یاد گرفته اید، میتوانید رنگین کمان بسازید؟
@ -99,7 +99,7 @@ vec4({{rn}},{{gn}},{{bn}},1.0)
### HSB در مختصات قطبی
HSB در ابتدا برای مختصاب قطبی(بر اساس زاویه و شعاع) به جای مختصات دکارتی طراحی شده است. برای ترسیم عملکرد HSB در مختصات قطبی، نیاز به فاصله و زاویه ار مرکز بیلبورد تا مختصات پیکسل مورد نظر داریم. برای این منظور نیاز به استفاده از تابع [`length()`](../glossary/?search=length) و تابع [`atan(y,x)`](../glossary/?search=atan) داریم.
HSB در ابتدا برای مختصاب قطبی(بر اساس زاویه و شعاع) به جای مختصات دکارتی طراحی شده است. برای ترسیم عملکرد HSB در مختصات قطبی، نیاز به فاصله و زاویه از مرکز بیلبورد تا مختصات پیکسل مورد نظر داریم. برای این منظور نیاز به استفاده از تابع [`length()`](../glossary/?search=length) و تابع [`atan(y,x)`](../glossary/?search=atan) داریم.
هنگام استفاده از بردار ها مثل vect2, 3, 4 حتی اگر نمایانگر رنگ باشند، باز هم به عنوان بردار با آنان رفتار میشود. ما در مورد رنگ ها و بردار ها به طور مشابه رفتار میکنیم، شما خواهید دید این انعطاف پذیری مفهمومی بسیار مفید است.