webGL入门-3

183 阅读4分钟

varying变量

image-20230811095420407.png

// 顶点着色器
const VERTEX_SHADER = `
    precision mediump float;
    attribute vec4 a_Position;
    varying vec4 v_Color; // 由顶点着色器向片元着色器传输数据
      void main() {
        v_Color = a_Position; // 将数据赋值并传递给片元着色器
        gl_Position = a_Position;
      }
    `
// 片元着色器
const FRAG_SHADER = `
    precision mediump float; 
    // uniform vec4 u_FragColor;
    varying vec4 v_Color;
​
      void main() {
        gl_FragColor = v_Color;
      }
    `

webgl渲染流程

  1. 确定顶点坐标

  2. 图片装配,将独立的 顶点坐标装配成几何图形,由g l.drawArrays()第一个参数确定

  3. 光栅化,将装配好的图形转换为片元

    性能优化:

    a . 对于不透明物体,背面不可见,渲染时可以剔除,不参与绘制,节省渲染开销
    

    b. 可视范围外的事物看不到,可以裁剪,不参与绘制

  4. 图形绘制

纹理坐标

又称st坐标

image-20230811101003666.png

在webgl中需要通过纹理坐标和图形顶点坐标的映射关系来确定贴图

开启纹理单元

webgl是通过纹理单元来管理纹理对象,每个纹理单元管理一张纹理图片

// 顶点着色器
const VERTEX_SHADER = `
    attribute vec4 a_Position;
    attribute vec4 a_Tex;
    varying vec2 v_Tex;
      void main() {
        gl_Position = a_Position;
        v_Tex=vec2(a_Tex.x,a_Tex.y);
      }
    `
// 片元着色器
const FRAG_SHADER = `
    precision mediump float; 
    uniform sampler2D u_Sampler;
    varying vec2 v_Tex;
      void main() {
        gl_FragColor = texture2D(u_Sampler, v_Tex );
      }
    `
​
const img = new Image()
img.src = './assets/2.jpg'
img.onload = function () {
  // 创建纹理对象
  const texture = gl.createTexture()
  // gl.deleteTexture(texture) // 删除纹理对象
  // 翻转图片y轴
  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1) // 参数1表示对纹理图像进行y轴反转,因为图片的y轴与webgl的y轴方向相反,参数2表示对所有纹理图像都进行y轴反转
  // 开启0号纹理单元
  gl.activeTexture(gl.TEXTURE0)
  // 向target绑定纹理对象
  gl.bindTexture(gl.TEXTURE_2D, texture)// target可以是gl.TEXTURE_2D或gl.TEXTURE_CUBE_MAP,表示绑定的纹理对象是二维纹理还是立方体纹理,纹理单元只能绑定一种类型的纹理对象
  // 配置纹理参数
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) // 纹理缩小,参数1表示纹理目标,参数2表示纹理缩小操作,参数3表示缩小操作的纹理过滤方式,参数4表示纹理缩小操作的纹理过滤方式
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) // 纹理放大,参数1表示纹理目标,参数2表示纹理放大操作,参数3表示放大操作的纹理过滤方式,参数4表示纹理放大操作的纹理过滤方式
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) // 纹理水平填充,参数1表示纹理目标,参数2表示纹理水平填充操作,参数3表示水平填充的纹理过滤方式
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) // 纹理垂直填充,参数1表示纹理目标,参数2表示纹理垂直填充操作,参数3表示垂直填充的纹理过滤方式
  // 配置纹理图像
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, img) // 参数1表示纹理目标,参数2表示纹理的详细级别,参数3表示纹理图像的内部格式,参数4表示纹理的格式,参数5表示纹理的数据类型,参数6表示纹理图像
  gl.uniform1i(u_Sampler, 0) // 将0号纹理传递给着色器

矢量和矩阵

矢量

vec2、vec3、vec4具有2,3,4个浮点数元素矢量

ivec2、ivec3、ivec4具有2,3,4个整形数元素矢量

bvec2、bvec3、bvec4具有2,3,4个布尔元素矢量

通过构造函数赋值: vec4 position = vec(0.0, 0.0, 0.0, 0.0, 1.0)

访问分量:

x,y,z,w访问顶点坐标分量,(position.x position.xy)

s, t, p, q访问纹理坐标分量

矩阵

mat2、mat3、mat4 2 * 2, 3 * 3 4 * 4的浮点数元素矩阵

矩阵入参 ,参数是列主序的

纹理取样器

sampler2D samplerCube

只能声明为uniform变量

uniform sampler2D u_Sampler;
uniform samplerCube u_SamplerCube;

分支和循环

if else , for ,while, do while

跳出循环

continue

break

discard(只能在片元着色器中使用,表示放弃 当前片元直接处理下一个片元)

内置函数

角度函数

  • radians 角度转弧度
  • degress 弧度转角度

三角函数

sin正弦

cos余弦

tan正切

asin反正弦

acos 反余弦

atan反正切

指数函数

pow 次方

exp 自然质数

log 对数

sqrt 开平方

inversesqrt 开平方的倒数

通用函数

abs 绝对值

min/max 最小最大值

mod 取余数

sign 取符号

floor 向下取整

ceil 向上取整

clamp 限定范围

fract 获取小数部分

几何函数

length(x) 计算向量x 的长度

distance(x,y) 计算向量xy直接的距离

dot(x,y)计算向量xy的点积

cross(x,y)计算向量xy的差积

normalize(x) 返回方向同x,长度为1的向量

存储限定词

const 声明一个常量,定义后不可改变

attribute 只能顶点着色器里,只能声明为全局变量表示单个顶点信息

uniform 可同时出现在顶点着色器和片元着色器中,只读类型,强度一致性,存储的是用来影响所有顶点的数据,如变换矩阵

varying 顶点着色器向片元着色器传递数据

精度限定

提升运行效率,消减内存开支

  • 可以单独针对某个变量声明精度 如 mediup float f;(不足:会出现精度歧义,不利于后期维护)
  • 通过precision 关键字来修改着色器的默认精度,如 precision mediump float;

精度枚举

高精度 highp 中精度 mediump 低精度 lowp

片元着色器中的float 类型没有默认精度,所以如果需要在片元着色器中使用浮点型数据的时候,需要修改默认精度