Material

ShaderMaterial

Материал, отрисованный с помощью пользовательских шейдеров. Шейдер - это небольшая программа, написанная на языке [ссылка:https://www.khronos.org/files/opengles_shading_language.pdf GLSL], которая выполняется на GPU. При необходимости вы можете использовать пользовательские шейдеры чтобы:

При использовании ShaderMaterial следует помнить о следующих моментах:

Пример

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

Вертексные шейдеры и фрагментные шейдеры

Для каждого материала можно задать два разных типа шейдеров:

В шейдерах существует три типа переменных: форма, атрибуты и вариации:

Обратите внимание, что в пределах самого шейдера формы и атрибуты действуют как константы; вы можете изменять их значения только путем передачи различных значений в буферы из вашего кода JavaScript.

Встроенные атрибуты и униформы

WebGLRenderer по умолчанию предоставляет шейдерам множество атрибутов и форм; определения этих переменных добавляются в ваш код fragmentShader и vertexShader программой WebGLProgram при компиляции шейдера; вам не нужно декларировать их самостоятельно. Подробности об этих переменных см. в WebGLProgram.

Некоторые из этих форм или атрибутов (например, относящиеся к освещению, туману и т.д.) требуют установки свойств на материале, чтобы WebGLRenderer скопировал соответствующие значения на GPU - обязательно установите эти флажки, если вы хотите использовать эти возможности в собственном шейдере.

Если вы не хотите, чтобы WebGLProgram добавлял что-либо в ваш код шейдера, вы можете использовать RawShaderMaterial вместо этого класса.

Пользовательские атрибуты и униформы

Как пользовательские атрибуты, так и униформы должны быть задекларированы в коде шейдера GLSL (в vertexShader и/или fragmentShader). Пользовательские униформы должны быть определены в свойстве uniforms вашего ShaderMaterial, тогда как любые пользовательские атрибуты должны быть определены через экземпляры BufferAttribute. Обратите внимание, что varying нужно объявлять только в коде шейдера (не в материале).

Чтобы задекларировать пользовательский атрибут, обратитесь к странице BufferGeometry для ознакомления, и странице BufferAttribute для детального рассмотрения API BufferAttribute.

При создании атрибутов каждый массив, который вы создаете для хранения данных атрибута, должен быть кратен размеру вашего типа данных. Например, если ваш атрибут имеет тип v3d.Vector3, и у вас 3000 вершин в массиве BufferGeometry, значение вашего типизированного массива должно быть создано с длиной 3000 * 3, или 9000 (по одному значению на компонент). Таблица размеров каждого типа данных приведена ниже (для справки):

Attribute sizes
GLSL type JavaScript type Size
float Number 1
vec2 v3d.Vector2 2
vec3 v3d.Vector3 3
vec3 v3d.Color 3
vec4 v3d.Vector4 4

Обратите внимание, что буферы атрибутов не обновляются автоматически при изменении их значений. Чтобы обновить пользовательские атрибуты, установите флажок needsUpdate в true на BufferAttribute геометрии (см. подробнее BufferGeometry).

Чтобы задекларировать пользовательскую Uniform, используйте свойство uniforms: uniforms: { time: { value: 1.0 }, resolution: { value: new v3d.Vector2() } }

Рекомендуется обновлять пользовательские значения Uniform в зависимости от object и camera в Object3D.onBeforeRender, поскольку Material может быть общим для meshes, matrixWorld из Scene и Camera обновляются в WebGLRenderer.render, а некоторые эффекты рендерят scene со своими частными cameras.

Конструктор

ShaderMaterial(parameters : Object)

parameters — (опционально) объект с одним или несколькими свойствами, определяющими внешний вид материала. Сюда можно передать любое свойство материала (включая любое свойство, унаследованное от Material).

Свойства

Общие свойства см. в базовом классе Material.

.clipping : Boolean

Определяет, поддерживает ли этот материал клиппинг; true - позволяет рендереру передавать униформу clippingPlanes. По умолчанию false.

.customPrepTokens : Object

Пользовательские маркеры препроцессинга - объект, аналогичный свойству .defines, но вместо добавления директивы #define для каждой пары ключ/значение они вручную заменяются в коде GLSL перед компиляцией шейдера. Используется в директиве #pragma unroll_loop для определения инициализатора цикла и значений условия так же, как и в директиве #define, но поскольку разворачивание выполняется до компиляции, эти значения также должны быть известны заранее, поэтому это свойство является отдельным контейнером для таких значений: customPrepTokens: { MAX_SIZE: 10 } делает следующий код: for (int i = 1; i <= MAX_SIZE; i++) { // ... } перед компиляцией: for (int i = 1; i <= 10; i++) { // ... }

.defaultAttributeValues : Object

Если отрисованная геометрия не включает эти атрибуты, но материал включает, эти значения по умолчанию будут переданы шейдерам. Это позволяет избежать ошибок при отсутствии данных буфера. this.defaultAttributeValues = { 'color': [1, 1, 1], 'uv': [0, 0], 'uv2': [0, 0] };

.defines : Object

Определяет пользовательские константы с помощью директив *#define* в коде GLSL для вертескного шейдера и фрагментного шейдера; каждая пара ключ/значение дает другую директиву: defines: { FOO: 15, BAR: true } дает линии #define FOO 15 #define BAR true в коде GLSL.

.extensions : Object

Объект со следующими свойствами: this.extensions = { derivatives: false, // set to use derivatives fragDepth: false, // set to use fragment depth values drawBuffers: false, // set to use draw buffers shaderTextureLOD: false // set to use shader texture LOD };

.fog : Boolean

Определяет, влияет ли на цвет материала глобальные настройки тумана; true, чтобы передать шейдеру форму тумана. По умолчанию - false.

.fragmentShader : String

Код GLSL шейдера фрагментов. Это фактический код шейдера. В приведенном примере код vertexShader и fragmentShader извлекается из DOM; его можно передать в виде строки напрямую или загрузить через AJAX.

.glslVersion : String

Определяет GLSL-версию пользовательского шейдерного кода. Актуально только для WebGL 2, чтобы определить, следует ли указывать GLSL 3.0 или нет. Допустимые значения: v3d.GLSL1 или v3d.GLSL3. По умолчанию null.

.index0AttributeName : String

Если задано, то вызывается gl.bindAttribLocation чтобы связать общий индекс вершины с переменной атрибута. По умолчанию не определено.

.lights : Boolean

Определяет, использует ли этот материал освещение; true для передачи данных униформ, связанных с освещением, в этот шейдер. По умолчанию - false.

.linewidth : Float

Управляет толщиной вайрфрейма. По умолчанию 1.

Из-за ограничений OpenGL Core Profile с WebGL рендерером на большинстве платформ ширина линии всегда будет равна 1, независимо от установленного значения.

.morphTargets : Boolean

Если установлено значение true, атрибуты morph target доступны в вертексном шейдере. По умолчанию false.

.morphNormals : Boolean

Если установлено значение true, атрибуты morph normal доступны в вертексном шейдере. По умолчанию false.

.flatShading : Boolean

Определяет, будет ли материал отображаться с плоским затенением. По умолчанию false.

.skinning : Boolean

Определяет, использует ли материал скиннинг; true для передачи атрибутов скиннинга в шейдер. По умолчанию false.

.uniforms : Object

Объект формы: { "uniform1": { value: 1.0 }, "uniform2": { value: 2 } } определяет униформы, которые будут переданы в код шейдера; ключи - имена униформ, значения - определения формы. { value: 1.0 } где value - значение униформы. Имена должны совпадать с именем формы, как определено в коде GLSL. Обратите внимание, что униформы обновляются на каждом кадре, поэтому обновление значения униформы немедленно обновит значение, доступное коду GLSL.

.uniformsNeedUpdate : Boolean

Может использоваться для принудительного изменения униформы при смене униформы в Object3D.onBeforeRender(). По умолчанию false.

.vertexColors : Boolean

Определяет, будет ли использоваться раскраска вертексов. По умолчанию false.

.vertexShader : String

Код вертексного шейдера GLSL. Это фактический код шейдера. В приведенном выше примере, код vertexShader и fragmentShader извлекается из DOM; он может быть передан в виде строки напрямую или загружаться через AJAX.

.wireframe : Boolean

Рендер геометрии виде сетки (используя GL_LINES вместо GL_TRIANGLES). По умолчанию false (т.е. рендеринг в виде плоских полигонов)..

.wireframeLinewidth : Float

Управляет толщиной вайрфрейма. По умолчанию 1.

Из-за ограничений OpenGL Core Profile с WebGL рендерером на большинстве платформ ширина линии всегда будет равна 1, независимо от установленного значения.

Методы

Общие методы см. в базовом классе Material.

.clone() → ShaderMaterial this : ShaderMaterial

Генерирует мелкую копию этого материала. Обратите внимание, что вертексный и фрагментный шейдеры копируются референсом, как и описания атрибутов; это означает, что клоны материала будут иметь одинаковые скомпилированные WebGLProgram. Однако униформы копируются по значению, что позволяет иметь разные наборы униформ для разных копий материала.

Исходный файл

О том как получить исходный код этого модуля читайте тут.