WEBGL 学习使用代码

news/2025/3/25 18:01:38/文章来源:https://www.cnblogs.com/duyuanshang/p/18779505

目录
  • 杂七杂八
  • 第一节 绘制出了一个点
  • 第二节 动态传递点数据
  • 第三节 缓冲区和画线
  • 第四节 彩色线段
  • 第五节 单个 buffer 渲染颜色
  • 第六节 抽离代码 & 画彩色三角形
  • 第七节 图元的七种绘制方式
  • 第八节 uniform 传值变换数据
  • 第九节 旋转矩阵
    • 三角函数
    • 矩阵的计算
    • 推导
    • 代码实现
  • 第十节 线框立方体
    • X & Y 轴旋转矩阵公式
    • 代码实现

杂七杂八

WEBGL 学习:

https://www.bilibili.com/video/BV1AS411A74T

MDN 的文档是:https://developer.mozilla.org/zh-CN/docs/Web/API/WebGL_API
课程文档:https://bx2eq6ulg18.feishu.cn/docx/I4hTdO95qozPBOxauPlcbDfInVd?from=from_copylink
在线文本比对: https://www.qianbo.com.cn/Tool/Text-Difference/
在线画布:https://excalidraw.com/

  1. 类型化数组

const int8 = new Int8Array(8)

  1. 着色器

是一种编程语言,是一个画点工具,每个点都有自己的颜色。(GLSL)

顶点着色器,片元着色器

顶点着色器:处理每个顶点的属性
片元着色器:处理每个像素的颜色

获取上下文对象,创建着色器对象,绑定着色器源码,编译着色器源码。
创建程序对象,附加着色器对象,链接对象,把当前程序成为当前的渲染状态。

绘制图元。

第一节 绘制出了一个点

绘制出了一个点:

    <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 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);// 绘制gl.drawArrays(gl.POINTS, 0, 1);</script>

