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

相关推荐
bugcome_com42 分钟前
JWT 知识小课堂:从入门到精通,一文吃透 JSON Web Token
前端·json
To_OC1 小时前
写了三天 Next.js,我的 React 世界观被拆了又装回去
前端·全栈·next.js
独泪了无痕1 小时前
viewer.js 安装与配置指南:实现图片预览功能
前端·vue.js
Fluxart.ai3 小时前
电商商品图审核怎么自动化?规则引擎、人工复核与发布门禁
java·前端·自动化
why技术4 小时前
AI 写的文章,可能都带着手敲一遍都去不掉的“隐形水印”。
前端·人工智能·后端
愚公搬代码4 小时前
【愚公系列】《Android应用案例开发大全》016-LBS类应用掌上杭州(辅助工具类的开发)
android·前端
CodeSheep4 小时前
又一个华为天才少年,离职了!
前端·后端·程序员
kyriewen4 小时前
面试官说"打开你的AI工具"——我才发现,他考的根本不是写代码
前端·人工智能·面试
IT_陈寒5 小时前
Vue的双向绑定把我坑惨了,原来这个场景不能用
前端·人工智能·后端
hunterandroid6 小时前
[Android 从零到一] Compose LazyColumn 性能优化:key、稳定性与重组治理
android·前端