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绘制第一个图形。

相关推荐
卸任11 小时前
Vibe coding工具使用心得
前端·ai编程
brien912 小时前
为什么模型标称 1M,Google Antigravity 聊到 256K 却突然失忆?我们给它做了个原生行内监控圆环
前端
修炼的dance12 小时前
录屏关键帧间隔多少合适?六档实测,2秒到10秒小了75.6%
前端
Lank_M12 小时前
关键帧从1秒拉到10秒,录屏小87.3%,摄像头小10.8%
前端
补码缩写12 小时前
用 ffprobe 拆录屏,八成字节在 29 个关键帧上
前端
百思不得小李12 小时前
一个复杂的动态表单是如何实现的
前端·设计模式
陈随易13 小时前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员
风骏时光牛马13 小时前
前沿视界
前端
kyriewen13 小时前
我扫了 814 个依赖,97 个还敢要 Node 10
前端·javascript·程序员
陈随易13 小时前
3000 万人在用的翻译插件,重写一遍就是一门生意
前端·后端·程序员