WebGL 添加背景图

news2024/11/28 14:29:25

1. 纹理坐标(st坐标)简介

ST纹理坐标(也称为UV坐标)是一种二维坐标系统,用于在三维模型的表面上精确地定位二维纹理图像。这种坐标系统通常将纹理的左下角映射到(0,0),而右上角映射到(1,1)。

  • S坐标(U坐标):通常对应纹理图像的水平方向,即纹理的宽度。
  • T坐标(V坐标):通常对应纹理图像的垂直方向,即纹理的高度。

1.1 纹理坐标的工作原理

  • 纹理坐标的范围通常是从0.0到1.0,其中(0.0, 0.0)代表纹理的左下角,而(1.0, 1.0)代表右上角。
  • 在WebGL中,纹理坐标系统的t轴(垂直轴)与传统图像文件的y轴方向相反,这意味着当你在WebGL中使用纹理时,通常需要翻转图像的Y轴以确保正确的映射。
  • 这可以通过设置gl.UNPACK_FLIP_Y_WEBGL为1来实现。

2. 基本步骤

​​​​2.1 创建纹理对象

  • 使用gl.createTexture()创建一个新的纹理对象。
  • 可以通过 gl.deleteTexture(textrue)来删除纹理对象。
 const texture = gl.createTexture();

2.2 翻转图片Y轴

gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); 

2.3 开启纹理单元

gl.activeTexture(gl.TEXTURE0)

2.4绑定纹理对象

使用gl.bindTexture(type, texture)将纹理对象绑定到纹理单元上。type 参数有以下两种:

  • gI.TEXTURE_2D:二维纹理
  • gI.TEXTURE_CUBE_MAP:立方体纹理
gl.bindTexture(gl.TEXTURE_2D, texture);

2.5 配置纹理参数

设置纹理的过滤方式(gl.TEXTURE_MIN_FILTER和gl.TEXTURE_MAG_FILTER)、包裹方式(gl.TEXTURE_WRAP_S和gl.TEXTURE_WRAP_T)等参数。

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);

2.6 上传纹理图像数据

使用gl.texImage2D(type, level,internalformat, format,dataType, image)将图像数据上传到纹理对象中。

2.6.1 type参数:
  • gI.TEXTURE_2D:二维纹理
  • gI.TEXTURE_CUBE_MAP:立方体纹理
2.6.2 level参数:
  • 默认为0
2.6.3 internalformat参数
  • gI.RGB
  • gI.RGBA
  • gI.ALPHA
  • gI.LUMINANCE 使用物体表面的红绿蓝 分量的加权平均值来计算
  • gI.LUMINANCE ALPHA
2.6.4 format参数
  • format 纹理的内部格式,必须和internalformat 相同
2.6.5 dataType参数
  • 9I.UNSIGNED_BYTE
  • gI.UNSIGNED_SHORT_5_6_5
  • gI.UNSIGNED_SHORT_4_4_4_4
  • gI.UNSIGNED_SHORT_5_5_5_1
 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);

3. 实例代码

以下是一个简单的WebGL示例,展示了如何给一个简单的四边形添加背景图:

/** @type {HTMLCanvasElement} */
        const ctx = document.getElementById('canvas')
        const gl = ctx.getContext('webgl')
        // 顶点着色器源码
        const vertexShaderSource = `
            attribute vec4 aPosition;
            attribute vec4 aTex;
            varying vec2 vTex;

            void main() {
                gl_Position = aPosition;
                vTex = vec2(aTex.x, aTex.y);
            }`

        // 片源着色器源码
        const fragmentShaderSource = `
            precision lowp float;
            uniform sampler2D uSampler;
            varying vec2 vTex;

            void main() {
                gl_FragColor = texture2D(uSampler, vTex);
            }`
        const program = initShader(gl, vertexShaderSource, fragmentShaderSource);
        const aPosition = gl.getAttribLocation(program, 'aPosition');
        const aTex = gl.getAttribLocation(program, 'aTex');
        const uSampler = gl.getUniformLocation(program, 'uSampler');//赋值

        const points = new Float32Array([
            -0.5, 0.5, 0.0, 1.0,
            -0.5, -0.5, 0.0, 0.0,
            0.5, 0.5, 1.0, 1.0,
            0.5, -0.5, 1.0, 0.0,
        ])
        const buffer = gl.createBuffer();
        const BYTES = points.BYTES_PER_ELEMENT; // 偏移字节
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
        gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);
        gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, BYTES * 4, 0);
        gl.enableVertexAttribArray(aPosition);
        gl.vertexAttribPointer(aTex, 2, gl.FLOAT, false, BYTES * 4, BYTES * 2);
        gl.enableVertexAttribArray(aTex);

        const img = new Image();
        img.onload = function () {
            // 创建纹理对象并加载图片
            const texture = gl.createTexture();
            // 翻转图片Y轴
            gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
            // 开启一个单元纹理
            gl.activeTexture(gl.TEXTURE0)
            // 绑定纹理对象
            gl.bindTexture(gl.TEXTURE_2D, texture);
            // 配置纹理参数
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
            // 传纹理图像数据
            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, img);
            gl.uniform1i(uSampler, 0);
            gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
        }
        img.src = './images/img2.png';

