WebGL笔记(六):简单灯光
来源:广州中睿信息技术有限公司官网
发布时间:2012/10/21 23:25:16 编辑:admin 阅读 386
按MDN的顺序,这篇应该是讲贴图的。但贴图有两个问题不好处理:1、贴图来源跨域。这种约束的感觉和AJAX差不多,而且MDN也有解释,我想根据经验应该很容易理解2、图片格式。这个交待得比较含糊,仅仅有

按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>
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

运行效果如下:

捕获3

 

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

void main(void) {
    highp vec4 texelColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
    gl_FragColor = vec4(vColor.a * vLighting, vColor.a);
}
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

猜测一下第三行:计算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  
]);
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

 

见下面的效果

捕获4

 

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

 

下篇讲贴图

联系我们CONTACT 扫一扫
愿景:成为最专业的软件研发服务领航者
中睿信息技术有限公司 广州•深圳 Tel:020-38931912 务实 Pragmatic
广州:广州市天河区翰景路1号金星大厦18层中睿信息 Fax:020-38931912 专业 Professional
深圳:深圳市福田区车公庙有色金属大厦509~510 Tel:0755-25855012 诚信 Integrity
所有权声明:PMI, PMP, Project Management Professional, PMI-ACP, PMI-PBA和PMBOK是项目管理协会(Project Management Institute, Inc.)的注册标志。
版权所有:广州中睿信息技术有限公司 粤ICP备13082838号-2