From ee11d3449da45dcc3757e4caaa4f7e46d633fe94 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Sat, 28 May 2022 15:58:24 +0800 Subject: [PATCH 1/3] AutoCorrect files/zh-cn/web/api/webgl_api --- .../basic_2d_animation_example/index.html | 6 +- .../by_example/basic_scissoring/index.html | 2 +- .../by_example/boilerplate_1/index.html | 10 +- .../canvas_size_and_webgl/index.html | 12 +- .../clearing_by_clicking/index.html | 2 +- .../clearing_with_colors/index.html | 10 +- .../by_example/color_masking/index.html | 2 +- .../by_example/detect_webgl/index.html | 8 +- .../by_example/hello_glsl/index.html | 4 +- .../web/api/webgl_api/by_example/index.html | 4 +- .../by_example/scissor_animation/index.html | 6 +- .../simple_color_animation/index.html | 16 +-- .../web/api/webgl_api/constants/index.html | 48 +++---- files/zh-cn/web/api/webgl_api/data/index.html | 12 +- files/zh-cn/web/api/webgl_api/index.html | 74 +++++------ .../matrix_math_for_the_web/index.html | 80 ++++++------ .../index.html | 44 +++---- .../animating_objects_with_webgl/index.html | 6 +- .../animating_textures_in_webgl/index.html | 10 +- .../index.html | 8 +- .../getting_started_with_webgl/index.html | 26 ++-- .../web/api/webgl_api/tutorial/index.html | 38 +++--- .../tutorial/lighting_in_webgl/index.html | 20 +-- .../index.html | 8 +- .../using_textures_in_webgl/index.html | 38 +++--- .../zh-cn/web/api/webgl_api/types/index.html | 28 ++-- .../api/webgl_api/using_extensions/index.html | 6 +- .../webgl_api/webgl_best_practices/index.html | 16 +-- .../webgl_model_view_projection/index.html | 122 +++++++++--------- 29 files changed, 333 insertions(+), 333 deletions(-) diff --git a/files/zh-cn/web/api/webgl_api/basic_2d_animation_example/index.html b/files/zh-cn/web/api/webgl_api/basic_2d_animation_example/index.html index 0b0f4f4193c825..d0b0a2d4b91bcb 100644 --- a/files/zh-cn/web/api/webgl_api/basic_2d_animation_example/index.html +++ b/files/zh-cn/web/api/webgl_api/basic_2d_animation_example/index.html @@ -8,11 +8,11 @@
{{WebGLSidebar}}
-

在这个WebGL示例中,我们创建一个画布,并在其中使用WebGL渲染旋转正方形。我们用来表示场景的坐标系与画布的坐标系相同。也就是说,(0, 0)这个坐标在左上角,右下角是坐标在(600, 460)。

+

在这个 WebGL 示例中,我们创建一个画布,并在其中使用 WebGL 渲染旋转正方形。我们用来表示场景的坐标系与画布的坐标系相同。也就是说,(0, 0)这个坐标在左上角,右下角是坐标在(600, 460)。

Vertex shader

-

首先,让我们看一下顶点着色器。它的工作如同以往,是将我们用于场景的坐标转换为剪贴空间的坐标(即系统中的(0,0)位于上下文的中心,每个轴从-1.0扩展到1.0,而不管上下文的实际大小)。

+

首先,让我们看一下顶点着色器。它的工作如同以往,是将我们用于场景的坐标转换为剪贴空间的坐标(即系统中的(0,0)位于上下文的中心,每个轴从-1.0 扩展到 1.0,而不管上下文的实际大小)。

<script id="vertex-shader" type="x-shader/x-vertex">
   attribute vec2 aVertexPosition;
@@ -32,7 +32,7 @@ 

Vertex shader

} </script>
-

主程序与我们共享属性aVertexPosition,它是顶点在其使用的任何坐标系中的位置。我们需要转换这些值,以便位置的两个组件都在-1.0到1.0的范围内。通过乘以基于上下文宽高比的缩放因子,可以很容易地完成此操作。我们很快就会看到这个计算。

+

主程序与我们共享属性 aVertexPosition,它是顶点在其使用的任何坐标系中的位置。我们需要转换这些值,以便位置的两个组件都在-1.0 到 1.0 的范围内。通过乘以基于上下文宽高比的缩放因子,可以很容易地完成此操作。我们很快就会看到这个计算。

我们也可以通过一次变换来旋转这个图形。 The rotated position of the vertex is computed by applying the rotation vector, found in the uniform uRotationVector, that's been computed by the JavaScript code.

diff --git a/files/zh-cn/web/api/webgl_api/by_example/basic_scissoring/index.html b/files/zh-cn/web/api/webgl_api/by_example/basic_scissoring/index.html index 27a3b6441d10f3..b64d1b73251fb4 100644 --- a/files/zh-cn/web/api/webgl_api/by_example/basic_scissoring/index.html +++ b/files/zh-cn/web/api/webgl_api/by_example/basic_scissoring/index.html @@ -8,7 +8,7 @@
-

在本例中,我们将学会如何使用WebGL (scissoring operations)剪切操作来绘制简单的矩形和正方形。Scissoring建立了一个剪切区域,在此区域外不会发生绘图。

+

在本例中,我们将学会如何使用 WebGL(scissoring operations)剪切操作来绘制简单的矩形和正方形。Scissoring 建立了一个剪切区域,在此区域外不会发生绘图。

{{EmbedLiveSample("basic-scissoring-source",660,425)}}

diff --git a/files/zh-cn/web/api/webgl_api/by_example/boilerplate_1/index.html b/files/zh-cn/web/api/webgl_api/by_example/boilerplate_1/index.html index 21e306df30b226..3aaa54f124f273 100644 --- a/files/zh-cn/web/api/webgl_api/by_example/boilerplate_1/index.html +++ b/files/zh-cn/web/api/webgl_api/by_example/boilerplate_1/index.html @@ -7,21 +7,21 @@
-

这个例子描述了从现在开始将要隐藏重复的代码片断,以及定义一个JavaScript函数复用以简化WebGL初始化。

+

这个例子描述了从现在开始将要隐藏重复的代码片断,以及定义一个 JavaScript 函数复用以简化 WebGL 初始化。

{{EmbedLiveSample("boilerplate-1-source",660,400)}}

-

用于设置WebGL呈现上下文的复用代码

+

用于设置 WebGL 呈现上下文的复用代码

现在你很习惯看到相同的{{Glossary("HTML")}}, {{Glossary("CSS")}}和{{Glossary("JavaScript")}}重复一遍又一遍。所以我们从现在起要隐藏他们。这将使我们能够专注于代码最有趣的部分相关学习{{Glossary("WebGL")}}。

-

特别是,在HTML的{{HTMLElement("p")}}元素包含一些描述性的文本页面也可以是错误消息;一个{{HTMLElement("canvas")}} 元素;和一个可选的{{HTMLElement("button")}}。CSS规则包含bodycanvas, 和button。任何额外的冗余的CSS和HTML将不会显示在页面的具体的例子。

+

特别是,在 HTML 的{{HTMLElement("p")}}元素包含一些描述性的文本页面也可以是错误消息;一个{{HTMLElement("canvas")}} 元素;和一个可选的{{HTMLElement("button")}}。CSS 规则包含bodycanvas, 和button。任何额外的冗余的 CSS 和 HTML 将不会显示在页面的具体的例子。

-

在以下示例中,我们将使用一个JavaScript函数功能,getRenderingContext() ,来初始化{{domxref("WebGLRenderingContext","WebGL rendering context", "", 1)}}。现在,您应该能够了解什么功能。基本上,它得到了WebGL从画布元素,渲染上下文初始化绘图缓冲区,清除它黑色,并返回初始化上下文。在错误的情况下,它会显示一个错误消息,并返回 {{jsxref("null")}}。

+

在以下示例中,我们将使用一个 JavaScript 函数功能,getRenderingContext() ,来初始化{{domxref("WebGLRenderingContext","WebGL rendering context", "", 1)}}。现在,您应该能够了解什么功能。基本上,它得到了 WebGL 从画布元素,渲染上下文初始化绘图缓冲区,清除它黑色,并返回初始化上下文。在错误的情况下,它会显示一个错误消息,并返回 {{jsxref("null")}}。

-

最后,所有JavaScript代码将运行在一个直接的函数,这是一种常见的JavaScript技术(see {{Glossary("Function")}})。函数声明和调用也将被隐藏。

+

最后,所有 JavaScript 代码将运行在一个直接的函数,这是一种常见的 JavaScript 技术 (see {{Glossary("Function")}})。函数声明和调用也将被隐藏。

diff --git a/files/zh-cn/web/api/webgl_api/by_example/canvas_size_and_webgl/index.html b/files/zh-cn/web/api/webgl_api/by_example/canvas_size_and_webgl/index.html index 868a191d31fd9b..bf69360690e8a5 100644 --- a/files/zh-cn/web/api/webgl_api/by_example/canvas_size_and_webgl/index.html +++ b/files/zh-cn/web/api/webgl_api/by_example/canvas_size_and_webgl/index.html @@ -6,22 +6,22 @@

{{PreviousNext("Learn/WebGL/By_example/Basic_scissoring","Learn/WebGL/By_example/Boilerplate_1")}}

-

此WebGL案例将探究设置(或不设置)Canvas属性的宽高值在浏览器中显示的影响。

+

此 WebGL 案例将探究设置(或不设置)Canvas 属性的宽高值在浏览器中显示的影响。

{{EmbedLiveSample("canvas-size-and-webgl-source",660,180)}}

-

canvas属性值大小对WebGL渲染的作用

+

canvas 属性值大小对 WebGL 渲染的作用

-

使用 {{domxref("WebGLRenderingContext.scissor()","scissor()")}} 和 {{domxref("WebGLRenderingContext.clear()","clear()")}} 我们可以观察到canvas属性大小是如何影响WebGL绘图展示的。

+

使用 {{domxref("WebGLRenderingContext.scissor()","scissor()")}} 和 {{domxref("WebGLRenderingContext.clear()","clear()")}} 我们可以观察到 canvas 属性大小是如何影响 WebGL 绘图展示的。

-

第一个canvas元素通过css样式定义了元素的大小,之后通过javascript获取该元素的 {{domxref("Element.clientWidth","clientWidth")}} 和{{domxref("Element.clientHeight","clientHeight")}} 值,并分别赋值给元素的  {{domxref("HTMLCanvasElement.width","width")}} 和{{domxref("HTMLCanvasElement.height","height")}}。

+

第一个 canvas 元素通过 css 样式定义了元素的大小,之后通过 javascript 获取该元素的 {{domxref("Element.clientWidth","clientWidth")}} 和{{domxref("Element.clientHeight","clientHeight")}} 值,并分别赋值给元素的  {{domxref("HTMLCanvasElement.width","width")}} 和{{domxref("HTMLCanvasElement.height","height")}}。

-

相反的,第二个canvas元素并没有这样做,canvas内部对象的{{domxref("HTMLCanvasElement.width","width")}} 和 {{domxref("HTMLCanvasElement.height","height")}} 属性值仍然是默认值,这样导致在浏览器中实际画布大小是不同的。

+

相反的,第二个 canvas 元素并没有这样做,canvas 内部对象的{{domxref("HTMLCanvasElement.width","width")}} 和 {{domxref("HTMLCanvasElement.height","height")}} 属性值仍然是默认值,这样导致在浏览器中实际画布大小是不同的。

-

使用 {{domxref("WebGLRenderingContext.scissor()","scissor()")}} 和{{domxref("WebGLRenderingContext.clear()","clear()")}}在canvas中绘制矩形的效果是清晰可见的,在第一个canvas中,通过指定位置和像素大小,可以得到我们想要的效果,但是在第二个canvas中,这个矩形的位置、大小都是错误展示的。

+

使用 {{domxref("WebGLRenderingContext.scissor()","scissor()")}} 和{{domxref("WebGLRenderingContext.clear()","clear()")}}在 canvas 中绘制矩形的效果是清晰可见的,在第一个 canvas 中,通过指定位置和像素大小,可以得到我们想要的效果,但是在第二个 canvas 中,这个矩形的位置、大小都是错误展示的。

diff --git a/files/zh-cn/web/api/webgl_api/by_example/clearing_by_clicking/index.html b/files/zh-cn/web/api/webgl_api/by_example/clearing_by_clicking/index.html index d4a2f6ceb4f4b6..28403d37245dbb 100644 --- a/files/zh-cn/web/api/webgl_api/by_example/clearing_by_clicking/index.html +++ b/files/zh-cn/web/api/webgl_api/by_example/clearing_by_clicking/index.html @@ -7,7 +7,7 @@
-

此示例演示了如何通过用户单击时用随机颜色渲染上下文来将用户交互与WebGL图形操作结合起来。

+

此示例演示了如何通过用户单击时用随机颜色渲染上下文来将用户交互与 WebGL 图形操作结合起来。

{{EmbedLiveSample("clearing-by-clicking-source",660,425)}}

diff --git a/files/zh-cn/web/api/webgl_api/by_example/clearing_with_colors/index.html b/files/zh-cn/web/api/webgl_api/by_example/clearing_with_colors/index.html index 147cfd6cf4d5ac..da89a2233ff5c0 100644 --- a/files/zh-cn/web/api/webgl_api/by_example/clearing_with_colors/index.html +++ b/files/zh-cn/web/api/webgl_api/by_example/clearing_with_colors/index.html @@ -13,15 +13,15 @@

{{EmbedLiveSample("clearing-with-colors-source",660,425)}}

-

清除画布(使用单一颜色清除WebGl区域)

+

清除画布(使用单一颜色清除 WebGl 区域)

-

这是一个最简单的WebGL代码。通过{{domxref("WebGLRenderingContext","rendering context", "", 1)}}设置好状态后,直接将整个区域清除为绿色。要注意css 已经将canvas画布设置为黑色了,所以当画布变为绿色时,我们就知道神奇的WebGL魔法起作用了!

+

这是一个最简单的 WebGL 代码。通过{{domxref("WebGLRenderingContext","rendering context", "", 1)}}设置好状态后,直接将整个区域清除为绿色。要注意 css 已经将 canvas 画布设置为黑色了,所以当画布变为绿色时,我们就知道神奇的 WebGL 魔法起作用了!

-

此外,你需要注意用单色绘制图像是两个步骤:首先,通过使用{{domxref("WebGLRenderingContext.clearColor()","clearColor()")}}设置清除色为绿色。这只会改变Webgl 内部的一个状态,但并不会绘制任何东西。接下来,我们就真的开始绘制了,使用{{domxref("WebGLRenderingContext.clear()","clear()")}}方法,这是一个典型的用webgl绘制的方法,webgl 实际上只有少数的几个绘制方法(clear() 就是其中之一)。其他方法大多都是类似设置或改变WebGl状态和变量的(例如设置clearcolor)。

+

此外,你需要注意用单色绘制图像是两个步骤:首先,通过使用{{domxref("WebGLRenderingContext.clearColor()","clearColor()")}}设置清除色为绿色。这只会改变 Webgl 内部的一个状态,但并不会绘制任何东西。接下来,我们就真的开始绘制了,使用{{domxref("WebGLRenderingContext.clear()","clear()")}}方法,这是一个典型的用 webgl 绘制的方法,webgl 实际上只有少数的几个绘制方法 (clear() 就是其中之一)。其他方法大多都是类似设置或改变 WebGl 状态和变量的(例如设置 clearcolor)。

-

这里有许多属性和方法作用于Webgl,清除方法只是你第一个掌握的,这也就是为什么WebGL/OpenGl经常被叫做状态机,通过调整这些属性和方法可以修改WebGL内部的状态,从而进行输出(例如先设置好绿色,在清除画布的时候像素点都变成了绿色)

+

这里有许多属性和方法作用于 Webgl,清除方法只是你第一个掌握的,这也就是为什么 WebGL/OpenGl 经常被叫做状态机,通过调整这些属性和方法可以修改 WebGL 内部的状态,从而进行输出(例如先设置好绿色,在清除画布的时候像素点都变成了绿色)

-

最后,我们知道在WebGl中颜色格式是由RGBA(红,绿,蓝,透明度)组成的,因此clearColor()方法接受四个参数

+

最后,我们知道在 WebGl 中颜色格式是由 RGBA(红,绿,蓝,透明度)组成的,因此 clearColor() 方法接受四个参数

 

diff --git a/files/zh-cn/web/api/webgl_api/by_example/color_masking/index.html b/files/zh-cn/web/api/webgl_api/by_example/color_masking/index.html index 2853cf45c58039..1a8a8571bb2d57 100644 --- a/files/zh-cn/web/api/webgl_api/by_example/color_masking/index.html +++ b/files/zh-cn/web/api/webgl_api/by_example/color_masking/index.html @@ -7,7 +7,7 @@
-

这个 WebGL 示例 通过随机的颜色(random colors)应用到colorMask,从而将显示的颜色范围限制在特定的颜色通道(red/green/blue);

+

这个 WebGL 示例 通过随机的颜色 (random colors) 应用到 colorMask,从而将显示的颜色范围限制在特定的颜色通道 (red/green/blue);

{{EmbedLiveSample("color-masking-source",660,425)}}

diff --git a/files/zh-cn/web/api/webgl_api/by_example/detect_webgl/index.html b/files/zh-cn/web/api/webgl_api/by_example/detect_webgl/index.html index ded47c2674ee2a..80b56a1653408f 100644 --- a/files/zh-cn/web/api/webgl_api/by_example/detect_webgl/index.html +++ b/files/zh-cn/web/api/webgl_api/by_example/detect_webgl/index.html @@ -1,5 +1,5 @@ --- -title: 检测WebGL +title: 检测 WebGL slug: Web/API/WebGL_API/By_example/Detect_WebGL translation_of: Web/API/WebGL_API/By_example/Detect_WebGL --- @@ -13,11 +13,11 @@

{{EmbedLiveSample("detect-webgl-source",660,150)}}

-

WebGL特性检测

+

WebGL 特性检测

-

在第一个例子中,我们将检查浏览器是否支持{{Glossary("WebGL")}}。为此,我们将尝试从{{domxref("HTMLCanvasElement","canvas")}}元素获取{{domxref("WebGLRenderingContext","WebGL渲染的上下文","",1)}} 。{{domxref("WebGLRenderingContext","WebGL渲染的上下文", "", 1)}}是一个接口,通过它你可以设置和查询绘图器的状态,发送数据到WebGL,执行绘制命令。

+

在第一个例子中,我们将检查浏览器是否支持{{Glossary("WebGL")}}。为此,我们将尝试从{{domxref("HTMLCanvasElement","canvas")}}元素获取{{domxref("WebGLRenderingContext","WebGL 渲染的上下文","",1)}} 。{{domxref("WebGLRenderingContext","WebGL 渲染的上下文", "", 1)}}是一个接口,通过它你可以设置和查询绘图器的状态,发送数据到 WebGL,执行绘制命令。

-

在单个上下文接口中保存绘图器的状态并不是{{Glossary("WebGL")}}独有的。这在其他绘图技术里也是存在的{{Glossary("API")}},比如{{domxref("CanvasRenderingContext2D","2D渲染上下文的canvas", "", 1)}}。然而,您可以调整的属性和变量对于每个{{Glossary("API")}}来说都是不同的。

+

在单个上下文接口中保存绘图器的状态并不是{{Glossary("WebGL")}}独有的。这在其他绘图技术里也是存在的{{Glossary("API")}},比如{{domxref("CanvasRenderingContext2D","2D 渲染上下文的 canvas", "", 1)}}。然而,您可以调整的属性和变量对于每个{{Glossary("API")}}来说都是不同的。

diff --git a/files/zh-cn/web/api/webgl_api/by_example/hello_glsl/index.html b/files/zh-cn/web/api/webgl_api/by_example/hello_glsl/index.html index 214966b9c4ee11..e599d451445a7d 100644 --- a/files/zh-cn/web/api/webgl_api/by_example/hello_glsl/index.html +++ b/files/zh-cn/web/api/webgl_api/by_example/hello_glsl/index.html @@ -11,13 +11,13 @@
-

注意:本例子能在大多数现代桌面版浏览器上运行。但或许不能在移动端或者古老的浏览器上运行。如果canvas显示一片空白,你可以试着用下一个例子检查一下输出是否绘制的是同样的图形。 但要记住在前往下一个例子之前,要仔细阅读本页并动手写代码。

+

注意:本例子能在大多数现代桌面版浏览器上运行。但或许不能在移动端或者古老的浏览器上运行。如果 canvas 显示一片空白,你可以试着用下一个例子检查一下输出是否绘制的是同样的图形。 但要记住在前往下一个例子之前,要仔细阅读本页并动手写代码。

{{EmbedLiveSample("hello-glsl-source",660,425)}}

-

用GLSL语言写Hello World 程序

+

用 GLSL 语言写 Hello World 程序

第一个非常简单的着色器程序。

