只可以绘制纯色的模型是不够的,为了呈现出更真实的模型,我们还需要通过纹理贴图给模型进行上色。

丢失上下文

GPU作为一种公用资源,是会被多个进程同时使用的,在资源不足的情况下(比如PC或手机系统进入休眠状态前或被唤醒后),我们持有的上下文会出现丢失的情况,为了保证程序运行的健壮性,我们必须在丢失上下文之后做出处理。

Canvas为我们提供了两个事件来监听,上下文的丢失和恢复,具体使用看下面的代码:

 var canvas = document.getElementById("myGLCanvas");
// 监听上下文丢失的事件
canvas.addEventListener("webglcontextlost", function (event) {
// 取消默认行为
event.preventDefault();
// 停止继续绘图的代码
}, false);
// 监听上下文恢复的事件
canvas.addEventListener("webglcontextrestored", function () {
// 重新初始化的代码
// 需要注意的是 Canvas 通过 getContext 方法获得的上下文对象不需要重新获取, 还可以继续使用之前获取的上下文对象
// 开始继续绘图的代码
}, false);

模拟丢失上下文

我们要测试丢失上下文的处理代码是否正常,就需要触发丢失上下文,我们可以使用下面的js库来模拟上下文的丢失:

https://github.com/KhronosGroup/WebGLDeveloperTools

可以参考其目录下的src\debug\lost-context-simulator-test.html示例来使用。

2D映射和立方体映射

我们需要将2D图片贴到3D模型上,需要使用到2D的图片,采用UV坐标来确定3D的面上的一个点可以对应2D图片上的一个像素或多个像素(采样),下面是uv坐标的坐标系:

(s对应u、t对应v),范围[0-1]。

立方体映射,是一个包含了6个2D图片的映射,一般用来实现环境映射,或者实现环境反射,下面的示例可以很好的展现环境反射的应用:

https://threejs.org/examples/#webgl_materials_envmaps

另外立方体映射还常用于创建天空盒(SkyBox)。

纹理大小

我们提交到GPU的图片尺寸的高和宽必须是2的n次方,即(2、4、8、16、32、64、128、256...),不过在OpenGL ES 2.0和WebGL中,我们也可以使用高宽非2的n次方的图片,即NPOT(Non Power Of Two);

如果我们使用了非2的n次方的图片,会有下面的一些限制:

  • 不能使用MipMap映射;
  • 在着色器中采样纹理贴图时:纹理过滤方式只能用最近点或线性, 不能使用重复模式。

具体请看:https://www.khronos.org/webgl/wiki/WebGL_and_OpenGL_Differences

关于y轴翻转

我们先看看DOM里的Image对象的坐标系和WebGL纹理的坐标系的区别:

可以发现,两个坐标系的y轴刚好是相反的,所以为了使坐标系一致,我们需要使用下面的代码来翻转y轴:

gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);

纹理过滤

我们的纹理图片和将要渲染的区域尺寸是不一定完全一致的,当纹理小于渲染区域时需要纹理伸展,当纹理大于渲染区域时需要纹理收缩;

MipMap

当纹理进行伸展过大和收缩过大时,会出现模糊和锯齿,为了解决这个问题,我们可以使用多套尺寸的纹理,来对应不同尺寸的渲染区域,GPU会根据渲染区域的大小自动选择;

优点

  • 模型无论是远离还是离摄像机较近时,显示都会比较自然;
  • 渲染效率更高;

缺点

  • 内存使用会增大为单张图片的1/3;

创建MipMap的方法

  • 提交纹理之后,调用gl.generateMipmap方法WebGL会自动生成指定纹理的MipMap;
  • 通过外部工具,直接将所有的MipMap生成好之后,手动进行提交,该方法一般用于比较特殊的情况,比如不同级别的MipMap纹理图像不一致的情况;

纹理坐标包装

  • GL_REPEAT: 超出纹理范围的坐标整数部分被忽略,形成重复效果。
  • GL_MIRRORED_REPEAT: 超出纹理范围的坐标整数部分被忽略,但当整数部分为奇数时进行取反,形成镜像效果。
  • GL_CLAMP_TO_EDGE:超出纹理范围的坐标被截取成0和1,形成纹理边缘延伸的效果。

activeTexture和bindTexture

gl.activeTexture

激活当前的操作贴图,指定后续代码操作的贴图是哪一个,参数是枚举gl.TEXTURE0到gl.TEXTURE7(最大值请查看gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS,最少是8);

后面会调用bindTexture来绑定当前的操作贴图,如果没有调用activeTexture就调用了bindTexture,则默认激活0号纹理单元(可以理解为默认调用了gl.activeTexture(gl.TEXTURE0)代码);

gl.bindTexture

绑定指定纹理到activeTexture激活的纹理单元中,同时可以指定该纹理的类型;

更多详细信息可以参考这里:https://www.jianshu.com/p/1829b4acc58d

