WebGL学习笔记(六):纹理贴图
只可以绘制纯色的模型是不够的,为了呈现出更真实的模型,我们还需要通过纹理贴图给模型进行上色。
丢失上下文
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学习笔记(六):纹理贴图的更多相关文章
- webgl学习笔记五-纹理
写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放 术语 : 纹理 :图像 图形装配区域 :顶点着色器顶点坐标 ...
- java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)
java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...
- 【opencv学习笔记六】图像的ROI区域选择与复制
图像的数据量还是比较大的,对整张图片进行处理会影响我们的处理效率,因此常常只对图像中我们需要的部分进行处理,也就是感兴趣区域ROI.今天我们来看一下如何设置图像的感兴趣区域ROI.以及对ROI区域图像 ...
- # go微服务框架kratos学习笔记六(kratos 服务发现 discovery)
目录 go微服务框架kratos学习笔记六(kratos 服务发现 discovery) http api register 服务注册 fetch 获取实例 fetchs 批量获取实例 polls 批 ...
- 学习笔记:APP切图那点事儿–详细介绍android和ios平台
学习笔记:APP切图那点事儿–详细介绍android和ios平台 转载自:http://www.woofeng.cn/articles/168.html 版权归原作者所有 作者:亚茹有李 原文地址 ...
- Learning ROS for Robotics Programming Second Edition学习笔记(六) indigo xtion pro live
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...
- Typescript 学习笔记六:接口
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- python3.4学习笔记(六) 常用快捷键使用技巧,持续更新
python3.4学习笔记(六) 常用快捷键使用技巧,持续更新 安装IDLE后鼠标右键点击*.py 文件,可以看到Edit with IDLE 选择这个可以直接打开编辑器.IDLE默认不能显示行号,使 ...
- Go语言学习笔记六: 循环语句
Go语言学习笔记六: 循环语句 今天学了一个格式化代码的命令:gofmt -w chapter6.go for循环 for循环有3种形式: for init; condition; increment ...
- webgl学习笔记四-动画
写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放 下面我们将讲解下如何让一个正方形动起来~不断擦除和重绘 ...
随机推荐
- 【Git】.DS_Store 是什么文件
一.为啥会注意到该文件 合并代码的时候,.DS_Store文件发生了冲突,然后进入到项目目录去看,果然存在该文件,就比较好奇该文件是干什么的. 二..DS_Store 是什么文件 .DS_Store( ...
- 实例讲解ip地址、子网掩码、可用地址范围的计算
关于ip以及相关的掩码.网络号等概念可以查看相关的博客.资料,这些东西很容易找着,一搜一大片.本文主要记录通过实例进行ip相关的计算. 我自己使用的在线网络计算器地址:https://www.sojs ...
- js动画--透明度变化
对于设置元素的透明度的变化.主要思想也是通过一个定时器来控制的. 此外对于透明度有一点要说明一下,就是在IE中我们在css中设置透明度的方式filter:alpha(opacity:value)其中v ...
- WebLogic任意文件上传漏洞(CVE-2019-2618)
WebLogic任意文件上传漏洞(CVE-2019-2618) 0x01 漏洞描述 漏洞介绍 CVE-2019-2618漏洞主要是利用了WebLogic组件中的DeploymentService接口, ...
- 利用requests库访问网站
1.关于requests库 函数 Response对象包含服务器返回的所有信息,也包含请求的Request信息. 访问百度二十次 import requests def getHTMLText(url ...
- OpenCV录制视频,播放视频
一.录制视频 获取摄像头操作 camObj = cv2.VideoCapture(0) :0为默认计算机默认摄像头,多个摄像头依次后面1.2.3 检查是否成功初始化: camObj.isOpen() ...
- GAME-BASED LEARNING
https://collegestar.org/modules/game-based-learning Introduction Appalachian State University Game ...
- Educational Codeforces Round 47 (Rated for Div. 2) G. Allowed Letters
把原字符看成 $X$,每个位置看成 $Y$,每种字符向每个能去的位置连边,就成了一个二分图完美匹配的问题.现要得到字典序最小,那么就枚举每一位要放什么,然后看放完这种字符,剩下的字符的个数和后面能不能 ...
- 监听localStorage中的数据变化
问题描述:我们在js里面获取了某一个localstorage的值,但是后期它可能改变了,我们js只执行一遍没办法再次获取它的值,当然可以刷新页面获取,但如果是我们的但页面就不能刷新页面了,此时:我们可 ...
- DiaryDayBayDayDiary
Every day, an email reminder will be sent to you, along with a random copy of your previous diary. Y ...