【WebGL教程】Lesson 3 引入纹理以及简单的图像处理 2

本文地址:http://blog.wysaid.org/745.html
原创,转载请注明出处。系列教程: webgl-lesson.wysaid.org

第三话,传递uniform变量以及引入纹理, 做一些简单的2D处理

上一期讲到了从文件和从html标签加载shader,这一期直接上纹理了。所有教程内容包括教程本身都可以在https://github.com/wysaid/WebGL-Lessons直接获得,喜欢的话就fork&star吧。这里就不放上一话的代码了。

先卖个萌:我是手写html的!什么叫手写html呢?意思就是像“<script>, <p>,<br>,<pre>”这样的东西是我一个字符一个字符手动输入的,包括input的button,因为用word这样的编辑器会乱了格式~看我多辛苦呀,电脑前的你是不是有一点小感动呀?

进入正题,天依酱镇楼。

第一步

首先说明,本次我们要加入的纹理图片就是上面的天依酱了。不但要加入她,还要在此图像上进行一些处理,此处理仅在Fragment Shader之上进行更改。

加载图片资源的方式

我们要知道,加载图片跟加载shader也是很相似的,你可以用代码方式把图片内容写进来,比如常见的img标签里面src后面跟data:image/png;base64 + base64 编码的图像数据等。你可以用js创建一个img标签或者一个image对象,然后把这些数据写入进去直接使用。但是这种方法显然不适用于此处,我们不会把图片的编码写到代码里面的。我们只需要用到图片文件。

第一种方式:直接从img标签里面加载。这种方式的跟直接把shader代码直接写到script标签里面是一个意思,用起来方便快捷。当然,你也许并不希望把这个img标签显示出来,那么,你只需要给这个img标签加上属性 style=”display:none”就ok了。

使用方式:

第二种方式:通过JavaScript动态请求。在这一步上,我们必须做一个变通。

首先需要知道的是,每个浏览器都会缓存图片,所以,我们动态请求的话,就算对某一张图片请求很多次,实际上真正用到网络的只是第一次请求而已。以及,有的浏览器,比如firefox,ctrl+f5都很难清楚这种缓存,只能打开设置清除。所以如果我们是在做测试,图片经常替换而图片url不换的话,很容易遇到这种问题(img标签方式的话,只需要多刷新几次就好了):我们明明替换了图片文件,但不管怎么刷新,还是显示的前面的一张。 解决方法就是给我们请求的文件加上随机的get参数……当然,最终发布产品的时候肯定要去掉,毕竟有缓存对于服务器来说是好事。

其次,我们请求的image对象和纹理不需要共存,如果你长期保存了创建的纹理,那么这个请求的image对象就不需要保存,或者你可以删除纹理保存这个image对象……再或者,你可以创建一个隐藏的img标签悄悄地把这张图保存下来……对于用到大量纹理且纹理需要重复使用的时候更要注意,因为纹理是很占内存的。

使用方式:(这里先提供较为简单的直接写入img标签的方式, 将用到上面的函数。)

上面的方法并不好用,并且也不直观。正确的方法应该是用户在运行程序之前就把需要加载的纹理资源全部或者说当前需要用到的部分加载完毕。因为js的回调看起来并不那么直观。上面的方法仅仅提供了一种思路,如果你要加载多张图片,希望你能想出更好的方法。后面的章节会提到更好的解决办法

第二步

有了纹理对象,那么接下来只要使用这个纹理对象,传递给我们的fragment shader就ok了。

这个过程异常轻松,我们就直接写完吧。

首先我们必须要有shader 代码, 本章用到的顶点着色器代码:

本章用到的简单片元着色器代码:

好了,有了着色器代码,我们就可以写调用代码了:

那么,讲了这么多,我们来看看本次的demo吧:







好的,第三期教程到此为止,请关注lesson 4。系列教程地址:webgl-lesson.wysaid.org