سلام درود خدمت همراهان همیشگی سایت پی وی لرن . با آموزش WebGL همراهتون هستیم. شیدر به معنی سایهزن است به عبارتی شیدرها برنامههایی هستند که ما آنها را به زبان کارت گرافیکی، برای اجرا در آنها مینویسم که کارت گرافیک آنها را با قدرت بالا، سریع و به صورت موازی اجرا کند. Shaders ها در WebGL انواع مختلف و کاربردهای متفاوتی نیز دارد. در این قسمت به بیان هر یک از Shaders ها در WebGL و ایجاد شیدر ها از جمله ایجاد Vertex Shader در WebGL خواهیم پرداخت.
شیدرها برنامه هایی هستند که روی GPU اجرا می شوند. Shader ها در زبان OpenGL ES Shader Language نوشته شده اند (ES SL نامیده می شود). ES SL دارای متغیرهایی از نوع خود، انواع داده ها، ردیف ها، ورودی ها و خروجی های تعبیه شده است.
جدول زیر لیستی از انواع داده های اولیه ارائه شده توسط OpenGL ES SL را فهرست می کند.
ردیف | نوع و توضیحات |
---|---|
۱ | void مقدار خالی را نشان می دهد |
۲ | bool درست یا غلط را قبول می کند. |
۳ | int این یک نوع داده از اعداد صحیح یا integer است. |
۴ | float این یک نوع داده اسکالر شناور است. |
۵ | vec2, vec3, vec4 بردار نقطه شناور n-component |
۶ | bvec2, bvec3, bvec4 بردار بولین |
۷ | ivec2, ivec3, ivec4 علامت بردار عدد صحیح یا integer |
۸ | mat2, mat3, mat4 ماتریس شناور ۲×۲، ۳×۳، ۴×۴ |
۹ | sampler2D دسترسی به بافت ۲D |
۱۰ | samplerCube دسترسی به بافت مکعب نقشه برداری |
در OpenGL ES SL سه رقم اصلی وجود دارد:
ردیف | شرایط و توضیحات |
---|---|
۱ | attribute این مقدماتی به عنوان یک پیوند بین یک شیدر vertex و OpenGL ES برای داده های هر vertex عمل می کند. مقدار این ویژگی برای هر اجرا از شیدر vertex تغییر می کند. |
۲ | uniform این مقدمات برنامه های شیدر و برنامه WebGL را پیوند می دهد. بر خلاف تعریف مقدماتی مقادیر uniform تغییری نمی کنند. uniform تنها خوانده می شوند. شما می توانید آن ها را با هر گونه داده های اساسی استفاده کنید تا یک متغیر را اعلام کنید. |
۳ | varying این فرم مقدماتی یک پیوند بین یک شیدر vertex و یک شیدر fragment را برای داده های تعبیه شده است. این می تواند با انواع داده های مقابل استفاده شود: شناور، vec2، vec3، vec4، mat2، mat3، mat4، یا آرایه. مثال – متغیر عادی ;vec3 |
در ادامه معرفی Shaders ها در WebGL به شیدر ورتکس خواهیم پرداخت.
Vertex shader کد برنامه ای است که در هر vertex نامیده می شود. این geometry را از یک مکان به دیگری منتقل می کند(جا به جا می کند) . این داده ها را از هر vertex (داده های هر رشته) مانند مختصات رأس، عادی، رنگ ها و مختصات بافت مدیریت می کند.
در کد ES GL از شیدر vertex برنامه نویسان باید مشخصه هایی را برای رسیدگی به داده ها تعریف کنند. این صفات به یک Object Buffer Vertex نوشته شده در جاوا اسکریپت اشاره دارد. وظایف زیر می تواند با استفاده از شیدر vertex در طول با vertex transformation باشد.
OpenGL ES SL متغیرهای از پیش تعریف شده زیر را برای سایه دار Vertex ارائه می کند .
ردیف | متغیرها و توضیحات |
---|---|
۱ | ;highp vec4 gl_Position موقعیت Vertex را نگه می دارد. |
۲ | ;mediump float gl_PointSize ادارای اندازه نقطه تغییر یافته است. واحد برای این متغیر پیکسل است. |
نگاهی به کد نمونه شیدر vertex در Shaders ها در WebGL داریم. این رأسهای یک مثلث را پردازش می کند.
1 2 3 4 5 | attribute vec2 coordinates; void main(void) { gl_Position = vec4(coordinates, 0.0, 1.0); }; |
اگر با دقت بالا را کد را مشاهده کردید، یک متغیر attribute را با نام coordinates اعلام کردیم. (این متغیر با Object Buffer Vertex با استفاده از روش ()getAttribLocation در ارتباط است. مختصات attribute به عنوان یک پارامتر به این روش همراه با object برنامه شیدر منتقل می شود.)
در مرحله دوم برنامه vertex شیدر داده شد، متغیر gl_position تعریف شده است.
gl_Position متغیر از پیش تعریف شده است که تنها در برنامه شیدر vertex در دسترس است. این شامل موقعیت vertex است. در کد بالا، مختصات attribute در فرم بردار منتقل می شود. به عنوان یک ستون vertex یک عملیات در vertex است، مقدار gl_position برای هر vertex محاسبه می شود.
بعدا، مقدار gl_position توسط مونتاژ اولیه، قطع، حذف و دیگر عملیات ثابت که در ابتدای کار پس از پردازش vertex انجام می شود استفاده می شود.
ما می توانیم برنامه های شیدر ورتکس را بنویسیم تا تمام عملیات شیدر vertex را ممکن سازیم. ما در این آموزش به صورت جداگانه بحث خواهیم کرد.
یک مش توسط چند مثلث تشکیل شده است، و سطح هر مثلث به عنوان یک قطعه شناخته می شود. یک شیدر fragment قطعه کدی است که بر روی هر پیکسل بر روی هر fragment اجرا می شود. این برای محاسبه و پر کردن رنگ در پیکسل های مختلف نوشته شده است. وظایف زیر می تواند با استفاده از شیدرهای fragment انجام شود .
عملیات بر روی مقادیر بینابینی
دسترسی به بافت
نرم افزار بافت
مه
مجموع رنگ
متغیرهای از پیش تعریف شده
OpenGL ES SL متغیرهای از پیش تعریف شده زیر را برای شیدر fragment فراهم می کند.
ردیف | متغیرها و توضیحات |
---|---|
۱ | ;mediump vec4 gl_FragCoord موقعیت fragment را درون بافر frame نگه می دارد. |
۲ | ;bool gl_FrontFacing fragment ی که متعلق به یک front-facing ابتدایی است را نگه می دارد. |
۳ | ;mediump vec2 gl_PointCoord موقعیت fragment را در یک نقطه قرار می دهد . |
۴ | ;mediump vec4 gl_FragColor مقدار رنگ خروجی fragment شیدر را نگه می دارد. |
۵ | mediump vec4 gl_FragData[n] رنگ fragment را برای پیوست رنگ n نگه می دارد. |
کد نمونه زیر یک شیدر fragment را نشان می دهد که چگونه رنگ را به هر پیکسل در یک مثلث اعمال کنیم.
1 2 3 | void main(void) { gl_FragColor = vec4(0, 0.8, 0, 1); } |
در کد بالا، مقدار رنگ در متغیر gl.FragColor ذخیره می شود. برنامه fragment shader خروجی را به pipeline انتقال می دهد با استفاده از متغیرهای عملکرد ثابت؛ FragColor یکی از آن هاست. این متغیر مقدار رنگ پیکسل های مدل را نگه می دارد.
ذخیره و کامپایل کردن Shader Programs
از آنجا که شیدرها برنامه های مستقل هستند، می توانیم آن ها را به عنوان یک اسکریپت جداگانه بنویسیم و در برنامه کاربردی استفاده کنیم. یا، شما می توانید آن ها را به طور مستقیم در فرمت رشته ذخیره کنید، همانطور که در زیر نشان داده شده است.
1 2 3 4 5 6 | var vertCode = 'attribute vec2 coordinates;' + 'void main(void) {' + ' gl_Position = vec4(coordinates, 0.0, 1.0);' + '}'; |
۱. کامپایل کردن شامل سه مرحله است .
۲. ایجاد shader object
۳. ضمیمه کد منبع برای ساخت shader object
۴. کامپایل برنامه
در این قسمت ایجاد Vertex Shader در WebGL رو توضیح خواهیم داد.
برای ایجاد یک شیدر خالی، WebGL یک روش به نام ()createShader ایجاد می کند. این shader object را ایجاد و باز می کند. نحوه آن به شرح زیر است .
1 | Object createShader (enum type) |
همانطور که در روش بالا مشاهده می شود، این روش یک مقدار enum را از پیش تعیین شده به عنوان پارامتر پذیرش می کند. ما برای این دو گزینه داریم .
gl.VERTEX_SHADER برای ایجاد شیدر vertex
gl.FRAGMENT_SHADER برای ایجاد شیدر fragment .
خب پس در ایجاد Vertex Shader در WebGL شیدر خالی به وجود آوردیم تا بتوانیم بقیه کارها را نیز انجام دهیم.
شما می توانید کد منبع را به شیء شیدر با استفاده از ()shaderSource متصل کنید. نحوه آن به شرح زیر است .
1 | void shaderSource(Object shader, string source) |
این روش دو پارامتر را می پذیرد .
shader – شما باید شیء شیدر ایجاد شده را به عنوان یک پارامتر انتقال دهید.
Source – شما باید کد برنامه شیدر را در قالب رشته منتقل کنید.
بعد از ایجاد Vertex Shader در WebGL کامپایل برنامه رو داریم.
برای کامپایل برنامه، شما باید از روش ()compileShaderاستفاده کنید. نحو آن به شرح زیر است .
1 | compileShader(Object shader) |
این روش شیدر program object را به عنوان یک پارامتر قبول می کند. پس از ایجاد یک shader program object، کد منبع را به آن وصل کنید و آن object را به این روش منتقل کنید.
قطعه کد زیر نشان می دهد که چگونه بسازیم و کامپایل کنیم شیدر vertex را و همچنین شیدر fragment را برای ایجاد مثلث.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | // Vertex Shader var vertCode = 'attribute vec3 coordinates;' + 'void main(void) {' + ' gl_Position = vec4(coordinates, 1.0);' + '}'; var vertShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertShader, vertCode); gl.compileShader(vertShader); // Fragment Shader var fragCode = 'void main(void) {' + ' gl_FragColor = vec4(0, 0.8, 0, 1);' + '}'; var fragShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragShader, fragCode); gl.compileShader(fragShader); |
پس از ایجاد و ادغام برنامه های شیدر، شما باید یک برنامه ترکیبی حاوی هر دو شیدر (vertex & fragment) ایجاد کنید. مراحل زیر باید دنبال شود .
۱. یک program object ایجاد کنید.
۲. پیوستن هر دو شیدر
۳. هر دو شیدر را لینک کنید
۴. از program استفاده کنید
۵. یک Program Object ایجاد کنید
۶. با استفاده از روش ()createProgram یک Program Object ایجاد کنید. این یک Program Object خالی را برمی گرداند. در اینجا نحو آن را نشان خواهیم داد.
1 | createProgram(); |
ضمیمه کردن شیدرها
شیدرها را به program object ساخته شده با استفاده از متد ()attachShader متصل کنید. نحوه آن به شرح زیر است .
1 | attachShader(Object program, Object shader); |
این روش دو پارامتر را می پذیرد .
Program – انتقال دهید program object خالی را به عنوان یک پارامتر.
shader – یکی از shaders programs های کامپایل شده (shader vertex، shader fragment) را منتقل کنید.
توجه – شما باید هر دو شیدر را با استفاده از این روش پیوست کنید.
پیوند دادن شیدرها با استفاده از روش ()linkProgram ، به وسیله ی انتقال program object ی که به آن شیدرها را متصل کرده اید. نحوه آن به شرح زیر است .
1 | linkProgram(shaderProgram); |
استفاده از Program
WebGL یک روش به نام ()useProgram را فراهم می کند. شما باید برنامه را به آن منتقل کنید. نحوه آن به شرح زیر است .
1 | useProgram(shaderProgram); |
کد زیر نشان می دهد که چگونه برای ایجاد، پیوند و استفاده از برنامه combined شیدر را داشته باشید.
1 2 3 4 5 | var shaderProgram = gl.createProgram(); gl.attachShader(shaderProgram, vertShader); gl.attachShader(shaderProgram, fragShader); gl.linkProgram(shaderProgram); gl.useProgram(shaderProgram); |
خب اینم از معرفی Shaders ها در WebGL و ایجاد Vertex Shader در WebGL و جابجایی و پیوند دادن شیدرها. همونطور که دیدید در قسمت ایجاد Vertex Shader در WebGL یک شیدر خالی به وجود آوردیم.بعد از بیان Shaders ها در WebGL و ایجاد Vertex Shader در WebGL در ادامه جلسات به بافر ها و مسایل مربوط به آن رو خواهیم داشت.