凹凸映射的算法及GLSL实现

凹凸映射的 算法
及 GLSL 实现
顾伟  Motorola 南京软件中心 211102
向量决定了该点表面的形状,如果给表 没有被偏移,是凹凸纹理帖图被偏移。 面每个点的法线向量一个微小的扰动, 可以通过改变法线向量 n ,而非位置 就得到了外形起伏变化的表面。倘若这 向量 p ,得到所需要的效果,在明暗调 种扰动只发生在绘制期间,也就是在可 计算过程中,采用扰动后的法线向量 n'。 见图元经过光栅化后变成片元,片元经 在扰动点 p' 的法线向量 n' 用叉积公式求
过处理后生成最终的帧缓存中的像素这一 得:n'=p' × p' 。式中的偏微分值可以 u
v
渲染阶段,这样就可以使用光滑表面的 对 p' 方程两边求微分得到,p' =p +(d/
u  u
模型,不需要增加被渲染对象的几何复 u)n+d(u,v)n 和p' =p +(d/ v)n+d(u,
u v  v
杂度。光滑表面的模型具有光滑的法线 v)n 。当 d 值很小时,可以省略 d(u,v)n
v u 向量,但是可以按照某种扰动方式把光 和 d(u,v)n ,上面的两式代入 n'=p' × v
u
滑的表面绘制成具有复杂效果的表面。 p' ,而且 n × n=0 。最后的扰动后的法 v
法律法规查询系统由于扰动只作用于法线向量上,因此绘 线向量 n' ≈ n+(d/ u)n × p +(d/ v)
v
制计算要针对扰动后的表面,即先进行 n × p 。该式右边两项都是移位量,即原
u
1 凹凸映射的定义
扰动计算后进行光照计算,这样才能得 法线向量与扰动后的法线向量之差。由 凹凸映射是纹理映射的一种,它不
到期望中的粗糙质感效果。
于两个向量的叉积正交于这两个向量, 用修改物体模型就使物体表面具有凹凸不 以下是一个很有效的算法:设 p(u,v)
因此在上式中,两个向量的叉积是一个
平粗糙的外表, 外表受光源的位置影  是参数表面上的一点,该点的单位法向 向量,它处在 p 点的切平面上,它们的 响,其显示的明暗和颜会发生变化。 矢量用两个偏微分矢量的叉积表示, 向量和也处在 p 点的切平面上。 这种具有微细节特性的表面表现更加丰 即:n=(p × p )÷ |p × p |,式中 p = u
v
u v u 虽然 p' 和 p' 位于同一个切平面上, u  v
富、细致,更加接近物体在自然界本身 [x/u y/u
z/u]T ,p =[x/
v
且与 n' 正交,但是它们之间并非都正 的模样。
v
y/ v z/ v]T 。
交。利用向量叉积运算,可以求得一个 凹凸映射和纹理映射非常相似,不需 假设用一个移位函数把表面沿法线方 正交基和一个相应的变换矩阵。先归一 要增加对象的几何复杂度,就可以生成表 向进行移动,用 d(u,v) 表示这个移位函 化 n' 和 p' ,即 m=n'/|n'|,t=p' /|p' |。
u
u
u
面复杂的视觉效果。然而,纹理映射是把 数,d(u,v)已知且它的值比较小(|d(u,v)| 归一化后的向量为 m 和 t ,使用 m 和 t 的 颜加到多边形上,而凹凸映射是把粗糙 <<1),则移动后的表面为:p'=p+d(u,v) 叉积可以得到正交向量 b ,b=m × t 。向 信息加到多边形上。当光源或对象移动时, n 。
渗透聚苯板
量 t 称为切向量,t 是切平面上纹理坐标 u 凹凸映射会显示明暗着值发生变化的效 在凹凸纹理映射中,只有法线向量 的正方向,向量 b 称为副法线向量,b 是 果,使得一个光滑的表面外形发生变化。
拉配进行了扰动,而几何体本身没有扰动, 切平面上纹理坐标 v 的正方向。矩阵 M=
这样的结果就是粗糙质感的改变只出现在 [t b m]T 是变换矩阵,它把对象从原空间 2 凹凸映射的算法原理
物体的轮廓上,而物体本身仍然是原来 变换为由 t 、b 、m 组成的切平面空间。 凹凸映射的算法原理是使用纹理图像
的光滑物体。所以上式的目的不是建立 用两个数组分别用来保存 d/ u 和 中的数据修改光照方程中的法线向量。
位移后的实际表面,不然这个粗糙表面 d/ v 的值。预先计算这两个数组的 在这项技术中每个待渲染的像素在计 比起扰动之前的光滑表面具有复杂的几何 值,在明暗处理过程中对法线向量进行 算光照之前都要加上一个扰动,扰动基 结构,这会明显降低图形系统的运算速 扰动。求得这些扰动数组的方法之一是 于将凹凸图中的高度信息转换成补渲染 度。凹凸映射只是让表面看起来好像受 对偏移函数d(u,v) 直接采用图像处理的方 用到的法线调节信息。表面某点的法线
电梯轿厢空调到了偏移的作用,物体的光滑表面结构
法。假设在像素阵列D=[d ]上得到d(u,v)
ij
基础及前沿研究
中国科技信息 2008 年第 9 期 CHINA SCIENCE AND TECHNOLOGY INFORMATION May.2008
摘  要
凹凸映射是纹理映射的一种,它不用修改物 体模型就使物体表面具有凹凸不平粗糙的外 表,外表受光源的位置影响,其显示的明暗 和颜会发生变化。该文探讨了使用 OpenGL 着语言(GL SL)实现凹凸映射的算法,并介 绍其生成原理。算法可以应用在计算机三维 绘图中。  关键词
凹凸映射;变换矩阵;Op en GL 着语言
- -d ij
的采样值,所求的偏微分值正比于阵列 中相邻两个元素的差分,即 d/u ∝ d b=cross(n,t);”
“// 光线向量从视点坐标系变换到 (G L _F R AG M EN T _S H AD E R);
电子顺磁共振g l S h a d e r S o u r c e (f S h a d e r ,
i-1,j 和 d/ v ∝ d
ij    i, j-1
纹理坐标系里”
“light.x=dot();” N U M B E R O F L I N E S (f S h a d e r S r c ), fShaderSrc,NULL);
3 凹凸映射的 GLSL 实现
OpenGL2.0 除了固定功能的管线之
外,还增加了一种可编程着管线,可
半导体除湿机
以使用 Op en GL  着语言(简称 GLS L ) 编写程序来控制顶点处理和片段处理。
就像在不同的程序中使用同一个函数一
样,GLSL 程序创建着器对象来沿用这 种设计。它所创建的顶点着器对象和
片元着器对象可以在多个着器程序中 使用,在多个着器程序就不必重复使
用大量的通用代码,仅仅是把需要的着
器对象连接到着器程序。
本示例用 GLSL 实现了凹凸映射。顶
点着器首先用模型 - 视图矩阵将顶点位 置从对象坐标系变换到视点坐标系,然 后用投影矩阵在把顶点位置视点坐标系变 换到裁剪坐标系里。凹凸映射要在纹理 坐标系中计算,所以要将光线向量与视 线向量先变换到视点坐标系,然后再通
过纹理坐标变换矩阵变换到纹理坐标系 里。 所需要的纹理坐标变换矩阵由切 线、副法线和法线向量组成。
/* 凹凸映射的顶点着器 */
varying vec3 light; / / 在纹理坐标系里的光线向量
varying vec3 view; / / 在纹理坐标系里的视线向量 attribute vec3 tangent; // 在对象坐 标系里的切线向量 const GLchar* vShaderSrc[ ]=“{ void
main () ”“{“ “// 将顶点位置从对象坐标系变换 到裁剪坐标系” “gl_Position=gl_ModelView
ProjectionMatrix*gl_Vertex;” “// 在视点坐标系里的视线向量” “v e c 3 v i e w E y e =v e c 3 (gl_ModelViewMatrix*gl_Vertex);” “ g l _ T e x C o o r d [ 0  ] =gl_MultiTexCoord0;” “// 在视点坐标系里的光线向量” “vec3 lightEye=normalize(vec3
(gl_LightSource[0].position)–viewEye);”
“ v e c 3 n =n o r m a l i z e  (gl_NormalMatrix*gl_Normal);” “ v e c 3 t =n o r m a l i z e
(gl_NormalMatrix*tangent);”“vec3
“light.y=dot();” “light.z=dot();” “// 视线向量从视点坐标系变换到 纹理坐标系里
“ “view.x=dot();” “view.y=dot();”
“view.z=dot();” “light=normalize(light);”
“view=normalize(view);”“}”}; 片元着器使用漫反射光项,对光 源位置向量与法线向量进行点积计算。 光源位置向量来自于片元着器对顶点着
器的光线向量进行插值运算的结果。
法线向量来自于法线贴图
n o r ma l Ma p  , 它是二维压缩的纹理坐标。颜分量存
放在另一个二维纹理贴图
texMap 中。 /* 凹凸映射的片元着器 */ varying vec3 light; // 顶点着 器处理后的光线向量,传递给片元着 器
varying vec3 view; // 顶点着器处理后的视线向量,传递给片元着器 uniform sampler2D texMap; uniform sampler2D normalMap; const GLchar* fShaderSrc[ ]=“{ void main()”“{““vec3 lightLoc=normalize (light);” “vec4 texColor=texture2D(texMap, gl_TexCoord[0].st);” “vec3 n=2*(texture2D(normalMap, gl_TexCoord[0].st).rgb –0.5);” “gl_FragColor=max(dot(lightLoc,n), 0.0)*texColor;”“}”}; /* 创建和链接 GLSL 着器 */ GLuint vShader,fShader,pro; #d ef i ne  N UM B E RO F L IN E S(x (sizeof(x)/sizeof(x[0])) // 创建并编译顶点着器对象 vShader=glCreateShaderObject (GL _VE RT EX_SH ADE R);  g l S h a d e r S o u r c e (v S h a d e r , N U M B E R O F L I N E S (v S h a d e r S r c ), vShaderSrc,NULL); glCompileShader(vShader); // 创建并编译片元着器对象 fShader=glCreateShaderObject glCompileShader(fShader);
// 创建着器程序,连接着器对 象。 如果链接成功, 使用该着器程 序 。
p r o =g l C r e a te P r o O b j ec t (); glAttachObject(pro,vShader);
glAttachObject(pro, fShader);
glLinkPro(pro);glUseProObject(pro);  参考文献 [1] Edward Angel.吴文国译.交互式计算机
图形学-基于OpenGL 的自顶向下方法
[M]. 第4版.清华大学出版社.2007.
[2]DaveShreiner 等.徐波译.OpenGL 编程指
南[M].第5版.机械工业出版社.2006.
作者简介
顾伟,Motorola 南京软件中心软件工程师,现
攻读南京东南大学计算机系计算机技术专业 工程硕士学位,本科毕业于南京东南大学计 算机系计算机科学与技术专业。
d 。

本文发布于:2024-09-22 02:07:40,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/1/251563.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:向量   表面   凹凸   法线   映射   纹理   扰动   着色器
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议