diff --git a/files/zh-cn/web/api/webgl_api/by_example/index.html b/files/zh-cn/web/api/webgl_api/by_example/index.html index a6a02b0055fa12..70a9eab0883b6d 100644 --- a/files/zh-cn/web/api/webgl_api/by_example/index.html +++ b/files/zh-cn/web/api/webgl_api/by_example/index.html @@ -7,7 +7,7 @@
-

WebGL 例子是一系列附有简短的解释的样本用来展示WebGL的概念和功能。这些示例根据主题和难度级别进行排序,涵盖WebGL渲染上下文,着色器编程,纹理,几何图形,用户交互等。

+

WebGL 例子是一系列附有简短的解释的样本用来展示 WebGL 的概念和功能。这些示例根据主题和难度级别进行排序,涵盖 WebGL 渲染上下文,着色器编程,纹理,几何图形,用户交互等。

@@ -15,7 +15,7 @@

主题例子

这些范例是有浅到深的,它们除了是一个个可以让你实现的例子外,还和主题高度重合,当我们需要在中级和高级阶段实现这个例子时有时我们会重复此例子的基础内容。

-

在第一个程序中,并没有尝试着色着色器,几何图形和使用{{Glossary("GPU")}} 内存,这里的示例以渐进的方式探索WebGL。我们相信它会带来更有效的学习体验,并最终更深入地理解底层概念。

+

在第一个程序中,并没有尝试着色着色器,几何图形和使用{{Glossary("GPU")}} 内存,这里的示例以渐进的方式探索 WebGL。我们相信它会带来更有效的学习体验,并最终更深入地理解底层概念。

有关这些例子的解释可以在代码的正文和注释中找到。您应该阅读所有注释,因为更高级的示例不会重复注释以前的代码。

diff --git a/files/zh-cn/web/api/webgl_api/by_example/scissor_animation/index.html b/files/zh-cn/web/api/webgl_api/by_example/scissor_animation/index.html index b5084a249699e5..91b2c3a616da70 100644 --- a/files/zh-cn/web/api/webgl_api/by_example/scissor_animation/index.html +++ b/files/zh-cn/web/api/webgl_api/by_example/scissor_animation/index.html @@ -7,7 +7,7 @@
-

使用剪切和清除操作实现一些动画的简单WebGL的例子。

+

使用剪切和清除操作实现一些动画的简单 WebGL 的例子。

{{EmbedLiveSample("scissor-animation-source",660,425)}}

@@ -15,9 +15,9 @@

剪切动画

-

本例中,我们使用{{domxref("WebGLRenderingContext.scissor()","scissor()")}} 和 {{domxref("WebGLRenderingContext.clear()","clear()")}}。我们再次建立一个动画循环使用计时器。注意,这次是方块的位置(剪切区)更新每一帧(我们设置帧率大约每17毫秒,约60 fps -帧每秒)

+

本例中,我们使用{{domxref("WebGLRenderingContext.scissor()","scissor()")}} 和 {{domxref("WebGLRenderingContext.clear()","clear()")}}。我们再次建立一个动画循环使用计时器。注意,这次是方块的位置 (剪切区) 更新每一帧 (我们设置帧率大约每 17 毫秒,约 60 fps -帧每秒)

-

相比之下,方块的颜色(用{{domxref("WebGLRenderingContext.clearColor()","clearColor")}})仅创建一个新的方块。这是一个很好的演示{{Glossary("WebGL")}}是一个状态机。对于每一个方块,我们设置它的颜色,然后只更新它的位置每一帧。WebGL的清晰的颜色状态维持在设定值,直到我们再次改变它创建一个新的方块。

+

相比之下,方块的颜色 (用{{domxref("WebGLRenderingContext.clearColor()","clearColor")}}) 仅创建一个新的方块。这是一个很好的演示{{Glossary("WebGL")}}是一个状态机。对于每一个方块,我们设置它的颜色,然后只更新它的位置每一帧。WebGL 的清晰的颜色状态维持在设定值,直到我们再次改变它创建一个新的方块。

diff --git a/files/zh-cn/web/api/webgl_api/by_example/simple_color_animation/index.html b/files/zh-cn/web/api/webgl_api/by_example/simple_color_animation/index.html index 77c11056eeb256..9eb38c48cb8422 100644 --- a/files/zh-cn/web/api/webgl_api/by_example/simple_color_animation/index.html +++ b/files/zh-cn/web/api/webgl_api/by_example/simple_color_animation/index.html @@ -7,7 +7,7 @@
-

这是一个非常基础的{{Glossary("WebGL")}}色彩动画案例, 通过定时器来逐秒填充不同的颜色来实现.

+

这是一个非常基础的{{Glossary("WebGL")}}色彩动画案例,通过定时器来逐秒填充不同的颜色来实现。

{{EmbedLiveSample("simple-color-animation-source",660,425)}}

@@ -15,15 +15,15 @@

通过填充实现色彩动画

-

本案例使用{{Glossary("WebGL")}}来实现简单的色彩动画和用户交互效果,用户可以通过按按钮来开始/暂停/重新开始动画.

+

本案例使用{{Glossary("WebGL")}}来实现简单的色彩动画和用户交互效果,用户可以通过按按钮来开始/暂停/重新开始动画。

-

我们把 {{Glossary("WebGL")}}函数放在一个定时循环器里(setInterval)。通过监听点击事件来让用户开始/暂停动画.并通过定时器来循环执行绘制指令(通常是逐帧动画,这次我们设置为逐秒动画) 

+

我们把 {{Glossary("WebGL")}}函数放在一个定时循环器里 (setInterval)。通过监听点击事件来让用户开始/暂停动画。并通过定时器来循环执行绘制指令 (通常是逐帧动画,这次我们设置为逐秒动画) 

-
<p>一个色彩动画的简单WebGl程序</p>
+
<p>一个色彩动画的简单 WebGl 程序</p>
 <p>点击下面的按钮来开/关动画</p>
-<canvas id="canvas-view">你的浏览器不支持Html5 canvas</canvas>
+<canvas id="canvas-view">你的浏览器不支持 Html5 canvas</canvas>
 <button id="animation-onoff">
   点我来
 <strong>[verb goes here]</strong>
@@ -55,7 +55,7 @@ 

通过填充实现色彩动画

"use strict" window.removeEventListener(evt.type, setupAnimation, false); - // 定义一个变量来保存定时器,以播放动画 + // 定义一个变量来保存定时器,以播放动画 var timer; // 点击事件处理器 @@ -77,7 +77,7 @@

通过填充实现色彩动画

// 通过清除定时器来停止动画 clearInterval(timer); } - // 调用stopAnimation() 来初始化按钮的事件处理器 + // 调用 stopAnimation() 来初始化按钮的事件处理器 stopAnimation({type: "click"}); var gl; @@ -98,7 +98,7 @@

通过填充实现色彩动画

// 使用辅助函数 得到随机颜色 var color = getRandomColor(); - // 将随机颜色设置到WebGL渲染上下文的填充颜色上去 + // 将随机颜色设置到 WebGL 渲染上下文的填充颜色上去 gl.clearColor(color[0], color[1], color[2], 1.0); // 使用新设置的颜色来清除上下文 gl.clear(gl.COLOR_BUFFER_BIT); diff --git a/files/zh-cn/web/api/webgl_api/constants/index.html b/files/zh-cn/web/api/webgl_api/constants/index.html index 14666b987cba77..804b22a74dbe09 100644 --- a/files/zh-cn/web/api/webgl_api/constants/index.html +++ b/files/zh-cn/web/api/webgl_api/constants/index.html @@ -7,7 +7,7 @@

WebGL API 提供了一些常量,这些常量常作为参数传入函数调用,或常作为函数的返回值。所有这些常量都是 {{domxref("GLenum")}} 类型。

-

标准WebGL常量挂载在WebGL的两个渲染上下文环境({{domxref("WebGLRenderingContext")}} 和{{domxref("WebGL2RenderingContext")}})中,因此,以形如gl.CONSTANT_NAME的形式使用WebGL常量:

+

标准 WebGL 常量挂载在 WebGL 的两个渲染上下文环境({{domxref("WebGLRenderingContext")}} 和{{domxref("WebGL2RenderingContext")}})中,因此,以形如gl.CONSTANT_NAME的形式使用 WebGL 常量:

var canvas = document.getElementById('myCanvas');
 var gl = canvas.getContext('webgl');
@@ -20,7 +20,7 @@
 
var debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
 var vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);
-

WebGL tutorial 中有更多关于WebGL的信息,示例和如何开始WebGL编程的其它资源。

+

WebGL tutorial 中有更多关于 WebGL 的信息,示例和如何开始 WebGL 编程的其它资源。

常量表

@@ -106,7 +106,7 @@

指定渲染图元 Rendering pr TRIANGLE_STRIP 0x0005 - 传递给drawElements或drawArrays 画一组相连的三角形带。 + 传递给drawElements 或drawArrays 画一组相连的三角形带。 TRIANGLE_FAN @@ -120,7 +120,7 @@

指定渲染图元 Rendering pr

混合模式

-

传递给 {{domxref("WebGLRenderingContext.blendFunc()")}} 或{{domxref("WebGLRenderingContext.blendFuncSeparate()")}} 的常量来指定混合模式 (同时用于或分别用于RBG和alpha).

+

传递给 {{domxref("WebGLRenderingContext.blendFunc()")}} 或{{domxref("WebGLRenderingContext.blendFuncSeparate()")}} 的常量来指定混合模式 (同时用于或分别用于 RBG 和 alpha).

@@ -149,27 +149,27 @@

混合模式

- + - + - + - + - + @@ -179,12 +179,12 @@

混合模式

- + - + @@ -194,24 +194,24 @@

混合模式

- + - + - +
ONE_MINUS_SRC_COLOR 0x0301传递给 blendFunc 或 blendFuncSeparate 以将分量乘以1 减去源颜色分量。传递给 blendFunc 或 blendFuncSeparate 以将分量乘以 1 减去源颜色分量。
SRC_ALPHA 0x0302传递给 blendFunc 或 blendFuncSeparate 以将分量乘以源颜色的 alpha值。传递给 blendFunc 或 blendFuncSeparate 以将分量乘以源颜色的 alpha 值。
ONE_MINUS_SRC_ALPHA 0x0303传递给 blendFunc 或 blendFuncSeparate 以将分量乘以一个源颜色的 alpha值。传递给 blendFunc 或 blendFuncSeparate 以将分量乘以一个源颜色的 alpha 值。
DST_ALPHA 0x0304传递给 blendFunc 或 blendFuncSeparate 以将分量乘以目标颜色的alpha值。传递给 blendFunc 或 blendFuncSeparate 以将分量乘以目标颜色的 alpha 值。
ONE_MINUS_DST_ALPHA 0x0305传递给 blendFunc 或 blendFuncSeparate 以将分量乘以1减去目标颜色的alpha值。传递给 blendFunc 或 blendFuncSeparate 以将分量乘以 1 减去目标颜色的 alpha 值。
DST_COLOR
ONE_MINUS_DST_COLOR 0x0307传递给 blendFuncblendFuncSeparate 以将分量乘以1减去目标颜色分量。传递给 blendFuncblendFuncSeparate 以将分量乘以 1 减去目标颜色分量。
SRC_ALPHA_SATURATE 0x0308传递给 blendFuncblendFuncSeparate 以将分量乘以源颜色alpha与目标颜色alpha中的最小值。传递给 blendFuncblendFuncSeparate 以将分量乘以源颜色 alpha 与目标颜色 alpha 中的最小值。
CONSTANT_COLOR
ONE_MINUS_CONSTANT_COLOR 0x8002传递给 blendFuncblendFuncSeparate 以指定1减去常量颜色的混合函数。传递给 blendFuncblendFuncSeparate 以指定 1 减去常量颜色的混合函数。
CONSTANT_ALPHA 0x8003传递给 blendFuncblendFuncSeparate 以指定常量alpha混合函数。传递给 blendFuncblendFuncSeparate 以指定常量 alpha 混合函数。
ONE_MINUS_CONSTANT_ALPHA 0x8004传递给 blendFuncblendFuncSeparate 以指定1减去一个常量alpha的混合函数。传递给 blendFuncblendFuncSeparate 以指定 1 减去一个常量 alpha 的混合函数。

混合方程

-

传递给 {{domxref("WebGLRenderingContext.blendEquation()")}} 或 {{domxref("WebGLRenderingContext.blendEquationSeparate()")}} 的常量,以控制混合的计算方式(同时用于或分别用于RBG和alpha)。

+

传递给 {{domxref("WebGLRenderingContext.blendEquation()")}} 或 {{domxref("WebGLRenderingContext.blendEquationSeparate()")}} 的常量,以控制混合的计算方式(同时用于或分别用于 RBG 和 alpha)。

@@ -256,37 +256,37 @@

获取 GL 参数信息

- + - + - + - + - + - + - + @@ -316,7 +316,7 @@

获取 GL 参数信息

- + @@ -331,7 +331,7 @@

获取 GL 参数信息

- + diff --git a/files/zh-cn/web/api/webgl_api/data/index.html b/files/zh-cn/web/api/webgl_api/data/index.html index c9d4b0a08d6710..41c7ba12d71c03 100644 --- a/files/zh-cn/web/api/webgl_api/data/index.html +++ b/files/zh-cn/web/api/webgl_api/data/index.html @@ -19,19 +19,19 @@ ---
{{WebGLSidebar}}
-

GLSL 为 Shader 提供了三种不同作用的数据存储,每种都有一个特定的用例。每种数据依作用不同可以被一种或者全部shader访问(取决于数据存储类型),也可能通过站点的Javascript代码进行访问,这取决于变量的特定类型。

+

GLSL 为 Shader 提供了三种不同作用的数据存储,每种都有一个特定的用例。每种数据依作用不同可以被一种或者全部 shader 访问(取决于数据存储类型),也可能通过站点的 Javascript 代码进行访问,这取决于变量的特定类型。

GLSL 数据类型

-

<<关于 基本数据类型, 向量等,参见Khronos WebGL Wiki的文档:Data Type (GLSL) >>

+

<<关于 基本数据类型,向量等,参见 Khronos WebGL Wiki 的文档:Data Type (GLSL) >>

GLSL 变量

-

GLSL中有三种类型的“变量”或者说数据存储类型。每一种类型都有特定的目标和使用方法:: attributesvaryingsuniforms.

+

GLSL 中有三种类型的“变量”或者说数据存储类型。每一种类型都有特定的目标和使用方法:: attributesvaryingsuniforms.

Attributes

-

Attributes 可以被JavaScript代码操作,也可以在 vertex shader 中被作为变量访问。Attributes 通常被用于存储颜色、纹理坐标以及其他需要在JavaScript代码和 vertex shader 之间互相传递的数据。

+

Attributes 可以被 JavaScript 代码操作,也可以在 vertex shader 中被作为变量访问。Attributes 通常被用于存储颜色、纹理坐标以及其他需要在 JavaScript 代码和 vertex shader 之间互相传递的数据。

