Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

WebGL(拾玖) 顶点贴图

  “贴图”最早确实只是作为3D物体表面的贴图而已,它是狭义的。但是随着技术的发展,“贴图”早已不是往日那么单一的东西了。现在的“贴图”只是从图片上加载了数据而已。我们可以用贴图载入物体的一些不规则属性,比如材质分布、法向量,甚至顶点坐标。
  在实现阴影的时候我们就是把帧缓冲中的数据作为贴图,但是数据并不是作为颜色使用的,而是作为深度使用的。既然可以这样,我们在绘制不规则物体时也可以用贴图的方式来设置物体表面的材质或法向量等一些不规则的顶点属性。这些东西应该很容易想到吧?不过这些仍然是局限片段着色器中的。应该把思维再扩大一些,我们要在顶点着色器中使用贴图数据来绘制不规则表面。
  一般的3D物体顶点数据都是直接在模型中给定的,现在咱就把这个贴图数据当作不规则表面的顶点模型。图片本身是二维的,有平面坐标和相应位置的颜色信息。把颜色信息当作一个维度来使用它就变成三维的了,这样我们就可以把它绘制成物体。现在我用PS的云彩滤镜做了个这样的图片。

  然后把它当作顶点着色器的贴图数据来计算高度,就可以得到。。。火星了。。

  下面是顶点着色器代码。
attribute vec3 position_vec; //顶点位置数据
attribute vec2 coords_vec; //贴图坐标数据
uniform mat4 model_mat; //变换矩阵
uniform mat4 view_mat; //视图矩阵
uniform mat4 projection_mat; //投射矩阵
uniform sampler2D hight_map; //高度贴图
varying vec3 color;
void main(){
  //获取图片数据
  vec4 map=texture2D(hight_map,vec2(coords_vec.x,coords_vec.y));
  float y=map.r*12.0-12.0;
  //设置顶点位置,把图片的红色通道作为物体的Y坐标
  gl_Position=
    projection_mat*view_mat*model_mat*
    vec4(position_vec.x,y,position_vec.z,1.0);
  //这个例子就不做光线处理了,法向量计算麻烦,直接使用贴图的颜色
  color=map.xyz;
}
  这个代码其实啥难点吧?也许难的就是法向量的计算,不过我的例子中不计算光线所以用不到。如果非要计算,可以先根据临近点的值估算出y(x,z)在x和z方向上的增量,找出构成切平面的两个向量,再做差积得到垂于它们的法向量。使用贴图只是制作不规则表面最简单的方法,它是有很大局限性的。有时候我们需要动态生成世界,而图片的尺寸是固定的,所以贴图的方法会无法达到需求。那时就只能自己计算了,所以研究曲线与曲面的插值构造还是很重要的。
  由于打算做个小小的封装,所以这个例子了比较规范的变量名。而且整个代码会和之前的例子有点不同,不过都算一些JavaScript基础。如果对JavaScript本身就一知半解那我就不知说啥好了。
  这篇文章就说这些吧,虽然内容有点少。这几天我也有点不在状态了,体谅下~ 最后是完整的实例,你可以用方向键来移动摄像机。

  WebGL顶点贴图
网名:
34.203.245.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^