WebGL笔记(七):贴图(笔记终结)
上篇提到过关于贴图的两个限制:
1、跨域安全限制
跟AJAX之类差不多,但是没有测试根目录下具有安全配置文件(一些xml)的情况。当然,不出意外,本地浏览(file协议)调用相对路径图片也是不可以的。所以,连测试只能在一个web平台下进行。
2、图片格式问题
MDN上有个提示:
https://developer.mozilla.org/en/WebGL/Using_textures_in_WebGL
Note: Textures' widths and heights must be a power of two number of pixels (that is, 1, 2, 4, 8, 16, etc).
我理解为:图片的宽度和高度只能为2^n(n=0|自然数),单位为像素(px)。但限制还远不止此。测试通过的图片格式情况:
- GIF,8位颜色
- PNG,32/64位颜色
- BMP,32位颜色
JPG格式不知什么原因,竟然没有通过;需要注意,颜色位数似乎也应该是2^n,24位也未通过;然而虽然8位的gif可以使用,但是8位的png却不能。tag/tiff不支持。PNG透明不支持,GIF的透明支持。
上图是MDN例子里的原图,请下载后看属性里的详细信息。
MDN关于贴图的例子:https://developer.mozilla.org/samples/webgl/sample6/index.html
本例做了较大的修改,并增加了灯光效果。注意,原例中没有灯光变化。
我们首先修改Shader
<script id="shader-vs" type="x-shader/x-vertex">
attribute highp vec3 aVertexNormal;
attribute highp vec3 aVertexPosition;
attribute highp vec2 aTextureCoord;
uniform highp mat4 uNormalMatrix;
uniform highp mat4 uMVMatrix;
uniform highp mat4 uPMatrix;
varying highp vec2 vTextureCoord;
varying highp vec3 vLighting;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vTextureCoord = aTextureCoord.st;
highp vec3 ambientLight = vec3(0.6, 0.6, 0.6);
highp vec3 directionalLightColor = vec3(0.5, 0.5, 0.75);
highp vec3 directionalVector = vec3(0.85, 0.8, 0.75);
highp vec4 transformedNormal = uNormalMatrix * vec4(aVertexNormal, 1.0);
highp float directional = max(dot(transformedNormal.xyz, directionalVector), 0.0);
vLighting = ambientLight + (directionalLightColor * directional);
}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
varying highp vec2 vTextureCoord;
varying highp vec3 vLighting;
uniform sampler2D uSampler;
void main(void) {
highp vec2 texCoord = vec2(vTextureCoord.s, vTextureCoord.t);
highp vec4 color = texture2D(uSampler, texCoord);
gl_FragColor = vec4(color.rgb * vLighting, color.a);
}
</script>
一些代码:
var igl = new iWebGL('glcanvas', 0);
/* 立方体顶点和三角面顶点索引顺序 */
var vs = CubeVertices();
igl.paramVertices('aVertexPosition').define(vs.data);
igl.paramVerticesIndex().define(vs.indices);
/* 顶点贴图数据 */
igl.paramVertices('aVertexNormal').define([
// Front
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
// Back
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
// Top
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
// Bottom
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
// Right
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
// Left
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0
]);
igl.paramTexture('aTextureCoord').define([
// Front
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// Back
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// Top
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// Bottom
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// Right
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// Left
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0
]);
/* 调用贴图 */
igl.loadTexture2('ff32.png');
/* 设置场景 */
igl.matrix.trans([0.0, 0.0, -5.0]);
igl.matrix.make(40, 640 / 480, 0.1, 100.0);
var animate = function(){
igl.matrix.rotate(1, [1, 0, 1]);
igl.drawCube();;
}
/* 动画效果 */
setInterval(animate, 40);
我觉得效果还不错的。
Ops…忘了链接:
至此,除了动画贴图(以视频作为贴图,个人不感兴趣,暂时不打算搞),MDN上的关于WebGL的入门课程都学完了。乱七八糟记了些东西,希望对大家有帮助。下一篇列个索引,供大家一起学习讨论。