//init colors
     var vertexColors = [
@@ -70,13 +70,13 @@ 

Attributes

Varyings

-

Varyings 在 vertex shader 中定义,用于从 vertex shader 向 fragment shader 传递数据。通常传递 {{interwiki("wikipedia", "Normal_(geometry)", "normal vector")}} 等在 vertex shader 中计算生成的数据会使用varying。

+

Varyings 在 vertex shader 中定义,用于从 vertex shader 向 fragment shader 传递数据。通常传递 {{interwiki("wikipedia", "Normal_(geometry)", "normal vector")}} 等在 vertex shader 中计算生成的数据会使用 varying。

<<how to use>>

Uniforms

-

Uniform 通常是由 JavaScript 代码设置并且在 vertex shader 和 fragment shader 中都能够访问。 使用uniform设定在一帧的所有绘制中相同的数据,例如光源颜色、亮度、全局变换以及透视数据等等。

+

Uniform 通常是由 JavaScript 代码设置并且在 vertex shader 和 fragment shader 中都能够访问。 使用 uniform 设定在一帧的所有绘制中相同的数据,例如光源颜色、亮度、全局变换以及透视数据等等。

<<添加细节>>

diff --git a/files/zh-cn/web/api/webgl_api/index.html b/files/zh-cn/web/api/webgl_api/index.html index e99bdcb3ae15cd..e979031d350925 100644 --- a/files/zh-cn/web/api/webgl_api/index.html +++ b/files/zh-cn/web/api/webgl_api/index.html @@ -2,7 +2,7 @@ title: WebGL slug: Web/API/WebGL_API tags: - - 3D图形 + - 3D 图形 - WebGL - WebGL API - 图像 @@ -14,14 +14,14 @@
{{WebGLSidebar}}
-

WebGL(Web图形库)是一个JavaScript API,可在任何兼容的Web浏览器中渲染高性能的交互式3D和2D图形,而无需使用插件。WebGL通过引入一个与OpenGL ES 2.0非常一致的API来做到这一点,该API可以在HTML5 {{HTMLElement("canvas")}}元素中使用。 这种一致性使API可以利用用户设备提供的硬件图形加速。

+

WebGL(Web 图形库)是一个 JavaScript API,可在任何兼容的 Web 浏览器中渲染高性能的交互式 3D 和 2D 图形,而无需使用插件。WebGL 通过引入一个与 OpenGL ES 2.0 非常一致的 API 来做到这一点,该 API 可以在 HTML5 {{HTMLElement("canvas")}}元素中使用。 这种一致性使 API 可以利用用户设备提供的硬件图形加速。

-

目前支持 WebGL 的浏览器有:Firefox 4+, Google Chrome 9+, Opera 12+, Safari 5.1+, Internet Explorer 11+和Microsoft Edge build 10240+;然而, WebGL一些特性也需要用户的硬件设备支持。

+

目前支持 WebGL 的浏览器有:Firefox 4+, Google Chrome 9+, Opera 12+, Safari 5.1+, Internet Explorer 11+ 和Microsoft Edge build 10240+;然而,WebGL 一些特性也需要用户的硬件设备支持。

-

WebGL 2 API引入了对大部分的OpenGL ES 3.0功能集的支持; 它是通过{{domxref("WebGL2RenderingContext")}}界面提供的。

+

WebGL 2 API 引入了对大部分的 OpenGL ES 3.0 功能集的支持; 它是通过{{domxref("WebGL2RenderingContext")}}界面提供的。

-

 {{HTMLElement("canvas")}} 元素也被 Canvas API 用于在网页上进行2D图形处理。

+

 {{HTMLElement("canvas")}} 元素也被 Canvas API 用于在网页上进行 2D 图形处理。

参考

@@ -102,13 +102,13 @@

事件

常量和类型

WebGL 2

-

WebGL 2 是WebGL的一个主要更新,它通过{{domxref("WebGL2RenderingContext")}} 接口提供。它基于OpenGL ES 3.0,新功能包括:

+

WebGL 2 是 WebGL 的一个主要更新,它通过{{domxref("WebGL2RenderingContext")}} 接口提供。它基于 OpenGL ES 3.0,新功能包括:

  • 3D textures,
  • @@ -124,15 +124,15 @@

    WebGL 2

    指南和教程

    -

    下面,您将找到各种指南,以帮助您学习WebGL概念和教程,提供分步课程和示例。

    +

    下面,您将找到各种指南,以帮助您学习 WebGL 概念和教程,提供分步课程和示例。

    指南 

    WebGL 中的数据
    -
    编写WebGL代码时使用的变量,缓冲区和其他类型数据的指南。
    +
    编写 WebGL 代码时使用的变量,缓冲区和其他类型数据的指南。
    WebGL 最佳实践
    -
    提示和建议,以帮助您提高WebGL内容的质量,性能和可靠性。
    +
    提示和建议,以帮助您提高 WebGL 内容的质量,性能和可靠性。
    使用扩展
    WebGL 扩展的使用指南。
    @@ -149,43 +149,43 @@

    示例

    一个基础的 WebGL 的 2D 动画示例
    此示例演示了单色形状的简单动画。检查的主题是适应宽高比差异,从多个着色器集合构建着色器程序的功能,以及 WebGL 绘图的基础知识。
    -
    WebGL示例
    -
    一系列带有简短说明的实时示例展示了WebGL的概念和功能。根据主题和难易程度对示例进行了排序,涵盖了WebGL渲染上下文,着色器编程,纹理,几何图形,用户交互等。
    +
    WebGL 示例
    +
    一系列带有简短说明的实时示例展示了 WebGL 的概念和功能。根据主题和难易程度对示例进行了排序,涵盖了 WebGL 渲染上下文,着色器编程,纹理,几何图形,用户交互等。

    高级教程

    WebGL 模型视图投影
    -
    详述了常用于显示3D物体视图的三种核心矩阵:模型,视图和投影矩阵。
    +
    详述了常用于显示 3D 物体视图的三种核心矩阵:模型,视图和投影矩阵。
    Web 中的矩阵运算
    -
    讲述 3D 变换矩阵工作原理的指南 —— 这也能在WebGL计算和CSS3变换中派上用场。
    +
    讲述 3D 变换矩阵工作原理的指南 —— 这也能在 WebGL 计算和 CSS3 变换中派上用场。

    资源

      -
    • Raw WebGL: WebGL入门 Nick Desaulniers 主讲的WebGL 基础知识。如果你从未接触过底层的图形编程,这是一个开始学习初级图形编程的好地方。
    • -
    • WebGL官网 Khronos Group 的WebGL官方站点。
    • -
    • 学习WebGL 一个关于如何使用WebGL的教程站点。
    • -
    • WebGL基础 一个关于WebGL的基础教程。
    • -
    • WebGL试炼 一个在线创建和分享WebGL的工具站点,非常适合快速创建一个原型或者体验一个成品。
    • -
    • WebGL Academy 通过一个 HTML/JavaScript 编辑器来学习一个基础的WebGl基础知识。
    • -
    • WebGL Stats 一个统计WebGL在不同平台上能力表现的网站。
    • +
    • Raw WebGL: WebGL 入门 Nick Desaulniers 主讲的 WebGL 基础知识。如果你从未接触过底层的图形编程,这是一个开始学习初级图形编程的好地方。
    • +
    • WebGL 官网 Khronos Group 的 WebGL 官方站点。
    • +
    • 学习 WebGL 一个关于如何使用 WebGL 的教程站点。
    • +
    • WebGL 基础 一个关于 WebGL 的基础教程。
    • +
    • WebGL 试炼 一个在线创建和分享 WebGL 的工具站点,非常适合快速创建一个原型或者体验一个成品。
    • +
    • WebGL Academy 通过一个 HTML/JavaScript 编辑器来学习一个基础的 WebGl 基础知识。
    • +
    • WebGL Stats 一个统计 WebGL 在不同平台上能力表现的网站。

      -
    • glMatrix 创建高性能WebGL应用的JavaScript矩阵矢量库。
    • -
    • PhiloGL 一个用于数据可视化、创意编程和游戏开发的WebGL库。
    • -
    • Pixi.js是一种快速的开源2D WebGL渲染器。
    • +
    • glMatrix 创建高性能 WebGL 应用的 JavaScript 矩阵矢量库。
    • +
    • PhiloGL 一个用于数据可视化、创意编程和游戏开发的 WebGL 库。
    • +
    • Pixi.js是一种快速的开源 2D WebGL 渲染器。
    • PlayCanvas是一个开源游戏引擎。
    • -
    • Sylvester是一个用于处理向量和矩阵的开源库。尚未针对WebGL进行优化,但功能极其强大。
    • -
    • three.js是一个开源的,功能齐全的3D WebGL库。
    • -
    • Phaser是一个适用于Canvas和WebGL的浏览器游戏的快速,免费和有趣的开源框架。
    • -
    • RedGL  是一个开源3D WebGL库。
    • -
    • vtk.js  是一个JavaScript库,用于在浏览器中进行科学可视化。
    • +
    • Sylvester是一个用于处理向量和矩阵的开源库。尚未针对 WebGL 进行优化,但功能极其强大。
    • +
    • three.js是一个开源的,功能齐全的 3D WebGL 库。
    • +
    • Phaser是一个适用于 Canvas 和 WebGL 的浏览器游戏的快速,免费和有趣的开源框架。
    • +
    • RedGL  是一个开源 3D WebGL 库。
    • +
    • vtk.js  是一个 JavaScript 库,用于在浏览器中进行科学可视化。

    规范

    @@ -243,25 +243,25 @@

    WebGL 2

    兼容性说明

    -

    不仅是浏览器,GPU本身也需要支持该特性。比如 S3 纹理压缩 (S3TC) 只在基于图睿的GPU的设备上可用。大多数浏览器可以通过 webgl 这一上下文名称来使用 WebGL,但是旧的浏览器需要使用 experimental-webgl。另外,将来的 WebGL 2 只会向后兼容,其使用的上下文名称为 webgl2 。

    +

    不仅是浏览器,GPU 本身也需要支持该特性。比如 S3 纹理压缩 (S3TC) 只在基于图睿的 GPU 的设备上可用。大多数浏览器可以通过 webgl 这一上下文名称来使用 WebGL,但是旧的浏览器需要使用 experimental-webgl。另外,将来的 WebGL 2 只会向后兼容,其使用的上下文名称为 webgl2 。

    -

    Gecko备忘

    +

    Gecko 备忘

    -

    WebGL调试与检测

    +

    WebGL 调试与检测

    -

    开始使用Gecko 10.0 {{geckoRelease("10.0")}}, 在测试中,这里有两个参数可以让你来控制WebGL性能:

    +

    开始使用 Gecko 10.0 {{geckoRelease("10.0")}}, 在测试中,这里有两个参数可以让你来控制 WebGL 性能:

    webgl.min_capability_mode
    -
    一个以布尔值存储的属性。当它的值为True时,将会启用最小性能模式。当这个模式启用时,WebGL将会仅提供由其标准指定的最基本的功能集和性能支持。这样可以确保您的WebGL代码能够在性能的设备和浏览器上正确运行。它的默认值是False
    +
    一个以布尔值存储的属性。当它的值为True时,将会启用最小性能模式。当这个模式启用时,WebGL 将会仅提供由其标准指定的最基本的功能集和性能支持。这样可以确保您的 WebGL 代码能够在性能的设备和浏览器上正确运行。它的默认值是False
    webgl.disable_extensions
    -
    一个以布尔值存储的属性。当它的值为True时,会禁用所有的WebGL拓展。它的默认值是False
    +
    一个以布尔值存储的属性。当它的值为True时,会禁用所有的 WebGL 拓展。它的默认值是False

    参见

    diff --git a/files/zh-cn/web/api/webgl_api/matrix_math_for_the_web/index.html b/files/zh-cn/web/api/webgl_api/matrix_math_for_the_web/index.html index 26472a5c15cf22..6e1674651de10c 100644 --- a/files/zh-cn/web/api/webgl_api/matrix_math_for_the_web/index.html +++ b/files/zh-cn/web/api/webgl_api/matrix_math_for_the_web/index.html @@ -10,13 +10,13 @@ ---

    {{WebGLSidebar}}

    -

    矩阵可以用于表示空间中的对象的变换,并且是Web页面可视化的重要工具。本文探索如何创建并配合CSS3变换和matrix3d变换类型使用矩阵。

    +

    矩阵可以用于表示空间中的对象的变换,并且是 Web 页面可视化的重要工具。本文探索如何创建并配合CSS3 变换和 matrix3d 变换类型使用矩阵。

    -

    虽然本文为了便于解释而使用了CSS3, 矩阵却是许多技术中的核心概念, 包括WebGL和着色器。本文也是MDN content kit的一部分。示例使用了一组全局对象MDN下的工具函数

    +

    虽然本文为了便于解释而使用了 CSS3, 矩阵却是许多技术中的核心概念, 包括 WebGL 和着色器。本文也是MDN content kit的一部分。示例使用了一组全局对象 MDN 下的工具函数

    什么是变换矩阵?

    -

    虽然存在许多类型的矩阵,但我们感兴趣的是三维变换矩阵。这种矩阵由一个4x4方阵,共16个值组成。在JavaScript中,可以很方便的用数组表示矩阵。比如典型的单位矩阵。单位阵乘上一个点或者矩阵, 其结果保持不变。

    +

    虽然存在许多类型的矩阵,但我们感兴趣的是三维变换矩阵。这种矩阵由一个 4x4 方阵,共 16 个值组成。在 JavaScript 中,可以很方便的用数组表示矩阵。比如典型的单位矩阵。单位阵乘上一个点或者矩阵, 其结果保持不变。

    var identityMatrix = [
       1, 0, 0, 0,
    @@ -26,7 +26,7 @@ 

    什么是变换矩阵?

    ];
    -

    说到乘法,这种运算用于矩阵是什么样的呢?最简单的例子是矩阵乘一个点。你可能注意到,三维空间中的点和一个4x4矩阵并不匹配,为此我们加上了额外的第四维W。一般来说,把W设为1就可以了。W维度还有一些额外的用途超出本文的讨论范围。查看WebGL model view projection看它有哪些用途。

    +

    说到乘法,这种运算用于矩阵是什么样的呢?最简单的例子是矩阵乘一个点。你可能注意到,三维空间中的点和一个 4x4 矩阵并不匹配,为此我们加上了额外的第四维 W。一般来说,把 W 设为 1 就可以了。W 维度还有一些额外的用途超出本文的讨论范围。查看WebGL model view projection看它有哪些用途。

    注意矩阵和点的对齐方式:

    @@ -44,7 +44,7 @@

    定义相乘函数

    function multiplyMatrixAndPoint(matrix, point) {
     
    -  // 给矩阵的每一部分一个简单的变量名, 列数(c)与行数(r)
    +  // 给矩阵的每一部分一个简单的变量名,列数(c)与行数(r)
       var c0r0 = matrix[ 0], c1r0 = matrix[ 1], c2r0 = matrix[ 2], c3r0 = matrix[ 3];
       var c0r1 = matrix[ 4], c1r1 = matrix[ 5], c2r1 = matrix[ 6], c3r1 = matrix[ 7];
       var c0r2 = matrix[ 8], c1r2 = matrix[ 9], c2r2 = matrix[10], c3r2 = matrix[11];
    @@ -56,16 +56,16 @@ 

    定义相乘函数

    var z = point[2]; var w = point[3]; - // 点坐标和第一列对应相乘, 再求和 + // 点坐标和第一列对应相乘,再求和 var resultX = (x * c0r0) + (y * c0r1) + (z * c0r2) + (w * c0r3); - // 点坐标和第二列对应相乘, 再求和 + // 点坐标和第二列对应相乘,再求和 var resultY = (x * c1r0) + (y * c1r1) + (z * c1r2) + (w * c1r3); - // 点坐标和第三列对应相乘, 再求和 + // 点坐标和第三列对应相乘,再求和 var resultZ = (x * c2r0) + (y * c2r1) + (z * c2r2) + (w * c2r3); - // 点坐标和第四列对应相乘, 再求和 + // 点坐标和第四列对应相乘,再求和 var resultW = (x * c3r0) + (y * c3r1) + (z * c3r2) + (w * c3r3); return [resultX, resultY, resultZ, resultW] @@ -74,7 +74,7 @@

    定义相乘函数

    现在我们可以使用上面的函数将一个点乘上一个矩阵。乘以单位阵将会返回原值:

    -
    // identityResult等于[4,3,2,1]
    +
    // identityResult 等于 [4,3,2,1]
     var identityResult = multiplyMatrixAndPoint(identityMatrix, [4,3,2,1]);
     
    @@ -126,7 +126,7 @@

    用法

    0, 0, 0, 1 ]; -// 返回someMatrix的数组表示 +// 返回 someMatrix 的数组表示 var someMatrixResult = multiplyMatrices(identityMatrix, someMatrix);
    @@ -136,7 +136,7 @@

    用法

    平移矩阵

    -

    平移矩阵基于单位矩阵。它将一个对象沿x,y,z其中一个方向进行移动。最简单的想象平移的方式是设想拿起一个咖啡杯。咖啡杯必须保持直立和朝向以免咖啡洒出来。它可以离开桌子在空间中移动。

    +

    平移矩阵基于单位矩阵。它将一个对象沿 x,y,z 其中一个方向进行移动。最简单的想象平移的方式是设想拿起一个咖啡杯。咖啡杯必须保持直立和朝向以免咖啡洒出来。它可以离开桌子在空间中移动。

    现在我们还喝不到这个杯子里的咖啡,因为在平移矩阵的单独作用下杯子并不能倾斜。在之后的部分,我们会讨论新的矩阵,来解决这个问题。

    @@ -152,9 +152,9 @@

    平移矩阵

    ];
    -

    用矩阵操作DOM

    +

    用矩阵操作 DOM

    -

    一个非常简单的开始使用矩阵的方法是使用CSS3里的matrix3d变换。首先, 我们新建一个简单的{{htmlelement("div")}}并加上一些内容。这里样式没有展示出来,但我们将其设置成了页面居中且固定宽度与高度。我们同样为变换设定了动画以便清晰的观察发生的变化。

    +

    一个非常简单的开始使用矩阵的方法是使用 CSS3 里的matrix3d变换。首先, 我们新建一个简单的{{htmlelement("div")}}并加上一些内容。这里样式没有展示出来,但我们将其设置成了页面居中且固定宽度与高度。我们同样为变换设定了动画以便清晰的观察发生的变化。

    <div id='move-me' class='transformable'>
       <h2>Move me with a matrix</h2>
    @@ -162,14 +162,14 @@ 

    用矩阵操作DOM

    </div>
    -

    最后,我们会为每一个例子生成一个4x4矩阵,然后更新<div>的样式,对其应用一个matrix3d变换。要记住即使矩阵有四行四列,也要将其写成单行16个值。

    +

    最后,我们会为每一个例子生成一个 4x4 矩阵,然后更新<div>的样式,对其应用一个 matrix3d 变换。要记住即使矩阵有四行四列,也要将其写成单行 16 个值。

    -
    // 从矩阵数组创建matrix3d样式属性
    +
    // 从矩阵数组创建 matrix3d 样式属性
     function matrixArrayToCssMatrix(array) {
       return "matrix3d(" + array.join(',') + ")";
     }
     
    -// 获取DOM元素
    +// 获取 DOM 元素
     var moveMe = document.getElementById('move-me');
     
     // 返回结果如:"matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 50, 100, 0, 1);"
    @@ -179,13 +179,13 @@ 

    用矩阵操作DOM

    moveMe.style.transform = matrix3dRule;
    -

    在JSFiddle中查看

    +

    在 JSFiddle 中查看

    An example of matrix translation

    缩放矩阵

    -

    缩放矩阵使对象的高度、宽度和深度三个维度的其中之一变大或变小。在典型(笛卡尔)坐标系中, 这将使得x,y,z坐标拉伸或收缩。

    +

    缩放矩阵使对象的高度、宽度和深度三个维度的其中之一变大或变小。在典型(笛卡尔)坐标系中, 这将使得 x,y,z 坐标拉伸或收缩。

    var w = 1.5; // width  (x)
     var h = 0.7; // height (y)
    @@ -199,7 +199,7 @@ 

    缩放矩阵

    ];
    -

    在JSFiddle中查看

    +

    在 JSFiddle 中查看

    An example of matrix scaling

    @@ -213,7 +213,7 @@

    旋转矩阵

    // 计算到原点的距离 var distance = Math.sqrt(point[0] * point[0] + point[1] * point[1]); -// 60度 +// 60 度 var rotationInRadians = Math.PI / 3; var transformedPoint = [ @@ -222,7 +222,7 @@

    旋转矩阵

    ];
    -

    我们可以将上述步骤表示为一个矩阵,并且单独应用到x, y,和z坐标。下面是绕Z轴旋转的表示:

    +

    我们可以将上述步骤表示为一个矩阵,并且单独应用到 x, y,和 z 坐标。下面是绕 Z 轴旋转的表示:

    var sin = Math.sin;
     var cos = Math.cos;
    @@ -232,7 +232,7 @@ 

    旋转矩阵

    var a = Math.PI * 0.3; // 转角 -// 绕Z轴旋转 +// 绕 Z 轴旋转 var rotateZMatrix = [ cos(a), -sin(a), 0, 0, sin(a), cos(a), 0, 0, @@ -241,11 +241,11 @@

    旋转矩阵

    ];
    -

    在JSFiddle中查看

    +

    在 JSFiddle 中查看

    -

    这里是一组返回旋转矩阵的函数。要注意的是由于没有加入透视,所以旋转看起来没有那么3D。这就好像摄像机在极近距离拍摄一个物体——透视的感觉消失了。

    +

    这里是一组返回旋转矩阵的函数。要注意的是由于没有加入透视,所以旋转看起来没有那么 3D。这就好像摄像机在极近距离拍摄一个物体——透视的感觉消失了。

    function rotateAroundXAxis(a) {
     
    @@ -278,44 +278,44 @@ 

    旋转矩阵

    }
    -

    在JSFiddle中查看

    +

    在 JSFiddle 中查看

    矩阵组合

    矩阵的真正厉害之处在于矩阵的组合。当一组特定类型的矩阵连乘起来,它们保留了变换的经过并且是可逆的。这意味着如果平移、旋转和缩放矩阵组合在一起,当我们使用逆变换并颠倒应用的顺序,可以得到原来的点。

    -

    矩阵相乘的结果与顺序有关。两个数相乘时,a * b = c, 和 b * a = c 都是正确的。例如,3 * 4 = 12, 和 4 * 3 = 12。在数学上这些数被称为可交换。矩阵不能保证交换顺序后的运算结果,所以矩阵是不可交换的。

    +

    矩阵相乘的结果与顺序有关。两个数相乘时,a * b = c,和 b * a = c 都是正确的。例如,3 * 4 = 12,和 4 * 3 = 12。在数学上这些数被称为可交换。矩阵不能保证交换顺序后的运算结果,所以矩阵是不可交换的。

    -

    另一个需要记住的点是在WebGL和CSS3中的矩阵相乘需要和变换发生的顺序相反。例如,缩放对象到80%,向下移动200像素,然后绕原点旋转90度在伪代码中应该像下面这样。

    +

    另一个需要记住的点是在 WebGL 和 CSS3 中的矩阵相乘需要和变换发生的顺序相反。例如,缩放对象到 80%,向下移动 200 像素,然后绕原点旋转 90 度在伪代码中应该像下面这样。

      transformation = rotate * translate * scale
     

    组合多种变换

    -

    我们将使用的函数是工具函数的一部分。其接受矩阵的数组并把它们乘起来。在WebGL着色器代码里,这内建在语言里,并且我们可以使用 * 运算符。除此之外,本例使用了一个缩放函数,一个平移函数,它们返回之前定义的矩阵。

    +

    我们将使用的函数是工具函数的一部分。其接受矩阵的数组并把它们乘起来。在 WebGL 着色器代码里,这内建在语言里,并且我们可以使用 * 运算符。除此之外,本例使用了一个缩放函数,一个平移函数,它们返回之前定义的矩阵。

    var transformMatrix = MDN.multiplyArrayOfMatrices([
    -  rotateAroundZAxis(Math.PI * 0.5),    // 第3步:旋转90度
    -  translate(0, 200, 0),                // 第2步:下移100像素
    -  scale(0.8, 0.8, 0.8),                // 第1步:缩小
    +  rotateAroundZAxis(Math.PI * 0.5),    // 第 3 步:旋转 90 度
    +  translate(0, 200, 0),                // 第 2 步:下移 100 像素
    +  scale(0.8, 0.8, 0.8),                // 第 1 步:缩小
     ]);
     
     
    -

    在JSFiddle中查看

    +

    在 JSFiddle 中查看

    An example of matrix composition

    最后是展示矩阵用途的有趣的一步,看看怎样颠倒这些步骤并得到最开始的单位矩阵。

    var transformMatrix = MDN.multiplyArrayOfMatrices([
    -  scale(1.25, 1.25, 1.25),             // 第6步:放大
    -  translate(0, -200, 0),               // 第5步:上移
    -  rotateAroundZAxis(-Math.PI * 0.5),   // 第4步:倒转
    -  rotateAroundZAxis(Math.PI * 0.5),    // 第3步:旋转90度
    -  translate(0, 200, 0),                // 第2步:下移100像素
    -  scale(0.8, 0.8, 0.8),                // 第1步:缩小
    +  scale(1.25, 1.25, 1.25),             // 第 6 步:放大
    +  translate(0, -200, 0),               // 第 5 步:上移
    +  rotateAroundZAxis(-Math.PI * 0.5),   // 第 4 步:倒转
    +  rotateAroundZAxis(Math.PI * 0.5),    // 第 3 步:旋转 90 度
    +  translate(0, 200, 0),                // 第 2 步:下移 100 像素
    +  scale(0.8, 0.8, 0.8),                // 第 1 步:缩小
     ]);
     
    @@ -323,4 +323,4 @@

    为什么矩阵这么重要?

    矩阵之所以重要,是因为它可以用少量的数字描述大量的空间中的变换,并且能轻易地在程序间共享。矩阵可以不同的坐标空间,甚至一些矩阵乘法可以将一组数据从一个坐标空间映射到另一个坐标空间。矩阵能够高效率地保存生成它们的每一步变换。

    -

    对于在WebGL中使用,显卡尤其擅长大量的点乘矩阵运算。各种各样的运算,如点定位、光线运算、动态角色,都依赖这个基础工具。

    +

    对于在 WebGL 中使用,显卡尤其擅长大量的点乘矩阵运算。各种各样的运算,如点定位、光线运算、动态角色,都依赖这个基础工具。

    diff --git a/files/zh-cn/web/api/webgl_api/tutorial/adding_2d_content_to_a_webgl_context/index.html b/files/zh-cn/web/api/webgl_api/tutorial/adding_2d_content_to_a_webgl_context/index.html index 4b3de122d7b682..36f771e484f880 100644 --- a/files/zh-cn/web/api/webgl_api/tutorial/adding_2d_content_to_a_webgl_context/index.html +++ b/files/zh-cn/web/api/webgl_api/tutorial/adding_2d_content_to_a_webgl_context/index.html @@ -9,7 +9,7 @@ ---

    {{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL")}}

    -

    一旦创建WebGL上下文创建成功,你就可以在这个上下文里渲染画图了。而对我们而言最简单的事,莫过于绘制一个没有纹理的2D图形了。那就让我们从画出一个正方形开始吧。

    +

    一旦创建 WebGL 上下文创建成功,你就可以在这个上下文里渲染画图了。而对我们而言最简单的事,莫过于绘制一个没有纹理的 2D 图形了。那就让我们从画出一个正方形开始吧。

    渲染场景

    @@ -17,21 +17,21 @@

    渲染场景

    着色器

    -

    着色器是使用 OpenGL ES 着色语言(GLSL)编写的程序,它携带着绘制形状的顶点信息以及构造绘制在屏幕上像素的所需数据,换句话说,它负责记录着像素点的位置和颜色。

    +

    着色器是使用 OpenGL ES 着色语言(GLSL) 编写的程序,它携带着绘制形状的顶点信息以及构造绘制在屏幕上像素的所需数据,换句话说,它负责记录着像素点的位置和颜色。

    -

    绘制WebGL时候有两种不同的着色器函数,顶点着色器和片段着色器。你需要通过用GLSL 编写这些着色器,并将代码文本传递给WebGL , 使之在GPU执行时编译。顺便一提,顶点着色器和片段着色器的集合我们通常称之为着色器程序。

    +

    绘制 WebGL 时候有两种不同的着色器函数,顶点着色器和片段着色器。你需要通过用 GLSL 编写这些着色器,并将代码文本传递给 WebGL , 使之在 GPU 执行时编译。顺便一提,顶点着色器和片段着色器的集合我们通常称之为着色器程序。

    -

    下面我们通过在WebGL 环境绘制一个2D图像的例子快速介绍这两种着色器。

    +

    下面我们通过在 WebGL 环境绘制一个 2D 图像的例子快速介绍这两种着色器。

    顶点着色器

    -

    每次渲染一个形状时,顶点着色器会在形状中的每个顶点运行。 它的工作是将输入顶点从原始坐标系转换到WebGL使用的缩放空间(clipspace)坐标系,其中每个轴的坐标范围从-1.0到1.0,并且不考虑纵横比,实际尺寸或任何其他因素。

    +

    每次渲染一个形状时,顶点着色器会在形状中的每个顶点运行。 它的工作是将输入顶点从原始坐标系转换到 WebGL 使用的缩放空间 (clipspace) 坐标系,其中每个轴的坐标范围从-1.0 到 1.0,并且不考虑纵横比,实际尺寸或任何其他因素。

    -

    顶点着色器需要对顶点坐标进行必要的转换,在每个顶点基础上进行其他调整或计算,然后通过将其保存在由GLSL提供的特殊变量(我们称为gl_Position)中来返回变换后的顶点

    +

    顶点着色器需要对顶点坐标进行必要的转换,在每个顶点基础上进行其他调整或计算,然后通过将其保存在由 GLSL 提供的特殊变量(我们称为 gl_Position)中来返回变换后的顶点

    -

    顶点着色器根据需要, 也可以完成其他工作。例如,决定哪个包含 {{interwiki("wikipedia", "texel_(graphics)", "texel")}}面部纹理的坐标,可以应用于顶点;通过法线来确定应用到顶点的光照因子等。然后将这些信息存储在变量(varyings)属性(attributes)属性中,以便与片段着色器共享

    +

    顶点着色器根据需要, 也可以完成其他工作。例如,决定哪个包含 {{interwiki("wikipedia", "texel_(graphics)", "texel")}}面部纹理的坐标,可以应用于顶点;通过法线来确定应用到顶点的光照因子等。然后将这些信息存储在变量(varyings)属性 (attributes)属性中,以便与片段着色器共享

    -

    以下的顶点着色器接收一个我们定义的属性(aVertexPosition)的顶点位置值。之后这个值与两个4x4的矩阵(uProjectionMatrix和uModelMatrix)相乘; 乘积赋值给gl_Position。有关投影和其他矩阵的更多信息,在这里您可能可以找到有帮助的文章.。

    +

    以下的顶点着色器接收一个我们定义的属性(aVertexPosition)的顶点位置值。之后这个值与两个 4x4 的矩阵(uProjectionMatrix 和 uModelMatrix)相乘; 乘积赋值给 gl_Position。有关投影和其他矩阵的更多信息,在这里您可能可以找到有帮助的文章.。

    // Vertex shader program
     
    @@ -46,11 +46,11 @@ 

    顶点着色器

    } `;
    -

    这个例子中,我们没有计算任何光照效果,因为我们还没有应用到场景,它将后面的 WebGL光照章节介绍。同样我们也还没应用任何纹理,这将在WebGL添加纹理章节补充。

    +

    这个例子中,我们没有计算任何光照效果,因为我们还没有应用到场景,它将后面的 WebGL 光照章节介绍。同样我们也还没应用任何纹理,这将在WebGL 添加纹理章节补充。

    片段着色器

    -

    片段着色器在顶点着色器处理完图形的顶点后,会被要绘制的每个图形的每个像素点调用一次。它的职责是确定像素的颜色,通过指定应用到像素的纹理元素(也就是图形纹理中的像素),获取纹理元素的颜色,然后将适当的光照应用于颜色。之后颜色存储在特殊变量gl_FragColor中,返回到WebGL层。该颜色将最终绘制到屏幕上图形对应像素的对应位置。

    +

    片段着色器在顶点着色器处理完图形的顶点后,会被要绘制的每个图形的每个像素点调用一次。它的职责是确定像素的颜色,通过指定应用到像素的纹理元素(也就是图形纹理中的像素),获取纹理元素的颜色,然后将适当的光照应用于颜色。之后颜色存储在特殊变量 gl_FragColor 中,返回到 WebGL 层。该颜色将最终绘制到屏幕上图形对应像素的对应位置。

    const fsSource = `
         void main() {
    @@ -60,10 +60,10 @@ 

    片段着色器

    初始化着色器

    -

    现在我们已经定义了两个着色器,我们需要将它们传递给WebGL,编译并将它们连接在一起。下面的代码通过调用loadShader(),为着色器传递类型和来源,创建了两个着色器。然后创建一个附加着色器的程序,将它们连接在一起。如果编译或链接失败,代码将弹出alert。

    +

    现在我们已经定义了两个着色器,我们需要将它们传递给 WebGL,编译并将它们连接在一起。下面的代码通过调用 loadShader(),为着色器传递类型和来源,创建了两个着色器。然后创建一个附加着色器的程序,将它们连接在一起。如果编译或链接失败,代码将弹出 alert。

    //
    -//  初始化着色器程序,让WebGL知道如何绘制我们的数据
    +//  初始化着色器程序,让 WebGL 知道如何绘制我们的数据
     function initShaderProgram(gl, vsSource, fsSource) {
       const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
       const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
    @@ -85,7 +85,7 @@ 

    初始化着色器

    } // -// 创建指定类型的着色器,上传source源码并编译 +// 创建指定类型的着色器,上传 source 源码并编译 // function loadShader(gl, type, source) { const shader = gl.createShader(type); @@ -110,7 +110,7 @@

    初始化着色器

    }
    -

    loadShader函数将WebGL上下文,着色器类型和源码作为参数输入,然后按如下步骤创建和编译着色器:

    +

    loadShader 函数将 WebGL 上下文,着色器类型和源码作为参数输入,然后按如下步骤创建和编译着色器:

    1. 调用{{domxref("WebGLRenderingContext.createShader", "gl.createShader()")}}.创建一个新的着色器。

    @@ -118,7 +118,7 @@

    初始化着色器

    3. 一旦着色器获取到源代码,就使用{{domxref("WebGLRenderingContext.compileShader", "gl.compileShader()")}}.进行编译。

    -

    4. 为了检查是否成功编译了着色器,将检查着色器参数gl.COMPILE_STATUS状态。通过调用{{domxref("WebGLRenderingContext.getShaderParameter", "gl.getShaderParameter()")}}获得它的值,并指定着色器和我们想要检查的参数的名字(gl.COMPILE_STATUS)。如果返回错误,则着色器无法编译,因此通过{{domxref("WebGLRenderingContext.getShaderInfoLog", "gl.getShaderInfoLog()")}}从编译器中获取日志信息并alert,然后删除着色器返回null,表明加载着色器失败。

    +

    4. 为了检查是否成功编译了着色器,将检查着色器参数 gl.COMPILE_STATUS 状态。通过调用{{domxref("WebGLRenderingContext.getShaderParameter", "gl.getShaderParameter()")}}获得它的值,并指定着色器和我们想要检查的参数的名字(gl.COMPILE_STATUS)。如果返回错误,则着色器无法编译,因此通过{{domxref("WebGLRenderingContext.getShaderInfoLog", "gl.getShaderInfoLog()")}}从编译器中获取日志信息并 alert,然后删除着色器返回 null,表明加载着色器失败。

    5. 如果着色器被加载并成功编译,则返回编译的着色器。

    @@ -126,7 +126,7 @@

    初始化着色器

      const shaderProgram = initShaderProgram(gl, vsSource, fsSource);
    -

    在创建着色器程序之后,我们需要查找WebGL返回分配的输入位置。在上述情况下,我们有一个属性和两个uniforms。属性从缓冲区接收值。顶点着色器的每次迭代都从分配给该属性的缓冲区接收下一个值。uniforms类似于JavaScript全局变量。它们在着色器的所有迭代中保持相同的值。由于属性和统一的位置是特定于单个着色器程序的,因此我们将它们存储在一起以使它们易于传递

    +

    在创建着色器程序之后,我们需要查找 WebGL 返回分配的输入位置。在上述情况下,我们有一个属性和两个 uniforms。属性从缓冲区接收值。顶点着色器的每次迭代都从分配给该属性的缓冲区接收下一个值。uniforms 类似于 JavaScript 全局变量。它们在着色器的所有迭代中保持相同的值。由于属性和统一的位置是特定于单个着色器程序的,因此我们将它们存储在一起以使它们易于传递

    const programInfo = {
         program: shaderProgram,
    @@ -141,7 +141,7 @@ 

    初始化着色器

    创建对象

    -

    在画正方形前,我们需要创建一个缓冲器来存储它的顶点。我们会用到名字为 initBuffers() 的函数。当我们了解到更多WebGL 的高级概念时,这段代码会将有更多参数,变得更加复杂,并且用来创建更多的三维物体。

    +

    在画正方形前,我们需要创建一个缓冲器来存储它的顶点。我们会用到名字为 initBuffers() 的函数。当我们了解到更多 WebGL 的高级概念时,这段代码会将有更多参数,变得更加复杂,并且用来创建更多的三维物体。

    function initBuffers(gl) {
       const positionBuffer = gl.createBuffer();
    @@ -166,14 +166,14 @@ 

    创建对象

    这段代码简单给出了绘画场景的本质。首先,它调用 gl 的成员函数 {{domxref("WebGLRenderingContext.createBuffer()", "createBuffer()")}} 得到了缓冲对象并存储在顶点缓冲器。然后调用 {{domxref("WebGLRenderingContext.bindBuffer()", "bindBuffer()")}} 函数绑定上下文。

    -

    当上一步完成,我们创建一个Javascript 数组去记录每一个正方体的每一个顶点。然后将其转化为 WebGL 浮点型类型的数组,并将其传到 gl 对象的  {{domxref("WebGLRenderingContext.bufferData()", "bufferData()")}} 方法来建立对象的顶点。

    +

    当上一步完成,我们创建一个 Javascript 数组去记录每一个正方体的每一个顶点。然后将其转化为 WebGL 浮点型类型的数组,并将其传到 gl 对象的  {{domxref("WebGLRenderingContext.bufferData()", "bufferData()")}} 方法来建立对象的顶点。

    绘制场景

    当着色器和物体都创建好后,我们可以开始渲染这个场景了。因为我们这个例子不会产生动画,所以 drawScene() 方法非常简单。它还使用了几个工具函数,稍后我们会介绍。

    -

    注意: 你可能会得到这样一段错误报告:“ mat4 is not defined”,意思是说你缺少glmatrix库。该库的js文件gl-matrix.js可以从这里获得.

    +

    注意: 你可能会得到这样一段错误报告:“ mat4 is not defined”,意思是说你缺少glmatrix库。该库的 js 文件gl-matrix.js可以从这里获得。

    function drawScene(gl, programInfo, buffers) {
    @@ -262,13 +262,13 @@ 

    创建对象

    }
    -

    第一步,用背景色擦除画布,接着建立摄像机透视矩阵。设置45度的视图角度,并且设置一个适合实际图像的宽高比。 指定在摄像机距离0.1到100单位长度的范围内的物体可见。

    +

    第一步,用背景色擦除画布,接着建立摄像机透视矩阵。设置 45 度的视图角度,并且设置一个适合实际图像的宽高比。 指定在摄像机距离 0.1 到 100 单位长度的范围内的物体可见。

    -

    接着加载特定位置,并把正方形放在距离摄像机6个单位的的位置。然后,我们绑定正方形的顶点缓冲到上下文,并配置好,再通过调用 {{domxref("WebGLRenderingContext.drawArrays()", "drawArrays()")}} 方法来画出对象。 

    +

    接着加载特定位置,并把正方形放在距离摄像机 6 个单位的的位置。然后,我们绑定正方形的顶点缓冲到上下文,并配置好,再通过调用 {{domxref("WebGLRenderingContext.drawArrays()", "drawArrays()")}} 方法来画出对象。 

    {{EmbedGHLiveSample('webgl-examples/tutorial/sample2/index.html', 670, 510) }}

    -

    如果你的浏览器支持WebGL的话,可以点击这里看看DEMO。完整的源代码从这里获得

    +

    如果你的浏览器支持 WebGL 的话,可以点击这里看看 DEMO。完整的源代码从这里获得

    矩阵通用计算

    diff --git a/files/zh-cn/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.html b/files/zh-cn/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.html index e2111f13911d45..30768c54c38d30 100644 --- a/files/zh-cn/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.html +++ b/files/zh-cn/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.html @@ -1,5 +1,5 @@ --- -title: 用WebGL让目标动起来 +title: 用 WebGL 让目标动起来 slug: Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL tags: - WebGL @@ -24,7 +24,7 @@

    使正方形旋转

                  squareRotation,   // amount to rotate in radians               [0, 0, 1]);       // axis to rotate around
    -

    这会将modelViewMatrix的当前值squareRotation绕Z轴旋转。

    +

    这会将 modelViewMatrix 的当前值squareRotation绕 Z 轴旋转。

    要进行动画制作,我们需要添加squareRotation随时间更改值的代码。为此,我们可以创建一个新变量来跟踪上次动画播放的时间(我们称之为then),然后将以下代码添加到主函数的末尾

    @@ -42,7 +42,7 @@

    使正方形旋转

      }   requestAnimationFrame(render);
    -

    该代码用于  requestAnimationFrame 要求浏览器在每一帧上调用函数“render”。requestAnimationFrame 自页面加载以来经过的时间(以毫秒为单位)。我们将其转换为秒,然后从中减去,以计算deltaTime 自渲染最后一帧以来的秒数  。在drawscene的结尾,我们添加了要更新的代码 squareRotation.

    +

    该代码用于  requestAnimationFrame 要求浏览器在每一帧上调用函数“render”。requestAnimationFrame 自页面加载以来经过的时间(以毫秒为单位)。我们将其转换为秒,然后从中减去,以计算deltaTime 自渲染最后一帧以来的秒数  。在 drawscene 的结尾,我们添加了要更新的代码 squareRotation.

      squareRotation += deltaTime;
    diff --git a/files/zh-cn/web/api/webgl_api/tutorial/animating_textures_in_webgl/index.html b/files/zh-cn/web/api/webgl_api/tutorial/animating_textures_in_webgl/index.html index fc14473ae98eee..a0b9bb3f82fce0 100644 --- a/files/zh-cn/web/api/webgl_api/tutorial/animating_textures_in_webgl/index.html +++ b/files/zh-cn/web/api/webgl_api/tutorial/animating_textures_in_webgl/index.html @@ -7,7 +7,7 @@ ---

    {{WebGLSidebar("Tutorial") }} {{Previous("Web/API/WebGL_API/Tutorial/Lighting_in_WebGL")}}

    -

    在本演示中,我们以上一个示例为基础,将静态纹理替换为正在播放的mp4视频文件的帧。实际上,这很容易做到,而且观看起来很有趣,所以让我们开始吧。您可以使用类似的代码来使用任何类型的数据(例如 {{ HTMLElement("canvas") }}) 作为纹理的源。

    +

    在本演示中,我们以上一个示例为基础,将静态纹理替换为正在播放的 mp4 视频文件的帧。实际上,这很容易做到,而且观看起来很有趣,所以让我们开始吧。您可以使用类似的代码来使用任何类型的数据(例如 {{ HTMLElement("canvas") }}) 作为纹理的源。

    获取视频

    @@ -52,7 +52,7 @@

    获取视频

    }
    -

    首先,我们创建一个视频元素。我们将其设置为自动播放,静音和循环播放视频。然后,我们设置了两个事件以确保视频正在播放并且时间轴已更新。我们需要进行这两项检查,因为如果将视频上传到WebGL尚无可用数据,它将产生错误。检查这两个事件可确保有可用数据,并且可以安全地开始将视频上传到WebGL纹理。在上面的代码中,我们确认是否同时发生了这两个事件。如果是这样,我们将全局变量设置 copyVideo 为 true,以表示可以安全地开始将视频复制到纹理。

    +

    首先,我们创建一个视频元素。我们将其设置为自动播放,静音和循环播放视频。然后,我们设置了两个事件以确保视频正在播放并且时间轴已更新。我们需要进行这两项检查,因为如果将视频上传到 WebGL 尚无可用数据,它将产生错误。检查这两个事件可确保有可用数据,并且可以安全地开始将视频上传到 WebGL 纹理。在上面的代码中,我们确认是否同时发生了这两个事件。如果是这样,我们将全局变量设置 copyVideo 为 true,以表示可以安全地开始将视频复制到纹理。

    最后,我们将 src 属性设置为 start 并调用 play 以开始加载和播放视频。

    @@ -101,7 +101,7 @@

    用视频帧作为纹理

    srcFormat, srcType, video); }
