返回顶部
首页 > 资讯 > 前端开发 > JavaScript >WebGL 多重纹理的使用介绍
  • 664
分享到

WebGL 多重纹理的使用介绍

WebGL 多重纹理WebGL 多重纹理 2023-05-16 17:05:00 664人浏览 八月长安
摘要

目录引言激活绑定配置分配传递效果代码着色器设置数据缓存区的设置纹理对象的初始化绘制和动态变化小结一下引言 基于上篇的内容,纹理中最小的单位是纹素,若干纹素组成一个纹理单元,每个纹理单

引言

基于上篇的内容,纹理中最小的单位是纹素,若干纹素组成一个纹理单元,每个纹理单元用一个number值来管理,那么我们来看看它是如何工作的。

激活

在使用纹理单元之前,得需要激活纹理单元

activeTexture()

参数:

  • 指定准备激活的纹理单元:webGL.TEXTURE0、WEBgl.TEXTURE1...最后的数字表示纹理单元的编号

绑定

这一步,需要告诉WebGL系统纹理对象使用的是何种类型的纹理,在对该对象的操作之前,需要先绑定该对象,这和之前的缓冲区对象的数据写操作类似。

bindTexture(webgl.TEXTURE_2D, texture0)

参数:

  • webgl.TEXTURE_2D: 二维纹理;webgl.TEXTURE_CUBE_MAP: 立方体纹理
  • texture0:需要绑定指定的纹理对象

该方法开启纹理对象,以及将纹理对象texture0绑定到纹理单元webgl.TEXTURE0上,之后通过操作纹理单元去操作纹理对象。

配置

这儿主要是对纹理对象具体的信息操作了,例如纹理单元类型、尺寸、是否裁剪、纹理的展示方式(放大或缩小)等,下面我们再一一分析。

texParameteri(target, pname, param)

参数:

  • target: webgl.TEXTURE_2D或webgl.TEXTURE_CUBE_MAP
  • pname: webgl.TEXTURE_MAG_FILTER纹理放大,例如16x16的纹理图像映射到32x32的像素空间中;webgl.TEXTURE_MIN_FILTER纹理缩小, 应用场景相反;webgl.TEXTURE_WRAP_S纹理水平轴(ST坐标系统)方向填充;webgl.TEXTURE_WRAP_T纹理T轴方向填充。
  • param: webgl.LINEAR线性变换,使用距离像素中心最近的四个点,进行线性平均加权,然后作为新的颜色值; webgl.NEAREST最近的距离优先,新的像素值取中心像素的值;CLAMP_TO_EDGE: 设置纹理 S/T 轴方向上的边缘环绕方式为CLAMP_TO_EDGE,即在超出边缘的部分使用纹理边缘的像素颜色填充. webgl.REPEAT纹理重复补充;webgl.MIRRORED_REPEAT:纹理镜像对称式重复

会发现参数pname、param中的参数常量分类比较多,对应的分类是

  • pname : TEXTURE_MAG_FILTER、TEXTURE_MIN_FILTER
  • param: NEAREST、LINEAR

  • pname : TEXTURE_WRAP_S、TEXTURE_WRAP_T
  • param: REPEAT、MIRRORED_REPEAT、CLAMP_TO_EDGE

分配

纹理对象信息配置好后,接着可以将纹理图像分配给纹理对象

webgl.texImage2D(target, level, internalfORMat, format type, image)

参数:

  • target: webgl.TEXTURE_2D或webgl.TEXTURE_CUBE_MAP
  • level: 指定纹理缓冲区中要加载的纹理级别,一般为 0
  • internalformat: 纹理对象内部数据格式,通常使用webgl.RGBA
  • format: 纹理数据格式,必须与internalformat相同的值
  • type: 纹理数据类型
  • image: 纹理对象中image对象

其中的纹理数据类型有:

webgl.UNSIGNED_BYTE: 无符号整型,每个颜色分量占据1字节
webgl.UNSIGNED_SHORT_5_6_5:RGB
webgl.UNSIGNED_SHORT_4_4_4:RGBA
webgl.UNSIGNED_SHORT_5_5_5_1:RGBA

传递

经过上面一系列准备后,我们就可以把最终的纹理单元传递给片元着色器了,这儿就用到了方法 webgl.uniform1i(),上篇这个方法已经说过了,就不再说明了。

