Это 110-я оригинальная статья без воды.Если вы хотите получить больше оригинальных статей, выполните поиск в публичном аккаунте и подпишитесь на нас~ Эта статья была впервые опубликована в блоге Zhengcaiyun:Начало работы с понятиями и основами WebGL
Что такое WebGL
Объяснение, данное Википедией для WebGL, заключается в том, что WebGL — это протокол трехмерного рисования, а объяснение, данное Википедией, — это API JavaScript. Поскольку технология WebGL предназначена для того, чтобы помочь нам разрабатывать интерактивные 2D- и 3D-эффекты веб-страницы в любом совместимом веб-браузере без использования плагинов, мы можем понимать ее как технологию рисования, которая помогает нам разрабатывать 3D-веб-страницы, конечно же, базовый или JavaScript API.
История WebGL
Развитие WebGL можно проследить до 2006 года. WebGL возник из экспериментального проекта Canvas 3D сотрудника Mozilla Владимира Вукисевича, а в 2006 году был впервые продемонстрирован прототип Canvas 3D. Эта технология была реализована в браузерах FireFox и Opera в конце 2007 года. В начале 2009 года консорциум Khronos Group создал рабочую группу WebGL, в состав первых рабочих членов которой вошли Apple, Google, Mozilla, Opera и другие. Спецификация WebGL 1.0 была выпущена в марте 2011 года. Разработка спецификации WebGL 2 началась в 2013 году и была завершена в январе 2017 года. Спецификация WebGL 2 впервые была поддержана в Firefox 51, Chrome 56 и Opera 43.
Основные понятия в WebGL
WebGL работает на графическом процессоре компьютера, поэтому он должен использовать код, который может работать на графическом процессоре.Такой код должен предоставлять пары методов, один из которых называется вершинным шейдером, а другой — фрагментным шейдером, и использует язык GLSL. . Метод связывания вершинных и фрагментных шейдеров называется шейдерной программой.
- вершинный шейдер
Функция вершинного шейдера состоит в том, чтобы вычислить положение вершины, то есть предоставить значение координаты вершины в пространстве отсечения.
Содержимое этого блока относится к статьеwebglfundamentals
- фрагментный шейдер
Роль фрагментного шейдера заключается в вычислении значения цвета примитива.Фрагментный шейдер можно грубо понять как пиксели на веб-странице.
- Метод сбора данных
Ранее мы упоминали концепции вершинного шейдера и фрагментного шейдера, а для работы двух методов вершинного шейдера и фрагментного шейдера требуются соответствующие данные. Теперь давайте посмотрим, как шейдер получает данные. Четыре способа:
- Свойства и буферизация
- глобальная переменная
- текстура
- Переменная
резюме
WebGL заботятся только о двух вещах: значениях координат в пространстве отсечения и значениях цвета. Использование WebGL должно обеспечить только эти две вещи. Таким образом, мы делаем и то, и другое, предоставляя два шейдера: вершинный шейдер для координат пространства отсечения и фрагментный шейдер для значений цвета.
Как работает WebGL
После понимания некоторых основных концепций WebGL мы можем взглянуть на то, что WebGL делает на графическом процессоре. Как мы узнали ранее, работа WebGL на графическом процессоре в основном делится на две части, а именно работу, выполняемую вершинным шейдером (преобразование вершин в координаты пространства отсечения), и работу, выполняемую фрагментным шейдером (на основе вершинного шейдера). результат расчета рисует пиксели). Если нам нужно нарисовать треугольник, работа на GPU в это время заключается в том, чтобы трижды вызвать вершинный шейдер для вычисления соответствующих положений трех вершин треугольника в системе координат отсечения, и сохранить их в GPU через переменную gl_Position, а затем вызвать Фрагментный шейдер завершает вычисление значения цвета каждой вершины и сохраняет соответствующее значение цвета в графическом процессоре через переменную gl_FragColor. После завершения этой работы мы получили пиксели, необходимые для рисования треугольника, и, наконец, растеризованного треугольника.
Собственный WebGL API для рисования треугольников
Мы узнали об истории развития, основных концепциях и принципах работы WebGL раньше, а затем нам следует попрактиковаться в реальных знаниях, поэтому давайте посмотрим, как нарисовать простой треугольник на веб-странице через WebGL. Мы знаем, что WebGL как технология 3D-рисования существует на основе элемента canvas в HTML5, поэтому нам нужно выполнить ряд подготовительных действий, прежде чем мы начнем рисовать:
-
Во-первых, нам нужно создать элемент холста в качестве холста, необходимого для рисования треугольника, и выполнить тест совместимости браузера для элемента холста.
function webglInit () { const canvasEl = document.createElement('canvas'); // canvas 元素创建 canvasEl.width = document.body.clientWidth; // 设置 canvas 画布的宽度 canvasEl.height = document.body.clientHeight; // 设置 canvas 画布的高度 document.body.append(canvasEl); // 将创建好的 canvas 画布添加至页面中的 body 元素下 // 接下来我们需要判断浏览器对于 WebGL 的兼容性,如果浏览器不支持 WebGL 那么我们就不需要再进行下去了 if(!canvasEl.getContext("webgl") && !canvasEl.getContext("experimental-webgl ")) { alert("Your Browser Doesn't Support WebGL"); return; } // 如果浏览器支持 WebGL,那么我们就获取 WebGL 的上下文对象并复制给变量 gl const context = (canvasEl.getContext("webgl")) ? canvasEl.getContext("webgl") : getContext("experimental-webgl"); /* 设置视口 context.viewport(x, y, width, height); x: 用来设定视口的左下角水平坐标。默认值:0 y: 用来设定视口的左下角垂直坐标。默认值:0 width: 用来设定视口的宽度。默认值:canvas 的宽度 height: 用来设定视口的高度。默认值:canvas 的高度 当你第一次创建 WebGL 上下文的时候,视口的大小和 canvas 的大小是匹配的。然而,如果你重新改变了canvas的大小,你需要告诉 WebGL 上下文设定新的视口,因此这里作为初次创建这行代码可以省略 */ context.viewport(0, 0, context.canvas.width, context.canvas.height); return context; }
-
После того, как холст готов, следующий шаг — начать рисовать треугольники.Как мы обычно рисуем, нам нужно подготовить вершины, необходимые для рисования треугольников, а именно вершинные шейдеры, и цвет заливки, соответствующий треугольникам, а именно фрагментные шейдеры.
const gl = webglInit(); // 创建顶点着色器 语法 gl.createShader(type) 此处 type 为枚举型值为 gl.VERTEX_SHADER 或 gl.FRAGMENT_SHADER 两者中的一个 const vShader = gl.createShader(gl.VERTEX_SHADER) // 编写顶点着色器的 GLSL 代码 语法 gl.shaderSource(shader, source); shader - 用于设置程序代码的 webglShader(着色器对象) source - 包含 GLSL 程序代码的字符串 gl.shaderSource(vShader, ` attribute vec4 v_position; void main() { gl_Position = v_position; // 设置顶点位置 } `) gl.compileShader(vShader) // 编译着色器代码 const fShader = gl.createShader(gl.FRAGMENT_SHADER) gl.shaderSource(fShader, ` precision mediump float; uniform vec4 f_color; void main() { gl_FragColor = f_color; // 设置片元颜色 } `) // 编写片元着色器代码 gl.compileShader(fShader) // 编译着色器代码
-
Мы завершили настройку вершинного шейдера и фрагментного шейдера ранее и выполнили все приготовления перед рисованием.Далее нам нужно создать программу для соединения нашего вершинного шейдера и фрагментного шейдера, чтобы завершить Окончательную работу по рисованию треугольника.
// 创建一个程序用于连接顶点着色器和片元着色器
const program = gl.createProgram()
gl.attachShader(program, vShader) // 添加顶点着色器
gl.attachShader(program, fShader) // 添加片元着色器
gl.linkProgram(program) // 连接 program 中的着色器
gl.useProgram(program) // 告诉 WebGL 用这个 program 进行渲染
const color = gl.getUniformLocation(program, 'f_color')
// 获取 f_color 变量位置
gl.uniform4f(color, 0.93, 0, 0.56, 1) // 设置它的值
const position = gl.getAttribLocation(program, 'v_position')
// 获取 v_position 位置
const pBuffer = gl.createBuffer()
// 创建一个顶点缓冲对象,返回其 id,用来放三角形顶点数据,
gl.bindBuffer(gl.ARRAY_BUFFER, pBuffer)
// 将这个顶点缓冲对象绑定到 gl.ARRAY_BUFFER
// 后续对 gl.ARRAY_BUFFER 的操作都会映射到这个缓存
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
0, 0.5,
0.5, 0,
-0.5, -0.5
]), // 三角形的三个顶点
// 因为会将数据发送到 GPU,为了省去数据解析,这里使用 Float32Array 直接传送数据
gl.STATIC_DRAW // 表示缓冲区的内容不会经常更改
)
// 将顶点数据加入的刚刚创建的缓存对象
gl.vertexAttribPointer( // 告诉 OpenGL 如何从 Buffer 中获取数据
position, // 顶点属性的索引
2, // 组成数量,必须是 1,2,3 或 4。我们只提供了 x 和 y
gl.FLOAT, // 每个元素的数据类型
false, // 是否归一化到特定的范围,对 FLOAT 类型数据设置无效
0, // stride 步长 数组中一行长度,0 表示数据是紧密的没有空隙,让 OpenGL 决定具体步长
0 // offset 字节偏移量,必须是类型的字节长度的倍数。
)
gl.enableVertexAttribArray(position);
// 开启 attribute 变量额,使顶点着色器能够访问缓冲区数据
gl.clearColor(0, 1, 1, 1) // 设置清空颜色缓冲时的颜色值
gl.clear(gl.COLOR_BUFFER_BIT) // 清空颜色缓冲区,也就是清空画布
// 语法 gl.drawArrays(mode, first, count); mode - 指定绘制图元的方式 first - 指定从哪个点开始绘制 count - 指定绘制需要使用到多少个点
gl.drawArrays( gl.TRIANGLES, 0, 3 )
После запуска приведенного выше кода с файлом HTML мы можем увидеть треугольник, как показано на рисунке на веб-странице, и размер треугольника адаптируется в соответствии с размером окна браузера.Видно, что мы уже написали длинную серию JS-кода, просто нарисовав простой треугольник.Если мы действительно используем собственный WebGL API для написания динамической трехмерной интерактивной веб-страницы, стоимость разработки может оказаться чрезвычайно высокой.
Недостатки разработки собственного API WebGL
Приведенный выше пример рисования треугольников с помощью собственного API WebGL полностью показывает нам проблемы использования собственного API WebGL для разработки интерактивных 3D-страниц. Хотя функционально родной WebGL API может удовлетворить потребности в разработке любого из наших сценариев, затраты на его разработку и обучение чрезвычайно высоки. Крайне недружелюбен к новичкам в WebGL.Нам нужно настроить вершинный шейдер для вычисления того, где отрисовываются вершины.Для этого требуется определенная математическая база,чтобы разработчики были знакомы с матричными операциями,а также с пространственной геометрией.Концепция знакомства с пространственное распределение 3D-объектов. Освещение, текстура и прочее оформление сцены также должны иметь свое мнение о цветовой конфигурации. Поэтому, чтобы облегчить новичкам задачу, ниже я представлю некоторые распространенные фреймворки для разработки WebGL.
Несколько фреймворков для разработки WebGL
- Three.js
- Three.js — это всеобъемлющая библиотека WebGL, которая имеет широкий спектр приложений.Ложка дегтя в том, что библиотека Three.js не имеет исчерпывающих и подробных официальных документов, что не особенно дружелюбно к пользователям.
- Cesium.js
- Cesium.js — это библиотека WebGL, предназначенная для разработки 3D-карт. Она имеет относительно полный API для разработки 3D-карт. Это хороший выбор для разработчиков, которым необходимо разрабатывать 3D-карты, но разработка приложений для других сценариев не рассматривается.
- Babylon.js
- Babylon.js — это широко используемая библиотека WebGL в зарубежных странах, заинтересованные партнеры могут ознакомиться с ней самостоятельно, здесь я не буду ее подробно представлять.
Three.js — это 3D-движок, работающий в браузере, вы можете использовать его для создания различных 3D-сцен, а Three.js — это также комплексная библиотека WebGL. Если вам нужно разработать веб-страницы с 3D-картами, вы можете использовать Cesium.js, библиотеку WebGL, предназначенную для разработки карт. Babylon.js — популярная библиотека WebGL за рубежом.
Рисование вращающегося куба на основе Three.js
-
Первый шаг для рисования вращающегося куба с Three.js такой же, как и с родным WebGl.Первый шаг — подготовить среду, необходимую для запуска Three.js.
// 创建 renderer 变量用于存储渲染器对象 var renderer; // initThree 函数用来初始化 Three.js 运行所需的环境 function initThree() { // 同原生 WebGL 环境搭建过程一样,Three.js 也需要先设置画布 canvas 元素的大小 width = document.getElementById('canvas-frame').clientWidth; // 设置宽度属性为浏览器窗口宽度 height = document.getElementById('canvas-frame').clientHeight; // 设置高度属性为浏览器窗口高度 // 新建一个 WebGL 渲染器并赋值给 renderer 变量 renderer = new THREE.WebGLRenderer({ antialias: true }); // 设置画布大小为浏览器窗口大小 renderer.setSize(width, height); // 将画布元素挂载到页面 document.getElementById('canvas-frame').appendChild(renderer.domElement); // 设置清空画布的颜色为白色 renderer.setClearColor(0xFFFFFF, 1.0); }
-
Далее, в отличие от родного WebGL, которому нужно подготовить вершинные и фрагментные шейдеры, Three.js нужно подготовить камеры. Тремя основными элементами, необходимыми Three.js для рисования 3D-страниц, являются камера, сцена и объект.Конечно, если есть необходимость установить эффект света и тени, нам также нужно добавить источник света четвертого элемента. Источник света ставить не обязательно, но камера, сцена и объект должны быть.
// 创建 camera 变量用于存储相机对象 var camera; // 初始化相机函数 Three.js 中相机的类型有好几种可以根据具体需要进行选择这里我们要创建的是一个旋转的立方体所以采用的是透视相机,而如果需要创建 3D 阴影效果的场景则需要使用正交相机 function initCamera() { /* 创建透一个视相机的实例语法 PerspectiveCamera( fov : Number, aspect : Number, near : Number, far : Number ) fov - 视角 aspect - 物体的长宽比 near - 相机近点截图 far - 相机远点截图 */ camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000); camera.position.x = 0; // 设置相机在三维空间坐标中 x 轴的位置 camera.position.y = 10; // 设置相机在三维空间坐标中 y 轴的位置 camera.position.z = 5; // 设置相机在三维空间坐标中 z 轴的位置 camera.up.x = 0; camera.up.y = 0; camera.up.z = 1; camera.lookAt(new THREE.Vector3(0,0,0));// 设置相机的观察点 }
-
На предыдущем шаге мы завершили настройку камеры Теперь давайте подготовим сцену второго элемента, необходимую Three.js для отрисовки 3D веб-страниц.
// 创建 scene 变量用于存储场景对象 var scene; // initScene 函数创建一个场景并赋值给 scene 变量 function initScene() { scene = new THREE.Scene(); }
-
Теперь, когда камера и сцена готовы, нам нужно установить объект для съемки и добавить его в сцену после того, как объект будет отрисован.
// 创建一个 cube 变量用于存放几何立方体 var cube; // initObject 函数就是我们创建场景的核心了 function initObject() { // 首先创建一个一个几何类的实例并赋值给 geometry 变量 var geometry = new THREE.BoxGeometry(1, 1, 1); // 然后创建一种材质的实例 MeshBasicMaterial 材质的构造函数能够创建一种简单的不受场景灯光效果影响的材质 var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); // Mesh 是一种三角形网格基本单元的构造函数,类似于我们原生 WebGL 中的片元着色器它用于连接几何体和材质 cube = new THREE.Mesh( geometry, material ); // 最后将创建好的几何立方体添加到场景中 scene.add(cube); }
-
На данный момент мы завершили базовую настройку, необходимую для Three.js для рисования 3D-веб-страниц.Конечно, если есть необходимость в световых и теневых эффектах на 3D-веб-страницах, мы также можем добавить в сцену конфигурации освещения. Cube не предъявляет особых требований к освещению, поэтому переходим непосредственно к завершающему этапу рендеринга сцены.
// render 函数提供了浏览器的循环渲染功能 function render() { cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render(scene, camera); requestAnimationFrame(render); } // 最后将 Threee.js 环境初始化,场景创建,相机创建渲染器创建以及渲染初始化等函数合成到一起执行我们就完成了一个旋转立方体的绘制 function threeStart() { initThree(); initCamera(); initScene(); initObject(); render(); } document.addEventListener('DOMContentLoaded',function(){ threeStart(); });
-
Рендеринг вращающегося куба Three.js также необходимо использовать с файлом HTML, чтобы увидеть эффект.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script type="text/javascript" src="../utils/three.js"></script> <style type="text/css"> div#canvas-frame { border: none; cursor: pointer; width: 100%; height: 600px; background-color: #EEEEEE; } </style> </head> <body> <div id="canvas-frame"></div> </body> </html>
После запуска приведенного выше кода с файлом HTML мы видим на веб-странице вращающийся зеленый куб.
резюме
Путем сравнения мы обнаружили, что, хотя мы создали более сложную сцену с помощью Three.js, объем кода был меньше, чем при рисовании треугольников с помощью собственного API WebGL. Видно, что новичкам явно нецелесообразно напрямую использовать нативный API WebGL для разработки 3D-веб-страниц. В настоящее время мы можем разрабатывать с помощью библиотек-оболочек WebGL, таких как Three.js. По сравнению с разработкой нативного API, такая сторонняя упакованная библиотека WebGL значительно снижает наши затраты на разработку, а также может помочь нам в разработке более интересных эффектов для страниц. Конечно, это не значит, что нативный API плохой, ведь если у вас есть возможность изучить разработку нативного API WebGL, это может помочь нам реализовать более произвольные функции при разработке 3D-веб-страниц, а документация по Three.js сам по себе не особенно совершенен, поэтому я хочу, чтобы использование Smooth также требовало глубокого понимания собственного API WebGL.
Суммировать
Появление технологии WebGL не за короткое время, но, несмотря на возможность разработки 3D-веб-страниц с крутыми эффектами, она не смогла загореться, и наиболее широко используемой сегодня является разработка 3D-веб-игр. Большая часть причин этого заключается в том, что она ограничена развитием скорости сети.В современном быстро меняющемся обществе люди чрезвычайно терпимы к скорости загрузки веб-страницы.Трехмерная веб-страница, разработанная WebGL, часто занимает три или четыре раза. секунды, чтобы открыть Время, несомненно, крайне недружелюбно к пользователям. Однако считается, что с развитием технологии связи 5G и быстрым развитием технологии сетевой связи технология WebGL завтра может открыть новые возможности для развития.
использованная литература
Рекомендуемое чтение
Самая знакомая незнакомка rc-форма
Возможности Vite и частичный анализ исходного кода
Как создать платформу сборки и развертывания, подходящую для вашей команды
работы с открытым исходным кодом
- Zhengcaiyun интерфейсный таблоид
адрес с открытым исходным кодомwww.zoo.team/openweekly/(На главной странице официального сайта таблоида есть группа обмена WeChat)
Карьера
ZooTeam, молодая, увлеченная и творческая команда, связанная с отделом исследований и разработок продукции Zhengcaiyun, базируется в живописном Ханчжоу. В настоящее время в команде более 40 фронтенд-партнеров, средний возраст которых составляет 27 лет, и почти 30% из них — инженеры полного стека, настоящая молодежная штурмовая группа. В состав членов входят «ветераны» солдат из Ali и NetEase, а также первокурсники из Чжэцзянского университета, Университета науки и технологий Китая, Университета Хандянь и других школ. В дополнение к ежедневным деловым связям, команда также проводит технические исследования и фактические боевые действия в области системы материалов, инженерной платформы, строительной платформы, производительности, облачных приложений, анализа и визуализации данных, а также продвигает и внедряет ряд внутренних технологий. Откройте для себя новые горизонты передовых технологических систем.
Если вы хотите измениться, вас забрасывают вещами, и вы надеетесь начать их бросать; если вы хотите измениться, вам сказали, что вам нужно больше идей, но вы не можете сломать игру; если вы хотите изменить , у вас есть возможность добиться этого результата, но вы не нужны; если вы хотите изменить то, чего хотите достичь, вам нужна команда для поддержки, но вам некуда вести людей; если вы хотите изменить установившийся ритм, это будет "5 лет рабочего времени и 3 года стажа работы"; если вы хотите изменить исходный Понимание хорошее, но всегда есть размытие того слоя оконной бумаги.. , Если вы верите в силу веры, верьте, что обычные люди могут достичь необыкновенных вещей, и верьте, что они могут встретить лучшего себя. Если вы хотите участвовать в процессе становления бизнеса и лично способствовать росту фронтенд-команды с глубоким пониманием бизнеса, надежной технической системой, технологиями, создающими ценность, и побочным влиянием, я думаю, что мы должны говорить. В любое время, ожидая, пока вы что-нибудь напишете, отправьте это наZooTeam@cai-inc.com