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

丢失上下文

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. 【Git】.DS_Store 是什么文件

    一.为啥会注意到该文件 合并代码的时候,.DS_Store文件发生了冲突,然后进入到项目目录去看,果然存在该文件,就比较好奇该文件是干什么的. 二..DS_Store 是什么文件 .DS_Store( ...

  2. 实例讲解ip地址、子网掩码、可用地址范围的计算

    关于ip以及相关的掩码.网络号等概念可以查看相关的博客.资料,这些东西很容易找着,一搜一大片.本文主要记录通过实例进行ip相关的计算. 我自己使用的在线网络计算器地址:https://www.sojs ...

  3. js动画--透明度变化

    对于设置元素的透明度的变化.主要思想也是通过一个定时器来控制的. 此外对于透明度有一点要说明一下,就是在IE中我们在css中设置透明度的方式filter:alpha(opacity:value)其中v ...

  4. WebLogic任意文件上传漏洞(CVE-2019-2618)

    WebLogic任意文件上传漏洞(CVE-2019-2618) 0x01 漏洞描述 漏洞介绍 CVE-2019-2618漏洞主要是利用了WebLogic组件中的DeploymentService接口, ...

  5. 利用requests库访问网站

    1.关于requests库 函数 Response对象包含服务器返回的所有信息,也包含请求的Request信息. 访问百度二十次 import requests def getHTMLText(url ...

  6. OpenCV录制视频,播放视频

    一.录制视频 获取摄像头操作 camObj = cv2.VideoCapture(0) :0为默认计算机默认摄像头,多个摄像头依次后面1.2.3 检查是否成功初始化: camObj.isOpen() ...

  7. GAME-BASED LEARNING

    https://collegestar.org/modules/game-based-learning Introduction   Appalachian State University Game ...

  8. Educational Codeforces Round 47 (Rated for Div. 2) G. Allowed Letters

    把原字符看成 $X$,每个位置看成 $Y$,每种字符向每个能去的位置连边,就成了一个二分图完美匹配的问题.现要得到字典序最小,那么就枚举每一位要放什么,然后看放完这种字符,剩下的字符的个数和后面能不能 ...

  9. 监听localStorage中的数据变化

    问题描述:我们在js里面获取了某一个localstorage的值,但是后期它可能改变了,我们js只执行一遍没办法再次获取它的值,当然可以刷新页面获取,但如果是我们的但页面就不能刷新页面了,此时:我们可 ...

  10. DiaryDayBayDayDiary

    Every day, an email reminder will be sent to you, along with a random copy of your previous diary. Y ...