主要看看片元着色器中是怎么做的

uniform sampler2D texture;
varying vec2 inUV;
vec4 color1=texture2D(texture, vec2(inUV.x, 1.0 - inUV.y));
gl_FraGColor=color1;
  • 定义了一个可以在外部访问的一种特殊的、专用于纹理对象的数据类型sampler2D,就是对应的纹理单元类型webgl.TEXTURE_2D;如果是webgl.TEXTURE_CUBE_MAP呢,则是samplerCube.
  • 通过uniform1i方法,将纹理对象传递到了片元着色器中的texture变量
  • inUV接收顶点着色器中的顶点的纹理坐标,当然这里的纹理坐标是在外部设置的
  • texture2D()在片元着色器中根据纹理坐标获取纹理图像上的纹素的颜色
  • 把获取到的颜色赋值给片元着色器

经过对纹理的加载、设置、映射,剩下的就是绘画了。

webgl.drawArrays(webgl.TRIANGLE_STRIP, 0, 4)

好了,晦涩难懂的概念介绍完了,就把具体的代码贴出来吧!

效果

代码

着色器设置

const VSHADER_SOURCE = `
  attribute vec2 a_position;
  attribute vec2 outUV;
  varying vec2 inUV;
  void main(void){
    gl_Position=vec4(a_position, 0.0, 1.0);
    inUV=outUV;
  }
`
const FSHADER_SOURCE = `
  precision mediump float;
  uniform sampler2D texture;
  uniform sampler2D texture1;
  varying vec2 inUV;
  uniform float anim;
  void main(void){
    vec4 color1=texture2D(texture, vec2(inUV.x, 1.0 - inUV.y));
    vec4 color2=texture2D(texture1, vec2(inUV.x + anim, 1.0 - inUV.y));
    gl_FragColor=color1+color2;
  }
`

数据缓存区的设置

const initBuffer = async () => {
  let positions = [
    0.8, -0.8,
    -0.8, -0.8,
    0.8, 0.8,
    -0.8, 0.8,
  ]
  let pointPosition = new Float32Array(positions)
  let aPsotion = webgl.getAttribLocation(webgl.program, "a_position")
  let triangleBuffer = webgl.createBuffer()
  webgl.bindBuffer(webgl.ARRAY_BUFFER, triangleBuffer)
  webgl.bufferData(webgl.ARRAY_BUFFER, pointPosition, webgl.STATIC_DRAW)
  webgl.enableVertexAttribArray(aPsotion)
  webgl.vertexAttribPointer(aPsotion, 2, webgl.FLOAT, false, 0, 0)
  var texCoords = [
    1, 0,
    0, 0,
    1, 1,
    0, 1,
  ]
  const attribOutUV = webgl.getAttribLocation(webgl.program, "outUV")
  let texCoordBuffer = webgl.createBuffer()
  webgl.bindBuffer(webgl.ARRAY_BUFFER, texCoordBuffer)
  webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(texCoords), webgl.STATIC_DRAW)
  webgl.enableVertexAttribArray(attribOutUV)
  webgl.vertexAttribPointer(attribOutUV, 2, webgl.FLOAT, false, 0, 0)
  uniformTexture = webgl.getUniformLocation(webgl.program, "texture")
  uniformTexture1 = webgl.getUniformLocation(webgl.program, "texture1")
  texture0 = await initTexture('/web-gl/landscape.png')
  texture1 = await initTexture("/web-gl/fog.png")
}

主要是设置顶点坐标和纹理坐标的数据

纹理对象的初始化

const initTexture = (imageSrc: string): Promise<WebGLTexture> => {
  return new Promise((resolve, reject) => {
    let textureHandle = webgl.createTexture()
    const image = new Image()
    image.onload = function () {
      webgl.bindTexture(webgl.TEXTURE_2D, textureHandle)
      webgl.texParameteri(
        webgl.TEXTURE_2D,
        webgl.TEXTURE_WRAP_S,
        webgl.CLAMP_TO_EDGE
      )
      webgl.texParameteri(
        webgl.TEXTURE_2D,
        webgl.TEXTURE_WRAP_T,
        webgl.CLAMP_TO_EDGE
      )
      webgl.texParameteri(
        webgl.TEXTURE_2D,
        webgl.TEXTURE_MIN_FILTER,
        webgl.LINEAR
      )
      webgl.texImage2D(
        webgl.TEXTURE_2D,
        0,
        webgl.RGBA,
        webgl.RGBA,
        webgl.UNSIGNED_BYTE,
        image
      )
      resolve(textureHandle)
    }
    image.onerror = reject
    image.src = imageSrc
  })
}