4.效果如下

 

5. 添加多张背景图 

  • 添加几张图,就定义几个sampler2D 
// 片源着色器源码
const fragmentShaderSource = `
    precision lowp float;
    uniform sampler2D uSampler;
    uniform sampler2D uSampler1;
    varying vec2 vTex;

    void main() {
    vec4 c1 = texture2D(uSampler, vTex);
    vec4 c2 = texture2D(uSampler1, vTex);
    texture2D(uSampler1, vTex);
        gl_FragColor = c1 * c2;
    }`
  • 将创建纹理的过程封装方法
// 封装函数
        function getImage(location, url, index) {
            // Promise
            return new Promise(resolve => {
                const img = new Image();
                img.onload = function () {
                    // 创建纹理对象并加载图片
                    const texture = gl.createTexture();
                    // 翻转图片Y轴
                    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
                    // 开启一个单元纹理
                    gl.activeTexture(gl[`TEXTURE${index}`])
                    // 绑定纹理对象
                    gl.bindTexture(gl.TEXTURE_2D, texture);
                    // 配置纹理参数
                    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
                    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
                    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
                    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
                    // 传纹理图像数据
                    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, img);
                    gl.uniform1i(location, index);

                    resolve();
                }
                img.src = url;
            });
        }
        Promise.all([getImage(uSampler, "./images/img.png", 0), getImage(uSampler1, "./images/img2.png", 1)]).then(() => {
            gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
        })

效果如下 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Multisim的可编程放大电路设计与仿真

74LS279(RS触发器),结合开关,将输出接入74LS163实现的8位计数器的时钟端,每拨动两次开关K,将产生一个脉冲信号,计数器将加一,产生的结果为000,001,010,011,100,101,110,111&#xff…

面试经典 150 题.P26. 删除有序数组中的重复项(003)

本题来自:力扣-面试经典 150 题 面试经典 150 题 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台https://leetcode.cn/studyplan/top-interview-150/ 题解: class Solution {public int removeDuplicates(int[] nums) …

并发编程(2)——线程管控

目录 二、day2 1. 线程管控 1.1 归属权转移 1.2 joining_thread 1.2.1 如何使用 joining_thread 1.3 std::jthread 1.3.1 零开销原则 1.3.2 线程停止 1.4 容器管理线程对象 1.4.1 使用容器 1.4.2 如何选择线程运行数量 1.5 线程id 二、day2 今天学习如何管理线程&a…

5个可替代Gamma的国产ppt软件推荐!职场办公不要太简单!

Gamma ppt是海外一款非常受欢迎的ai做ppt软件,这款软件上线的时间不长,却在短时间内收获了众多用户的好评和资本市场的青睐。 对国内用户而言,Gamma PPT在国内虽然可以使用,但是由于其站点架设在海外,访问时往往存在延…

2024年9月电子学会青少年软件编程Python等级考试(三级)真题试卷

2024年9月青少年软件编程Python等级考试(三级)真题试卷 选择题 第 1 题 单选题 以下python表达式的值为True的是?( ) A.all( ,1,2,3) B.any([]) C.bool(abc) D.divmod(6,0) 第 2 题 单选题 下列python代码的…

数据结构与算法-21算法专项(中文分词)(END)

中文分词 搜索引擎是如何理解我们的搜索语句的? mysql中使用 【like “%中国%”】,这样的使用方案 缺点1:mysql索引会失效缺点2:不能模糊,比如我搜湖南省 就搜不到湖南相关的 1 trie树 Trie树,又称前缀树…

【日志】力扣13.罗马数字转整数 || 解决泛型单例热加载失败问题

2024.10.28 【力扣刷题】 13. 罗马数字转整数 - 力扣(LeetCode)https://leetcode.cn/problems/roman-to-integer/description/?envTypestudy-plan-v2&envIdtop-interview-150这题用模拟的思想可以给相应的字母赋值,官方的答案用的是用一…

超好玩又简单-猜数字游戏(有手就行)

