
Если вам нужно добавить 3D-графику на сайт без плагинов, используйте WebGL. Эта технология работает в браузере и поддерживается 98% современных устройств. Для старта достаточно знать JavaScript и основы линейной алгебры.
WebGL ускоряет рендеринг сложных сцен за счёт GPU. Вы рисуете треугольники, настраиваете текстуры и освещение через шейдеры. Пример: анимация из 10 000 частиц на WebGL работает в 60 FPS, тогда как обычный Canvas справляется лишь с 2 000.
Библиотеки типа Three.js упрощают работу. Вместо ручного написания шейдеров вы создаёте сцену за 15 строк кода. Так делают интерактивные презентации, игры и визуализации данных. Например, сайт Airbnb использует WebGL для 3D-туров по жилью.
- Как начать работу с WebGL: настройка среды и базовый рендеринг
- Шейдеры в WebGL: вершинные и фрагментные программы для графики
- Оптимизация производительности: работа с буферами и текстурами
- Создание интерактивных 3D-сцен: обработка пользовательского ввода
- Реагирование на движение мыши
- Обработка клавиатуры
- Интеграция WebGL с HTML и CSS: встраивание графики в веб-страницы
- Связь WebGL с DOM
- Адаптация под макет
- Использование библиотек: Three.js и другие инструменты для упрощения разработки
Как начать работу с WebGL: настройка среды и базовый рендеринг

Установите современный браузер, например Chrome или Firefox, чтобы обеспечить поддержку WebGL. Проверьте его доступность, перейдя на сайт get.webgl.org.
Создайте HTML-файл с базовой структурой. Добавьте элемент <script> для кода WebGL и подключите библиотеку glMatrix для работы с матрицами:
| Шаг | Действие |
|---|---|
| 1 | Создайте контекст WebGL через canvas.getContext('webgl') |
| 2 | Проверьте успешность создания: если контекст равен null, браузер не поддерживает WebGL |
Напишите вершинный и фрагментный шейдеры на GLSL. Минимальный вершинный шейдер должен передавать позицию точки:
attribute vec3 aPosition;
void main() {
gl_Position = vec4(aPosition, 1.0);
}
Создайте буфер вершин и передайте в него данные. Для отрисовки треугольника задайте координаты:
const vertices = [
0.0, 0.5, 0.0,
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0
];
Настройте цикл рендеринга с помощью requestAnimationFrame. Очистите буфер цвета командой gl.clear(gl.COLOR_BUFFER_BIT) и вызовите gl.drawArrays для отображения примитивов.
Для отладки используйте WebGL Inspector или встроенные инструменты разработчика браузера. Они показывают состояние буферов, текстур и шейдеров.
Шейдеры в WebGL: вершинные и фрагментные программы для графики
Вершинные шейдеры обрабатывают координаты точек 3D-моделей, а фрагментные определяют цвет каждого пикселя. Для работы с ними в WebGL используйте язык GLSL (OpenGL Shading Language).
Создайте вершинный шейдер, который преобразует 3D-координаты в экранные. Например:
attribute vec3 aPosition;
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
void main() {
gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aPosition, 1.0);
}
Фрагментный шейдер задаёт цвет. Простой вариант – однотонная заливка:
precision mediump float;
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // Красный
}
Компилируйте шейдеры в WebGL так:
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderCode);
gl.compileShader(vertexShader);
Проверяйте ошибки после компиляции:
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
console.error(gl.getShaderInfoLog(vertexShader));
}
Связывайте шейдеры в программу:
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
Используйте атрибуты и uniform-переменные для передачи данных. Например, для анимации меняйте матрицу преобразования:
const timeUniform = gl.getUniformLocation(program, 'uTime');
gl.uniform1f(timeUniform, performance.now() / 1000);
Оптимизируйте шейдеры: минимизируйте ветвления, используйте встроенные функции GLSL (mix, smoothstep), избегайте лишних вычислений в циклах.
Для сложных эффектов комбинируйте шейдеры. Например, для текстурирования передавайте координаты из вершинного шейдера во фрагментный:
// Вершинный шейдер
varying vec2 vTexCoord;
attribute vec2 aTexCoord;
void main() {
vTexCoord = aTexCoord;
// ... остальной код
}
// Фрагментный шейдер
varying vec2 vTexCoord;
uniform sampler2D uTexture;
void main() {
gl_FragColor = texture2D(uTexture, vTexCoord);
}
Оптимизация производительности: работа с буферами и текстурами
Используйте статичные буферы для данных, которые не меняются часто. Например, если вершины меша остаются неизменными, создавайте буферы с флагом STATIC_DRAW. Это позволяет драйверу видеокарты оптимизировать хранение данных.
Объединяйте небольшие буферы в один, если они содержат схожие данные. Частые переключения между буферами снижают производительность, а один крупный буфер уменьшает количество вызовов gl.bindBuffer.
Для текстур выбирайте подходящий размер и формат. Уменьшайте разрешение текстур, если детализация не критична. Например, для фоновых элементов достаточно текстуры 512×512 вместо 2048×2048. Используйте RGB вместо RGBA, если прозрачность не нужна.
Сжимайте текстуры с помощью форматов вроде WEBGL_compressed_texture_s3tc. Это сокращает объем видеопамяти и ускоряет загрузку. Проверяйте поддержку сжатия через gl.getExtension.
Повторно используйте буферы и текстуры вместо создания новых. Если объект исчезает с экрана, не удаляйте его буфер – очистите данные и заполните заново при повторном появлении.
Минимизируйте вызовы gl.texImage2D для обновления текстур. При изменении части текстуры применяйте gl.texSubImage2D, который обновляет только указанную область.
Для анимированных текстур используйте атласы – одну большую текстуру с кадрами анимации. Переключайте UV-координаты вместо замены всей текстуры.
Отключайте фильтрацию для пиксельной графики. Установите gl.NEAREST вместо gl.LINEAR, чтобы избежать лишних вычислений.
Создание интерактивных 3D-сцен: обработка пользовательского ввода
Для обработки кликов и касаний в WebGL используйте raycasting – метод, который проверяет пересечение луча с 3D-объектами. Подключите библиотеку Three.js и создайте экземпляр Raycaster:
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
function onClick(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(scene.children);
if (intersects.length > 0) {
console.log('Объект выбран:', intersects[0].object);
}
}
window.addEventListener('click', onClick);
Реагирование на движение мыши
Добавьте вращение камеры или объектов при движении курсора:
- Зафиксируйте начальную позицию мыши при нажатии кнопки.
- Рассчитайте смещение курсора и преобразуйте его в углы поворота.
- Примените изменения к камере или целевому объекту.
let isDragging = false;
let previousMousePosition = { x: 0, y: 0 };
window.addEventListener('mousedown', () => isDragging = true);
window.addEventListener('mouseup', () => isDragging = false);
window.addEventListener('mousemove', (event) => {
if (!isDragging) return;
const deltaX = event.clientX - previousMousePosition.x;
const deltaY = event.clientY - previousMousePosition.y;
camera.rotation.y += deltaX * 0.01;
camera.rotation.x += deltaY * 0.01;
previousMousePosition = { x: event.clientX, y: event.clientY };
});
Обработка клавиатуры
Используйте события клавиш для перемещения объектов:
- Создайте объект для хранения состояния клавиш.
- Обновляйте позицию камеры или модели в основном цикле рендеринга.
const keys = {};
window.addEventListener('keydown', (event) => keys[event.code] = true);
window.addEventListener('keyup', (event) => keys[event.code] = false);
function animate() {
if (keys['KeyW']) camera.position.z -= 0.1;
if (keys['KeyS']) camera.position.z += 0.1;
if (keys['KeyA']) camera.position.x -= 0.1;
if (keys['KeyD']) camera.position.x += 0.1;
requestAnimationFrame(animate);
}
animate();
Для сенсорных устройств добавьте обработчики touchstart, touchmove и touchend, преобразуя координаты касаний в аналоги мыши.
Интеграция WebGL с HTML и CSS: встраивание графики в веб-страницы
Для встраивания WebGL-графики в веб-страницу создайте элемент <canvas> с идентификатором, например:
<canvas id="webgl-canvas" width="800" height="600"></canvas>
Укажите размеры явно в атрибутах width и height, чтобы избежать растягивания или сжатия контента. Стилизуйте элемент через CSS, задавая фон, отступы или границы:
#webgl-canvas {
display: block;
margin: 0 auto;
background: #f0f0f0;
border-radius: 8px;
}
Связь WebGL с DOM