这儿需要使用异步方法,因为需要在image.onload方法中返回设置信息数据后的纹理对象。 在 webgl 的纹理加载中,由于图片是异步加载的,因此我们需要使用 Promise 来处理加载完毕后的回调函数。

绘制和动态变化

const updateCount = () => {
  count = count + 0.001
  if (count >= 1.14) {
    count = -1.0
  }
}
const draw = () => {
  webgl.clearColor(0.0, 1.0, 1.0, 1.0)
  webgl.clear(webgl.COLOR_BUFFER_BIT | webgl.DEPTH_BUFFER_BIT)
  webgl.enable(webgl.DEPTH_TEST)
  //纹理变动
  uniformAnim = webgl.getUniformLocation(webgl.program, "anim");
  updateCount()
  webgl.uniform1f(uniformAnim, count);
  webgl.activeTexture(webgl.TEXTURE0)
  webgl.bindTexture(webgl.TEXTURE_2D, texture0)
  webgl.uniform1i(uniformTexture, 0)
  webgl.activeTexture(webgl.TEXTURE1)
  webgl.bindTexture(webgl.TEXTURE_2D, texture1)
  webgl.uniform1i(uniformTexture1, 1)
  webgl.drawArrays(webgl.TRIANGLE_STRIP, 0, 4)
  requestAnimationFrame(draw)
}

具体的代码就是这些了。

小结一下

到目前为止,我们已经了解了顶点着色器、片元着色器、顶点缓冲区、矩阵绘制和变换、纹理图像、纹理叠加等,这样我们已经基本上对二维绘图掌握了,一个面我们了解了,之后我们可能就去看看多个面的物体和场景。

那么就让我们一起看看三维世界吧!

以上就是WebGL 多重纹理的详细内容,更多关于WebGL 多重纹理的资料请关注编程网其它相关文章!

--结束END--

本文标题: WebGL 多重纹理的使用介绍