-

您之前已经看过此代码。它与上一个示例中的image onload函数几乎相同-除非我们调用 texImage2D(),不是传递 Image 对象,而是传递 {{ HTMLElement("video") }} 元素。WebGL知道如何拉出当前帧并将其用作纹理。

+

您之前已经看过此代码。它与上一个示例中的 image onload 函数几乎相同 - 除非我们调用 texImage2D(),不是传递 Image 对象,而是传递 {{ HTMLElement("video") }} 元素。WebGL 知道如何拉出当前帧并将其用作纹理。

然后,在 main() 代替通话,以 loadTexture() 在前面的例子中,我们调用 initTexture() 之后 setupVideo()

@@ -129,11 +129,11 @@

用视频帧作为纹理

} requestAnimationFrame(render); -

下面是结果:

+

下面是结果:

{{EmbedGHLiveSample('webgl-examples/tutorial/sample8/index.html', 670, 510) }}

-

查看完整的代码 | 在新页中打开这个demo

+

查看完整的代码 | 在新页中打开这个 demo

参见

diff --git a/files/zh-cn/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.html b/files/zh-cn/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.html index 00a35e0d299061..6af940210cae1a 100644 --- a/files/zh-cn/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.html +++ b/files/zh-cn/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.html @@ -7,11 +7,11 @@

现在让我们给之前的正方形添加五个面从而可以创建一个三维的立方体。最简单的方式就是通过调用方法 {{domxref("WebGLRenderingContext.drawElements()", "gl.drawElements()")}} 使用顶点数组列表来替换之前的通过方法{{domxref("WebGLRenderingContext.drawArrays()", "gl.drawArrays()")}} 直接使用顶点数组。而顶点数组列表里保存着将会被引用到一个个独立的顶点。

-

其实现在会存在这样一个问题:每个面需要4个顶点,而每个顶点会被3个面共享。我们会创建一个包含24个顶点的数组列表,通过使用数组下标来索引顶点,然后把这些用于索引的下标传递给渲染程序而不是直接把整个顶点数据传递过去,这样来减少数据传递。那么也许你就会问:那么使用8个顶点就好了,为什么要使用24个顶点呢?这是因为每个顶点虽然被3个面共享但是它在每个面上需要使用不同的颜色信息。24个顶点中的每一个都会有独立的颜色信息,这就会造成每个顶点位置都会有3份副本。