Инициализируйте WebGL-контекст в JavaScript, используя метод getContext:
const canvas = document.getElementById('webgl-canvas');
const gl = canvas.getContext('webgl');
Проверьте поддержку браузером:
if (!gl) {
console.error('WebGL не поддерживается');
canvas.innerHTML = 'Ваш браузер не поддерживает WebGL';
}
Адаптация под макет
Для адаптивности обрабатывайте изменение размеров окна:
window.addEventListener('resize', () => {
canvas.width = window.innerWidth * 0.9;
canvas.height = window.innerHeight * 0.7;
gl.viewport(0, 0, canvas.width, canvas.height);
});
Используйте CSS-переменные для синхронизации цветовых схем между WebGL и интерфейсом:
:root {
--primary-color: #3a86ff;
}
#webgl-canvas {
box-shadow: 0 0 10px var(--primary-color);
}
В шейдерах WebGL применяйте те же значения через uniform-переменные:
gl.uniform3f(colorUniformLocation, 0.23, 0.53, 1.0); // #3a86ff в RGB
Использование библиотек: Three.js и другие инструменты для упрощения разработки
Three.js – самая популярная библиотека для работы с WebGL, которая сокращает объем кода в 3-5 раз по сравнению с чистым API. Она предоставляет готовые решения для создания сцен, камер, освещения и анимации, избавляя от ручной работы с матрицами и шейдерами.
Начните с базового примера: загрузите Three.js через CDN, создайте сцену, камеру и рендерер за 10 строк кода. Добавьте куб с материалом и светом – и у вас уже есть интерактивная 3D-модель. Для анимации используйте requestAnimationFrame, а для загрузки моделей – GLTFLoader, который поддерживает форматы из Blender и Maya.
Если Three.js кажется избыточным, попробуйте lighter-альтернативы. Babylon.js подходит для сложных проектов с физикой и VR, а PixiJS фокусируется на 2D-графике с ускорением через WebGL. Для простых визуализаций используйте p5.js – его синтаксис близок к Processing и требует минимум настроек.
Инструменты вроде PlayCanvas предлагают визуальные редакторы для командной работы, а A-Frame добавляет WebGL-сцены в HTML через декларативные теги. Выбирайте библиотеку под задачу: Three.js универсальна, но для мобильных проектов проверьте производительность с Cannon.js или ammo.js.
Оптимизируйте рендеринг: уменьшайте полигоны в моделях, используйте атласы текстур и включайте frustum culling. Three.js предоставляет методы для автоматического управления детализацией, например LOD (Level of Detail). Для отладки добавьте stats.js – он покажет FPS и время рендера.
Большинство библиотек поддерживают TypeScript, что упрощает разработку. Документация Three.js содержит живые примеры – изменяйте их вместо написания кода с нуля. Для вдохновения изучите проекты на CodePen или GitHub, где авторы делятся настройками материалов и шейдеров.