第二节 动态传递点数据

    <!-- 顶点着色器--><script id="vertex-shader" type="x-shader/x-vertex">/* attribute :用于顶点着色器,冲顶点缓冲区传入的变量也就是 `gl.getAttribLocation` 使用*/attribute vec2 aPos;attribute vec2 aPos1;void main(){gl_PointSize = 10.0;vec2 newPos = aPos + aPos1;gl_Position = vec4(aPos, 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').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 posLocation = gl.getAttribLocation(program, 'aPos');const posLocation1 = gl.getAttribLocation(program, 'aPos1');const offset = [0.5, 0.5];const offset1 = [0.1, 0.3];gl.vertexAttrib2f(posLocation,...offset);gl.vertexAttrib2f(posLocation,...offset1);// 绘制gl.drawArrays(gl.POINTS, 0, 1);</script>

第三节 缓冲区和画线

    <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').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,  // 第一个点的 x & y 坐标0.5,0.5,  // 第二个点的 x & y 坐标]);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>

第四节 彩色线段

    <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').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,  // 第一个点的 x & y 坐标0.5,-0.5,  // 第二个点的 x & y 坐标]);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 colorLocation = gl.getAttribLocation(program, 'aColor');const colorBuffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 4 * Float32Array.BYTES_PER_ELEMENT, 0);gl.enableVertexAttribArray(colorLocation);// 绘制gl.drawArrays(gl.LINES, 0, 2);</script>

第五节 单个 buffer 渲染颜色

    <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').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,  // 第一个点的 x & y 坐标0.0, 0.0, 0.0, 1.0,  // 第一个点的颜色0.5, -0.5,  // 第二个点的 x & y 坐标1.0, 0.0, 0.0, 0.0,  // 第二个点的颜色]);// 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 colorLocation = gl.getAttribLocation(program, 'aColor');const colorBuffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 4 * Float32Array.BYTES_PER_ELEMENT, 2 * Float32Array.BYTES_PER_ELEMENT);gl.enableVertexAttribArray(colorLocation);// 绘制gl.drawArrays(gl.LINES, 0, 2);</script>

第六节 抽离代码 & 画彩色三角形

建立新的目录文件

'./utiles/initShader.js'

代码是:

export default function(gl){// 创建顶点着色器和片元着色器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);return program;
}

原来的 html 为:

    <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 type="module">import initShader from './utiles/initShader.js';const canvas = document.querySelector('.canvas');const gl = canvas.getContext('webgl');const program = initShader(gl);const vertices = new Float32Array([-0.5, -0.5, 1.0, 0.0, 0.0, 0.0,0.5, -0.5, 0.0, 1.0, 0.0, 0.0,-0.0, 0.5, 0.0, 0.0, 1.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');const colorLocation = gl.getAttribLocation(program, 'aColor');// 告诉解析器,怎么解析我们缓冲区里面的数据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, vertices, gl.STATIC_DRAW);gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 4 * Float32Array.BYTES_PER_ELEMENT, 2 * Float32Array.BYTES_PER_ELEMENT);gl.enableVertexAttribArray(colorLocation);// 绘制gl.drawArrays(gl.TRIANGLES, 0, 3);</script>

第七节 图元的七种绘制方式

    <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 type="module">import initShader from './utiles/initShader.js';const canvas = document.querySelector('.canvas');const gl = canvas.getContext('webgl');const program = initShader(gl);const vertices = new Float32Array([-1.0, 1.0, 1.0, 0.0, 0.0, 0.0,-0.5, -1.0, 0.0, 1.0, 0.0, 0.0,-0.5, 1.0, 0.0, 0.0, 1.0, 0.0,0.0, -1.0, 0.0, 1.0, 0.0, 0.0,0.0, 1.0, 0.0, 1.0, 0.0, 0.0,0.5, -1.0, 0.0, 0.0, 1.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');const colorLocation = gl.getAttribLocation(program, 'aColor');// 告诉解析器,怎么解析我们缓冲区里面的数据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, vertices, gl.STATIC_DRAW);gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 4 * Float32Array.BYTES_PER_ELEMENT, 2 * Float32Array.BYTES_PER_ELEMENT);gl.enableVertexAttribArray(colorLocation);// 绘制// gl.LINE_STRIP 连续的线、gl.LINE_LOOP 闭合的线// TRIANGLE_STRIP 三角形条带、gl.TRIANGLE_FAN 三角形扇形(都以第一个点来画三角形)gl.drawArrays(gl.POINTS, 0, 6);gl.drawArrays(gl.LINE_LOOP, 0, 6);gl.drawArrays(gl.TRIANGLE_FAN, 0, 6);</script>

第八节 uniform 传值变换数据

    <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">precision highp float;  // 声明精度varying vec4 vColor;void main(){gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);}</script><script type="module">import initShader from './utiles/initShader.js';const canvas = document.querySelector('.canvas');const gl = canvas.getContext('webgl');const program = initShader(gl);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');const translationLocation = gl.getUniformLocation(program, 'uTranslate');const translation = [-0.2, 0.2];gl.uniform2fv(translationLocation, translation);// 告诉解析器,怎么解析我们缓冲区里面的数据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>

第九节 旋转矩阵

三角函数

image

x1 = r * cosa
y1 = r * sinax2 = r * cos(a + b)= r * (cosa * cosb - sina * sinb)= r * cosa * cosb - r * sina * sinb= x1 * cosb - y1 * sinb
y2 = r * sin(a + b)= r * (sina * cosb + sinb * cosa)= r * sina * cosb + r * sinb * cosa= y1 * cosb + x1 * sinbx2 = x1 * cosb - y1 * sinb
y2 = y1 * cosb + x1 * sinb

矩阵的计算

相加,必须得有相同的维度:

\(\begin{bmatrix}1 & 1 & 1 \\2 & 2 & 2 \\3 & 3 & 3 \end{bmatrix}\) + \(\begin{bmatrix}1 & 1 & 1 \\1 & 1 & 1 \\1 & 1 & 1 \end{bmatrix}\) = \(\begin{bmatrix}2 & 2 & 2 \\3 & 3 & 3 \\4 & 4 & 4 \end{bmatrix}\)

相乘,第一个元素的每行的列数,必须等于第二个元素的行数:

\(\begin{bmatrix}1 & 1 & 1 \\2 & 2 & 2 \\3 & 3 & 3 \end{bmatrix}\) * \(\begin{bmatrix}1 \\2 \\3 \end{bmatrix}\) = \(\begin{bmatrix}6 \\12 \\18 \end{bmatrix}\)

第一行:1 * 1 + 1 * 2 + 1 * 3 = 6
第二行:2 * 1 + 2 * 2 + 2 * 3 = 12
第三行:3 * 1 + 3 * 2 + 3 * 3 = 18

推导

\(\begin{bmatrix}cosb & -sinb \\sinb & cosb \end{bmatrix}\) * \(\begin{bmatrix}x \\y \end{bmatrix}\) = \(\begin{bmatrix}cosb * x - sinb * y \\sinb * x + cosb * y \end{bmatrix}\)

代码实现

    <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">precision highp float;  // 声明精度varying vec4 vColor;void main(){gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);}</script><script type="module">import initShader from './utiles/initShader.js';const canvas = document.querySelector('.canvas');const gl = canvas.getContext('webgl');const program = initShader(gl);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>

第十节 线框立方体

X & Y 轴旋转矩阵公式

  1. 绕 X 轴旋转

\(\begin{bmatrix}1 & 0 & 0 & 0 \\0 & cos & -sin & 0 \\0 & sin & cos & 0 \\0 & 0 & 0 & 1 \end{bmatrix}\)

  1. 绕 Y 轴旋转

\(\begin{bmatrix}cos & 0 & -sin & 0 \\0 & 1 & 0 & 0 \\sin & 0 & cos & 0 \\0 & 0 & 0 & 1 \end{bmatrix}\)

  1. 绕 Z 轴旋转

\(\begin{bmatrix}cos & -sin & 0 & 0 \\sin & cos & 0 & 0 \\0 & 0 & 1 & 0 \\0 & 0 & 0 & 1 \end{bmatrix}\)

代码实现

    <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);mat4 mz = mat4(  // 旋转矩阵cos, -sin, 0, 0,sin, cos, 0, 0,0, 0, 1, 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 highp float;  // 声明精度varying vec4 vColor;void main(){gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);}</script><script type="module">import initShader from './utiles/initShader.js';const canvas = document.querySelector('.canvas');const gl = canvas.getContext('webgl');const program = initShader(gl);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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/904362.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kettle 版本这么多,到底该怎么选?

Kettle(Pentaho Data Integration)作为一款功能强大的开源 ETL(Extract, Transform, Load,即数据抽取、转换和加载)工具,拥有众多版本,这让许多用户在选择时犯了难。 1、提出问题 经常有群友提出使用kettle版本的问题,如下图所示:2、kettle版本 有许多的的历史版本,…

C++实验二

实验一#include <stdio.h>#include <stdlib.h>#include <time.h>#define N 5int main() {int number;int i;srand(time(0)); // 以当前系统时间作为随机种子for(i = 0; i < N; ++i) {number = rand() % 100 + 1;printf("20490042%04d\n", n…

ESP32 Audino 驱动12864点阵屏 自定义中文字库

一.安装u8g2 #include <Arduino.h> #include <U8g2lib.h>U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE, /* clock=*/22, /* data=*/21); // ESP32 Thing, HW I2C with pin remappingvoid setup(void) {u8g2.begin();u8g2.enableU…

Linux 离线安装 lz4

前言:本文操作是在 CentOS-7 下执行的,不确定在其他 Linux 发布版是否能同样正常执行。1、检查前置依赖组件在安装 lz4 之前,需要确认已安装了相关依赖组件: gcc 。 rpm -qa | grep gcc前置依赖组件的具体离线安装方法请参考:CentOS-7离线安装gcc 2、下载lz4安装包 官方下…

sql语句把图片存入数据库

这是一个小的练习,目的是把图片以二进制字符串形式存入sql数据库表中,后续练习尝试在WINCC把其还原成图片。 在以前的数据库MyDB中新建一个数据表,有四个字段: imageID 类型为bigint,作为标识符,自增1 mydatetime 日期事件类型 imagename varchar(100)数据类型 imagedata…

FSRCNN:加速超分辨率卷积神经网络

作为一种成功的图像超分辨率 (SR) 深度模型,超分辨率卷积神经网络 (SRCNN) 在速度和恢复质量方面都表现出优于以往手工制作模型的性能。然而,高计算成本仍然阻碍了它需要实时性能 (24 fps) 的实际使用。在本文中,我们旨在加速当前的 SRCNN,并提出一种紧凑的沙漏形 CN…

GNSS测量实习

实 习 报 告学院:建筑工程与空间信息学院 专业:地理信息科学 实习性质:校内实习 实习单位:建筑工程与空间信息学院 指导教师:冯建迪目录 一、实习的性质和目的要求 二、实习的任务和内容 三、静态测量 3.1 静态测量简介 3.2作业流程 3.3注意事项 3.4 GPS 控制网设计…

花束搭配

提取公式:Ai+Aj>Bi+Bj 变形得:Ai-Bi+Aj-Bj>0#include<bits/stdc++.h> using namespace std; #define int long long const int N = 1e6 + 10; int n, m, k, cnt, ans; string s;void solve() {cin >> n;vector<int> a(n), b(n), c(n);for (int i = 0…

题解:P11955 「ZHQOI R1」覆盖

https://www.luogu.com.cn/article/20vbz4zk对于一颗线段树,它的结构如图所示。一定是先有红色,再有绿色,再有蓝色,再有紫色。如果靠前的颜色没有那么靠后的颜色不可能出现。我们先考虑上一层(黑色)都已经处理完,新的一层会有什么影响,即已知 \(f_{2^j}\) 求 \(f_{2^j+…

sir.net,一个类似itdog/pingpe/chinaz的网络质量检测/监视工具

相信不少站长或主机爱好者都使用过itdog/pingpe/chinaz网络质量和ip质量检测这类工具,这其中最重要最常用的就是ping值检测工具了,如果你熟悉或接确过这方面的应用,那么现在,不防尝鲜下 sir.net(中文名:站长先生) ,它将不失作为你一个更有趣更稳定的选择。 1)类似google.…