+

其实现在会存在这样一个问题:每个面需要 4 个顶点,而每个顶点会被 3 个面共享。我们会创建一个包含 24 个顶点的数组列表,通过使用数组下标来索引顶点,然后把这些用于索引的下标传递给渲染程序而不是直接把整个顶点数据传递过去,这样来减少数据传递。那么也许你就会问:那么使用 8 个顶点就好了,为什么要使用 24 个顶点呢?这是因为每个顶点虽然被 3 个面共享但是它在每个面上需要使用不同的颜色信息。24 个顶点中的每一个都会有独立的颜色信息,这就会造成每个顶点位置都会有 3 份副本。

定义立方体顶点位置

-

首先,更新 initBuffers() 函数代码创建顶点位置数据缓存。现在的代码看起来和渲染正方形时的代码很相似,只是比之前的代码更长因为现在有了24个顶点(每个面使用4个顶点):

+

首先,更新 initBuffers() 函数代码创建顶点位置数据缓存。现在的代码看起来和渲染正方形时的代码很相似,只是比之前的代码更长因为现在有了 24 个顶点(每个面使用 4 个顶点):

var vertices = [
   // Front face
@@ -106,7 +106,7 @@ 

定义元素(三角形)数组

-

代码中的 cubeVertexIndices 数组声明每一个面都使用两个三角形来渲染。通过立方体顶点数组的索引指定每个三角形的顶点。那么这个立方体就是由12个三角形组成的了。

+

代码中的 cubeVertexIndices 数组声明每一个面都使用两个三角形来渲染。通过立方体顶点数组的索引指定每个三角形的顶点。那么这个立方体就是由 12 个三角形组成的了。

渲染立方体

@@ -117,7 +117,7 @@

渲染立方体

gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0);
-

立方体的每个面都由2个三角形组成,那就是每个面需要6个顶点,或者说总共36个顶点,尽管有许多重复的。然而,因为索引数组的每个元素都是简单的整数类型,所以每一帧动画需要传递给渲染程序的数据也不是很多。

+

立方体的每个面都由 2 个三角形组成,那就是每个面需要 6 个顶点,或者说总共 36 个顶点,尽管有许多重复的。然而,因为索引数组的每个元素都是简单的整数类型,所以每一帧动画需要传递给渲染程序的数据也不是很多。

到现在为止,我们已经创建了一个颜色生动的并且会在场景中移动和旋转的立方体,这一定很酷吧。

diff --git a/files/zh-cn/web/api/webgl_api/tutorial/getting_started_with_webgl/index.html b/files/zh-cn/web/api/webgl_api/tutorial/getting_started_with_webgl/index.html index 3b6de1ae6634ee..0c2f37ec177961 100644 --- a/files/zh-cn/web/api/webgl_api/tutorial/getting_started_with_webgl/index.html +++ b/files/zh-cn/web/api/webgl_api/tutorial/getting_started_with_webgl/index.html @@ -8,13 +8,13 @@ ---

{{WebGLSidebar("Tutorial")}} {{Next("Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context")}}

-

WebGL 使得在支持HTML 的 canvas 标签的浏览器中,不需要安装任何插件,便可以使用基于 OpenGL ES 2.0 的 API 在 canvas 中进行2D和3D渲染。WebGL程序包括用 JavaScript 写的控制代码,以及在图形处理单元(GPU, Graphics Processing Unit)中执行的着色代码(GLSL,注:GLSL为OpenGL着色语言)。WebGL 元素可以和其他 HTML 元素混合使用,并且可以和网页其他部分或者网页背景结合起来。

+

WebGL 使得在支持 HTML 的 canvas 标签的浏览器中,不需要安装任何插件,便可以使用基于 OpenGL ES 2.0 的 API 在 canvas 中进行 2D 和 3D 渲染。WebGL 程序包括用 JavaScript 写的控制代码,以及在图形处理单元(GPU, Graphics Processing Unit)中执行的着色代码(GLSL,注:GLSL 为 OpenGL 着色语言)。WebGL 元素可以和其他 HTML 元素混合使用,并且可以和网页其他部分或者网页背景结合起来。

-

本文将向您介绍 WebGL 的基本用法。此处假定您对三维图形方面的数学知识已经有一定的理解,本文也不会试图向您教授 3D图像概念本身。

+

本文将向您介绍 WebGL 的基本用法。此处假定您对三维图形方面的数学知识已经有一定的理解,本文也不会试图向您教授 3D 图像概念本身。

本文的代码也可以在这里下载 webgl-examples GitHub repository 。

-

THREE.jsBABYLON.js等很多框架封装了WebGL,提供了各个平台之间的兼容性。使用这些框架而非原生的WebGL可以更容易地开发3D应用和游戏。

+

THREE.jsBABYLON.js等很多框架封装了 WebGL,提供了各个平台之间的兼容性。使用这些框架而非原生的 WebGL 可以更容易地开发 3D 应用和游戏。

准备 3D 渲染

@@ -22,7 +22,7 @@

准备 3D 渲染

<body onload="main()">
   <canvas id="glcanvas" width="640" height="480">
-    你的浏览器似乎不支持或者禁用了HTML5 <code>&lt;canvas&gt;</code> 元素.
+    你的浏览器似乎不支持或者禁用了 HTML5 <code>&lt;canvas&gt;</code> 元素。
   </canvas>
 </body>
 
@@ -34,12 +34,12 @@

准备 WebGL 上下文

// 从这里开始
 function main() {
   const canvas = document.querySelector("#glcanvas");
-  // 初始化WebGL上下文
+  // 初始化 WebGL 上下文
   const gl = canvas.getContext("webgl");
 
-  // 确认WebGL支持性
+  // 确认 WebGL 支持性
   if (!gl) {
-    alert("无法初始化WebGL,你的浏览器、操作系统或硬件等可能不支持WebGL。");
+    alert("无法初始化 WebGL,你的浏览器、操作系统或硬件等可能不支持 WebGL。");
     return;
   }
 
@@ -51,20 +51,20 @@ 

准备 WebGL 上下文

我们所要做的第一件事就是是获取 canvas 的引用,把它保存在 ‘canvas’ 变量里。

-

当我们获取到 canvas之后,我们会调用getContext 函数并向它传递"webgl"参数,来尝试获取WebGLRenderingContext。如果浏览器不支持webgl,getContext将会返回null,我们就可以显示一条消息给用户然后退出。

+

当我们获取到 canvas 之后,我们会调用getContext 函数并向它传递"webgl"参数,来尝试获取WebGLRenderingContext。如果浏览器不支持 webgl,getContext将会返回null,我们就可以显示一条消息给用户然后退出。

-

如果WebGL上下文成功初始化,变量 ‘gl’ 会用来引用该上下文。在这个例子里,我们用黑色清除上下文内已有的元素。(用背景颜色重绘canvas)。

+

如果 WebGL 上下文成功初始化,变量 ‘gl’ 会用来引用该上下文。在这个例子里,我们用黑色清除上下文内已有的元素。(用背景颜色重绘 canvas)。

{{EmbedGHLiveSample('webgl-examples/tutorial/sample1/index.html', 670, 510) }}

-

看源码 | 看DEMO

+

看源码 | 看 DEMO

参见

    -
  • WebGL介绍: 由Luz Caballero所著, 发布在dev.opera.com。 这篇文章说明WebGL是什么, 解释了WebGL是如何工作的 (介绍了渲染管线的概念),并且介绍了一些WebGL库。
  • -
  • WebGL基础
  • -
  • 现代OpenGL介绍: 由Joe Groff写的一系列关于OpenGL的不错的文章,提供了一个清晰的介绍,从OpenGL的历史到图形管线概念,也包括一些说明OpenGL如何工作的例子,如果你对OpenGL没有任何概念的话,这是不错的出发点。
  • +
  • WebGL 介绍: 由 Luz Caballero 所著, 发布在 dev.opera.com。 这篇文章说明 WebGL 是什么, 解释了 WebGL 是如何工作的 (介绍了渲染管线的概念),并且介绍了一些 WebGL 库。
  • +
  • WebGL 基础
  • +
  • 现代 OpenGL 介绍: 由 Joe Groff 写的一系列关于 OpenGL 的不错的文章,提供了一个清晰的介绍,从 OpenGL 的历史到图形管线概念,也包括一些说明 OpenGL 如何工作的例子,如果你对 OpenGL 没有任何概念的话,这是不错的出发点。

{{Next("Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context")}}

diff --git a/files/zh-cn/web/api/webgl_api/tutorial/index.html b/files/zh-cn/web/api/webgl_api/tutorial/index.html index 7a499b4c5fd86a..97baf1c90a0fec 100644 --- a/files/zh-cn/web/api/webgl_api/tutorial/index.html +++ b/files/zh-cn/web/api/webgl_api/tutorial/index.html @@ -10,32 +10,32 @@
{{WebGLSidebar}}
-

WebGL 使得网页在支持HTML {{HTMLElement("canvas")}} 标签的浏览器中,不需要使用任何插件,便可以使用基于 OpenGL ES 2.0 的 API 在 canvas 中进行3D渲染. WebGL 程序由javascript的控制代码,和在计算机的图形处理单元(GPU, Graphics Processing Unit)中执行的特效代码(shader code,渲染代码) 组成. WebGL 元素可以和其他HTML元素混合, 并且会和页面的其他部分或页面背景相合成.

+

WebGL 使得网页在支持 HTML {{HTMLElement("canvas")}} 标签的浏览器中,不需要使用任何插件,便可以使用基于 OpenGL ES 2.0 的 API 在 canvas 中进行 3D 渲染. WebGL 程序由 javascript 的控制代码,和在计算机的图形处理单元(GPU, Graphics Processing Unit)中执行的特效代码 (shader code,渲染代码) 组成. WebGL 元素可以和其他 HTML 元素混合,并且会和页面的其他部分或页面背景相合成。

-

此教程从基础开始讲解如何使用<canvas> 元素来画WebGL 图形. 提供的例子会让你对WebGL有更清晰的认识, 并且会提供代码片段方便你构建自己的内容.

+

此教程从基础开始讲解如何使用<canvas> 元素来画 WebGL 图形。提供的例子会让你对 WebGL 有更清晰的认识,并且会提供代码片段方便你构建自己的内容。

开始之前

-

使用 <canvas> 元素并不困难,但你需要基本的 HTML 和 JavaScript 知识。一些老浏览器不支持<canvas> 元素和 WebGL,但所有最近的主流浏览器都支持它们.。为了能在canvas中绘制图形,我们使用Javascript的上下文环境(context)对象,此对象可以动态创建图形。

+

使用 <canvas> 元素并不困难,但你需要基本的 HTML 和 JavaScript 知识。一些老浏览器不支持<canvas> 元素和 WebGL,但所有最近的主流浏览器都支持它们.。为了能在 canvas 中绘制图形,我们使用 Javascript 的上下文环境(context)对象,此对象可以动态创建图形。

在本教程中

-
开始WebGL
-
如何设置WebGL上下文环境.
-
给WebGL的上下文环境添加2D内容
-
如何用WebGl渲染简单的平面化图形.
-
在WebGL中使用着色器(shader)去赋予颜色
-
演示如何使用着色器给图形添加颜色.
-
用WebGL让对象动起来
-
展示如何旋转移动物体来实现简单动画效果.
-
使用WebGL创建3D物体
-
展示如何创建并设置一个3D物体动画 (这里使用立方体).
-
在WebGL中使用纹理贴图(texture)
-
展示如何投射纹理贴图到物体的各个面.
-
WebGL中的灯光
-
如何在WebGL上下文环境中模拟灯光效果.
-
WebGL中的动画纹理贴图
-
展示如何让纹理贴图动起来; 在此例中, 会投射一个Ogg格式的视频在一个旋转立方体的各个面上.
+
开始 WebGL
+
如何设置 WebGL 上下文环境。
+
给 WebGL 的上下文环境添加 2D 内容
+
如何用 WebGl 渲染简单的平面化图形。
+
在 WebGL 中使用着色器 (shader) 去赋予颜色
+
演示如何使用着色器给图形添加颜色。
+
用 WebGL 让对象动起来
+
展示如何旋转移动物体来实现简单动画效果。
+
使用 WebGL 创建 3D 物体
+
展示如何创建并设置一个 3D 物体动画 (这里使用立方体).
+
在 WebGL 中使用纹理贴图 (texture)
+
展示如何投射纹理贴图到物体的各个面。
+
WebGL 中的灯光
+
如何在 WebGL 上下文环境中模拟灯光效果。
+
WebGL 中的动画纹理贴图
+
展示如何让纹理贴图动起来; 在此例中,会投射一个 Ogg 格式的视频在一个旋转立方体的各个面上。
diff --git a/files/zh-cn/web/api/webgl_api/tutorial/lighting_in_webgl/index.html b/files/zh-cn/web/api/webgl_api/tutorial/lighting_in_webgl/index.html index fcb6b665a166d3..3894461d77d0d4 100644 --- a/files/zh-cn/web/api/webgl_api/tutorial/lighting_in_webgl/index.html +++ b/files/zh-cn/web/api/webgl_api/tutorial/lighting_in_webgl/index.html @@ -5,11 +5,11 @@ ---

{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL", "Web/API/WebGL_API/Tutorial/Animating_textures_in_WebGL")}}

-

在使用灯光之前,首先我们需要了解,与定义更广泛的OpenGL不同,WebGL并没有继承OpenGL中灯光的支持。所以你只能由自己完全得控制灯光。幸运得是,这也并不是很难,本文接下来就会介绍完成灯光的基础。

+

在使用灯光之前,首先我们需要了解,与定义更广泛的 OpenGL 不同,WebGL 并没有继承 OpenGL 中灯光的支持。所以你只能由自己完全得控制灯光。幸运得是,这也并不是很难,本文接下来就会介绍完成灯光的基础。

-

在3D空间中模拟现实灯光

+

在 3D 空间中模拟现实灯光

-

在3D空间中模拟现实世界的灯光的具体原理和细节绝非本篇文章能够描述清楚的,但是对灯光模型有一定的了解对我们的学习还是很有帮助的。虽然这里没办法深入讲解,但是维基百科中的Phong着色法给出了一个不错的概要介绍,其中包含了最常用的几种光照模型。

+

在 3D 空间中模拟现实世界的灯光的具体原理和细节绝非本篇文章能够描述清楚的,但是对灯光模型有一定的了解对我们的学习还是很有帮助的。虽然这里没办法深入讲解,但是维基百科中的Phong 着色法给出了一个不错的概要介绍,其中包含了最常用的几种光照模型。

光源类型可以概括成如下三种:

@@ -32,7 +32,7 @@

在3D空间中模拟现实灯光

建立顶点法线

-

首先我们需要做的是建立一个数组来存放立方体所有顶点的法线。由于立方体是一个很简单的物体,所以很容易实现;显然如果是对复杂物体,则法线的计算方法需要更深入的研究。(注:译者调试后发现此处new WebGLFloatArray(...) 可能应该使用new Float32Array())

+

首先我们需要做的是建立一个数组来存放立方体所有顶点的法线。由于立方体是一个很简单的物体,所以很容易实现;显然如果是对复杂物体,则法线的计算方法需要更深入的研究。(注:译者调试后发现此处 new WebGLFloatArray(...) 可能应该使用 new Float32Array())

cubeVerticesNormalBuffer = gl.createBuffer();
 gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesNormalBuffer);
@@ -78,17 +78,17 @@ 

建立顶点法线

gl.bufferData(gl.ARRAY_BUFFER, new WebGLFloatArray(vertexNormals), gl.STATIC_DRAW);
-

现在我们应该对此非常熟悉了;创建新的buffer,将它和gl.ARRAR_BUFFER绑定在一起,然后通过调用bufferData()把我们的顶点法线数组一起传入。

+

现在我们应该对此非常熟悉了;创建新的 buffer,将它和 gl.ARRAR_BUFFER 绑定在一起,然后通过调用 bufferData() 把我们的顶点法线数组一起传入。

-

然后我们在drawScene()中添加代码,将法线数组和着色器的attribute绑定起来以便着色器能够获取到法线数组的信息。

+

然后我们在 drawScene() 中添加代码,将法线数组和着色器的 attribute 绑定起来以便着色器能够获取到法线数组的信息。

-

(此处变量 vertexNormalAttribute 应该在initShader()函数中声明, 并赋值: vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal"); gl.enableVertexAttribArray(vertexNormalAttribute);)

+

(此处变量 vertexNormalAttribute 应该在 initShader() 函数中声明, 并赋值: vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal"); gl.enableVertexAttribArray(vertexNormalAttribute);)

gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesNormalBuffer);
 gl.vertexAttribPointer(vertexNormalAttribute, 3, gl.FLOAT, false, 0, 0);
 
-

最后,我们(为了读者便于理解, 此处代码应该在setMatrixUniforms() 函数中添加)需要更新下代码,在着色器中建立和传递法线向量矩阵,用这个矩阵来处理当前立方体相对于光源位置法线向量的转换(注:译者调试后发现此处new WebGLFloatArray(...) 应该使用new Float32Array()):

+

最后,我们(为了读者便于理解, 此处代码应该在 setMatrixUniforms() 函数中添加)需要更新下代码,在着色器中建立和传递法线向量矩阵,用这个矩阵来处理当前立方体相对于光源位置法线向量的转换 (注:译者调试后发现此处 new WebGLFloatArray(...) 应该使用 new Float32Array()):

var normalMatrix = mvMatrix.inverse();
 normalMatrix = normalMatrix.transpose();
@@ -136,9 +136,9 @@ 

顶点着色器

一旦顶点位置计算完毕,我们就可以获得纹理对应于顶点的坐标,从而计算出顶点的阴影。

-

我们先根据立方体位置和朝向,通过顶点法线乘以法线矩阵来转换法线。接着我们可以通过计算转换过后的法线与方向向量(即,光来自的方向)的点积来计算得出顶点反射方向光的量。如果计算出的这个值小于0,则我们把值固定设为0,因为你不会有小于0的光。

+

我们先根据立方体位置和朝向,通过顶点法线乘以法线矩阵来转换法线。接着我们可以通过计算转换过后的法线与方向向量(即,光来自的方向)的点积来计算得出顶点反射方向光的量。如果计算出的这个值小于 0,则我们把值固定设为 0,因为你不会有小于 0 的光。

-

当方向光的量计算完,我们可以通过获取环境光并且添加方向光的颜色和要提供的定向光的量来生成光照值(lighting value)。最终结果我们会得到一个RGB值,用于片段着色器调整我们渲染的每一个像素的颜色。

+

当方向光的量计算完,我们可以通过获取环境光并且添加方向光的颜色和要提供的定向光的量来生成光照值(lighting value)。最终结果我们会得到一个 RGB 值,用于片段着色器调整我们渲染的每一个像素的颜色。

片段着色器

diff --git a/files/zh-cn/web/api/webgl_api/tutorial/using_shaders_to_apply_color_in_webgl/index.html b/files/zh-cn/web/api/webgl_api/tutorial/using_shaders_to_apply_color_in_webgl/index.html index 4f2c37046ca48b..162537f2c3772b 100644 --- a/files/zh-cn/web/api/webgl_api/tutorial/using_shaders_to_apply_color_in_webgl/index.html +++ b/files/zh-cn/web/api/webgl_api/tutorial/using_shaders_to_apply_color_in_webgl/index.html @@ -1,5 +1,5 @@ --- -title: 使用着色器将颜色应用于WebGL +title: 使用着色器将颜色应用于 WebGL slug: Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL tags: - WebGL @@ -12,9 +12,9 @@

给顶点着色

-

在GL中,物体是由一系列顶点组成的,每一个顶点都有位置和颜色信息。在默认情况下,所有像素的颜色(以及它所有的属性,包括位置)都由线性插值计算得来,自动形成平滑的渐变。我们以前的顶点着色器没有给顶点添加任何特定的颜色——在顶点着色器与片段着色器之间给每个像素着白色,于是整个正方形被渲染成纯白。

+

在 GL 中,物体是由一系列顶点组成的,每一个顶点都有位置和颜色信息。在默认情况下,所有像素的颜色(以及它所有的属性,包括位置)都由线性插值计算得来,自动形成平滑的渐变。我们以前的顶点着色器没有给顶点添加任何特定的颜色——在顶点着色器与片段着色器之间给每个像素着白色,于是整个正方形被渲染成纯白。

-

现在我们假设正方形的每个顶点使用不同的颜色:红,黄,绿,白,以此渲染一个渐变的色彩。第一步,要给这些顶点建立相应的颜色。首先我们要创建一个顶点颜色数组,然后将它们存在WebGL的缓冲区中。为实现这一功能,我们在 initBuffers() 函数中加入如下代码:

+

现在我们假设正方形的每个顶点使用不同的颜色:红,黄,绿,白,以此渲染一个渐变的色彩。第一步,要给这些顶点建立相应的颜色。首先我们要创建一个顶点颜色数组,然后将它们存在 WebGL 的缓冲区中。为实现这一功能,我们在 initBuffers() 函数中加入如下代码:

initBuffers() {
   const positionBuffer = gl.createBuffer();
@@ -50,7 +50,7 @@ 

给顶点着色

}; }
-

这段代码首先建立了一个JavaScript的数组,此数组中包含四组四值向量,每一组向量代表一个顶点的颜色。然后,创建一个WebGL缓冲区用来存储这些颜色——将数组中的值转换成WebGL所规定的浮点型后,存储在该缓冲区中。

+

这段代码首先建立了一个 JavaScript 的数组,此数组中包含四组四值向量,每一组向量代表一个顶点的颜色。然后,创建一个 WebGL 缓冲区用来存储这些颜色——将数组中的值转换成 WebGL 所规定的浮点型后,存储在该缓冲区中。

为了实际使用这些颜色,我们继续修改顶点着色器,使得着色器可以从颜色缓冲区中正确取出颜色:

diff --git a/files/zh-cn/web/api/webgl_api/tutorial/using_textures_in_webgl/index.html b/files/zh-cn/web/api/webgl_api/tutorial/using_textures_in_webgl/index.html index 07b3eb20423640..7ffeeb4fa8b849 100644 --- a/files/zh-cn/web/api/webgl_api/tutorial/using_textures_in_webgl/index.html +++ b/files/zh-cn/web/api/webgl_api/tutorial/using_textures_in_webgl/index.html @@ -5,11 +5,11 @@ ---

{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL", "Web/API/WebGL_API/Tutorial/Lighting_in_WebGL")}}

-

现在我们已经创建好了一个可以旋转的3D的立方体,接下来是时候使用贴图来代替每个面的单一的颜色了。

+

现在我们已经创建好了一个可以旋转的 3D 的立方体,接下来是时候使用贴图来代替每个面的单一的颜色了。

加载纹理

-

首先加入加载纹理的代码。现在我们只使用一张单一的纹理贴到立方体的6个面上,但是同样的方法可以用来加载任意数量的纹理贴图。

+

首先加入加载纹理的代码。现在我们只使用一张单一的纹理贴到立方体的 6 个面上,但是同样的方法可以用来加载任意数量的纹理贴图。

注意: 值得注意的一点是对纹理的加载同样需要遵循跨域访问规则;也就是说你只能从允许跨域访问的网址加载你需要的纹理。下面的例子就是支持跨域访问的。
@@ -32,25 +32,25 @@

加载纹理

}
-

函数 initTextures() 首先调用 GL {{domxref("WebGLRenderingContext.createTexture()", "createTexture()")}} 函数来创建一个GL纹理对象 cubeTexture 。为了把图片文件加载到纹理,代码首先创建了一个 Image 对象然后把需要当作纹理使用的图形文件加载了进来。当图片加载完成后回调函数 handleTextureLoaded() 就会执行。

+

函数 initTextures() 首先调用 GL {{domxref("WebGLRenderingContext.createTexture()", "createTexture()")}} 函数来创建一个 GL 纹理对象 cubeTexture 。为了把图片文件加载到纹理,代码首先创建了一个 Image 对象然后把需要当作纹理使用的图形文件加载了进来。当图片加载完成后回调函数 handleTextureLoaded() 就会执行。

接下来为了真正地形成纹理,我们通过把新创建的纹理对象绑定到 gl.TEXTURE_2D 来让它成为当前操作纹理。然后通过调用 {{domxref("WebGLRenderingContext.texImage2D()", "texImage2D()")}} 把已经加载的图片图形数据写到纹理。

-
注意: 在多数情况下,纹理的宽和高都必须是2的幂(如:1,2,4,8,16等等)。如果有什么特殊情况请参考下面的“非2的幂纹理”小节。
+
注意: 在多数情况下,纹理的宽和高都必须是 2 的幂(如:1,2,4,8,16 等等)。如果有什么特殊情况请参考下面的“非 2 的幂纹理”小节。

代码的接下来两行设置了纹理过滤器,过滤器用来控制当图片缩放时像素如何生成如何插值。在这个例子里,我们对图片放大使用的是线性过滤,而对图片缩小使用的是多级渐进纹理过滤。接下来我们通过调用 {{domxref("WebGLRenderingContext.generateMipMap()", "generateMipMap()")}} 来生成多级渐进纹理,接着通过给 gl.TEXTURE_2D 绑定值 null 来告诉 WebGL 我们对当前纹理的操作已经结束了。

-

非2的幂纹理

+

非 2 的幂纹理

-

一般来说,宽和高都是2的幂的纹理使用是最理想的。2的幂纹理在渲染内存里的存储更高效,而且对它们的使用限制也更少。由美术工作人员生成的纹理最终在用来渲染前都应该使用放大或缩小的方式把它生成为2的幂纹理,其实事实上来说,在创作纹理之初就应该直接使用大小是2的幂的宽和高。纹理的每一边都应该是像1,2,4,8,16,32,64,128,256,512,1024或2048这样的值。当然也要注意尺寸的大小,因为虽说现在的大部分设置都已经可以支持4096像素的图片,但也不是全部;而有一些设备甚至可以支持8192或更高像素呢。

+

一般来说,宽和高都是 2 的幂的纹理使用是最理想的。2 的幂纹理在渲染内存里的存储更高效,而且对它们的使用限制也更少。由美术工作人员生成的纹理最终在用来渲染前都应该使用放大或缩小的方式把它生成为 2 的幂纹理,其实事实上来说,在创作纹理之初就应该直接使用大小是 2 的幂的宽和高。纹理的每一边都应该是像 1,2,4,8,16,32,64,128,256,512,1024 或 2048 这样的值。当然也要注意尺寸的大小,因为虽说现在的大部分设置都已经可以支持 4096 像素的图片,但也不是全部;而有一些设备甚至可以支持 8192 或更高像素呢。

-

有的时候从你的特定情况出发,使用2的幂纹理会比较困难。当使用到第三方的资源时,一般来说最好的方式就是先使用HTML5的画布把图片修正成2的幂然后再放到WebGL中进行渲染使用,这样一来,如果图片拉伸比较明显的话纹理坐标的值可需要适当地进行修正。

+

有的时候从你的特定情况出发,使用 2 的幂纹理会比较困难。当使用到第三方的资源时,一般来说最好的方式就是先使用 HTML5 的画布把图片修正成 2 的幂然后再放到 WebGL 中进行渲染使用,这样一来,如果图片拉伸比较明显的话纹理坐标的值可需要适当地进行修正。

-

但是,如果你一定要使用非2的幂纹理的话,WebGL也有原生支持,不过这些支持是受限的。当然在某些情况下使用非2的幂纹理也是很有用的,比如这张纹理刚好与你的显示器的分辨率相匹配,或者使用画布重新生成纹理的方式并不值得时。但是要特别注意的是:这种非2的幂纹理不能用来生成多级渐进纹理,而且不能使用纹理重复(重复纹理寻址等)。

+

但是,如果你一定要使用非 2 的幂纹理的话,WebGL 也有原生支持,不过这些支持是受限的。当然在某些情况下使用非 2 的幂纹理也是很有用的,比如这张纹理刚好与你的显示器的分辨率相匹配,或者使用画布重新生成纹理的方式并不值得时。但是要特别注意的是:这种非 2 的幂纹理不能用来生成多级渐进纹理,而且不能使用纹理重复(重复纹理寻址等)。

使用重复纹理寻址的一个例子就是使用一张砖块的纹理来平铺满一面墙壁。

-

多级渐进纹理和纹理坐标重复可以通过调用 {{domxref("WebGLRenderingContext.texParameter()", "texParameteri()")}} 来禁用,当然首先你已经通过调用 {{domxref("WebGLRenderingContext.bindTexture()", "bindTexture()")}} 绑定过纹理了。这样虽然已经可以使用非2的幂纹理了,但是你将无法使用多级渐进纹理,纹理坐标包装,纹理坐标重复,而且无法控制设备如何处理你的纹理。

+

多级渐进纹理和纹理坐标重复可以通过调用 {{domxref("WebGLRenderingContext.texParameter()", "texParameteri()")}} 来禁用,当然首先你已经通过调用 {{domxref("WebGLRenderingContext.bindTexture()", "bindTexture()")}} 绑定过纹理了。这样虽然已经可以使用非 2 的幂纹理了,但是你将无法使用多级渐进纹理,纹理坐标包装,纹理坐标重复,而且无法控制设备如何处理你的纹理。

// gl.NEAREST is also allowed, instead of gl.LINEAR, as neither mipmap.
 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
@@ -59,7 +59,7 @@ 

非2的幂纹理

// Prevents t-coordinate wrapping (repeating). gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
-

现在,当使用以上参数时,兼容WebGL的设备就会自动变得可以使用任何分辨率的纹理(当然还要考虑像素上限)。如果不使用上面这些参数的话,任何非2的幂纹理使用都会失败然后返回一张纯黑图片。

+

现在,当使用以上参数时,兼容 WebGL 的设备就会自动变得可以使用任何分辨率的纹理(当然还要考虑像素上限)。如果不使用上面这些参数的话,任何非 2 的幂纹理使用都会失败然后返回一张纯黑图片。

映射纹理到面

@@ -105,11 +105,11 @@

映射纹理到面

gl.STATIC_DRAW);
-

