В библиотеке Three.js механизм чанков (shader
chunks) позволяет переиспользовать и комбинировать фрагменты
GLSL-кода между различными материалами и шейдерами. Чанк — это
по сути шаблон GLSL, который может быть вставлен в
стандартный шейдер через директивы #include. Такой подход
значительно упрощает поддержку сложных визуальных эффектов, снижает
дублирование кода и обеспечивает согласованность между материалами.
Three.js содержит обширную коллекцию встроенных чанков, которые охватывают:
lights_physical_fragment,
lights_pars_begin)map_fragment,
envmap_fragment)normal_fragment,
normal_pars_vertex)morphtarget_vertex,
skinning_vertex)fog_fragment,
shadowmap_pars_fragment)Каждый чанк хранится в виде строки GLSL и подключается через синтаксис:
#include <имя_чанка>
Например:
void main() {
#include <color_fragment>
gl_FragColor = vec4( diffuseColor, opacity );
}
Все встроенные чанки находятся в объекте
THREE.ShaderChunk. Например:
console.log(THREE.ShaderChunk);
Результатом будет объект, содержащий десятки строковых шаблонов, таких как:
envmap_pars_fragmentlights_physical_pars_fragmentshadowmap_pars_vertexfog_fragmentКаждый чанк обычно делится на две части:
*_pars_*) — объявления
переменных и функций, которые нужны шейдеру, например:uniform sampler2D map;
varying vec2 vUv;
main() шейдера:vec4 texelColor = texture2D( map, vUv );
diffuseColor *= texelColor;
Такое разделение позволяет подключать функционал либо к объявлению переменных, либо к основной логике.
Three.js позволяет создавать кастомные чанки, чтобы их потом
использовать как стандартные. Это делается через добавление строкового
шаблона в объект THREE.ShaderChunk:
THREE.ShaderChunk.myCustomChunk = `
vec3 modifyColor(vec3 color) {
return color * vec3(0.8, 0.9, 1.0);
}
`;
И подключение в шейдере:
#include <myCustomChunk>
void main() {
vec3 baseColor = vec3(1.0, 0.5, 0.2);
vec3 finalColor = modifyColor(baseColor);
gl_FragColor = vec4(finalColor, 1.0);
}
ShaderMaterialДля интеграции чанков с кастомными шейдерами используют
ShaderMaterial. Важно правильно комбинировать
vertexShader и fragmentShader, используя
директивы #include для переиспользования кода. Пример:
const material = new THREE.ShaderMaterial({
uniforms: {
time: { value: 0 }
},
vertexShader: `
#include <common>
#include <morphtarget_pars_vertex>
void main() {
#include <begin_vertex>
#include <project_vertex>
}
`,
fragmentShader: `
#include <common>
#include <color_pars_fragment>
uniform float time;
void main() {
vec3 dynamicColor = vec3(sin(time), cos(time), 0.5);
gl_FragColor = vec4(dynamicColor, 1.0);
}
`
});
Здесь используются как встроенные чанки (common,
color_pars_fragment), так и кастомная логика через
GLSL.
Three.js позволяет переопределять встроенные чанки для изменения стандартного поведения материалов без копирования всего шейдера. Например, можно заменить обработку освещения:
THREE.ShaderChunk.lights_fragment_begin = `
vec3 totalLight = vec3(0.0);
// кастомная логика освещения
`;
Все материалы, использующие lights_fragment_begin,
автоматически получат новую реализацию. Это удобно для глобальных
изменений стиля освещения или визуальных эффектов.
*_pars_* для объявлений,
*_fragment/*_vertex для логики).common, uv_pars,
lights_pars_begin).Для более сложных материалов возможна динамическая генерация шейдеров, когда чанки подключаются в зависимости от условий:
let fragmentShader = `
#include <common>
`;
if (useFog) fragmentShader += `#include <fog_fragment>`;
if (useTexture) fragmentShader += `#include <map_fragment>`;
fragmentShader += `
void main() {
gl_FragColor = vec4(1.0);
}
`;
Такой подход позволяет строить адаптивные шейдеры без дублирования базовой логики.
Чанки активно используются в:
MeshStandardMaterial и
MeshPhysicalMaterial для освещения и PBR.ShaderMaterial для кастомной визуализации.EffectComposer и шейдерные
пассы.Это делает код более модульным, поддерживаемым и расширяемым, особенно при работе с большими сценами и сложными эффектами.
Механизм чанков в Three.js — ключевой инструмент для создания масштабируемых и переиспользуемых шейдеров, позволяющий не только ускорять разработку, но и легко поддерживать визуальное соответствие между различными материалами в проекте. Он обеспечивает баланс между гибкостью кастомизации и удобством стандартных материалов, делая Three.js мощным инструментом для 3D-визуализации.