WebGL笔记(六):简单灯光

按MDN的顺序,这篇应该是讲贴图的。但贴图有两个问题不好处理:

1、贴图来源跨域。这种约束的感觉和AJAX差不多,而且MDN也有解释,我想根据经验应该很容易理解;

2、图片格式。这个交待得比较含糊,仅仅有一个提示:

Note: Textures' widths and heights must be a power of two number of pixels (that is, 1, 2, 4, 8, 16, etc).

其实图片格式的限制远不止这么蛋疼。

相比之下灯光问题更容易解决,所以打算先说这个。

首先,使用iWebGL和ArrayHelper/GroupHelper等这几个库,快速创建一个白色的立方体:

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>WebGL Step 03</title>
<style type="text/css">
canvas{ background-color:#666; }
</style>
<script type="text/ecmascript" src="http://muse-js-lib.googlecode.com/files/sylvester.js"></script>
<script type="text/ecmascript" src="http://muse-js-lib.googlecode.com/files/glUtils_mod.js"></script>
<script type="text/ecmascript" src="http://muse-js-lib.googlecode.com/files/iWebGL_beta_0.4.js"></script>
<script type="text/ecmascript" src="http://muse-js-lib.googlecode.com/files/ArrayHelper_beta_1.0.js"></script>
 
<script id="shader-fs" type="x-shader/x-fragment">
varying highp vec2 vTextureCoord;
varying highp vec3 vLighting;
varying lowp vec4 vColor;
uniform sampler2D uSampler;
void main(void) {
    highp vec4 texelColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
    gl_FragColor = vColor;
}
</script>
 
<script id="shader-vs" type="x-shader/x-vertex">
attribute highp vec3 aVertexNormal;
attribute highp vec3 aVertexPosition;
attribute highp vec2 aTextureCoord;
attribute highp vec4 aVertexColor;  
 
uniform highp mat4 uNormalMatrix;
uniform highp mat4 uMVMatrix;
uniform highp mat4 uPMatrix;
 
varying highp vec2 vTextureCoord;
varying highp vec3 vLighting;
varying lowp vec4 vColor;  
 
void main(void) {
    gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
    vTextureCoord = aTextureCoord;
    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);
    vColor = aVertexColor;
}
 
</script> 
 
</head>
 
<body>
 
<canvas id="glcanvas" width="640" height="480">看来您的浏览器不支持<code>&lt;canvas&gt;</code>标记</canvas>
 
<script type="text/ecmascript">
//iWebGL对象初始化
var igl = new iWebGL('glcanvas', 0);
//顶点管理对象
var vg = CubeVertices();
//颜色管理对象
var cg = CubeColors();
//设置六个面的颜色
cg.Front('f');
cg.Back('f');
cg.Left('f');
cg.Right('f');
cg.Top('f');
cg.Bottom('f');
 
//顶点位置数据
igl.paramVertices('aVertexPosition').define(vg.data);
//顶点着色数据
igl.paramColors('aVertexColor').define(cg.data);
//面三角形顶点索引顺序
igl.paramVerticesIndex().define(vg.indices);
//顶点光照数据
 
//设置场景
igl.matrix.trans([0.0, 0.0, -6.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);
 
</script>
</body>
</html>

运行效果如下:

捕获3

 

下面我们修改一下FragmentShader脚本中的main函数:

void main(void) {
    highp vec4 texelColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
    gl_FragColor = vec4(vColor.a * vLighting, vColor.a);
}

猜测一下第三行:计算vColor的Alpha通道值与灯光值vLighting的乘积,并重新赋值给vColor的Alpha属性。这句算法是关键。

下面定义顶点光源数据并传递给Shader:

//顶点光源数据
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  
]);

 

见下面的效果

捕获4

 

完整示例:WebGL-Step-06.html

 

下篇讲贴图

posted @ 2011-12-04 23:27  MKing's Kindom  阅读(2017)  评论(0编辑  收藏  举报