[page:Material] →

# [name]

مادة يتم عرضها بشيدرات مخصصة. الشيدر هو برنامج صغير مكتوب في [link:https://www.khronos.org/files/opengles_shading_language.pdf GLSL] يعمل على GPU. قد ترغب في استخدام شيدر مخصص إذا كنت بحاجة إلى:

- تنفيذ تأثير غير مضمن في أي من المواد المدمجة [page:Material materials]
- دمج العديد من الكائنات في [page:BufferGeometry] واحد لكي تحسين الأداء

هناك الملاحظات التالية التي يجب مراعاتها عند استخدام `ShaderMaterial`:

- سيتم عرض `ShaderMaterial` بشكل صحيح فقط من قِبَل [page:WebGLRenderer]، نظرًا لأن كود GLSL في [link:https://en.wikipedia.org/wiki/Shader#Vertex_shaders vertexShader] و [link:https://en.wikipedia.org/wiki/Shader#Pixel_shaders fragmentShader] يجب تجميعه وتشغيله على GPU باستخدام WebGL.
- اعتبارًا من THREE r72، لم يعد يتم دعم تعيين السمات مباشرة في ShaderMaterial. يجب استخدام نسخة [page:BufferGeometry] بدلاً من ذلك، باستخدام [page:BufferAttribute] instances لتعريف السمات المخصصة.
- اعتبارًا من THREE r77، لم يعد من المفترض استخدام نسخ [page:WebGLRenderTarget] أو [page:WebGLCubeRenderTarget] كموحدات. يجب استخدام خاصية [page:Texture texture] بدلاً من ذلك.
- يتم تمرير السمات والموحدات المضمنة إلى الشيدرات جنبًا إلى جنب مع كودك. إذا كنت لا ترغب في أن يضيف [page:WebGLProgram] أي شيء إلى كود شيدرك، يمكنك استخدام [page:RawShaderMaterial] بدلاً من هذه الفئة.
- يمكنك استخدام التوجيه #pragma unroll_loop_start و #pragma unroll_loop_end لفك حلقة `for` في GLSL بواسطة معالج شيدر قبل التشغيل. يجب وضع التوجيه فوق الحلقة مباشرة. يجب أن يتطابق تنسيق الحلقة مع معيار محدد.
  - يجب أن تكون الحلقة [link:https://en.wikipedia.org/wiki/Normalized_loop normalized].
  - يجب أن يكون متغير الحلقة *i*.
  - ستستبدل قِبَال `UNROLLED_LOOP_INDEX` بالقِبَال المُعَبرَة لـ *i* للتكرار المُعَبرَ ويمكن استخدامها في بيانات قِبَال التشغيل.
  `#pragma unroll_loop_start for ( int i = 0; i < 10; i ++ ) { // ... } #pragma unroll_loop_end`

## مثال الكود

`const material = new THREE.ShaderMaterial( { uniforms: { time: { value: 1.0 }, resolution: { value: new THREE.Vector2() } }, vertexShader: document.getElementById( 'vertexShader' ).textContent, fragmentShader: document.getElementById( 'fragmentShader' ).textContent } );`

## أمثلة (Examples)

[example:webgl_buffergeometry_custom_attributes_particles webgl / buffergeometry / custom / attributes / particles]
[example:webgl_buffergeometry_selective_draw webgl / buffergeometry / selective / draw]
[example:webgl_custom_attributes webgl / custom / attributes]
[example:webgl_custom_attributes_lines webgl / custom / attributes / lines]
[example:webgl_custom_attributes_points webgl / custom / attributes / points]
[example:webgl_custom_attributes_points2 webgl / custom / attributes / points2]
[example:webgl_custom_attributes_points3 webgl / custom / attributes / points3]
[example:webgl_depth_texture webgl / depth / texture]
[example:webgl_gpgpu_birds webgl / gpgpu / birds]
[example:webgl_gpgpu_protoplanet webgl / gpgpu / protoplanet]
[example:webgl_gpgpu_water webgl / gpgpu / water]
[example:webgl_interactive_points webgl / interactive / points]
[example:webgl_video_kinect webgl / video / kinect]
[example:webgl_lights_hemisphere webgl / lights / hemisphere]
[example:webgl_marchingcubes webgl / marchingcubes]
[example:webgl_materials_envmaps webgl / materials / envmaps]
[example:webgl_materials_wireframe webgl / materials / wireframe]
[example:webgl_modifier_tessellation webgl / modifier / tessellation]
[example:webgl_postprocessing_dof2 webgl / postprocessing / dof2]
[example:webgl_postprocessing_godrays webgl / postprocessing / godrays]

## شيدرات الرأس وشيدرات الجزء (Vertex shaders and fragment shaders)

يمكنك تحديد نوعين مختلفين من الشيدرات لكل مادة:

- يعمل شيدر الرأس أولاً؛ يتلقى `attributes`، يحسب / يعدل موضع كل رأس فردي، ويمرر بيانات إضافية (`varying`s) إلى شيدر الجزء.
- يعمل شيدر الجزء (أو البكسل) ثانيًا؛ يضبط لون كل "جزء" فردي (بكسل) يتم عرضه على الشاشة.

هناك ثلاثة أنواع من المتغيرات في الشيدرات: الموحدات، والسمات، و varyings:

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

يجب ملاحظة أن `within` الشيدر نفسه، تعمل الموحدات والسمات مثل المستمرات؛ يمكنك فقط تعديل قِبَالها بتمرير قِبَال مختلفة إلى المخازن من كود JavaScript الخاص بك.

## السمات والموحدات المدمجة (Built-in attributes and uniforms)

يوفر [page:WebGLRenderer] العديد من السمات والموحدات إلى الشيدرات افتراضيًا؛ يتم إلحاق تعريفات هذه المتغيرات بكود `fragmentShader` و `vertexShader` الخاص بك من قبل [page:WebGLProgram] عندما يتم تجميع الشيدر؛ ليس عليك إعلانها بنفسك. انظر [page:WebGLProgram] للحصول على تفاصيل هذه المتغيرات.

بعض هذه الموحدات أو السمات (على سبيل المثال تلك المتعلقة بالإضاءة، الضباب، إلخ) تتطلب تعيين خصائص على المادة لكي [page:WebGLRenderer] لنسخ القيم المناسبة إلى GPU - تأكد من تعيين هذه العلامات إذا كنت ترغب في استخدام هذه الميزات في شيدرك الخاص.

إذا كنت لا ترغب في أن يضيف [page:WebGLProgram] أي شيء إلى كود شيدرك ، يمكنك استخدام [page:RawShaderMaterial] بدلاً من هذه الفئة.

## السمات والموحدات المخصصة (Custom attributes and uniforms)

يجب إعلان كل من السمات والموحدات المخصصة في كود GLSL shader (داخل `vertexShader` و / أو `fragmentShader`). يجب تعريف الموحدات المخصصة في `both` خاصية `uniforms` لـ `ShaderMaterial`، في حين يجب تعريف أي سمات مخصصة عبر [page:BufferAttribute] instances. يجب ملاحظة أن `varying`s يجب فقط أن يتم إعلانها داخل كود الشيدر (وليس داخل المادة).

لإعلان سمة مخصصة، يرجى الإشارة إلى [page:BufferGeometry] للحصول على نظرة عامة، و [page:BufferAttribute] للحصول على نظرة مفصلة على API `BufferAttribute`.

عند إنشاء سماتك، يجب أن يكون كل مجموعة مُطَبَّقَة التي تقوم بإنشائها لحفظ بيانات سمتك مضروبًا في حجم نوع بياناتك. على سبيل المثال، إذا كانت سمتك من نوع [page:Vector3 THREE.Vector3] ، وكان لديك 3000 رأس في [page:BufferGeometry] ، فيجب إنشاء قيمة مجموعتك المُطَبَّقَة بطول 3000 * 3 ، أو 9000 (قيمة واحدة لكل مُكَوِّن). يظهر جدول حجم كل نوع من أنواع البيانات أدناه للإشارة:

Attribute sizes
GLSL type | JavaScript type | Size
--- | --- | ---
float | [page:Number] | 1
vec2 | [page:Vector2 THREE.Vector2] | 2
vec3 | [page:Vector3 THREE.Vector3] | 3
vec3 | [page:Color THREE.Color] | 3
vec4 | [page:Vector4 THREE.Vector4] | 4

يجب ملاحظة أن مخازن السمات `ليست` تتحدث تلقائيًا عندما تتغير قيمها. لتحديث السمات المخصصة، قم بتعيين علامة `needsUpdate` إلى true على [page:BufferAttribute] للهندسة (انظر [page:BufferGeometry] لمزيد من التفاصيل).

لإعلان [page:Uniform] مخصص، استخدم خاصية `uniforms`: `uniforms: { time: { value: 1.0 }, resolution: { value: new THREE.Vector2() } }`

يوصى بتحديث قيم [page:Uniform] المخصصة اعتمادًا على [page:Object3D object] و [page:Camera camera] في [page:Object3D.onBeforeRender] لأن [page:Material] يمكن أن يتم مشاركته بين [page:Mesh meshes]، يتم تحديث [page:Matrix4 matrixWorld] لـ [page:Scene] و [page:Camera] في [page:WebGLRenderer.render]، وبعض المؤثرات تعرض [page:Scene scene] باستخدام خاصة بهم [page:Camera cameras].

## المنشئ (Constructor)

### [name]( [param:Object parameters] )

[page:Object parameters] - (اختياري) كائن يحتوي على واحد أو أكثر خصائص تحدد مظهر المادة. يمكن تمرير أي خاصية من المادة (بما في ذلك أي خاصية موروثة من [page:Material]) هنا.

## الخصائص (Properties)

انظر إلى الفئة الأساسية [page:Material] للخصائص المشتركة.

### [property:Boolean clipping]

يحدد ما إذا كانت هذه المادة تدعم القطع؛ صحيح للسماح للعارض بتمرير الزي الرسمي clippingPlanes. الافتراضي هو false.

### [property:Object defaultAttributeValues]

عندما لا تتضمن الهندسة المعروضة هذه السمات ولكن المادة تفعل ذلك، سيتم تمرير هذه القيم الافتراضية إلى الشيدرات. هذا يتجنب الأخطاء عندما تكون بيانات المخزن المؤقت مفقودة. `this.defaultAttributeValues = { 'color': [ 1, 1, 1 ], 'uv': [ 0, 0 ], 'uv1': [ 0, 0 ] };`

### [property:Object defines]

يحدد ثوابت مخصصة باستخدام توجيهات `#define` داخل كود GLSL لكل من شيدر الرأس وشيدر الجزء؛ كل زوج من المفتاح / القيمة يولد توجيهًا آخر: `defines: { FOO: 15, BAR: true }` يولد الأسطر `#define FOO 15 #define BAR true` في كود GLSL.

### [property:Object extensions]

كائن يحتوي على الخصائص التالية: `this.extensions = { clipCullDistance: false, // set to use vertex shader clipping multiDraw: false // set to use vertex shader multi_draw / enable gl_DrawID };`

### [property:Boolean fog]

تحدد ما إذا كان يتم التأثير على لون المادة بإعدادات الضباب العالمية؛ صحيح لتمرير موحدات الضباب إلى الشيدر. الافتراضي هو false.

### [property:String fragmentShader]

كود GLSL لشيدر الجزء. هذا هو الكود الفعلي للشيدر. في المثال أعلاه، يتم استخراج كود `vertexShader` و `fragmentShader` من DOM؛ يمكن تمريره كسلسلة مباشرة أو تحميله عبر AJAX بدلاً من ذلك.

### [property:String glslVersion]

يحدد إصدار GLSL لكود الشيدر المخصص. ذو صلة فقط لـ WebGL 2 لتحديد ما إذا كان يجب تحديد GLSL 3.0 أم لا. القيم المتاحة هي `THREE.GLSL1` أو `THREE.GLSL3`. الافتراضي هو `null`.

### [property:String index0AttributeName]

إذا تم تعيينه، يستدعي هذا [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bindAttribLocation gl.bindAttribLocation] لربط فهرس رأس عام بمتغير سمة. الافتراضي هو غير معرف.

### [property:Boolean isShaderMaterial]

علامة قراءة فقط للتحقق مما إذا كان كائنًا معينًا من نوع [name].

### [property:Boolean lights]

يحدد ما إذا كانت هذه المادة تستخدم الإضاءة؛ صحيح لتمرير بيانات الموحدات المتعلقة بالإضاءة إلى هذا الشيدر. الافتراضي هو false.

### [property:Float linewidth]

يتحكم في سُمك الإطار السلكي. الافتراضي هو 1.
نظرًا للقيود [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile] مع [page:WebGLRenderer WebGL] renderer على معظم المنصات ستكون linewidth دائمًا 1 بغض النظر عن القيمة المُعَدَّة.

### [property:Boolean flatShading]

حدد ما إذا كان يتم عرض المادة بظلال مسطحة. الافتراضي هو false.

### [property:Object uniforms]

كائن من الشكل: `{ "uniform1": { value: 1.0 }, "uniform2": { value: 2 } }` يحدد الموحدات التي يتم تمريرها إلى كود الشيدر؛ المفاتيح هي أسماء الموحدات ، والقيم هي تعريفات من الشكل `{ value: 1.0 }` حيث `value` هو قيمة الموحد. يجب أن تتطابق الأسماء مع اسم الموحد، كما هو محدد في كود GLSL. يجب ملاحظة أن الموحدات يتم تحديثها في كل إطار، لذلك تحديث قيمة الموحد سيؤدي فورًا إلى تحديث القيمة المتاحة لكود GLSL.

### [property:Boolean uniformsNeedUpdate]

يمكن استخدامه لإجبار تحديث الموحدات أثناء تغيير الموحدات في [page:Object3D.onBeforeRender](). الافتراضي هو `false`.

### [property:Boolean vertexColors]

يعرف ما إذا كان يتم استخدام تلوين الرأس. الافتراضي هو `false`.

### [property:String vertexShader]

كود GLSL لشيدر الرأس. هذا هو الكود الفعلي للشيدر. في المثال أعلاه، يتم استخراج كود `vertexShader` و `fragmentShader` من DOM؛ يمكن تمريره كسلسلة مباشرة أو تحميله عبر AJAX بدلاً من ذلك.

### [property:Boolean wireframe]

عرض الهندسة كإطار سلكي (باستخدام GL_LINES بدلاً من GL_TRIANGLES). الافتراضي هو false (أي عرض كأشكال مسطحة).

### [property:Float wireframeLinewidth]

يتحكم في سُمك الإطار السلكي. الافتراضي هو 1.
نظرًا للقيود [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile] مع [page:WebGLRenderer WebGL] renderer على معظم المنصات ستكون linewidth دائمًا 1 بغض النظر عن القيمة المُعَدَّة.

## الطرق (Methods)

انظر إلى الفئة الأساسية [page:Material] للطرق المشتركة.

### [method:ShaderMaterial clone]()

يولِّد نسخة طبقية من هذه المادة. يجب ملاحظة أن vertexShader و fragmentShader يتم نسخهم `by reference`، كذلك تعاريف `attributes`؛ هذا يعني أن نسخ المادة ستشارك نفس [page:WebGLProgram] المُجَمَّع. ومع ذلك، فإن `uniforms` يتم نسخها `by value`، مما يتيح لك امتلاك مجموعات مختلفة من الموحدات لنسخ مختلفة من المادة.

## المصدر (Source)

[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]