示例

https://hammerc.github.io/dou3d-ts/learning/learningNotes/lesson_4/index.html

WebGL学习笔记(六):纹理贴图的更多相关文章

  1. webgl学习笔记五-纹理

    写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放 术语 : 纹理 :图像 图形装配区域 :顶点着色器顶点坐标 ...

  2. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

  3. 【opencv学习笔记六】图像的ROI区域选择与复制

    图像的数据量还是比较大的,对整张图片进行处理会影响我们的处理效率,因此常常只对图像中我们需要的部分进行处理,也就是感兴趣区域ROI.今天我们来看一下如何设置图像的感兴趣区域ROI.以及对ROI区域图像 ...

  4. # go微服务框架kratos学习笔记六(kratos 服务发现 discovery)

    目录 go微服务框架kratos学习笔记六(kratos 服务发现 discovery) http api register 服务注册 fetch 获取实例 fetchs 批量获取实例 polls 批 ...

  5. 学习笔记:APP切图那点事儿–详细介绍android和ios平台

    学习笔记:APP切图那点事儿–详细介绍android和ios平台 转载自:http://www.woofeng.cn/articles/168.html   版权归原作者所有 作者:亚茹有李 原文地址 ...

  6. Learning ROS for Robotics Programming Second Edition学习笔记(六) indigo xtion pro live

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  7. Typescript 学习笔记六:接口

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  8. python3.4学习笔记(六) 常用快捷键使用技巧,持续更新

    python3.4学习笔记(六) 常用快捷键使用技巧,持续更新 安装IDLE后鼠标右键点击*.py 文件,可以看到Edit with IDLE 选择这个可以直接打开编辑器.IDLE默认不能显示行号,使 ...

  9. Go语言学习笔记六: 循环语句

    Go语言学习笔记六: 循环语句 今天学了一个格式化代码的命令:gofmt -w chapter6.go for循环 for循环有3种形式: for init; condition; increment ...

  10. webgl学习笔记四-动画

    写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放   下面我们将讲解下如何让一个正方形动起来~不断擦除和重绘 ...

随机推荐

  1. 团队——Beta版本发布

    目录 最棒团队成员信息 一.7次冲刺博客链接 二.解决的Alpha版本问题 / Beta计划任务(与Alpha版本不同点) 二.项目本次α版本的发布地址.下载安装说明 四.PM最终报告(详细报告在各冲 ...

  2. PAT 乙级 1071.小赌怡情 C++/Java

    题目来源 常言道“小赌怡情”.这是一个很简单的小游戏:首先由计算机给出第一个整数:然后玩家下注赌第二个整数将会比第一个数大还是小:玩家下注 t 个筹码后,计算机给出第二个数.若玩家猜对了,则系统奖励玩 ...

  3. mysql 事件计划

    一.开启mysql事件计划 首先在sql中查询计划事件的状态:SHOW VARIABLES LIKE 'event_scheduler'如果返回的是off表示当前是关闭状态,如果是on当前已经开启了计 ...

  4. Css背景设置 、

    每天进步一小步,一年进步一大步. 第一次发博客园文章,主要记录自己学习的一个过程. CSS3 背景 CSS3 包含多个新的背景属性,它们提供了对背景更强大的控制. background-size ba ...

  5. 牛客NOIP暑期七天营-提高组6C:分班问题 (组合数)

    题意:A班有N个人,B班有M个人,现在要组成一个新的班级C班,为了公平,从AB班各抽相同人数的人. 现在求所有方案中,人数之和是多少. 思路:即求Σ k*C(N,k)*C(M,k);    先忽略这个 ...

  6. hive创建表

    一.为什么要创建分区表 1.select查询中会扫描整个表内容,会消耗大量时间.由于相当多的时候人们只关心表中的一部分数据, 故建表时引入了分区概念. 2.hive分区表:是指在创建表时指定的part ...

  7. 实现:API实现创建用户并且添加至管理员

    参考文章:https://www.cnblogs.com/17bdw/p/6790197.html#_label0 利用的API函数: 1.NetUserAdd 2.NetLocalGroupAddM ...

  8. 项目(1-2)ES32获取mpu9250传入数据库

    . 报一个错,找不到min函数 #define min(X,Y) ((X) < (Y) ? (X) : (Y)) 手动添加 之后不报错了 .最原始的采集 /******************* ...

  9. bootstrap入门&栅格系统

    一.概述 1. 概念: 一个前端开发的框架,Bootstrap,来自 Twitter,是目前很受欢迎的前端框架.Bootstrap 是基于 HTML.CSS.JavaScript 的,它简洁灵活,使得 ...

  10. ES6基础入门之let、const

    作者 | Jeskson来源 | 达达前端小酒馆 01 首先呢?欢迎大家来学习ES6入门基础let,const的基础知识内容.初始ECMA Script6. ESMAScript与JavaScript ...