介绍
WebGL 是一个 Web API,可以在浏览器中进行 3D 图形渲染。它是基于 OpenGL ES 2.0 的 Web 实现。WebGL 使得开发者可以使用 JavaScript 编写能够在浏览器中进行高性能 3D 绘制的程序。
Web Components 是另一个很有用的 Web 技术,可以使得开发者更容易地构建可重用的自定义元素。Web Components 由三个部分构成:Custom Elements、Shadow DOM 和 HTML Templates。
在本文中,我们将结合使用 WebGL 和 Web Components,实现一个 3D 游戏场景的渲染器,定制自定义元素,以及使用 Shadow DOM 和 HTML Templates 来构建可重用的 3D 渲染组件。
准备工作
在开始之前,我们需要确保我们已经配置好了:
- 最新的 Chrome 或 Firefox 浏览器
- 最新版的 Node.js 和 npm
- 一个用于存储静态资源的文件夹
创建一个简单的 3D 场景
让我们从最基本的开始,创建一个简单的 3D 场景,和一个最基本的 WebGL 应用。首先,我们需要创建一个空的 HTML 文件,加载必要的 JavaScript 库和 CSS 样式表。以下是一个简单的 HTML 文件:
-- -------------------- ---- ------- --------- ----- ------ ------ ----- --------------- -- ------------- -- ----- --- ----------------- ----- ---------------- ------------------- -- ------- ------ ------- -------------------------- ------- -------
现在,我们需要创建一个 JavaScript 文件,用于初始化 WebGL 应用并渲染 3D 场景。这个 JavaScript 文件包括以下步骤:
- 获取 WebGL 上下文。这是我们需要实现 3D 渲染的核心。
const canvas = document.createElement("canvas"); const gl = canvas.getContext("webgl");
- 创建一个 3D 场景,由两个三角形构成。以下是该场景的顶点坐标和颜色:
-- -------------------- ---- ------- ----- --------- - - --- --- -- -- --- -- -- -- -- --- -- -- -- ----- ------ - - -- -- -- -- -- -- -- -- -- -- -- -- -- ----- ------- - - -- -- -- -- -- -- --
- 创建一个顶点着色器和一个片元着色器。着色器是 WebGL 中用于对顶点和片元进行变换和着色的管道。以下是该着色器的例子:
-- -------------------- ---- ------- ----- ------------------ - - --------- ---- --------- --------- ---- ------ ------- ---- ------- ------- ---- ------ ------- ---- ----- ------- ---- ----------- ---- ------ - ------ - ------ ----------- - ---------- - ---- - ----- - --------- - -- ----- -------------------- - - --------- ------- ------ ------- ---- ------- ---- ------ - ------------ - ------------ ----- - -- ----- ------------ - ---------------------------------- ----------------------------- -------------------- ------------------------------- ----- -------------- - ------------------------------------ ------------------------------- ---------------------- ---------------------------------
- 创建一个 WebGL 程序,将着色器连接到 WebGL 上下文中。这个渲染器将顶点和着色器绑定在一起,以便 WebGL 知道如何将顶点转换为屏幕上的像素。
const program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program); gl.useProgram(program);
- 将顶点属性和 uniform 变量绑定到 WebGL 上下文中。顶点属性是每个顶点的属性,比如顶点的位置和颜色。uniform 变量是传递给着色器的常量值,如投影矩阵和模型矩阵。
-- -------------------- ---- ------- ----- ------------------------- - ----------------------------- ------------ ----- ---------------------- - ----------------------------- --------- ----- -------------------- - ------------------------------ --------- ----- ------------------- - ------------------------------ -------- ----- ------------------------- - ------------------------------ -------------- ----- -------------- - ------------------ ------------------------------ ---------------- ------------------------------ --- ------------------------ ---------------- ------------------------------------------------------ ------------------------------------------------- -- --------- ------ -- --- ----- ----------- - ------------------ ------------------------------ ------------- ------------------------------ --- --------------------- ---------------- --------------------------------------------------- ---------------------------------------------- -- --------- ------ -- --- -------------------------------------- ------------------- -------------------------------------- --- --------------------- ----------------
- 为 WebGL 程序提供投影矩阵、视角矩阵和模型矩阵。这些矩阵是用于将 3D 场景中的顶点转换为屏幕上的像素。
const modelMatrix = mat4.create(); const viewMatrix = mat4.create(); const projectionMatrix = mat4.create(); mat4.translate(modelMatrix, modelMatrix, [0, 0, -5]); mat4.perspective(projectionMatrix, glMatrix.toRadian(45), canvas.width / canvas.height, 0.1, 100.0);
- 在每一帧渲染时获取模型矩阵,视角矩阵和投影矩阵,并在 canvas 上绘制二维图像。
-- -------------------- ---- ------- -------- ------ - -------------- -- ------------- --------------- ---------------- -- -- --- ---------------------------- - --------------------- ------------------------- ------------------------ ------------------------- ------------ ------ ------------------------- ------------ ------ ----------------------------------------- ------ ------------- ---------------------------------------- ------ ------------ ---------------------------------------------- ------ ------------------ ----------------------------- --------------- ------------------ --- ---------------------------- - -------
这些步骤描述了一个简单的 3D 场景的渲染器。现在我们可以将该渲染器封装成一个可以重用的 Web Component,使我们可以使多个相同的 3D 场景渲染器共享相同的代码逻辑。
将 3D 渲染器封装成一个 Web Component
我们将使用 Web Components 和 Shadow DOM 来将 3D 渲染器封装成一个可重用的组件,以便我们可以在多个文件中使用。
Web Components 由三个部分组成 - Custom Elements、Shadow DOM 和 HTML Templates。Shadow DOM 将空间和作用域分离, Custom Elements 允许你定义新的 HTML 标签,HTML Templates 允许你在重用一组 HTML 元素的共同布局。
我们可以使用 Custom Elements 将 3D 渲染器封装到一个自定义标签中,并使用 Shadow DOM 隐藏它的渲染器和样式。以下是一个包装 3D 渲染器的 Web Component 的例子:
-- -------------------- ---- ------- ----- ---------------------- ------- ----------- - ------------- - -------- -- -- ------ --- ---- ----- ------ - ------------------- ----- ------ --- ----- ----- - -------------------------------- ----------------- - - ----- - -------- ------ ------ ----- ------- ----- - ------ - ------ ----- ------- ----- - -- -------------------------- -- -- -- ----- ----- ------ - --------------------------------- ----- -- - --------------------------- --------------------------- -- -------- ----- ------- --- - - ---------------------------------------- ------------------------
我们创建了一个自定义元素,命名为 simple-3d-scene,并在构造函数中创建了一个 canvas 元素和 WebGL 上下文。我们还创建了一些样式,将 iframe 中的 canvas 在当前页面上占用 100% 的宽度和高度。
Web Components 将此元素封装在 Shadow DOM 中,因此其样式和渲染器隐藏在此 DOM 内的私有空间中。这使组件更干净且更易于重用。
使用 HTML Templates 来定制 3D 场景
在上面的示例中,我们已经将 3D 场景渲染器封装在了 Custom Element 中,现在我们使用 HTML Templates 定义一些默认的场景,在任何地方的调用时可以直接继承默认配置。
首先,我们在 Custom Element 的 Shadow DOM 中添加一个 HTML 模板标签。此标签将包含渲染组件应呈现的 HTML 标记。将 HTML 内容放在 template 标记中,以下是一个简单的例子:
-- -------------------- ---- ------- ----- ---------------------- ------- ----------- - ------------- - -------- -- -- ------ --- ---- ----- ------ - ------------------- ----- ------ --- ----- ----- - -------------------------------- ----------------- - - ----- - -------- ------ ------ ----- ------- ----- - ------ - ------ ----- ------- ----- - -- -------------------------- -- -- -- ----- ----- ------ - --------------------------------- ----- -- - --------------------------- --------------------------- -- -- ---- -- ----- -------- - ---------------------------------------------------- ----- ----- - ------------------------------------- ------ -------------------------- -- -------- ----- ------- --- - - ---------------------------------------- ------------------------
第一步是获取对定义的 HTML 模板的引用。在这个例子中,我们通过使用 JavaScript 来获取模板的引用,然后使用 importNode() 方法将模板克隆到 Shadow DOM 中。
现在,我们可以添加默认 3D 场景到模板中。以下是一个完整的例子:
-- -------------------- ---- ------- --------- ------------------------------ ---- ---------------- ---- ------ -- ---------- ----------------------------------- ------ ----------- ------- -- ---- -- -------- -------- ----- ---------------------- ------- ----------- - ------------- - -------- -- -- ------ --- ---- ----- ------ - ------------------- ----- ------ --- ----- ----- - -------------------------------- ----------------- - - ----- - -------- ------ ------ ----- ------- ----- - ------ - ------ ----- ------- ----- - -- -------------------------- -- -- -- ----- ----- ------ - --------------------------------- ----- -- - --------------------------- --------------------------- -- -- ---- -- ----- -------- - ---------------------------------------------------- ----- ----- - ------------------------------------- ------ -------------------------- -- -------- ----- ------- --- - - ---------------------------------------- ------------------------ ---------
在这个例子中,我们创建了一个模板,并定义了一个 Simple3DSceneComponent,用 Simple 3D Scene 来填充模板。现在,任何引用模板的元素都将显示一个 3D 场景。
结论
在本文中,我们探讨了如何使用 WebGL 和 Web Components 创建 3D 渲染器和可重用 3D 渲染组件。我们了解了如何使用 WebGL 在浏览器中实现 3D 图形渲染,以及如何在 Web Components 中封装和使用 WebGL 应用程序。我们还研究了如何使用 HTML Templates 来定制 3D 场景。
使用 Web Components 在 Web 应用程序中重用代码变得更加容易。通过将代码封装在可重用的 Custom Elements 中,我们能够更轻松地共享代码和组件。此外,使用 Shadow DOM 可以隐藏组件的渲染器和样式,从而使每个组件更加独立和可维护。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6748315d93696b0268ea02c5