在页面的Page命令中,可以通过EnableSessionState="false"来关闭Session,但如果想在代码中想确认当前页面是否启用了Session,确没有相应的属性或方法,实现方法是通过当前页面是否实现了IRequiresSessionState,这个在VS中当然是看不到的,只有在代码被预编译后才会看到,使用aspnet_compiler预编译网站后,通过IL Dasm查看预编译后的网站,会发现如下IL代码
implements [System.Web]System.Web.SessionState.IRequiresSessionState
译序
Three.js是一个伟大的开源WebGL库,WebGL允许JavaScript操作GPU,在浏览器端实现真正意义的3D。但是目前这项技术还处在发展阶段,资料极为匮乏,爱好者学习基本要通过Demo源码和Three.js本身的源码来学习。
国外网站 aerotwist.com 有六篇较为简单的入门教程,我尝试着将其翻译过来,与大家分享。
0.简介
之前我已经给出了一篇《开始使用Three.js》。如果你还没有读过,你可能需要去读一下,本文的基础是在那一篇教程的基础上完成的。
我想讨论一下着色器。在Three.js帮助你免去了很多麻烦之前,原生WebGL就很优秀了。有的时候,你也许会想要完成一些特定的效果,或者想对呈现在你的屏幕上的东西钻研得更深入一些,那么着色器一定会进入你的视野。如果你像我一样,你也同样希望实现一些比上一篇教程中的基础更加有意思的东西。这篇教程中,我会讲解Three.js的基础,这些基础实际上为我们做了很多枯燥的工作。
在开始之前我还要说,这篇教程会有相当多的篇幅在解释着色器的代码,之后会有一篇教程会在着色器代码的基础上前进一点,利用着色器去做点什么。这是因为着色器shaders第一眼看上去并不易懂,需要一些解释。
1.两种着色器
WebGL没有固定的渲染管线,你无法直接使用一个黑盒子式的着色器(译者注:上个世纪的显卡基本都只支持固定渲染管线);WebGL提供的是可编程的管线,这种方式更强大但也更难理解和使用。长话短说,可编程渲染管线意味着编写程序的人要自己负责获取顶点并将它绘制在屏幕上了。着色器是渲染管线的一部分,有两种着色器:
你应当知道的是,这两种着色器都完全运行在显卡的GPU上,我们将需要它们处理的数据从CPU上卸下,装到GPU上,减轻了CPU的复旦。现代的GPU对着色器需要的调用的运算类型都做了大幅优化,这样做很值得。
2.顶点着色器
基元形状,比如一个球体,是由顶点构成的,是吧?顶点着色器被依次传入这些顶点中的一个顶点,然后处理它。如何处理每个顶点是可以自由定制的,但顶点着色器有一个必做的事,就是为一个名为 gl_Position 的变量赋值,该变量是一个4维数组,表示该顶点最终在屏幕上的位置。这本身是个有意思的过程,因为我们实际上在谈论如何将一个三维坐标(一个具有x、y、z值得顶点)转化为,或者说投影到二维的屏幕上。谢天谢地,要是我们使用Three.js之类的工具,我们能够如此方便地访问到 gl_Position 。
3.片元着色器
现在我们有包含顶点的三维物体了,现在要将物体投影到二维屏幕上了,但颜色哪里去了?纹理和光照呢?这正是片元着色器要处理的。
和顶点着色器类似,片元着色器有一项必须完成的任务:设置或消除变量 gl_FragColor ,另一个四维浮点变量,也就是片元点最终的颜色。什么是片元?想象一个具有三个顶点的三角形,片元就是经过这三个顶点计算后的,所有在三角形内部的点。因此,片元值由顶点的值内插生成。如果一个顶点的颜色是红色,相邻顶点的颜色是蓝色,那么我们可以观测到颜色从红色顶点附近渐变,由红色变成紫色,最终在蓝色顶点附近变成蓝色。
4.着色器变量
说到着色器变量,有三种:Uniforma,Attributes和Varyings。当我第一次听到这三个词语时,我很困惑,因为它们和我之前用到的东西完全不匹配。但现在,你可以这样理解它们:
在后面一篇教程中,我会使用这三种变量,你也会学习到这三种变量如何真正应用起来得。
现在,我们已经谈过了顶点着色器、片元着色器和三种着色器变量。是时候来看一个我们可以创建的最简单的着色器了。
5.Hello World(译者吐槽:能不能不要秀法语啊)
这儿有一个最简单的顶点着色器:
* 每个顶点坐标乘以模型视图矩阵在乘以投影矩阵
* 获得在二维屏幕上的坐标
*/
void main() {
gl_Position = projectionMatrix *
modelViewMatrix *
vec4(position,1.0);
}
一个最简单的片元着色器:
* 将任意一个像元色设置为粉红
*/
void main() {
gl_FragColor = vec4(1.0, // R
0.0, // G
1.0, // B
1.0); // A
}
这就是全部了。如果现在直接运行的话,你就可以在屏幕上看到一个“无光”的粉红色形体。不是很复杂,是吗?
在顶点着色器中,我们通过Three.js传入了一些uniforms变量。有两个4×4的矩阵uniforms变量:模型视图矩阵和投影矩阵。你并不需要太了解这两个矩阵是怎么工作的。简单地说,这两个矩阵描述了三维点坐标如何投影成为二维屏幕上的坐标。
事实上,我只介绍了这两段简短的代码段。Three.js在你自己的着色器代码前已经将它们加进来了,所以你不必担心。实话说,Three.js还加了很多东西在你的代码前面,比如光照数据、节点颜色和节点法向量等等。如果没有Three.js你要亲自创建并设置这些对象,真的。
6.使用着色器材质
* 假设我们可以使用JQuery
* 将着色器的代码文本从DOM中抽取出来
*/
var vShader = $('vertexshader');
var fShader = $('fragmentshader');
var shaderMaterial =
new THREE.ShaderMaterial({
vertexShader: vShader.text(),
fragmentShader: fShader.text()
});
看看效果
从这儿开始,Three.js将会编译并运行你的着色器,将其连接在你创建的材质上,材质又依附于你创建的mesh上。它并没有变得比真的更容易。也许是这样吧,但我们在考虑浏览器3D编程,我想你应该预期,这个话题是有一定复杂性的。
我
我们知道JavaScript是一种基于prototype的面向对象脚本语言,其面向对象特性可以参见我的博客《JavaScript中的面向对象》,但是 JavaScript 本身不能作为面向对象的语言,因为它无法全面实现面向对象编程的三个支柱:继承、多态性和封装,虽然通过对象原型可以获得部分继承特性,通过闭包也可以获得部分封装特性。因此 Microsoft AJAX Library 会先为语言提供更多强大的工具,然后再继续定义新的类和编程工具。
HTML代码:
<html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>面向对象系统</title> </head> <body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <script language ="javascript" type="text/javascript"> //注册命名空间 Type.registerNamespace("AspNetAjaxOverView"); //空间下建立类 AspNetAjaxOverView.Person = function (firstName, lastName) { //下划线开头表示私有 this._firstName = firstName; this._lastName = lastName; } //修改person的prototype AspNetAjaxOverView.Person.prototype = { get_firstName: function () { return this._firstName; }, get_lastName: function () { return this._lastName; }, //覆写toString toString: function () { return String.format("Hello,I am {0} {1}",this.get_firstName(), this.get_lastName()); } } //注册Person类 AspNetAjaxOverView.Person.registerClass("AspNetAjaxOverView.Person"); //命名空间下添加employee类 AspNetAjaxOverView.Employee = function (firstName, lastName, title) { AspNetAjaxOverView.Employee.initializeBase(this, [firstName, lastName]); this._title = title; } //修改Employee的prototype AspNetAjaxOverView.Employee.prototype = { get_title: function () { return this._title; }, toString: function () { return AspNetAjaxOverView.Employee.callBaseMethod(this, "toString") +". "+ "My position is" + " "+this.get_title() + "."; } } //让employee继承person AspNetAjaxOverView.Employee.registerClass("AspNetAjaxOverView.Employee", AspNetAjaxOverView.Person); </script> <!--两个按钮,alert姓名和职位--> <input id="btnBill" type="button" value="Bill Gates" onclick="alert(new AspNetAjaxOverView.Employee('Bill','Gates','chairman'));" /> <input id="btnLida" type="button" value="Li Da" onclick="alert(new AspNetAjaxOverView.Employee('Li','Da','CEO'));" /> </form> </body> </html>运行结果:
在此DEMO中,使用客户端的面向对象系统编程,可以看到在ASP.NET中,更方便直观的定义类、继承等信息,这里常用的主要是注册命名空间、注册类及继承的使用方法。