首先,代码创建了一个GL缓存区,用来保存每个面的纹理坐标信息,然后把这个缓存区绑定到GL以方便我们写入数据。

+

首先,代码创建了一个 GL 缓存区,用来保存每个面的纹理坐标信息,然后把这个缓存区绑定到 GL 以方便我们写入数据。

-

数组变量 textureCoordinates 中定义好了与每个面上的每个顶点一一对应的纹理坐标。请注意,纹理坐标的取值范围只能从0.0到1.0,所以不论纹理贴图的实际大小是多少,为了实现纹理映射,我们要使用的纹理坐标只能规范化到0.0到1.0的范围内。

+

数组变量 textureCoordinates 中定义好了与每个面上的每个顶点一一对应的纹理坐标。请注意,纹理坐标的取值范围只能从 0.0 到 1.0,所以不论纹理贴图的实际大小是多少,为了实现纹理映射,我们要使用的纹理坐标只能规范化到 0.0 到 1.0 的范围内。

-

纹理坐标信息给定了之后,把这个数组里的数据都写到GL缓存区,这样GL就能使用这个坐标数据了。

+

纹理坐标信息给定了之后,把这个数组里的数据都写到 GL 缓存区,这样 GL 就能使用这个坐标数据了。

更新着色器

@@ -174,7 +174,7 @@

绘制具体纹理贴图的立方 gl.uniform1i(gl.getUniformLocation(shaderProgram, "uSampler"), 0); -

GL 最多可同时注册32张纹理;gl.TEXTURE0 是第一张。我们把我们之前加载的纹理绑定到了第一个寄存器,然后着色器程序里的采样器 uSampler 就会完成它的功能:使用纹理。

+

GL 最多可同时注册 32 张纹理;gl.TEXTURE0 是第一张。我们把我们之前加载的纹理绑定到了第一个寄存器,然后着色器程序里的采样器 uSampler 就会完成它的功能:使用纹理。

好,现在我们的立方体就会像这样旋转起来了。

@@ -184,18 +184,18 @@

绘制具体纹理贴图的立方

关于跨域纹理

-

加载WebGL纹理应该也可以说是跨域访问控制里的一个话题。为了在我们的显示内容里使用其它域名里的纹理图片,允许跨域访问也是要考虑的。可以通过查看HTTP访问控制来获取到更多的相关细节。

+

加载 WebGL 纹理应该也可以说是跨域访问控制里的一个话题。为了在我们的显示内容里使用其它域名里的纹理图片,允许跨域访问也是要考虑的。可以通过查看HTTP 访问控制来获取到更多的相关细节。

-

这篇文章也对跨域加载纹理到WebGL做出了解释。而且文章里面还包含了一个使用的例子

+

这篇文章也对跨域加载纹理到 WebGL 做出了解释。而且文章里面还包含了一个使用的例子

-

注意:对跨域加载WebGL纹理的支持和对 image 元素的 crossOrigin 的属性的支持都是在 {{Gecko("8.0")}} 版本中实现的。

+

注意:对跨域加载 WebGL 纹理的支持和对 image 元素的 crossOrigin 的属性的支持都是在 {{Gecko("8.0")}} 版本中实现的。

-

被污染过的(只写)画布是不能拿来当作WebGL纹理来使用的。举个例子来说,当把一张跨域的图片画到一个2D的 {{ HTMLElement("canvas") }} 中时,这个画布就是“被污染过的”。

+

被污染过的(只写)画布是不能拿来当作 WebGL 纹理来使用的。举个例子来说,当把一张跨域的图片画到一个 2D 的 {{ HTMLElement("canvas") }} 中时,这个画布就是“被污染过的”。

-

注意: 对 Canvas 2D 的 drawImage 的跨域支持已经在 {{Gecko("9.0")}} 版本实现的。这就意味着使用支持跨域的图片来污染一个2D的画布,这张画布也已经可以作为WebGL的纹理来使用了。

+

注意: 对 Canvas 2D 的 drawImage 的跨域支持已经在 {{Gecko("9.0")}} 版本实现的。这就意味着使用支持跨域的图片来污染一个 2D 的画布,这张画布也已经可以作为 WebGL 的纹理来使用了。

diff --git a/files/zh-cn/web/api/webgl_api/types/index.html b/files/zh-cn/web/api/webgl_api/types/index.html index 20d8267e8af584..1c58d42dc86f32 100644 --- a/files/zh-cn/web/api/webgl_api/types/index.html +++ b/files/zh-cn/web/api/webgl_api/types/index.html @@ -15,7 +15,7 @@

WebGL 1

- + @@ -36,22 +36,22 @@

WebGL 1

- + - + - + - + @@ -66,40 +66,40 @@

WebGL 1

- + - + - + - + - +
BLEND_EQUATION 0x8009传递给 getParameter 以获取当前的RGB混合函数。传递给 getParameter 以获取当前的 RGB 混合函数。
BLEND_EQUATION_RGB 0x8009传递给 getParameter 以获取当前的RGB混合函数。与 BLEND_EQUATION 相同。传递给 getParameter 以获取当前的 RGB 混合函数。与 BLEND_EQUATION 相同。
BLEND_EQUATION_ALPHA 0x883D传递给 getParameter 以获取当前的alpha函数。与 BLEND_EQUATION 相同。传递给 getParameter 以获取当前的 alpha 函数。与 BLEND_EQUATION 相同。
BLEND_DST_RGB 0x80C8传递给 getParameter 以获取当前的目标RGB混合函数。传递给 getParameter 以获取当前的目标 RGB 混合函数。
BLEND_SRC_RGB 0x80C9传递给 getParameter 以获取当前的源RGB混合函数。传递给 getParameter 以获取当前的源 RGB 混合函数。
BLEND_DST_ALPHA 0x80CA传递给 getParameter 以获取当前目标的alpha混合函数。传递给 getParameter 以获取当前目标的 alpha 混合函数。
BLEND_SRC_ALPHA 0x80CB传递给 getParameter 以获取当前的源alpha混合函数。传递给 getParameter 以获取当前的源 alpha 混合函数。
BLEND_COLOR
ALIASED_LINE_WIDTH_RANGE 0x846E传递给 getParameter 得到一条线的可用宽度范围。返回一个长度为2的数组。其中低值为0,高值为1。传递给 getParameter 得到一条线的可用宽度范围。返回一个长度为 2 的数组。其中低值为 0,高值为 1。
CULL_FACE_MODE
DEPTH_RANGE 0x0B70传递给 getParameter 返回长度为2的浮点数数组,以表示当前深度范围。传递给 getParameter 返回长度为 2 的浮点数数组,以表示当前深度范围。
DEPTH_WRITEMASK
类型Web接口类型Web 接口类型 描述
GLbyte byte八位(一个字节),2的补码表示的有符号整数。八位(一个字节),2 的补码表示的有符号整数。
GLshort short十六位2的补码表示的有符号整数。十六位 2 的补码表示的有符号整数。
GLint long三十二位2的补码表示的有符号整数。三十二位 2 的补码表示的有符号整数。
GLsizei long用来描述尺寸(例如:绘画缓冲drawing buffer的宽和高)。用来描述尺寸(例如:绘画缓冲 drawing buffer 的宽和高)。
GLintptr
GLubyte octet八位(一个字节),2的补码表示的无符号整数。八位(一个字节),2 的补码表示的无符号整数。
GLushort unsigned short十六位2的补码表示的无符号整数。十六位 2 的补码表示的无符号整数。
GLuint unsigned long三十二位2的补码表示的有符号整数。三十二位 2 的补码表示的有符号整数。
GLfloat unrestricted float三十二位的IEEE标准的浮点数。三十二位的 IEEE 标准的浮点数。
GLclampf unrestricted float限值32位IEEE浮点数。限值 32 位 IEEE 浮点数。

WebGL 2

-

以下类型的变量属于 {{domxref("WebGL2RenderingContext")}}. 所有WebGL 1中的类型也有使用。

+

以下类型的变量属于 {{domxref("WebGL2RenderingContext")}}. 所有 WebGL 1 中的类型也有使用。

- + @@ -118,7 +118,7 @@

WebGL 扩展

- + @@ -146,7 +146,7 @@

规范

- + diff --git a/files/zh-cn/web/api/webgl_api/using_extensions/index.html b/files/zh-cn/web/api/webgl_api/using_extensions/index.html index 183cc5df3be2bf..5382ed39911eb9 100644 --- a/files/zh-cn/web/api/webgl_api/using_extensions/index.html +++ b/files/zh-cn/web/api/webgl_api/using_extensions/index.html @@ -7,13 +7,13 @@ ---
{{WebGLSidebar}}
-

WebGL,像它的姐妹API (OpenGL and OpenGL ES),支持使用扩展(extensions)。一份完整的扩展列表可在 khronos webgl extension registry

+

WebGL,像它的姐妹 API (OpenGL and OpenGL ES),支持使用扩展(extensions)。一份完整的扩展列表可在 khronos webgl extension registry

-
Note: 不像别的 GL APIs, 在webGL中 , 扩展只有在明确需要的情况下才会加载。
+
Note: 不像别的 GL APIs,在 webGL 中 , 扩展只有在明确需要的情况下才会加载。

规范扩展名,供应商前缀和首选项

-

扩展(extensions)在未被官方正式制定为标准前,某些浏览器厂商可能会支持WebGL扩展 (but only when they are in draft stage)。这样的话,扩展的名字应该加上相应的厂商前缀 (MOZ_, WEBKIT_, etc.),否则这个扩展只能在浏览器切换了偏好设置的前提下生效。

+

扩展(extensions)在未被官方正式制定为标准前,某些浏览器厂商可能会支持 WebGL 扩展 (but only when they are in draft stage)。这样的话,扩展的名字应该加上相应的厂商前缀 (MOZ_, WEBKIT_, etc.),否则这个扩展只能在浏览器切换了偏好设置的前提下生效。

