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的透明支持。

ff32

上图是MDN例子里的原图,请下载后看属性里的详细信息。

MDN关于贴图的例子:https://developer.mozilla.org/samples/webgl/sample6/index.html

本例做了较大的修改,并增加了灯光效果。注意,原例中没有灯光变化。

image

我们首先修改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);

image

我觉得效果还不错的。

Ops…忘了链接:

WebGL-Step-07pro.html

ff32.png


至此,除了动画贴图(以视频作为贴图,个人不感兴趣,暂时不打算搞),MDN上的关于WebGL的入门课程都学完了。乱七八糟记了些东西,希望对大家有帮助。下一篇列个索引,供大家一起学习讨论。

posted @ 2011-12-05 11:41  MKing's Kindom  阅读(1602)  评论(0编辑  收藏  举报