مادة يتم عرضها بشيدرات مخصصة. الشيدر هو برنامج صغير مكتوب في [link:https://www.khronos.org/files/opengles_shading_language.pdf GLSL] يعمل على GPU. قد ترغب في استخدام شيدر مخصص إذا كنت بحاجة إلى:
#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
} );
[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]
يمكنك تحديد نوعين مختلفين من الشيدرات لكل مادة:
هناك ثلاثة أنواع من المتغيرات في الشيدرات: الموحدات، والسمات، و varyings:
يجب ملاحظة أن `within` الشيدر نفسه، تعمل الموحدات والسمات مثل المستمرات؛ يمكنك فقط تعديل قِبَالها بتمرير قِبَال مختلفة إلى المخازن من كود JavaScript الخاص بك.
يوفر [page:WebGLRenderer] العديد من السمات والموحدات إلى الشيدرات افتراضيًا؛ يتم إلحاق تعريفات هذه المتغيرات بكود `fragmentShader` و `vertexShader` الخاص بك من قبل [page:WebGLProgram] عندما يتم تجميع الشيدر؛ ليس عليك إعلانها بنفسك. انظر [page:WebGLProgram] للحصول على تفاصيل هذه المتغيرات.
بعض هذه الموحدات أو السمات (على سبيل المثال تلك المتعلقة بالإضاءة، الضباب، إلخ) تتطلب تعيين خصائص على المادة لكي [page:WebGLRenderer] لنسخ القيم المناسبة إلى GPU - تأكد من تعيين هذه العلامات إذا كنت ترغب في استخدام هذه الميزات في شيدرك الخاص.
إذا كنت لا ترغب في أن يضيف [page:WebGLProgram] أي شيء إلى كود شيدرك ، يمكنك استخدام [page:RawShaderMaterial] بدلاً من هذه الفئة.
يجب إعلان كل من السمات والموحدات المخصصة في كود 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 (قيمة واحدة لكل مُكَوِّن). يظهر جدول حجم كل نوع من أنواع البيانات أدناه للإشارة:
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].
[page:Object parameters] - (اختياري) كائن يحتوي على واحد أو أكثر خصائص تحدد مظهر المادة. يمكن تمرير أي خاصية من المادة (بما في ذلك أي خاصية موروثة من [page:Material]) هنا.
انظر إلى الفئة الأساسية [page:Material] للخصائص المشتركة.
يحدد ما إذا كانت هذه المادة تدعم القطع؛ صحيح للسماح للعارض بتمرير الزي الرسمي clippingPlanes. الافتراضي هو false.
عندما لا تتضمن الهندسة المعروضة هذه السمات ولكن المادة تفعل ذلك، سيتم تمرير هذه القيم الافتراضية إلى الشيدرات. هذا يتجنب الأخطاء عندما تكون بيانات المخزن المؤقت مفقودة.
this.defaultAttributeValues = {
'color': [ 1, 1, 1 ],
'uv': [ 0, 0 ],
'uv1': [ 0, 0 ]
};
يحدد ثوابت مخصصة باستخدام توجيهات `#define` داخل كود GLSL
لكل من شيدر الرأس وشيدر الجزء؛ كل زوج من المفتاح / القيمة
يولد توجيهًا آخر:
defines: {
FOO: 15,
BAR: true
}
يولد الأسطر
#define FOO 15
#define BAR true
في كود GLSL.
كائن يحتوي على الخصائص التالية:
this.extensions = {
clipCullDistance: false, // set to use vertex shader clipping
multiDraw: false // set to use vertex shader multi_draw / enable gl_DrawID
};
تحدد ما إذا كان يتم التأثير على لون المادة بإعدادات الضباب العالمية؛ صحيح لتمرير موحدات الضباب إلى الشيدر. الافتراضي هو false.
كود GLSL لشيدر الجزء. هذا هو الكود الفعلي للشيدر. في المثال أعلاه، يتم استخراج كود `vertexShader` و `fragmentShader` من DOM؛ يمكن تمريره كسلسلة مباشرة أو تحميله عبر AJAX بدلاً من ذلك.
يحدد إصدار GLSL لكود الشيدر المخصص. ذو صلة فقط لـ WebGL 2 لتحديد ما إذا كان يجب تحديد GLSL 3.0 أم لا. القيم المتاحة هي `THREE.GLSL1` أو `THREE.GLSL3`. الافتراضي هو `null`.
إذا تم تعيينه، يستدعي هذا [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bindAttribLocation gl.bindAttribLocation] لربط فهرس رأس عام بمتغير سمة. الافتراضي هو غير معرف.
علامة قراءة فقط للتحقق مما إذا كان كائنًا معينًا من نوع [name].
يحدد ما إذا كانت هذه المادة تستخدم الإضاءة؛ صحيح لتمرير بيانات الموحدات المتعلقة بالإضاءة إلى هذا الشيدر. الافتراضي هو false.
يتحكم في سُمك الإطار السلكي. الافتراضي هو 1.
نظرًا للقيود
[link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile]
مع [page:WebGLRenderer WebGL] renderer على معظم
المنصات ستكون linewidth دائمًا 1 بغض النظر عن القيمة المُعَدَّة.
حدد ما إذا كان يتم عرض المادة بظلال مسطحة. الافتراضي هو false.
كائن من الشكل:
{
"uniform1": { value: 1.0 },
"uniform2": { value: 2 }
}
يحدد الموحدات التي يتم تمريرها إلى كود الشيدر؛ المفاتيح هي أسماء الموحدات
، والقيم هي تعريفات من الشكل
{
value: 1.0
}
حيث `value` هو قيمة الموحد. يجب أن تتطابق الأسماء مع اسم
الموحد، كما هو محدد في كود GLSL. يجب ملاحظة أن الموحدات يتم تحديثها
في كل إطار، لذلك تحديث قيمة الموحد سيؤدي فورًا إلى
تحديث القيمة المتاحة لكود GLSL.
يمكن استخدامه لإجبار تحديث الموحدات أثناء تغيير الموحدات في [page:Object3D.onBeforeRender](). الافتراضي هو `false`.
يعرف ما إذا كان يتم استخدام تلوين الرأس. الافتراضي هو `false`.
كود GLSL لشيدر الرأس. هذا هو الكود الفعلي للشيدر. في المثال أعلاه، يتم استخراج كود `vertexShader` و `fragmentShader` من DOM؛ يمكن تمريره كسلسلة مباشرة أو تحميله عبر AJAX بدلاً من ذلك.
عرض الهندسة كإطار سلكي (باستخدام GL_LINES بدلاً من GL_TRIANGLES). الافتراضي هو false (أي عرض كأشكال مسطحة).
يتحكم في سُمك الإطار السلكي. الافتراضي هو 1.
نظرًا للقيود
[link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile]
مع [page:WebGLRenderer WebGL] renderer على معظم
المنصات ستكون linewidth دائمًا 1 بغض النظر عن القيمة المُعَدَّة.
انظر إلى الفئة الأساسية [page:Material] للطرق المشتركة.
يولِّد نسخة طبقية من هذه المادة. يجب ملاحظة أن vertexShader و fragmentShader يتم نسخهم `by reference`، كذلك تعاريف `attributes`؛ هذا يعني أن نسخ المادة ستشارك نفس [page:WebGLProgram] المُجَمَّع. ومع ذلك، فإن `uniforms` يتم نسخها `by value`، مما يتيح لك امتلاك مجموعات مختلفة من الموحدات لنسخ مختلفة من المادة.
[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]