If you wish to work with the bleeding edge of extensions, and want to keep working on upon ratification (assuming, of course, that the extension doesn't change in incompatible ways), that you query the canonical extension name as well as the vendor extension name. For instance:

diff --git a/files/zh-cn/web/api/webgl_api/webgl_best_practices/index.html b/files/zh-cn/web/api/webgl_api/webgl_best_practices/index.html index 17e5c7816b3bf5..55b4a2a6419235 100644 --- a/files/zh-cn/web/api/webgl_api/webgl_best_practices/index.html +++ b/files/zh-cn/web/api/webgl_api/webgl_best_practices/index.html @@ -7,24 +7,24 @@ ---

{{WebGLSidebar}}

-

WebGL是一个复杂的API,通常我们不能明显的知道它的推荐使用方式。该页面涵盖了各种专业知识的建议,不仅仅是列举出什么该做,什么不该做,还有详细的解释为什么要这样做。你可以将本文档作为指导你选择的方法,确保你无论在何种浏览器以及硬件上都使用了正确的技巧。

+

WebGL 是一个复杂的 API,通常我们不能明显的知道它的推荐使用方式。该页面涵盖了各种专业知识的建议,不仅仅是列举出什么该做,什么不该做,还有详细的解释为什么要这样做。你可以将本文档作为指导你选择的方法,确保你无论在何种浏览器以及硬件上都使用了正确的技巧。

需要避免的事情

    -
  • 确保应用程序运行时不会产生任何WebGL错误(如getError()返回的). In Firefox, every WebGL error (until a certain limit), and some other WebGL issues, are reported as a JavaScript warning with a descriptive message. 在 Firefox 中,所有 WebGL 错误(直至超出数量限制)以及其它一些 WebGL 问题,都会以一段提供描述的 JavaScript 警告报告出来。你不想自己的应用在用户的控制台打印出一堆东西对吧?你当然不想了。
  • +
  • 确保应用程序运行时不会产生任何 WebGL 错误(如 getError() 返回的). In Firefox, every WebGL error (until a certain limit), and some other WebGL issues, are reported as a JavaScript warning with a descriptive message. 在 Firefox 中,所有 WebGL 错误(直至超出数量限制)以及其它一些 WebGL 问题,都会以一段提供描述的 JavaScript 警告报告出来。你不想自己的应用在用户的控制台打印出一堆东西对吧?你当然不想了。
  • 你应该永远不去触碰 WebGL shader 里的 #ifdef GL_ES ;虽然前边的一些例子使用了这个,这并无必要,因为这个条件判断在 WebGL shader 中始终为 true。
  • -
  • 在 fragment shader 中使用 highp 精度将阻碍你的内容在某些旧的移动设备上正确运行。这里,你可以使用 mediump;但是,你需要知道,由于在大多移动设备上的精度丢失,这经常导致渲染失败,这在典型的 PC 机型上没有问题。通常来说,在vertex 和 fragment shader 中仅使用 highp ,除非 shaders 通过了各大平台的测试。从 Firefox 11 开始,WebGL 的 getShaderPrecisionFormat() 函数的实现,允许你判断 highp 是否得到支持,进而允许你可以查询到实际的精度。
  • +
  • 在 fragment shader 中使用 highp 精度将阻碍你的内容在某些旧的移动设备上正确运行。这里,你可以使用 mediump;但是,你需要知道,由于在大多移动设备上的精度丢失,这经常导致渲染失败,这在典型的 PC 机型上没有问题。通常来说,在 vertex 和 fragment shader 中仅使用 highp ,除非 shaders 通过了各大平台的测试。从 Firefox 11 开始,WebGL 的 getShaderPrecisionFormat() 函数的实现,允许你判断 highp 是否得到支持,进而允许你可以查询到实际的精度。

需要记住的事情

    -
  • 在客户端/浏览器使用某些WebGL功能前,还是建议先使用 WebGL getParameter() 方法,获取此类参数的范围,这些数据反映了你的客户端能够支持的真实应用范围。例如,使用 webgl.getParameter(webgl.MAX_TEXTURE_SIZE)可以查询设备上支持的最大的2D纹理尺寸。从Firefox 10开始,WebGL 属性 webgl.min_capability_mode 则可以被用来测试最小性能模式下的实际表现,以测试可移植性。
  • -
  • 特别要注意的是,只有在 webgl.getParameter(webgl.MAX_VERTEX_TEXTURE_IMAGE_UNITS) 大于零时,才能使用vertex shaders中的纹理。然而,目前的移动硬件上是不支持的 (译者:待确认文档时效性)。
  • -
  • 大多数WebGL扩展的可用性取决于客户端。 在使用WebGL扩展时,如果可能的话,尝试通过优雅地适应不支持它们的情况,使它们成为可选的。从Firefox 10开始,属性 webgl.disable-extensions 允许模拟列出哪些扩展是不支持的,以测试可移植性。
  • -
  • 另外,即使支持 OES_texture_float 扩展,也可能不支持渲染浮点类型数据的纹理。 通常,这在当前的移动硬件上是不支持的 (译者:待确认文档时效性)。 要检查是否支持浮点类型数据,必须调用 checkFramebufferStatus() 来验证.
  • -
  • 实际渲染到画布的分辨率可以不同于样式表最终强制画布显示的分辨率。如果考虑性能,你应该试着渲染到一个低分辨率WebGL上下文,并使用CSS来升级它的画布到你想要的尺寸。
  • +
  • 在客户端/浏览器使用某些 WebGL 功能前,还是建议先使用 WebGL getParameter() 方法,获取此类参数的范围,这些数据反映了你的客户端能够支持的真实应用范围。例如,使用 webgl.getParameter(webgl.MAX_TEXTURE_SIZE)可以查询设备上支持的最大的 2D 纹理尺寸。从 Firefox 10 开始,WebGL 属性 webgl.min_capability_mode 则可以被用来测试最小性能模式下的实际表现,以测试可移植性。
  • +
  • 特别要注意的是,只有在 webgl.getParameter(webgl.MAX_VERTEX_TEXTURE_IMAGE_UNITS) 大于零时,才能使用 vertex shaders 中的纹理。然而,目前的移动硬件上是不支持的 (译者:待确认文档时效性)。
  • +
  • 大多数 WebGL 扩展的可用性取决于客户端。 在使用 WebGL 扩展时,如果可能的话,尝试通过优雅地适应不支持它们的情况,使它们成为可选的。从 Firefox 10 开始,属性 webgl.disable-extensions 允许模拟列出哪些扩展是不支持的,以测试可移植性。
  • +
  • 另外,即使支持 OES_texture_float 扩展,也可能不支持渲染浮点类型数据的纹理。 通常,这在当前的移动硬件上是不支持的 (译者:待确认文档时效性)。 要检查是否支持浮点类型数据,必须调用 checkFramebufferStatus() 来验证。
  • +
  • 实际渲染到画布的分辨率可以不同于样式表最终强制画布显示的分辨率。如果考虑性能,你应该试着渲染到一个低分辨率 WebGL 上下文,并使用 CSS 来升级它的画布到你想要的尺寸。

一般性能提示

diff --git a/files/zh-cn/web/api/webgl_api/webgl_model_view_projection/index.html b/files/zh-cn/web/api/webgl_api/webgl_model_view_projection/index.html index 84470f2439314d..3168904418545d 100644 --- a/files/zh-cn/web/api/webgl_api/webgl_model_view_projection/index.html +++ b/files/zh-cn/web/api/webgl_api/webgl_model_view_projection/index.html @@ -5,36 +5,36 @@ ---

{{WebGLSidebar}}

-

本文探讨如何在WebGL项目中获取数据,并将其投影到适当的空间以在屏幕上显示。 它假定了你具备用于平移,缩放和旋转的基本矩阵数学知识。它解释了组成3D场景时通常使用的三个核心矩阵:模型,视图和投影矩阵。

+

本文探讨如何在 WebGL 项目中获取数据,并将其投影到适当的空间以在屏幕上显示。 它假定了你具备用于平移,缩放和旋转的基本矩阵数学知识。它解释了组成 3D 场景时通常使用的三个核心矩阵:模型,视图和投影矩阵。

-

注意: 本文还可作为 MDN 内容套件 提供。它还使用 MDN全局对象下可用的 实用函数 集合。

+

注意:本文还可作为 MDN 内容套件 提供。它还使用 MDN全局对象下可用的 实用函数 集合。

模型、视图、投影矩阵

-

WebGL空间中的点和多边形的个体转化由基本的转换矩阵(例如平移,缩放和旋转)处理。可以将这些矩阵组合在一起并以特殊方式分组,以使其用于渲染复杂的3D场景。这些组合成的矩阵最终将原始数据类型移动到一个称为裁剪空间的特殊坐标空间中。这是一个中心点位于(0, 0, 0),角落范围在 (-1, -1, -1) 到 (1, 1, 1) 之间,2个单位宽的立方体。该剪裁空间被压缩到一个二维空间并栅格化为图像。

+

WebGL 空间中的点和多边形的个体转化由基本的转换矩阵(例如平移,缩放和旋转)处理。可以将这些矩阵组合在一起并以特殊方式分组,以使其用于渲染复杂的 3D 场景。这些组合成的矩阵最终将原始数据类型移动到一个称为裁剪空间的特殊坐标空间中。这是一个中心点位于 (0, 0, 0),角落范围在 (-1, -1, -1) 到 (1, 1, 1) 之间,2 个单位宽的立方体。该剪裁空间被压缩到一个二维空间并栅格化为图像。

-

下面讨论的第一个矩阵是模型矩阵,它定义了如何获取原始模型数据并将其在3D世界空间中移动。投影矩阵用于将世界空间坐标转换为剪裁空间坐标。常用的投影矩阵(透视矩阵)用于模拟充当3D虚拟世界中观看者的替身的典型相机的效果。视图矩阵负责移动场景中的对象以模拟相机位置的变化,改变观察者当前能够看到的内容。

+

下面讨论的第一个矩阵是模型矩阵,它定义了如何获取原始模型数据并将其在 3D 世界空间中移动。投影矩阵用于将世界空间坐标转换为剪裁空间坐标。常用的投影矩阵(透视矩阵)用于模拟充当 3D 虚拟世界中观看者的替身的典型相机的效果。视图矩阵负责移动场景中的对象以模拟相机位置的变化,改变观察者当前能够看到的内容。

以下的几个部分提供了对模型,视图和投影矩阵背后的思想及实现的深入理解。这些矩阵是在屏幕上移动数据的核心,是胜过各个框架和引擎的概念。

裁剪空间

-

在WebGL程序中,数据通常上传到具有自己的坐标系统的GPU上,然后顶点着色器将这些点转换到一个称为裁剪空间的特殊坐标系上。延展到裁剪空间之外的任何数据都会被剪裁并且不会被渲染。如果一个三角形超出了该空间的边界,则将其裁切成新的三角形,并且仅保留新三角形在裁剪空间中的部分。

+

在 WebGL 程序中,数据通常上传到具有自己的坐标系统的 GPU 上,然后顶点着色器将这些点转换到一个称为裁剪空间的特殊坐标系上。延展到裁剪空间之外的任何数据都会被剪裁并且不会被渲染。如果一个三角形超出了该空间的边界,则将其裁切成新的三角形,并且仅保留新三角形在裁剪空间中的部分。

A 3d graph showing clip space in WebGL.

-

上面的图像裁剪空间的可视化,所有点都必须被包含在其中。它是一个角在(-1, -1, -1),对角在 (1, 1, 1),中心点在 (0, 0, 0) 的每边2个单位的立方体。裁剪空间使用的这个两个立方米坐标系称为归一化设备坐标(NDC)。在研究和使用WebGL代码时,你可能时不时的会使用这个术语。

+

上面的图像裁剪空间的可视化,所有点都必须被包含在其中。它是一个角在 (-1, -1, -1),对角在 (1, 1, 1),中心点在 (0, 0, 0) 的每边 2 个单位的立方体。裁剪空间使用的这个两个立方米坐标系称为归一化设备坐标(NDC)。在研究和使用 WebGL 代码时,你可能时不时的会使用这个术语。

-

在本节中,我们将直接将数据放入裁剪空间坐标系中。通常使用位于任意坐标系中的模型数据,然后使用矩阵进行转换,将模型坐标转换为裁剪空间系下的坐标。这个例子,通过简单地使用从 (-1,-1,-1) 到 (1,1,1) 的模型坐标值来说明剪辑空间的工作方式是最简单的。下面的代码将创建2个三角形,这些三角形将在屏幕上绘制一个正方形。正方形中的Z深度确定当前正方形共享同一个空间时在顶部绘制的内容,较小的Z值将呈现在较大的Z值之上。

+

在本节中,我们将直接将数据放入裁剪空间坐标系中。通常使用位于任意坐标系中的模型数据,然后使用矩阵进行转换,将模型坐标转换为裁剪空间系下的坐标。这个例子,通过简单地使用从 (-1,-1,-1) 到 (1,1,1) 的模型坐标值来说明剪辑空间的工作方式是最简单的。下面的代码将创建 2 个三角形,这些三角形将在屏幕上绘制一个正方形。正方形中的 Z 深度确定当前正方形共享同一个空间时在顶部绘制的内容,较小的 Z 值将呈现在较大的 Z 值之上。

WebGLBox 例子

-

本示例将创建一个自定义WebGL对象,该对象将在屏幕上绘制一个2D框。

+

本示例将创建一个自定义 WebGL 对象,该对象将在屏幕上绘制一个 2D 框。

-

注意: 每一个WebGL示例代码在此 github repo 中可找到,并按章节组织。此外,每个章节底部都有一个 JSFiddle 链接。

+

注意: 每一个 WebGL 示例代码在此 github repo 中可找到,并按章节组织。此外,每个章节底部都有一个 JSFiddle 链接。

WebGLBox Constructor

@@ -51,7 +51,7 @@

WebGLBox Constructor

var gl = this.gl; - // 设置一个WebGL程序,任何MDN对象相关的部分在本文之外定义 + // 设置一个 WebGL 程序,任何 MDN 对象相关的部分在本文之外定义 this.webglProgram = MDN.createWebGLProgramFromIds(gl, 'vertex-shader', 'fragment-shader'); gl.useProgram(this.webglProgram); @@ -59,7 +59,7 @@

WebGLBox Constructor

this.positionLocation = gl.getAttribLocation(this.webglProgram, 'position'); this.colorLocation = gl.getUniformLocation(this.webglProgram, 'color'); - // 告诉WebGL在绘制时测试深度,所以如果一个正方形后面有另一个正方形 + // 告诉 WebGL 在绘制时测试深度,所以如果一个正方形后面有另一个正方形 // 另一个正方形不会被绘制 gl.enable(gl.DEPTH_TEST); @@ -112,7 +112,7 @@

WebGLBox 绘制

} -

着色器是用GLSL编写的代码片段,它接收我们的点数据并最终将它们渲染到屏幕上。为了方便起见,这些着色器存储在 {{htmlelement("script")}} 元素之中,该元素通过自定义函数 MDN.createWebGLProgramFromIds() 引入程序中。这个方法是为这些教程编写的 实用函数 集合的一部分,此处不再赘述。此函数用于处理获取一些GLSL源代码并将其编译为WebGL程序的基础操作。该函数具有三个参数-用于渲染程序的上下文,包含顶点着色器的 {{htmlelement("script")}} 元素的ID和包含片段着色器的 {{htmlelement("script")}} 元素的ID。顶点着色器放置顶点,片段着色器为每个像素着色。

+

着色器是用 GLSL 编写的代码片段,它接收我们的点数据并最终将它们渲染到屏幕上。为了方便起见,这些着色器存储在 {{htmlelement("script")}} 元素之中,该元素通过自定义函数 MDN.createWebGLProgramFromIds() 引入程序中。这个方法是为这些教程编写的 实用函数 集合的一部分,此处不再赘述。此函数用于处理获取一些 GLSL 源代码并将其编译为 WebGL 程序的基础操作。该函数具有三个参数 - 用于渲染程序的上下文,包含顶点着色器的 {{htmlelement("script")}} 元素的 ID 和包含片段着色器的 {{htmlelement("script")}} 元素的 ID。顶点着色器放置顶点,片段着色器为每个像素着色。

首先看一下将在屏幕上移动顶点的顶点着色器:

@@ -126,7 +126,7 @@

WebGLBox 绘制

} -

接下来,要实际将数据栅格化为像素,片段着色器将在每个像素的基础上计算评估一切,设置一个单一颜色。GPU为需要渲染的每个像素调用着色器方法。着色器的工作是返回要用于该像素的颜色。

+

接下来,要实际将数据栅格化为像素,片段着色器将在每个像素的基础上计算评估一切,设置一个单一颜色。GPU 为需要渲染的每个像素调用着色器方法。着色器的工作是返回要用于该像素的颜色。

precision mediump float;
 uniform vec4 color;
@@ -185,7 +185,7 @@ 

WebGLBox 绘制

结果

-

在JSFiddle中查看

+

在 JSFiddle 中查看

The results of drawing to clip space using WebGL.

@@ -200,11 +200,11 @@

齐次坐标

gl_Position = vec4(position, 1.0);
 
-

位置变量是在 draw() 方法中定义的,并作为 attribute 传递给着色器。这是一个三维点,但最终通过管线传递的 gl_Position 变量实际上是四维的 - 是 (x,y,z,w) 而不是  (x,y,z) 。 z 后面没有字母了,因此习惯上将第四维标记为 w。在上面的示例中,  w 坐标设置为1.0。

+

位置变量是在 draw() 方法中定义的,并作为 attribute 传递给着色器。这是一个三维点,但最终通过管线传递的 gl_Position 变量实际上是四维的 - 是 (x,y,z,w) 而不是  (x,y,z) 。 z 后面没有字母了,因此习惯上将第四维标记为 w。在上面的示例中,  w 坐标设置为 1.0。

-

显而易见的问题是:“为什么要增加维度?”。事实证明,这种增加允许使用许多不错的技术来处理3D数据。这个增加的维度将透视的概念引入坐标系中。将其放置在适当的位置后,我们可以将3D坐标映射到2D空间中,从而允许两条平行线当它们延伸到远方时相交。 w 的值被用作该坐标的其他分量放除数,因此  x,   y 和  z 的真实值被计算为  x/w ,  y/w 和  z/w(然后 w 也  w/w , 变成1)。

+

显而易见的问题是:“为什么要增加维度?”。事实证明,这种增加允许使用许多不错的技术来处理 3D 数据。这个增加的维度将透视的概念引入坐标系中。将其放置在适当的位置后,我们可以将 3D 坐标映射到 2D 空间中,从而允许两条平行线当它们延伸到远方时相交。 w 的值被用作该坐标的其他分量放除数,因此  x,   y 和  z 的真实值被计算为  x/w ,  y/w 和  z/w(然后 w 也  w/w , 变成 1)。

-

三维点定义在典型的笛卡尔坐标系中。增加的第四维将这一点变为  {{interwiki("wikipedia", "homogeneous coordinates", "齐次坐标")}} 。它仍然代表3D空间中的一个点,并且可以通过一对简单的函数轻松地演示如何构造这种类型的坐标。

+

三维点定义在典型的笛卡尔坐标系中。增加的第四维将这一点变为  {{interwiki("wikipedia", "homogeneous coordinates", "齐次坐标")}} 。它仍然代表 3D 空间中的一个点,并且可以通过一对简单的函数轻松地演示如何构造这种类型的坐标。

function cartesianToHomogeneous(point) {
 
@@ -226,7 +226,7 @@ 

齐次坐标

}
-

正如前面提到的和上面展示的函数,w 分量将和 x, y 和z相除。当 w 分量为非零实数时,齐次坐标很容易转换回笛卡尔空间中。现在,如果 w 分量为零会发生什么?在JavaScript 中,返回值如下:

+

正如前面提到的和上面展示的函数,w 分量将和 x, y 和 z 相除。当 w 分量为非零实数时,齐次坐标很容易转换回笛卡尔空间中。现在,如果 w 分量为零会发生什么?在 JavaScript 中,返回值如下:

homogeneousToCartesian([10, 4, 5, 0]);
 
@@ -237,9 +237,9 @@

齐次坐标

当计算机上的数字非常大(或非常小)时,它们的精确度将越来越低,因为仅用这么多的“1”和“0”来表示它们。对较大的数字执行的操作越多,结果中就会积累越来越多的错误。当除以 w 时,这可以通过两个可能更小,更不易出错的数字进行运算来有效地提高非常大的数字的精度。

-

使用齐次坐标的最终好处是,它们非常适合与4x4矩阵相乘。一个顶点必须至少与矩阵的一个维数(行/列)匹配,才能与其相乘。4x4矩阵可用于编码各种转换。实际上,典型的透视矩阵使用 w 分量除法来实现其变换。

+

使用齐次坐标的最终好处是,它们非常适合与 4x4 矩阵相乘。一个顶点必须至少与矩阵的一个维数(行/列)匹配,才能与其相乘。4x4 矩阵可用于编码各种转换。实际上,典型的透视矩阵使用 w 分量除法来实现其变换。

-

实际上,在将齐次坐标转换回笛卡尔坐标之后(通过除以w),会发生从裁剪空间中裁剪点和多边形的情况。该最终空间称为归一化设备坐标或NDC。

+

实际上,在将齐次坐标转换回笛卡尔坐标之后(通过除以 w),会发生从裁剪空间中裁剪点和多边形的情况。该最终空间称为归一化设备坐标或 NDC。

为了开始使用这个思想,可以修改前面的示例,以允许使用 w 分量。

@@ -258,7 +258,7 @@

齐次坐标

]);
-

然后,顶点着色器使用传入的4维点。

+

然后,顶点着色器使用传入的 4 维点。

attribute vec4 position;
 
@@ -267,7 +267,7 @@ 

齐次坐标

}
-

首先,我们在中间绘制一个红色框,但将 W 设置为 0.7。但坐标除以0.7时,它们全部会被放大。

+

首先,我们在中间绘制一个红色框,但将 W 设置为 0.7。但坐标除以 0.7 时,它们全部会被放大。

