WebGL学习之路:1. 理论基础

前言

WebGL就是画布的3D上下文,WebGL经常被当成3D API,人们总想"我可以使用WebGL和一些神奇的东西 做出炫酷的3D作品"。 事实上WebGL仅仅是一个光栅化引擎,它可以根据你的代码绘制出点,线和三角形。 想要利用WebGL完成更复杂任务,取决于你能否提供合适的代码,组合使用点,线和三角形代替实现。(摘自webglfundamentals.org/webgl/lesso...

然后废话不多说,直接看知识,本来想让AI帮我编一点废话,但是他写的太高级了,不符合本小白。

概念

开始之前,先准备好一张画布,canvas是画布,那么WebGL就是画笔:

html 复制代码
<!-- 在网页上挖一块画布区域 -->
<canvas id="myCanvas" width="400" height="400"></canvas> <script>
// 获取画笔(WebGL上下文) 
const canvas = document.getElementById('myCanvas');
const gl = canvas.getContext('webgl'); 
</script>

1. 着色器

WebGL的着色器分为两种:

  • 顶点着色器:确定点的位置和大小

  • 片元着色器:给点涂颜色

2. 着色器语法

WebGL在电脑的GPU中运行,所以我们需要使用可以在GPU中运行的代码,也就是GLSL(GL着色语言),在html中,可以将着色器语言写在script中,有两种写法:

1. 写到script标签中:

但是script的type属性不能为js类型,

html 复制代码
<!-- 顶点着色器 -->
<script id="vertex-shader" type="notjs">
    void main() {
        <!-- 确定点大小 -->
        gl_PointSize = 10.0;
        <!-- 确定点的位置,vec4用于定义一个四维向量,后边会介绍-->
        <!-- 这里的位置对应坐标x,y,z,w,四维裁剪坐标系-->
        gl_Position = vec4(0.0, 0.0, 1.0, 1.0);
    }
</script>

<!-- 片元着色器 -->
<script id="fragment-shader" type="notjs">
    void main() {
    // vec4用于定义一个四维向量,后边会介绍, 
    // 这里的1, 0, 0, 1 对应的是rgba,那么这里也就是定义了图形的颜色为红色
     gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0)
    }
</script>

2. 写到字符串中:

js 复制代码
const vectextSource = `
void main() {
     gl_PointSize = 10.0;
     gl_Position = vec4(0.0, 0.0, 1.0, 1.0);
  }
`

const fragmentSource = `
    void main() {
            gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
        }
`

数据类型:

  • 基本数据类型:float,int,bool
  • 向量:vec2,vec3,vec4,分别是浮点型二维,三维,四维向量,另外还有整数型和布尔型的, ivec2(整数型二维),bvec2(布尔型二维),这里就不一一列举了
  • 矩阵:mat2,mat3,mat4, 二维,三维,四维矩阵
  • 采样器:sampler2D,samplerCube

变量修饰符:

作用:用于指定变量的作用域,生命周期和用途

  • attribute:用于顶点着色器,定义从顶点缓冲区传入的变量,只能在顶点着色器中使用
  • uniform:定义在整个渲染过程中保持不变的变量,比如矩阵
  • varying:用于在顶点着色器和片段着色器之间传递插值数据

函数:

  • 数学函数:sin,cos,tan等等等等等
  • 向量函数:dot,length等等等等等
  • 纹理采样函数:texture2D,textureCube

定义精度: precision:用于变量的默认精度的关键字

  • highp:高精度
  • mediump:中精度
  • lowp:低精度

3. WebGL API

创建着色器对象: 浏览器并不理解原生GLSL代码,所以GLSL的代码必须经过编译并链接到一个着色器程序中。有了GLSL的字符串,就需要创建一个shader对象,也就是着色器对象。gl.createShader(type)方法用于创建着色器对象,根据接受参数可以创建顶点着色器和片元着色器。type参数的类型如下:

  • gl.VERTEX_SHADER:创建顶点着色器
  • gl.FRAGMENT_SHADER:创建片元着色器
js 复制代码
 const vertexShader = gl.createShader(gl.VERTEX_SHADER)
 const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)

有了着色器对象和着色器的代码,就需要将代码应用到着色器,那么就需要gl.shaderSource()方法:

js 复制代码
// 获取着色器源码
const vertexSource = document.getElementById('vertex-shader').innerText
const fragmentSource = document.getElementById('fragment-shader').innerText
// 应用
gl.shaderSource(vertexShader, vertexSource)
gl.shaderSource(fragmentShader,fragmentSource)

然后需要编译着色器:gl.compileShader():

js 复制代码
gl.compileShader(vertexShader)
gl.compileShader(fragmentShader)

创建着色器程序: 接下来就需要将两个着色器对象链接到着色器程序中,gl.attachShader()

js 复制代码
const program = gl.createProgram()
gl.attachShader(program, vertexShader)
gl.attachShader(program, fragmentShader)
gl.linkProgram(program)
gl.useProgram(program)

解释一下上方代码,gl.createProgram()用于创建一个着色器程序,gl.attachShader()用于添加着色器,调用gl.linkProgram(),将两个着色器链接到了变量program中,之后就可以通过gl.useProgram()让WebGL上下文使用这个着色器程序开始绘制。

总结

本文主要介绍了WebGL的基本概念知识和使用WebGL绘图的基本步骤,大致可以总结为下图:

下文将使用WebGL绘制第一个图形。

相关推荐
JeffongTan7 小时前
在LWC中镶嵌VF Page获取用户IP
前端·javascript·salesforce
陆枫Larry9 小时前
Astro 是什么
前端
是立不是利11 小时前
写给设计师的 CSS 博客美学指南
前端·css
默_笙11 小时前
🏝 Docker 就是"房地产开发":从施工图纸到小区物业的容器化指南
前端·javascript
计算机魔术师11 小时前
Rohan Paul 谈用时间跨度衡量智能体能力,并引用 OpenAI 自动化研究实习生里程碑
前端
kyriewen11 小时前
我手写了个极简版 React Router——才搞懂 v6 为什么砍了这么多 API
前端·javascript·程序员
a11177611 小时前
Shirone 二次元博客主题 开源
前端·开源
IT_陈寒12 小时前
Python的切片赋值把我坑惨了,这不是bug是特性
前端·人工智能·后端
掘金酱12 小时前
【社区公告】致每一位掘友:关于这次调整, 想再说几句
前端·人工智能
CoderLiu12 小时前
程序化工具调用(PTC)与动态工作流引擎:深入大模型工具调用的架构演进与实践
前端·人工智能·后端