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

相关推荐
ConardLi4 分钟前
Easy Dataset 已经突破 11.5K Star,这次又带来多项功能更新!
前端·javascript·后端
冴羽9 分钟前
10 个被严重低估的 JS 特性,直接少写 500 行代码
前端·javascript·性能优化
rising start11 分钟前
四、CSS选择器(续)和三大特性
前端·css
一 乐31 分钟前
高校后勤报修系统|物业管理|基于SprinBoot+vue的高校后勤报修系统(源码+数据库+文档)
java·前端·javascript·数据库·vue.js·毕设
爱喝水的小周32 分钟前
《UniApp 页面配置文件pages.json》
前端·uni-app·json
mapbar_front38 分钟前
React中useContext的基本使用和原理解析
前端·react.js
贪婪的君子1 小时前
【每日一面】实现一个深拷贝函数
前端·js
_安晓2 小时前
Rust 中精确大小迭代器(ExactSizeIterator)的深度解析与实践
java·前端·python
烛阴2 小时前
从create到yield:Lua协程完全上手指南
前端·lua
薛一半2 小时前
Vue3的Pinia详解
前端·javascript·vue.js