box.draw({
 
@@ -314,7 +314,7 @@ 

齐次坐标

结果

-

在JSFiddle中查看

+

在 JSFiddle 中查看

The results of using homogeneous coordinates to move the boxes around in WebGL.

@@ -327,17 +327,17 @@

练习

模型转换

-

将点直接放入裁剪空间的用途有限。在现实世界的应用程序中,你拥有的源坐标不全部在裁剪空间中。因此大多数时候,你需要将模型数据和其他坐标转换到裁剪空间中。简单的立方体就是一个如何执行此操作的简单示例。立方体数据由顶点位置,立方体表面颜色和构成单个多边形的顶点位置的顺序组成(以3个顶点为一组,以构成立方体表面的三角形)。这些位置和颜色存储在GL缓冲区中,作为属性发到着色器,然后分别进行操作。

+

将点直接放入裁剪空间的用途有限。在现实世界的应用程序中,你拥有的源坐标不全部在裁剪空间中。因此大多数时候,你需要将模型数据和其他坐标转换到裁剪空间中。简单的立方体就是一个如何执行此操作的简单示例。立方体数据由顶点位置,立方体表面颜色和构成单个多边形的顶点位置的顺序组成(以 3 个顶点为一组,以构成立方体表面的三角形)。这些位置和颜色存储在 GL 缓冲区中,作为属性发到着色器,然后分别进行操作。

最后,计算并设置单个模型矩阵。该矩阵表示要在组成模型的每个点上执行的转换,以将其移到正确的空间,并在模型中的每个点上执行任何其他所需的转换。这不仅适用于每一个顶点,而且还适用于模型每个表面的每个点。

-

在这种情况下,对于动画的每一帧,一系列缩放,旋转和平移矩阵会将数据移动到裁剪空间中所需的位置。这个立方体是裁剪空间(-1, -1, -1) 到 (1, 1, 1)的大小,因此需要缩小以不填满整个裁剪空间。该矩阵事先已经在JavaScript中进行了乘法运算,直接发到着色器。

+

在这种情况下,对于动画的每一帧,一系列缩放,旋转和平移矩阵会将数据移动到裁剪空间中所需的位置。这个立方体是裁剪空间 (-1, -1, -1) 到 (1, 1, 1) 的大小,因此需要缩小以不填满整个裁剪空间。该矩阵事先已经在 JavaScript 中进行了乘法运算,直接发到着色器。

以下代码示例在  CubeDemo 对象上定义了一个创建模型矩阵的方法。它使用了自定义函数来创建和乘以 MDN WebGL 共享代码中定义的矩阵。新的函数如下:

CubeDemo.prototype.computeModelMatrix = function(now) {
 
-  // 缩小50%
+  // 缩小 50%
   var scale = MDN.scaleMatrix(0.5, 0.5, 0.5);
 
   // 轻微旋转
@@ -364,12 +364,12 @@ 

模型转换

this.locations.model = gl.getUniformLocation(webglProgram, 'model');
 
-

最后,将 uniforms 设置在那个位置,这就把矩阵交给了GPU。

+

最后,将 uniforms 设置在那个位置,这就把矩阵交给了 GPU。

gl.uniformMatrix4fv(this.locations.model, false, new Float32Array(this.transforms.model));
 
-

在着色器中,每个位置顶点首先被转换为齐次坐标(vec4对象),然后与模型矩阵相乘。

+

在着色器中,每个位置顶点首先被转换为齐次坐标(vec4 对象),然后与模型矩阵相乘。

gl_Position = model * vec4(position, 1.0);
 
@@ -380,11 +380,11 @@

模型转换

结果

-

在JSFiddle中查看

+

在 JSFiddle 中查看

Using a model matrix

-

此时,变换点的w值仍为1.0。立方体仍然没有什么角度。下一节将进行此设置并修改w值以提供一些透视效果。

+

此时,变换点的 w 值仍为 1.0。立方体仍然没有什么角度。下一节将进行此设置并修改 w 值以提供一些透视效果。

练习

@@ -397,7 +397,7 @@

练习

除以 W

-

一个开始了解立方体模型透视的简单方法是获取Z坐标并将其复制到w坐标。通常,将笛卡尔点转换为齐次坐标时,它变为  (x,y,z,1) ,但我们将其设置为  (x,y,z,z) 。实际上,我们希望确保视图中的点的z值大于0,因此我们将其值改为  ((1.0 + z) * scaleFactor) 对其进行轻微的修改。这将需要一个通常位于裁剪空间(-1到1)中的点,并将其移到更像(0到1)的空间中,具体取决于比例因子设置为什么。比例因子将最终w值更改为总体上更高或更低。

+

一个开始了解立方体模型透视的简单方法是获取 Z 坐标并将其复制到 w 坐标。通常,将笛卡尔点转换为齐次坐标时,它变为  (x,y,z,1) ,但我们将其设置为  (x,y,z,z) 。实际上,我们希望确保视图中的点的 z 值大于 0,因此我们将其值改为  ((1.0 + z) * scaleFactor) 对其进行轻微的修改。这将需要一个通常位于裁剪空间(-1 到 1)中的点,并将其移到更像(0 到 1)的空间中,具体取决于比例因子设置为什么。比例因子将最终 w 值更改为总体上更高或更低。

着色器代码如下:

@@ -407,17 +407,17 @@

除以 W

// 透视有多大的影响? float scaleFactor = 0.5; -// 通过采用介于-1到1之间的z值来设置w -// 然后进行缩放为0到某个数,在这种情况下为0到1 +// 通过采用介于-1 到 1 之间的 z 值来设置 w +// 然后进行缩放为 0 到某个数,在这种情况下为 0 到 1 float w = (1.0 + transformedPosition.z) * scaleFactor; -// 使用自定义w分量保存新的 gl_Position +// 使用自定义 w 分量保存新的 gl_Position gl_Position = vec4(transformedPosition.xyz, w);

结果

-

在JSFiddle中查看

+

在 JSFiddle 中查看

Filling the W component and creating some projection.

@@ -425,13 +425,13 @@

结果

练习

-

如果这听起来有点抽象,请打开顶点着色器,然后使用比例因子,观察其如何将顶点向表面进一步收缩。完全更改w分量的值,以表示真实空间。

+

如果这听起来有点抽象,请打开顶点着色器,然后使用比例因子,观察其如何将顶点向表面进一步收缩。完全更改 w 分量的值,以表示真实空间。

-

在下一节中,我们将执行把Z值复制到w插槽并将其转换为矩阵的步骤。

+

在下一节中,我们将执行把 Z 值复制到 w 插槽并将其转换为矩阵的步骤。

简单投影

-

填充w分量的最后一步实际上可以用一个简单的矩阵完成。从 identity 矩阵开始:

+

填充 w 分量的最后一步实际上可以用一个简单的矩阵完成。从 identity 矩阵开始:

var identity = [
   1, 0, 0, 0,
@@ -492,7 +492,7 @@ 

简单投影

这与我们在前面示例中使用的  (z + 1) * scaleFactor 完全相同。

-

在 box demo中,添加了一个额外的 .computeSimpleProjectionMatrix() 方法。在 .draw() 方法中调用,并将比例因子传递给它。结果应该与上一个示例相同:

+

在 box demo 中,添加了一个额外的 .computeSimpleProjectionMatrix() 方法。在 .draw() 方法中调用,并将比例因子传递给它。结果应该与上一个示例相同:

CubeDemo.prototype.computeSimpleProjectionMatrix = function(scaleFactor) {
 
@@ -506,7 +506,7 @@ 

简单投影

};
-

尽管结果相同,但重要的步骤还是在顶点着色器中。与其直接修改顶点,不如将其乘以一个附加的 projection matrix,该矩阵将3D点投影到2D绘图表面上:

+

尽管结果相同,但重要的步骤还是在顶点着色器中。与其直接修改顶点,不如将其乘以一个附加的 projection matrix,该矩阵将 3D 点投影到 2D 绘图表面上:

// 确保以相反的顺序读取转换矩阵
 gl_Position = projection * model * vec4(position, 1.0);
@@ -514,25 +514,25 @@ 

简单投影

结果

-

在JSFiddle中查看

+

在 JSFiddle 中查看

A simple projection matrix

透视矩阵

-

至此,我们逐步构建了自己的3D渲染设置。但是,我们当前构建的代码存在一些问题。首先,每当我们调整窗口大小时,它就会倾斜。另外是我们的简单投影无法处理场景数据的大范围值。大多数场景在裁剪空间中不起作用。定义与场景相关的距离是很有帮助的,这样在转换数字时不会损失精度。最后,对哪些点放在裁剪空间的内部和外部进行精度控制非常有帮助。在前面的例子中,立方体的角偶尔会被裁剪。

+

至此,我们逐步构建了自己的 3D 渲染设置。但是,我们当前构建的代码存在一些问题。首先,每当我们调整窗口大小时,它就会倾斜。另外是我们的简单投影无法处理场景数据的大范围值。大多数场景在裁剪空间中不起作用。定义与场景相关的距离是很有帮助的,这样在转换数字时不会损失精度。最后,对哪些点放在裁剪空间的内部和外部进行精度控制非常有帮助。在前面的例子中,立方体的角偶尔会被裁剪。

-

透视矩阵是一种可以满足这些要求的投影矩阵。也开始涉及数学更多的内容,这些示例中将不做充分解释。简而言之,它结合了除以w(与前面的例子相同)和基于 相似三角形 相似三角形的一些巧妙操作。如果你想阅读有关其背后数学的完整说明,请查看以下一些链接:

+

透视矩阵是一种可以满足这些要求的投影矩阵。也开始涉及数学更多的内容,这些示例中将不做充分解释。简而言之,它结合了除以 w(与前面的例子相同)和基于 相似三角形 相似三角形的一些巧妙操作。如果你想阅读有关其背后数学的完整说明,请查看以下一些链接:

-

关于下面使用的透视矩阵,需要注意的一件重要的事是它会翻转z轴。在裁剪空间中,z+原理观察者,而使用此矩阵,它朝向观察者。

+

关于下面使用的透视矩阵,需要注意的一件重要的事是它会翻转 z 轴。在裁剪空间中,z+ 原理观察者,而使用此矩阵,它朝向观察者。

-

翻转z轴的原因是,裁剪空间坐标系是左手坐标系(z轴指向远离观察者并指入屏幕的位置),而数学,物理学和3D建模中的惯例与OpenGL中视图/眼睛坐标系一样,是使用右手坐标系(z轴指向屏幕,朝向观察者)。有关的Wikipedia文章的更多信息:直角坐标系右手法则

+

翻转 z 轴的原因是,裁剪空间坐标系是左手坐标系(z 轴指向远离观察者并指入屏幕的位置),而数学,物理学和 3D 建模中的惯例与 OpenGL 中视图/眼睛坐标系一样,是使用右手坐标系(z 轴指向屏幕,朝向观察者)。有关的 Wikipedia 文章的更多信息:直角坐标系右手法则

让我们看一下  perspectiveMatrix() 函数,该函数计算了透视矩阵。

@@ -558,10 +558,10 @@

透视矩阵

aspectRatio
场景的宽高比,等于其宽度除以其高度。在本示例中,就是窗口的宽度除以窗口的高度。此参数的引入最终解决了当画布调整大小和形状时模型的变形问题。
nearClippingPlaneDistance
-
一个正数,表示到屏幕的距离是垂直于地板的平面的距离,该距离比将所有内容都裁剪的距离更近。它在裁剪空间中映射为-1,并且不应设置为0。
+
一个正数,表示到屏幕的距离是垂直于地板的平面的距离,该距离比将所有内容都裁剪的距离更近。它在裁剪空间中映射为-1,并且不应设置为 0。
farClippingPlaneDistance
-
一个正数,表示与平面之间的距离,超出该距离将裁剪几何体。它在裁剪空间中映射为1.该值应保持合理的距离以接近几何图形的距离,以免在渲染时出现精度误差。
-
在最新版本的盒子demo中, computeSimpleProjectionMatrix() 函数已替换为 computePerspectiveMatrix() 函数。
+
一个正数,表示与平面之间的距离,超出该距离将裁剪几何体。它在裁剪空间中映射为 1.该值应保持合理的距离以接近几何图形的距离,以免在渲染时出现精度误差。
+
在最新版本的盒子 demo 中, computeSimpleProjectionMatrix() 函数已替换为 computePerspectiveMatrix() 函数。
CubeDemo.prototype.computePerspectiveMatrix = function() {
@@ -589,7 +589,7 @@ 

透视矩阵

结果

-

在JSFiddle中查看

+

在 JSFiddle 中查看

A true perspective matrix

@@ -597,28 +597,28 @@

练习

  • 使用透视矩阵和模型矩阵的参数进行体验。
  • -
  • 将透视矩阵替换为 {{interwiki("wikipedia", "正交矩阵")}}。在MDN WebGL共享代码中可以找到 MDN.orthographicMatrix() 替换 CubeDemo.prototype.computePerspectiveMatrix() 中的 MDN.perspectiveMatrix() 函数。
  • +
  • 将透视矩阵替换为 {{interwiki("wikipedia", "正交矩阵")}}。在 MDN WebGL 共享代码中可以找到 MDN.orthographicMatrix() 替换 CubeDemo.prototype.computePerspectiveMatrix() 中的 MDN.perspectiveMatrix() 函数。

视图矩阵

-

尽管某些图形库提供的虚拟相机可以在构成场景时可以定位和指向,但OpenGL(以及扩展的WebGL)却没有。这是视图矩阵的用处。它的作用是平移,旋转和缩放场景中的物体,以使根据观察者的位置和方向将它们放置到正确的位置。

+

尽管某些图形库提供的虚拟相机可以在构成场景时可以定位和指向,但 OpenGL(以及扩展的 WebGL)却没有。这是视图矩阵的用处。它的作用是平移,旋转和缩放场景中的物体,以使根据观察者的位置和方向将它们放置到正确的位置。

模拟相机

这利用了爱因斯坦狭义相对论的基本理论之一:参考系和相对运动的原理说,从观察者的角度来看,你可以通过将相反的变化应用于场景中的物体来模拟改变观察者的位置和方向。无论哪种方式,结果似乎对于观察者是一样的。

-

假设一个位于桌子上的盒子和一个放在一米外的桌子上的相机,它指向盒子,盒子的正面指向相机。然后考虑将相机从盒子中移开,直到2米远(通过在相机的Z值增加1米),然后将其向左滑动10厘米。盒子与相机的距离缩小了一定量,并向右稍微滑动,从而在相机中看起来较小,左侧的一小部分也暴露在相机前。

+

假设一个位于桌子上的盒子和一个放在一米外的桌子上的相机,它指向盒子,盒子的正面指向相机。然后考虑将相机从盒子中移开,直到 2 米远(通过在相机的 Z 值增加 1 米),然后将其向左滑动 10 厘米。盒子与相机的距离缩小了一定量,并向右稍微滑动,从而在相机中看起来较小,左侧的一小部分也暴露在相机前。

-

现在,让我们重置场景,将盒子放回它的起始点,使相机距离盒子2米,并正对着盒子。但这一次,相机被锁定在桌子上无法移动或旋转。这就是在WebGL中运作的样子。那,我们如何模拟在空间中移动的相机?

+

现在,让我们重置场景,将盒子放回它的起始点,使相机距离盒子 2 米,并正对着盒子。但这一次,相机被锁定在桌子上无法移动或旋转。这就是在 WebGL 中运作的样子。那,我们如何模拟在空间中移动的相机?

-

我们没有向后和向左移动相机,而是对盒子应用了逆变换:我们将盒子向后移动1米,然后向右移动10厘米。从两个物体的角度来看,结果是一样的。

+

我们没有向后和向左移动相机,而是对盒子应用了逆变换:我们将盒子向后移动 1 米,然后向右移动 10 厘米。从两个物体的角度来看,结果是一样的。

<<< insert image(s) here >>>

最后一步是创建视图矩阵,该矩阵将转换场景中的对象,以便对它们进行定位以模拟相机当前位置与方向。目前的代码可以在世界空间中移动立方体并投影所有内容以获得透视图,但我们仍然无法移动相机。

-

想象一下使用物理摄像机拍摄电影。你可以自由地将相机放到任何你想放置的位置,并对准任何你选择的方向。为了在3D图形中对此进行仿真,我们使用视图矩阵来模拟物理相机的位置和旋转。

+

想象一下使用物理摄像机拍摄电影。你可以自由地将相机放到任何你想放置的位置,并对准任何你选择的方向。为了在 3D 图形中对此进行仿真,我们使用视图矩阵来模拟物理相机的位置和旋转。

与直接转换模型顶点的模型矩阵不同,视图矩阵会移动一个抽象的相机。实际上,顶点着色器仍然移动的是模型,而“相机”保持在原位。为了使此计算正确,必须使用变换矩阵的逆。逆矩阵实质上是逆转了变换,因此,如果我们向前移动相机,则逆矩阵会导致场景中的物体向后移动。

@@ -635,7 +635,7 @@

模拟相机

// 相乘,确保以相反的顺序读取它们 var matrix = MDN.multiplyArrayOfMatrices([ - // 练习: 旋转相机的视角 + // 练习:旋转相机的视角 position ]); @@ -650,11 +650,11 @@

模拟相机

gl_Position = projection * view * model * vec4(position, 1.0);
 
-

此步骤后,GPU管线将裁剪超出范围的顶点,并将模型向下发送到片段着色器以进行栅格化。

+

此步骤后,GPU 管线将裁剪超出范围的顶点,并将模型向下发送到片段着色器以进行栅格化。

结果

-

在JSFiddle中查看

+

在 JSFiddle 中查看

The view matrix

@@ -677,7 +677,7 @@

练习

  • 在场景中移动相机。
  • 向视图矩阵中添加一些旋转矩阵以四处看看。
  • -
  • 最后,跟踪鼠标的位置。使用2个旋转矩阵可以根据用户鼠标在屏幕上的位置上下移动相机。
  • +
  • 最后,跟踪鼠标的位置。使用 2 个旋转矩阵可以根据用户鼠标在屏幕上的位置上下移动相机。

参见

From 5d4a9f04144b0bbfba9ee808a79564f37255f48b Mon Sep 17 00:00:00 2001 From: A1lo Date: Thu, 2 Jun 2022 13:31:58 +0800 Subject: [PATCH 2/3] Apply suggestions from code review --- files/zh-cn/web/api/webgl_api/constants/index.html | 2 +- .../webgl_api/tutorial/animating_objects_with_webgl/index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/files/zh-cn/web/api/webgl_api/constants/index.html b/files/zh-cn/web/api/webgl_api/constants/index.html index 804b22a74dbe09..6632c5cc0a9140 100644 --- a/files/zh-cn/web/api/webgl_api/constants/index.html +++ b/files/zh-cn/web/api/webgl_api/constants/index.html @@ -106,7 +106,7 @@

指定渲染图元 Rendering pr

- + diff --git a/files/zh-cn/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.html b/files/zh-cn/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.html index 30768c54c38d30..1d641389ae66ef 100644 --- a/files/zh-cn/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.html +++ b/files/zh-cn/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.html @@ -42,7 +42,7 @@

使正方形旋转

  }   requestAnimationFrame(render); -

该代码用于  requestAnimationFrame 要求浏览器在每一帧上调用函数“render”。requestAnimationFrame 自页面加载以来经过的时间(以毫秒为单位)。我们将其转换为秒,然后从中减去,以计算deltaTime 自渲染最后一帧以来的秒数  。在 drawscene 的结尾,我们添加了要更新的代码 squareRotation.

+

该代码用于 requestAnimationFrame 要求浏览器在每一帧上调用函数“render”。requestAnimationFrame 自页面加载以来经过的时间(以毫秒为单位)。我们将其转换为秒,然后从中减去,以计算 deltaTime 自渲染最后一帧以来的秒数。在 drawscene 的结尾,我们添加了要更新的代码 squareRotation

  squareRotation += deltaTime;
From 4df8a71e0345e1c622256b010fe9ded4c2885f09 Mon Sep 17 00:00:00 2001 From: A1lo Date: Thu, 2 Jun 2022 13:32:23 +0800 Subject: [PATCH 3/3] Apply suggestions from code review --- .../webgl_api/tutorial/animating_objects_with_webgl/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/zh-cn/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.html b/files/zh-cn/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.html index 1d641389ae66ef..273822680c83c1 100644 --- a/files/zh-cn/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.html +++ b/files/zh-cn/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.html @@ -44,7 +44,7 @@

使正方形旋转

该代码用于 requestAnimationFrame 要求浏览器在每一帧上调用函数“render”。requestAnimationFrame 自页面加载以来经过的时间(以毫秒为单位)。我们将其转换为秒,然后从中减去,以计算 deltaTime 自渲染最后一帧以来的秒数。在 drawscene 的结尾,我们添加了要更新的代码 squareRotation

-
  squareRotation += deltaTime;
+
squareRotation += deltaTime;

该代码使用自上次我们更新值以来所经过的时间squareRotation来确定旋转正方形的距离。

类型Web接口类型Web 接口类型 描述
类型Web接口类型Web 接口类型 描述
{{SpecName('WebGL2', "#3.1", "Types")}} {{Spec2('WebGL2')}}定义额外的类型.定义额外的类型。
{{SpecName('EXT_disjoint_timer_query', "", "GLuint64EXT")}}
TRIANGLE_STRIP 0x0005传递给drawElements 或drawArrays 画一组相连的三角形带。传递给 drawElementsdrawArrays 画一组相连的三角形带。
TRIANGLE_FAN