本文链接: https://lsjlt.com/news/210331.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • WebGL 多重纹理的使用介绍
    目录引言激活绑定配置分配传递效果代码着色器设置数据缓存区的设置纹理对象的初始化绘制和动态变化小结一下引言 基于上篇的内容,纹理中最小的单位是纹素,若干纹素组成一个纹理单元,每个纹理单...
    99+
    2023-05-16
    WebGL 多重纹理 WebGL 多重纹理
  • WebGL颜色与纹理使用介绍
    目录引言颜色三角形颜色纹理纹理坐标特别说明: 图片坐标解决方案纹理图像着色器设置引言 基于之前的知识,这里主要是 将顶点的其他数据--如颜色等-传入顶点着色器图元光栅化--在顶点着色...
    99+
    2023-05-16
    WebGL 颜色纹理 WebGL 纹理
  • WebGL高级变换之Matrix4使用介绍
    目录引言gl-matrix简介示例--旋转矩阵变换WebGL按列矩阵gl-matrix 旋转矩阵复合变换效果放缩因子引言 上一篇结尾的说到了按列矩阵,但是如果是按照最原始的方式变换的...
    99+
    2023-05-16
    WebGL高级变换Matrix4 WebGL Matrix4
  • Android多线程处理机制中的Handler使用介绍
    接下来让我介绍Android的Handler的使用方法。Handler可以发送Messsage和Runnable对象到与其相关联的线程的消息队列。每个Handler对象与创建它...
    99+
    2022-06-06
    android多线程 handler 线程 Android
  • VueNextTick介绍与使用原理
    目录一、NextTick是什么定义理解为什么要有nexttick二、使用场景三、实现原理一、NextTick是什么 定义 在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后...
    99+
    2022-11-13
    Vue NextTick Vue NextTick的作用
  • Java多线程之FutureTask的介绍及使用
    目录一、FutureTask的理解二、FutureTask类图三、FutureTask类中常用方法四、FutureTask类的使用示例一、FutureTask的理解 FutureTa...
    99+
    2024-04-02
  • 重点介绍Golang方法的语法和使用
    Golang作为一门比较年轻的语言,在方法中也有自己独特的实现方式。本文将重点介绍Golang方法的语法和使用。一、方法定义Golang中可以为任何类型定义方法,包括引用类型和非引用类型。方法定义格式如下:func (t Type) met...
    99+
    2023-05-14
  • VuePostCSS的使用介绍
    目录PostCSS使用安装依赖运行使用第三方插件autoprefixer使用第三方插件postcss-preset-env使用第三方插件postcss-pxtorem运行的新方式Po...
    99+
    2023-02-06
    Vue PostCSS Vue PostCSS的使用
  • C/C++中多重继承详解及其作用介绍
    目录概述优缺点优点缺点声明多重继承的方法格式例子二义性两个基类有同名成员基类和派生类有同名成员两个基类从同一个基类派生概述 多重继承 (multiple inheritance): ...
    99+
    2024-04-02
  • JDBC的介绍与使用
    1. JDBC的介绍   jdbc为java开发者使用数据库提供了统一的编程接口,它由一组java类和接口组成。  访问数据库的流程  在连接这一过程中,一般初学者是MySQL和java在同一个电脑上,建立...
    99+
    2024-04-02
  • ResultSet的介绍与使用
    ResultSet是Java中用于表示数据库查询结果的对象,它可以对查询结果进行遍历和访问。一般来说,当使用JDBC进行数据库查询时...
    99+
    2023-09-11
    ResultSet
  • CountDownLatch介绍和使用【Java多线程必备】
    点击 Mr.绵羊的知识星球 解锁更多优质文章。 目录 一、介绍 二、特性 三、实现原理 四、适用场景 五、注意事项 六、实际应用 一、介绍     CountDownLatch 是 Java 中的一个并发工具类,用于协调多个线程之间...
    99+
    2023-10-21
    java
  • Node.js中多进程模块Cluster的介绍与使用
    前言 我们都知道nodejs最大的特点就是单进程、无阻塞运行,并且是异步事件驱动的。Nodejs的这些特性能够很好的解决一些问题,例如在服务器开发中,并发的请求处理是个大问题,阻塞式的函数会导致资源浪费和时...
    99+
    2022-06-04
    模块 进程 Node
  • JavaScript闭包原理与使用介绍
    目录1. 认识闭包2. 变量的作用域和生命周期2.1 变量的作用域2.2 变量的生命周期3. 闭包的概念及其作用3.1 闭包的概念3.2 闭包的应用3.2.1 保存私有变量3.2.2...
    99+
    2022-11-13
    JavaScript闭包 JS闭包
  • Repo工作原理和使用介绍
    目录1. 概要2. 工作原理2.1 项目清单库(.repo/manifests)2.2 repo脚本库(.repo/repo)2.3 仓库目录和工作目录3. 使用介绍3.1 init...
    99+
    2024-04-02
  • Vuesnippets插件原理与使用介绍
    目录vue-snippetssnippets是什么vue-3-snippets插件支持的功能vue-snippets 随着开发者的年限的增加,不仅头发有点少,重复的代码也不断的增多,...
    99+
    2022-11-13
    Vue snippets原理 Vue snippets插件
  • Android 使用压缩纹理的方案
    目录一、压缩纹理概念二、OpenGL 接口1.glCompressedTexImage2D2.判断压缩纹理是否支持三、压缩纹理加载1.ETC12.ETC23.ASTC四、总结本文介绍...
    99+
    2024-04-02
  • TIDB简介及TIDB部署、原理和使用介绍
    TiDB简介及TiDB部署、原理和使用介绍 从MySQL架构到TiDB 数据库分类 ​ 介绍TiDB数据库之前,先引入使用场景。如今的数据库种类繁多,RDBMS(关系型数据库)、NoSQL(Not Only SQL)、NewSQL,在数据库...
    99+
    2023-08-17
    tidb 数据库 mysql 大数据 etl工程师
  • Node.js中 __dirname 的使用介绍
    前言 本文主要给大家介绍的是关于Node.js中 __dirname 使用的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍: 方法如下 新建个文件 app.js 里面的内容如下: conso...
    99+
    2022-06-04
    Node js __dirname
  • Swoole与HTTP的使用介绍
    这篇文章主要讲解了“Swoole与HTTP的使用介绍”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Swoole与HTTP的使用介绍”吧!目标了解swoole的http_server的使用了解...
    99+
    2023-06-07
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作