2024年全网最新最详细《WebGL教程》
https://www.bilibili.com/video/BV1AS411A74T/
1 2
02-canvas的基础知识
https://bx2eq6ulg18.feishu.cn/docx/I4hTdO95qozPBOxauPlcbDfInVd
2.1 获取渲染上下文
HTMLCanvasElement.getContext()方法用于返回绘图上下文对象,绘图上下文对象是2D上下文还是3D上下文取决于传入的参数。
getContext('2d'):创建一个CanvasRenderingContext2D 二维的渲染上下文对象getContext('webgl'):创建一个 WebGLRenderingContext 三维的渲染上下文对象
css图片会拉伸 标签属性width不会
03-了解类型化数组
作用:常用在处理图像数据、音频数据、视频数据这些方向。对应的API有:WebGL、Canvas API、WebRTC、File
04-着色器基础语法
GLSL(OpenGL Shading Language)是一种用于编写图形着色器的编程语言。着色器是用于在图形处理单元
(GPU)上执行特定图形处理任务的程序。通俗讲,着色器是画点的工具,一个图形是由无数个点组成的,每个点都有其自己的颜色。
变量修饰符:
用于指定变量的作用域、生命周期和用途。不同的修饰符在顶点着色器和片段着色器中起到不同的作用。
attribute:用于顶点着色器,定义从顶点缓冲区传入的变量(仅在顶点着色器中使用)。
uniform:定义在整个渲染过程中保持不变的变量,常用于传递变换矩阵、光照参数等。
varying:用于在顶点着色器和片段着色器之间传递插值数据。
内罟变量:
05-webGL接口api
06-第一个WebGL程序
另类script 需要加;才行
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.canvas{border: 1px solid #ccc;}</style>
</head>
<body><canvas class="canvas" width="500" height="500"></canvas><!-- 顶点着色器 --><script id="vertex-shader" type="x-shader/x-vertex">void main(){gl_PointSize=10.0;gl_Position=vec4(0.0,0.0,0.0,1.0);}</script><!-- 片段着色器 --><script id="fragment-shader" type="x-shader/x-fragment">void main(){gl_FragColor=vec4(1.0,0.0,0.0,1.0);}</script><script>// const vertexSource=`// void main(){// gl_PointSize=10.0;// gl_Position=vec4(0.0,0.0,0.0,1.0)// }// `const canvas=document.querySelector('.canvas')const gl=canvas.getContext("webgl")//创建顶点着色器和片元着色器const vertexShader=gl.createShader(gl.VERTEX_SHADER)const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)//获取着色器源码const vertexSource=document.getElementById('vertex-shader').innerTextconst fragmentSource=document.getElementById('fragment-shader').innerText//绑定着色器源码gl.shaderSource(vertexShader, vertexSource)gl.shaderSource(fragmentShader, fragmentSource)//编译着色器源码gl.compileShader(vertexShader)gl.compileShader(fragmentShader)//创建程序对象const program=gl.createProgram()gl.attachShader(program, vertexShader)gl.attachShader(program, fragmentShader)gl.linkProgram(program)gl.useProgram(program);gl.drawArrays(gl.POINTS, 0, 1);</script>
</body>
</html>
07-attribute动态传递点数据
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.canvas{border: 1px solid #ccc;}</style>
</head>
<body><canvas class="canvas" width="500" height="500"></canvas><!-- 顶点着色器 --><script id="vertex-shader" type="x-shader/x-vertex">attribute vec2 aPos;attribute vec2 aPos1;void main(){gl_PointSize=10.0;vec2 newPos=aPos+aPos1;gl_Position=vec4(newPos,0.0,1.0);}</script><!-- 片段着色器 --><script id="fragment-shader" type="x-shader/x-fragment">void main(){gl_FragColor=vec4(1.0,0.0,0.0,1.0);}</script><script>// const vertexSource=`// void main(){// gl_PointSize=10.0;// gl_Position=vec4(0.0,0.0,0.0,1.0)// }// `const canvas=document.querySelector('.canvas')const gl=canvas.getContext("webgl")//创建顶点着色器和片元着色器const vertexShader=gl.createShader(gl.VERTEX_SHADER)const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)//获取着色器源码const vertexSource=document.getElementById('vertex-shader').innerTextconst fragmentSource=document.getElementById('fragment-shader').innerText//绑定着色器源码gl.shaderSource(vertexShader, vertexSource)gl.shaderSource(fragmentShader, fragmentSource)//编译着色器源码gl.compileShader(vertexShader)gl.compileShader(fragmentShader)//创建程序对象const program=gl.createProgram()gl.attachShader(program, vertexShader)gl.attachShader(program, fragmentShader)gl.linkProgram(program)gl.useProgram(program);//动态传数据 坐标const posLocation=gl.getAttribLocation(program, 'aPos')const posLocation1=gl.getAttribLocation(program, 'aPos1')const offset=[0.5,0.5]const offset1=[-0.1,-0.2]gl.vertexAttrib2f(posLocation,...offset)gl.vertexAttrib2f(posLocation1,...offset1)gl.drawArrays(gl.POINTS, 0, 1);</script>
</body>
</html>
08-使用缓冲区数据绘制线段
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.canvas{border: 1px solid #ccc;}</style>
</head>
<body><canvas class="canvas" width="500" height="500"></canvas><!-- 顶点着色器 --><script id="vertex-shader" type="x-shader/x-vertex">attribute vec2 aPosition;void main(){gl_Position=vec4(aPosition,0.0,1.0);}</script><!-- 片段着色器 --><script id="fragment-shader" type="x-shader/x-fragment">void main(){gl_FragColor=vec4(1.0,0.0,0.0,1.0);}</script><script>const canvas=document.querySelector('.canvas')const gl=canvas.getContext("webgl")//创建顶点着色器和片元着色器const vertexShader=gl.createShader(gl.VERTEX_SHADER)const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)//获取着色器源码const vertexSource=document.getElementById('vertex-shader').innerTextconst fragmentSource=document.getElementById('fragment-shader').innerText//绑定着色器源码gl.shaderSource(vertexShader, vertexSource)gl.shaderSource(fragmentShader, fragmentSource)//编译着色器源码gl.compileShader(vertexShader)gl.compileShader(fragmentShader)//创建程序对象const program=gl.createProgram()gl.attachShader(program, vertexShader)gl.attachShader(program, fragmentShader)gl.linkProgram(program)gl.useProgram(program);const vertices=new Float32Array([-0.5,-0.5, //第一个点的x轴和y轴坐标0.5,0.5, //第二个点的xy轴坐标])const buffer=gl.createBuffer()gl.bindBuffer(gl.ARRAY_BUFFER, buffer)gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)const posLocation=gl.getAttribLocation(program, 'aPosition')gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 2*Float32Array.BYTES_PER_ELEMENT, 0)gl.enableVertexAttribArray(posLocation)gl.drawArrays(gl.LINES, 0, 2);</script>
</body>
</html>
09-varying实现彩色线段
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.canvas{border: 1px solid #ccc;}</style>
</head>
<body><canvas class="canvas" width="500" height="500"></canvas><!-- 顶点着色器 --><script id="vertex-shader" type="x-shader/x-vertex">attribute vec2 aPosition;attribute vec4 aColor;varying vec4 vColor;void main(){gl_Position=vec4(aPosition,0.0,1.0);vColor=aColor;}</script><!-- 片段着色器 --><script id="fragment-shader" type="x-shader/x-fragment">precision highp float;varying vec4 vColor;void main(){gl_FragColor=vColor;}</script><script>const canvas=document.querySelector('.canvas')const gl=canvas.getContext("webgl")//创建顶点着色器和片元着色器const vertexShader=gl.createShader(gl.VERTEX_SHADER)const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)//获取着色器源码const vertexSource=document.getElementById('vertex-shader').innerTextconst fragmentSource=document.getElementById('fragment-shader').innerText//绑定着色器源码gl.shaderSource(vertexShader, vertexSource)gl.shaderSource(fragmentShader, fragmentSource)//编译着色器源码gl.compileShader(vertexShader)gl.compileShader(fragmentShader)//创建程序对象const program=gl.createProgram()gl.attachShader(program, vertexShader)gl.attachShader(program, fragmentShader)gl.linkProgram(program)gl.useProgram(program);const vertices=new Float32Array([-0.5,-0.5, //第一个点的x轴和y轴坐标0.5,0.5, //第二个点的xy轴坐标])const colors=new Float32Array([0.0,0.0,0.0,1.0,1.0,0.0,0.0,0.0,])const buffer=gl.createBuffer()gl.bindBuffer(gl.ARRAY_BUFFER, buffer)gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)const posLocation=gl.getAttribLocation(program, 'aPosition')gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 2*Float32Array.BYTES_PER_ELEMENT, 0)gl.enableVertexAttribArray(posLocation)const colorBuffer=gl.createBuffer()gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW)const colorLocation=gl.getAttribLocation(program, 'aColor')gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 2*Float32Array.BYTES_PER_ELEMENT, 0)gl.enableVertexAttribArray(colorLocation)gl.drawArrays(gl.LINES, 0, 2);</script>
</body>
</html>
10-如何使用单个buffer解析数据
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.canvas{border: 1px solid #ccc;}</style>
</head>
<body><canvas class="canvas" width="500" height="500"></canvas><!-- 顶点着色器 --><script id="vertex-shader" type="x-shader/x-vertex">attribute vec2 aPosition;attribute vec4 aColor;varying vec4 vColor;void main(){gl_Position=vec4(aPosition,0.0,1.0);vColor=aColor;}</script><!-- 片段着色器 --><script id="fragment-shader" type="x-shader/x-fragment">precision highp float;varying vec4 vColor;void main(){gl_FragColor=vColor;}</script><script>const canvas=document.querySelector('.canvas')const gl=canvas.getContext("webgl")//创建顶点着色器和片元着色器const vertexShader=gl.createShader(gl.VERTEX_SHADER)const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)//获取着色器源码const vertexSource=document.getElementById('vertex-shader').innerTextconst fragmentSource=document.getElementById('fragment-shader').innerText//绑定着色器源码gl.shaderSource(vertexShader, vertexSource)gl.shaderSource(fragmentShader, fragmentSource)//编译着色器源码gl.compileShader(vertexShader)gl.compileShader(fragmentShader)//创建程序对象const program=gl.createProgram()gl.attachShader(program, vertexShader)gl.attachShader(program, fragmentShader)gl.linkProgram(program)gl.useProgram(program);const vertices=new Float32Array([-0.5,-0.5, 0.0,0.0,0.0,1.0, //第一个点的x轴和y轴坐标0.5,0.5, 1.0,0.0,0.0,0.0, //第二个点的xy轴坐标])// const colors=new Float32Array([// 0.0,0.0,0.0,1.0,// 1.0,0.0,0.0,0.0,// ])const buffer=gl.createBuffer()gl.bindBuffer(gl.ARRAY_BUFFER, buffer)gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)const posLocation=gl.getAttribLocation(program, 'aPosition')gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 6*Float32Array.BYTES_PER_ELEMENT, 0)gl.enableVertexAttribArray(posLocation)// const colorBuffer=gl.createBuffer()// gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)// gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW)const colorLocation=gl.getAttribLocation(program, 'aColor')gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 6*Float32Array.BYTES_PER_ELEMENT, 2*Float32Array.BYTES_PER_ELEMENT)gl.enableVertexAttribArray(colorLocation)gl.drawArrays(gl.LINES, 0, 2);</script>
</body>
</html>
11-绘制三角形案例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.canvas{border: 1px solid #ccc;}</style>
</head>
<body><canvas class="canvas" width="500" height="500"></canvas><!-- 顶点着色器 --><script id="vertex-shader" type="x-shader/x-vertex">attribute vec2 aPosition;attribute vec4 aColor;varying vec4 vColor;void main(){gl_Position=vec4(aPosition,0.0,1.0);vColor=aColor;}</script><!-- 片段着色器 --><script id="fragment-shader" type="x-shader/x-fragment">precision highp float;varying vec4 vColor;void main(){gl_FragColor=vColor;}</script><script>const canvas=document.querySelector('.canvas')const gl=canvas.getContext("webgl")//创建顶点着色器和片元着色器const vertexShader=gl.createShader(gl.VERTEX_SHADER)const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)//获取着色器源码const vertexSource=document.getElementById('vertex-shader').innerTextconst fragmentSource=document.getElementById('fragment-shader').innerText//绑定着色器源码gl.shaderSource(vertexShader, vertexSource)gl.shaderSource(fragmentShader, fragmentSource)//编译着色器源码gl.compileShader(vertexShader)gl.compileShader(fragmentShader)//创建程序对象const program=gl.createProgram()gl.attachShader(program, vertexShader)gl.attachShader(program, fragmentShader)gl.linkProgram(program)gl.useProgram(program);const vertices=new Float32Array([-0.5,-0.5, 0.0,0.0,0.0,1.0, //第一个点的x轴和y轴坐标 前2坐标 后4颜色0.5,-0.5, 1.0,0.0,0.0,0.0, //第二个点的xy轴坐标0.0,0.5, 0.0,0.0,1.0,0.0, //3 point])// const colors=new Float32Array([// 0.0,0.0,0.0,1.0,// 1.0,0.0,0.0,0.0,// ])const buffer=gl.createBuffer()gl.bindBuffer(gl.ARRAY_BUFFER, buffer)gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)const posLocation=gl.getAttribLocation(program, 'aPosition')gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 6*Float32Array.BYTES_PER_ELEMENT, 0)gl.enableVertexAttribArray(posLocation)// const colorBuffer=gl.createBuffer()// gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)// gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW)const colorLocation=gl.getAttribLocation(program, 'aColor')gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 6*Float32Array.BYTES_PER_ELEMENT, 2*Float32Array.BYTES_PER_ELEMENT)gl.enableVertexAttribArray(colorLocation)gl.drawArrays(gl.TRIANGLES, 0, 3);</script>
</body>
</html>
12-图元绘制类型详解
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.canvas{border: 1px solid #ccc;}</style>
</head>
<body><canvas class="canvas" width="500" height="500"></canvas><!-- 顶点着色器 --><script id="vertex-shader" type="x-shader/x-vertex">attribute vec2 aPosition;attribute vec4 aColor;varying vec4 vColor;void main(){gl_Position=vec4(aPosition,0.0,1.0);gl_PointSize=10.0;vColor=aColor;}</script><!-- 片段着色器 --><script id="fragment-shader" type="x-shader/x-fragment">precision highp float;varying vec4 vColor;void main(){gl_FragColor=vColor;}</script><script>const canvas=document.querySelector('.canvas')const gl=canvas.getContext("webgl")//创建顶点着色器和片元着色器const vertexShader=gl.createShader(gl.VERTEX_SHADER)const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)//获取着色器源码const vertexSource=document.getElementById('vertex-shader').innerTextconst fragmentSource=document.getElementById('fragment-shader').innerText//绑定着色器源码gl.shaderSource(vertexShader, vertexSource)gl.shaderSource(fragmentShader, fragmentSource)//编译着色器源码gl.compileShader(vertexShader)gl.compileShader(fragmentShader)//创建程序对象const program=gl.createProgram()gl.attachShader(program, vertexShader)gl.attachShader(program, fragmentShader)gl.linkProgram(program)gl.useProgram(program);const vertices=new Float32Array([-1.0,1.0, 0.0,0.0,0.0,1.0, //第一个点的x轴和y轴坐标 前2坐标 后4颜色-0.5,-1.0, 1.0,0.0,0.0,0.0, //第二个点的xy轴坐标-0.5,1.0, 0.0,0.0,1.0,0.0, //3 point0.0,-1.0, 0.0,0.0,1.0,0.0, //3 point0.0,1.0, 0.0,0.0,1.0,0.0, //3 point0.5,-1.0, 0.0,0.0,1.0,0.0, //3 point])// const colors=new Float32Array([// 0.0,0.0,0.0,1.0,// 1.0,0.0,0.0,0.0,// ])const buffer=gl.createBuffer()gl.bindBuffer(gl.ARRAY_BUFFER, buffer)gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)const posLocation=gl.getAttribLocation(program, 'aPosition')gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 6*Float32Array.BYTES_PER_ELEMENT, 0)gl.enableVertexAttribArray(posLocation)// const colorBuffer=gl.createBuffer()// gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)// gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW)const colorLocation=gl.getAttribLocation(program, 'aColor')gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 6*Float32Array.BYTES_PER_ELEMENT, 2*Float32Array.BYTES_PER_ELEMENT)gl.enableVertexAttribArray(colorLocation)gl.drawArrays(gl.POINTS, 0, 6);gl.drawArrays(gl.LINE_LOOP, 0, 6);gl.drawArrays(gl.TRIANGLES, 0, 6);</script>
</body>
</html>
13-uniform传递矩阵变换数据
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.canvas{border: 1px solid #ccc;}</style>
</head>
<body><canvas class="canvas" width="500" height="500"></canvas><!-- 顶点着色器 --><script id="vertex-shader" type="x-shader/x-vertex">attribute vec2 aPosition;uniform vec2 uTranslate;void main(){vec2 newPos=uTranslate+aPosition;gl_Position=vec4(newPos,0.0,1.0);gl_PointSize=10.0;}</script><!-- 片段着色器 --><script id="fragment-shader" type="x-shader/x-fragment">void main(){gl_FragColor=vec4(1.0,0.0,0.0,1.0);}</script><script>const canvas=document.querySelector('.canvas')const gl=canvas.getContext("webgl")//创建顶点着色器和片元着色器const vertexShader=gl.createShader(gl.VERTEX_SHADER)const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)//获取着色器源码const vertexSource=document.getElementById('vertex-shader').innerTextconst fragmentSource=document.getElementById('fragment-shader').innerText//绑定着色器源码gl.shaderSource(vertexShader, vertexSource)gl.shaderSource(fragmentShader, fragmentSource)//编译着色器源码gl.compileShader(vertexShader)gl.compileShader(fragmentShader)//创建程序对象const program=gl.createProgram()gl.attachShader(program, vertexShader)gl.attachShader(program, fragmentShader)gl.linkProgram(program)gl.useProgram(program);const vertices=new Float32Array([-0.5,0.5,-0.5,-0.5,0.5,-0.5,0.5,0.5,])const buffer=gl.createBuffer()gl.bindBuffer(gl.ARRAY_BUFFER, buffer)gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)const posLocation=gl.getAttribLocation(program, 'aPosition')gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 2*Float32Array.BYTES_PER_ELEMENT, 0)gl.enableVertexAttribArray(posLocation)const translationLocation=gl.getUniformLocation(program,'uTranslate')const translation=[0.2,0.2]gl.uniform2fv(translationLocation,translation)gl.drawArrays(gl.POINTS, 0, 4);gl.drawArrays(gl.LINE_LOOP, 0, 4);</script>
</body>
</html>
14-推导旋转矩阵
scale *
一行 矩阵 行向量
三角形 cos sin tan 等知识换算
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.canvas{border: 1px solid #ccc;}</style>
</head>
<body><canvas class="canvas" width="500" height="500"></canvas><!-- 顶点着色器 --><script id="vertex-shader" type="x-shader/x-vertex">attribute vec2 aPosition;void main(){float radian=radians(45.0);float sin=sin(radian);float cos=cos(radian);mat4 roatate=mat4(cos,-sin,0,0,sin,cos,0,0,0,0,1,0,0,0,0,1);gl_Position=roatate * vec4(aPosition,0.0,1.0);gl_PointSize=10.0;}</script><!-- 片段着色器 --><script id="fragment-shader" type="x-shader/x-fragment">void main(){gl_FragColor=vec4(1.0,0.0,0.0,1.0);}</script><script>const canvas=document.querySelector('.canvas')const gl=canvas.getContext("webgl")//创建顶点着色器和片元着色器const vertexShader=gl.createShader(gl.VERTEX_SHADER)const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)//获取着色器源码const vertexSource=document.getElementById('vertex-shader').innerTextconst fragmentSource=document.getElementById('fragment-shader').innerText//绑定着色器源码gl.shaderSource(vertexShader, vertexSource)gl.shaderSource(fragmentShader, fragmentSource)//编译着色器源码gl.compileShader(vertexShader)gl.compileShader(fragmentShader)//创建程序对象const program=gl.createProgram()gl.attachShader(program, vertexShader)gl.attachShader(program, fragmentShader)gl.linkProgram(program)gl.useProgram(program);const vertices=new Float32Array([-0.5,0.5,-0.5,-0.5,0.5,-0.5,0.5,0.5,])const buffer=gl.createBuffer()gl.bindBuffer(gl.ARRAY_BUFFER, buffer)gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)const posLocation=gl.getAttribLocation(program, 'aPosition')gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 2*Float32Array.BYTES_PER_ELEMENT, 0)gl.enableVertexAttribArray(posLocation)gl.drawArrays(gl.POINTS, 0, 4);gl.drawArrays(gl.LINE_LOOP, 0, 4);</script>
</body>
</html>
15-绘制线框立方体
也有旋转公式
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.canvas{border: 1px solid #ccc;}</style>
</head>
<body><canvas class="canvas" width="500" height="500"></canvas><!-- 顶点着色器 --><script id="vertex-shader" type="x-shader/x-vertex">attribute vec4 aPosition;void main(){float radian=radians(10.0);float sin=sin(radian);float cos=cos(radian);mat4 mx=mat4(1,0,0,0,0,cos,-sin,0,0,sin,cos,0,0,0,0,1);mat4 my=mat4(cos,0,-sin,0,0,1,0,0,sin,0,cos,0,0,0,0,1);gl_Position= mx * my * aPosition;gl_PointSize=10.0;}</script><!-- 片段着色器 --><script id="fragment-shader" type="x-shader/x-fragment">void main(){gl_FragColor=vec4(1.0,0.0,0.0,1.0);}</script><script>const canvas=document.querySelector('.canvas')const gl=canvas.getContext("webgl")//创建顶点着色器和片元着色器const vertexShader=gl.createShader(gl.VERTEX_SHADER)const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)//获取着色器源码const vertexSource=document.getElementById('vertex-shader').innerTextconst fragmentSource=document.getElementById('fragment-shader').innerText//绑定着色器源码gl.shaderSource(vertexShader, vertexSource)gl.shaderSource(fragmentShader, fragmentSource)//编译着色器源码gl.compileShader(vertexShader)gl.compileShader(fragmentShader)//创建程序对象const program=gl.createProgram()gl.attachShader(program, vertexShader)gl.attachShader(program, fragmentShader)gl.linkProgram(program)gl.useProgram(program);const vertices=new Float32Array([0.5,0.5,0.5,-0.5,0.5,0.5,-0.5,-0.5,0.5,0.5,-0.5,0.5,0.5,0.5,-0.5,-0.5,0.5,-0.5,-0.5,-0.5,-0.5,0.5,-0.5,-0.5,0.5,0.5,0.5,0.5,0.5,-0.5,-0.5,0.5,0.5,-0.5,0.5,-0.5,-0.5,-0.5,0.5, -0.5,-0.5,-0.5, 0.5,-0.5,0.5,0.5,-0.5,-0.5,])const buffer=gl.createBuffer()gl.bindBuffer(gl.ARRAY_BUFFER, buffer)gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)const posLocation=gl.getAttribLocation(program, 'aPosition')gl.vertexAttribPointer(posLocation, 3, gl.FLOAT, false, 3*Float32Array.BYTES_PER_ELEMENT, 0)gl.enableVertexAttribArray(posLocation)gl.drawArrays(gl.POINTS, 0, 4);gl.drawArrays(gl.LINE_LOOP, 0, 4);gl.drawArrays(gl.POINTS, 4, 4);gl.drawArrays(gl.LINE_LOOP, 4, 4);gl.drawArrays(gl.LINES, 8, 8);</script>
</body>
</html>
16-顶点索引绘制立方体
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.canvas{border: 1px solid #ccc;}</style>
</head>
<body><canvas class="canvas" width="500" height="500"></canvas><!-- 顶点着色器 --><script id="vertex-shader" type="x-shader/x-vertex">attribute vec4 aPosition;void main(){float radian=radians(10.0);float sin=sin(radian);float cos=cos(radian);mat4 mx=mat4(1,0,0,0,0,cos,-sin,0,0,sin,cos,0,0,0,0,1);mat4 my=mat4(cos,0,-sin,0,0,1,0,0,sin,0,cos,0,0,0,0,1);gl_Position= mx * my * aPosition;gl_PointSize=10.0;}</script><!-- 片段着色器 --><script id="fragment-shader" type="x-shader/x-fragment">precision mediump float;uniform vec4 uColor;void main(){gl_FragColor=uColor;}</script><script>const canvas=document.querySelector('.canvas')const gl=canvas.getContext("webgl")//创建顶点着色器和片元着色器const vertexShader=gl.createShader(gl.VERTEX_SHADER)const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)//获取着色器源码const vertexSource=document.getElementById('vertex-shader').innerTextconst fragmentSource=document.getElementById('fragment-shader').innerText//绑定着色器源码gl.shaderSource(vertexShader, vertexSource)gl.shaderSource(fragmentShader, fragmentSource)//编译着色器源码gl.compileShader(vertexShader)gl.compileShader(fragmentShader)//创建程序对象const program=gl.createProgram()gl.attachShader(program, vertexShader)gl.attachShader(program, fragmentShader)gl.linkProgram(program)gl.useProgram(program);const vertices=new Float32Array([//前面-0.5,-0.5,0.5,0.5,-0.5,0.5,0.5,0.5,0.5,-0.5,0.5,0.5,//后面-0.5,-0.5,-0.5,-0.5,0.5,-0.5,0.5,0.5,-0.5,0.5,-0.5,-0.5,//上面-0.5,0.5,-0.5,-0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,-0.5,//下面-0.5,-0.5,-0.5,0.5,-0.5,-0.5,0.5,-0.5,0.5,-0.5,-0.5,0.5,//右边0.5,-0.5,-0.5, 0.5,0.5,-0.5, 0.5,0.5,0.5,0.5,-0.5,0.5,//左边-0.5,-0.5,-0.5, -0.5,-0.5,0.5, -0.5,0.5,0.5,-0.5,0.5,-0.5,])const buffer=gl.createBuffer()gl.bindBuffer(gl.ARRAY_BUFFER, buffer)gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)const indices=new Uint16Array([0,1,2, 0,2,3,4,5,6, 4,6,7,8,9,10, 8,10,11,12,13,14, 12,14,15,16,17,18, 16,18,19,20,21,22, 20,22,23])const indexBuffer=gl.createBuffer()gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer)gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW)const posLocation=gl.getAttribLocation(program, 'aPosition')gl.vertexAttribPointer(posLocation, 3, gl.FLOAT, false, 3*Float32Array.BYTES_PER_ELEMENT, 0)gl.enableVertexAttribArray(posLocation)// gl.drawElements(gl.TRIANGLES,indices.length,gl.UNSIGNED_SHORT,0)const faceColors=[[1.0,0.0,0.0,1.0],//前面[0.0,1.0,0.0,1.0],[1.0,0.0,1.0,1.0],[0.0,0.0,0.0,1.0],[1.0,0.0,1.0,1.0],[1.0,0.0,0.0,1.0],];const colorLocation=gl.getUniformLocation(program,'uColor')for(let i=0;i<6;i++){gl.uniform4fv(colorLocation,faceColors[i])gl.drawElements(gl.TRIANGLES,6,gl.UNSIGNED_SHORT,i*6*Uint16Array.BYTES_PER_ELEMENT)}</script>
</body>
</html>
17-实现webgl动画
requestAnimationFrmae(callback)
每秒钟60次
20 = 360
Π = 180
弧度 = 角度*(n/180)
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.canvas{border: 1px solid #ccc;}</style>
</head>
<body><canvas class="canvas" width="500" height="500"></canvas><!-- 顶点着色器 --><script id="vertex-shader" type="x-shader/x-vertex">attribute vec4 aPosition;uniform mat4 u_x_matrix;uniform mat4 u_y_matrix;void main(){gl_Position= u_x_matrix * u_y_matrix * aPosition;gl_PointSize=10.0;}</script><!-- 片段着色器 --><script id="fragment-shader" type="x-shader/x-fragment">precision mediump float;uniform vec4 uColor;void main(){gl_FragColor=uColor;}</script><script>const canvas=document.querySelector('.canvas')const gl=canvas.getContext("webgl")//创建顶点着色器和片元着色器const vertexShader=gl.createShader(gl.VERTEX_SHADER)const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)//获取着色器源码const vertexSource=document.getElementById('vertex-shader').innerTextconst fragmentSource=document.getElementById('fragment-shader').innerText//绑定着色器源码gl.shaderSource(vertexShader, vertexSource)gl.shaderSource(fragmentShader, fragmentSource)//编译着色器源码gl.compileShader(vertexShader)gl.compileShader(fragmentShader)//创建程序对象const program=gl.createProgram()gl.attachShader(program, vertexShader)gl.attachShader(program, fragmentShader)gl.linkProgram(program)gl.useProgram(program);const vertices=new Float32Array([//前面-0.5,-0.5,0.5,0.5,-0.5,0.5,0.5,0.5,0.5,-0.5,0.5,0.5,//后面-0.5,-0.5,-0.5,-0.5,0.5,-0.5,0.5,0.5,-0.5,0.5,-0.5,-0.5,//上面-0.5,0.5,-0.5,-0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,-0.5,//下面-0.5,-0.5,-0.5,0.5,-0.5,-0.5,0.5,-0.5,0.5,-0.5,-0.5,0.5,//右边0.5,-0.5,-0.5, 0.5,0.5,-0.5, 0.5,0.5,0.5,0.5,-0.5,0.5,//左边-0.5,-0.5,-0.5, -0.5,-0.5,0.5, -0.5,0.5,0.5,-0.5,0.5,-0.5,])const buffer=gl.createBuffer()gl.bindBuffer(gl.ARRAY_BUFFER, buffer)gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)const indices=new Uint16Array([0,1,2, 0,2,3,4,5,6, 4,6,7,8,9,10, 8,10,11,12,13,14, 12,14,15,16,17,18, 16,18,19,20,21,22, 20,22,23])const indexBuffer=gl.createBuffer()gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer)gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW)const posLocation=gl.getAttribLocation(program, 'aPosition')gl.vertexAttribPointer(posLocation, 3, gl.FLOAT, false, 3*Float32Array.BYTES_PER_ELEMENT, 0)gl.enableVertexAttribArray(posLocation)// gl.drawElements(gl.TRIANGLES,indices.length,gl.UNSIGNED_SHORT,0)const faceColors=[[1.0,0.0,1.0,1.0],//前面[0.0,1.0,0.0,1.0],[1.0,0.0,1.0,1.0],[0.0,1.0,1.0,1.0],[1.0,0.0,1.0,1.0],[1.0,1.0,0.0,1.0],];const colorLocation=gl.getUniformLocation(program,'uColor')gl.enable(gl.DEPTH_TEST)const u_x_matrix=gl.getUniformLocation(program,'u_x_matrix')const u_y_matrix=gl.getUniformLocation(program,'u_y_matrix')let deg=30function render(){deg+=0.1const cosB=Math.cos(deg*Math.PI/180)const sinB=Math.sin(deg*Math.PI/180)gl.uniformMatrix4fv(u_x_matrix,false,new Float32Array([1,0,0,0,0,cosB,-sinB,0,0,sinB,cosB,0,0,0,0,1]))gl.uniformMatrix4fv(u_y_matrix,false,new Float32Array([cosB,0,-sinB,0,0,1,0,0,sinB,0,cosB,0,0,0,0,1]))for(let i=0;i<6;i++){gl.uniform4fv(colorLocation,faceColors[i])gl.drawElements(gl.TRIANGLES,6,gl.UNSIGNED_SHORT,i*6*Uint16Array.BYTES_PER_ELEMENT)}window.requestAnimationFrame(render)}window.requestAnimationFrame(render)</script>
</body>
</html>
18-glmatrix矩阵库的使用
gl-matrix矩阵库
glmatrix.net/docs/
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.canvas{border: 1px solid #ccc;}</style>
</head>
<body><canvas class="canvas" width="500" height="500"></canvas><!-- 顶点着色器 --><script id="vertex-shader" type="x-shader/x-vertex">attribute vec4 aPosition;unifrom mat4 mTranslate;void main(){gl_Position=mTranslate*aPosition;}</script><!-- 片段着色器 --><script id="fragment-shader" type="x-shader/x-fragment">void main(){gl_FragColor=vec4(1.0,0.0,0.0,1.0);}</script><script type="module">import {mat4} from 'gl-matrix';const canvas=document.querySelector('.canvas')const gl=canvas.getContext("webgl")//创建顶点着色器和片元着色器const vertexShader=gl.createShader(gl.VERTEX_SHADER)const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)//获取着色器源码const vertexSource=document.getElementById('vertex-shader').innerTextconst fragmentSource=document.getElementById('fragment-shader').innerText//绑定着色器源码gl.shaderSource(vertexShader, vertexSource)gl.shaderSource(fragmentShader, fragmentSource)//编译着色器源码gl.compileShader(vertexShader)gl.compileShader(fragmentShader)//创建程序对象const program=gl.createProgram()gl.attachShader(program, vertexShader)gl.attachShader(program, fragmentShader)gl.linkProgram(program)gl.useProgram(program);const vertices=new Float32Array([-0.5,-0.5,0.5, //第一个点的x轴和y轴坐标-0.5,0,0.5 //第二个点的xy轴坐标])const buffer=gl.createBuffer()gl.bindBuffer(gl.ARRAY_BUFFER, buffer)gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)const posLocation=gl.getAttribLocation(program, 'aPosition')gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 2*Float32Array.BYTES_PER_ELEMENT, 0)gl.enableVertexAttribArray(posLocation)const uniformTranslate=gl.getUniformLocation(program,'mTranslate')const matrix=mat4.create()mat4.translate(matrix,matrix,[0.5,0.5,0])gl.uniformMatrix4fv(uniformTranslate,false,matrix)gl.drawArrays(gl.TRIANGLES, 0, 3);</script>
</body>
</html>
19-矩阵方法的使用
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title><style>.canvas {border: 1px solid #ccc;}</style></head><body><canvas class="canvas" width="500" height="500"></canvas><!-- 顶点着色器 --><script id="vertex-shader" type="x-shader/x-vertex">attribute vec4 aPosition;uniform mat4 mTranslate;void main(){gl_Position=mTranslate * aPosition;}</script><!-- 片段着色器 --><script id="fragment-shader" type="x-shader/x-fragment">void main(){gl_FragColor=vec4(1.0,0.0,0.0,1.0);}</script><script type="module">import { mat4 } from "gl-matrix";const canvas = document.querySelector(".canvas");const gl = canvas.getContext("webgl");//创建顶点着色器和片元着色器const vertexShader = gl.createShader(gl.VERTEX_SHADER);const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);//获取着色器源码const vertexSource = document.getElementById("vertex-shader").innerText;const fragmentSource =document.getElementById("fragment-shader").innerText;//绑定着色器源码gl.shaderSource(vertexShader, vertexSource);gl.shaderSource(fragmentShader, fragmentSource);//编译着色器源码gl.compileShader(vertexShader);gl.compileShader(fragmentShader);//创建程序对象const program = gl.createProgram();gl.attachShader(program, vertexShader);gl.attachShader(program, fragmentShader);gl.linkProgram(program);gl.useProgram(program);const vertices = new Float32Array([-0.5,-0.5,0.5, //第一个点的x轴和y轴坐标-0.5,0.0,0.5, //第二个点的xy轴坐标]);const buffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, buffer);gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);const posLocation = gl.getAttribLocation(program, "aPosition");gl.vertexAttribPointer(posLocation,2,gl.FLOAT,false,2 * Float32Array.BYTES_PER_ELEMENT,0);gl.enableVertexAttribArray(posLocation);const uniformTranslate = gl.getUniformLocation(program, "mTranslate");const matrix = mat4.create();// mat4.translate(matrix, matrix, [0.5, 0.5, 0]);mat4.scale(matrix, matrix, [0.5, 0.5, 0]);gl.uniformMatrix4fv(uniformTranslate, false, matrix);gl.drawArrays(gl.TRIANGLES, 0, 3);</script></body>
</html>