云边有个稻草人-CSDN博客 我的个人主页 目录 云边有个稻草人-CSDN博客 前言 猜数字游戏的游戏要求 1. 随机数的生成 1.1 rand 1.2 srand 1.3 time 1.4 设置随机数的范围 2. 猜数字游戏实现 2.1 游戏实现基本思路 2.2 代码实现 Relaxing Time! —————————…

微信小程序25__实现卡片变换

先看效果图 实现代码如下&#xff1a; <view class"page" style"filter:hue-rotate({{rotation}}deg)"><view class"prev" catchtap"toPrev">《《《</view><view class"next" catchtap"toNext&q…

git下载和配置

git是什么&#xff1f; Git是一种分布式版本控制系统&#xff0c;用于跟踪文件的变化&#xff0c;尤其是源代码。它允许多个开发者在同一项目上进行协作&#xff0c;同时保持代码的历史记录。Git的主要特点包括&#xff1a; 分布式&#xff1a;每个开发者都有项目的完整副本&a…

前端自学资料(笔记八股)分享—CSS(4)

更多详情&#xff1a;爱米的前端小笔记&#xff08;csdn~xitujuejin~zhiHu~Baidu~小红shu&#xff09;同步更新&#xff0c;等你来看&#xff01;都是利用下班时间整理的&#xff0c;整理不易&#xff0c;大家多多&#x1f44d;&#x1f49b;➕&#x1f914;哦&#xff01;你们…

无人机避障——4D毫米波雷达Octomap从点云建立三维栅格地图

Octomap安装 sudo apt-get install ros-melodic-octomap-ros sudo apt-get install ros-melodic-octomap-msgs sudo apt-get install ros-melodic-octomap-server sudo apt-get install ros-melodic-octomap-rviz-plugins # map_server安装 sudo apt-get install ros-melodic-…

SLAM|2. 差异与统一:坐标系变换与外参标定

本章主要内容 1.坐标系变换 2.相机外参标定 上一章我们了解了相机内参的概念&#xff0c;内参主要解决三维世界与二维图像之间的映射关系。有了内参我们可以一定程度上还原相机看到了什么&#xff08;但缺乏尺度&#xff09;。但相机看到的数据只是处于相机坐标系&#xff0c;为…

Solidworks二次开发 获取装配体里面组件列表以及名称

******************************************************************************从装配体里面获取组件******************************************************************************Option Explicit 强制在模块级别显式声明所有变量 *********************定义SOLIDWOR…

《链表篇》---环形链表II(返回节点)

题目传送门 方法一&#xff1a;哈希表&#xff08;与环形链表类似&#xff09; 很容易就可以找到链表的相交位置。 public class Solution {public ListNode detectCycle(ListNode head) {if(head null || head.next null){return null;}Set<ListNode> visited new Ha…

2024 年 MathorCup 数学应用挑战赛——大数据竞赛-赛道 A:台风的分类与预测

2024年MathorCup大数据挑战赛-赛道A初赛-第四版论文.ziphttps://download.csdn.net/download/qq_52590045/89930645 ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ …

解决Github下载速度慢的问题

1. 方式一 先把hosts文件先复制一份到其他文件夹下&#xff0c;以免造成不小心改动出现的后果在C盘的C:\Windows\System32\drivers\etc 下的hosts文件 用编辑器打开后&#xff0c;在末尾处添加访问如下的两个网站所返回的两个IP https://github.com.ipaddress.com/ http://gi…

基于SSM大学生互动交流网站设计与实现

前言 随着社会的发展&#xff0c;系统的管理形势越来越严峻。越来越多的用户利用互联网获得信息&#xff0c;但各种信息鱼龙混杂&#xff0c;信息真假难以辨别。为了方便用户更好的获得信息&#xff0c;因此&#xff0c;设计一种安全高效的大学生互动交流网站极为重要。 开发…

C语言复习第8章 数据在内存中的存储

目录 一、数据类型1.1 数据类型介绍1.2 类型的意义1.3 类型的基本归类整形家族浮点数家族构造类型(自定义类型)指针类型空类型 二、整型在内存中的存储2.1 原反补2.2 为什么内存中要存补码?2.3 大小端介绍2.4 为什么会有大小端之分2.5 写一个程序 判断当前机器的字节序 三、练…

创业板权限开通有何要求?创业板的股票交易佣金最低是多少?

创业板 创业板又称二板市场&#xff08;Second-board Market&#xff09;即第二股票交易市场&#xff0c;是与主板市场&#xff08;Main-Board Market&#xff09;不同的一类证券市场&#xff0c;专为暂时无法在主板市场上市的创业型企业提供融资途径和成长空间的证券交易市场…