图表的渲染,除了着色外,还有设置透明度、纹理映射、添加光照和设置材质等内容。本节进一步进行介绍。
透明度
将图形对象设置为半透明在三维可视化中是一个很有用的技巧。它使用户不仅能看到对象的外观,还能看到对象内部的结构特征。支持透明性的对象有图像、面片和曲面。
透明度值常用alpha值表示,界于0和1之间。当alpha值等于0时,表示完全透明;alpha值等于1时,表示完全不透明。
MATLAB中处理透明性的方式与处理颜色的方式有些类似:
面片和表面可以定义小面和边的alpha值,或根据alpha查找表中的值使用刻面或插值透明度。
图像、面片和表面对象可以将alpha数据作为索引值查找alpha查找表中的透明度或直接用作alpha值。
坐标系对象定义alpha的范围,它控制对象数据向alpha值的映射。
图形窗口对象包含alpha查找表,它是一个m×1的数组,元素为alpha值。
表1-8中概括了一些控制对象透明性的属性。
表1-8 控制对象透明性的属性
| 属 性 | 功 能 |
|---|---|
| AlphaData | 图形和表面对象的透明度数据 |
| AlphaDataMapping | 透明度数据映射方法 |
| FaceAlpha | 小面的透明度(只对面片和表面可用) |
| EdgeAlpha | 边的透明度(只对面片和表面可用) |
| FaceVertexAlphaData | 只对面片可用的alpha数据属性 |
| ALim | alpha坐标限制 |
| ALimMode | alpha坐标限制模式 |
| Alphamap | 图形窗口的alpha查找表 |
表1-9列出了可以简化alpha属性设置过程的3个函数。
表1-9 可以简化alpha属性设置过程的函数
| 函 数 | 功 能 |
|---|---|
| alpha | 设置或查询当前坐标系中对象的透明度属性 |
| alphamap | 指定图形窗口的alpha查找表 |
| alim | 设置或查询坐标系的alpha限制 |
希望揭示不透明对象的内部结构时,指定透明度是很有用的。对于面片和曲面,用FaceAlpha和EdgeAlpha属性指定小面和边的透明度。用alpha函数可以指定曲面的透明度。
下面的代码绘制球面坐标系函数的图形。在命令窗口键入:
>> r=@(u,v) 2 + sin(7.*u + 5.*v);
>> funx=@(u,v) r(u,v).*cos(u).*sin(v);
>> funy=@(u,v) r(u,v).*sin(u).*sin(v);
>> funz=@(u,v) r(u,v).*cos(v);
>> fsurf(funx,funy,funz,[0 2*pi 0 pi],'edgecolor','none')
生成图1-32左图。
>> camlight
>> alpha(.5)
添加光照并设置为半透明,生成图1-32右图。
图1-32 将曲面设置为半透明
给Patch对象的FaceAlpha属性赋值,可以设置面片的透明度。跟曲面着色类似,透明度也可以设置为单值、刻面和插值等几种效果。
下面用patch函数生成一个立方体。立方体各小面的颜色用刻面着色,FaceAlpha属性的值设置为0.3。此时所有小面的透明度都设置为0.3。
vert=[1 1 1;1 2 1;2 2 1;2 1 1;1 1 2;1 2 2;2 2 2;2 1 2];
fac=[1 2 3 4;2 6 7 3;4 3 7 8;1 5 8 4;1 2 6 5;5 6 7 8];
tcolor = [1 0 1;1 1 0;1 0 0;0 1 0;0 0 1;0 1 1];
patch('Faces',fac,'Vertices',vert,'FaceVertexCData',tcolor,'FaceColor','flat','FaceAlpha',0.3);
view(3);
axis square;
生成图1-33左图。
图1-33 透明度设置为单值、刻面和插值的效果
下面将面片的FaceAlpha属性值设置为flat。注意,设置为flat或interp时,必须指定各小面或各顶点的透明度值,并赋给FaceVertexAlphaData属性。
vert=[1 1 1;1 2 1;2 2 1;2 1 1;1 1 2;1 2 2;2 2 2;2 1 2];
fac=[1 2 3 4;2 6 7 3;4 3 7 8;1 5 8 4;1 2 6 5;5 6 7 8];
tcolor = [1 0 1;1 1 0;1 0 0;0 1 0;0 0 1;0 1 1];
talpha = [.2;.3;.4;.5;.6;.7;.8;.1];
patch('Faces',fac,'Vertices',vert,'FaceVertexCData',tcolor,'FaceVertexAlphaData',talpha,'FaceColor','flat','FaceAlpha', 'flat');
view(3);
axis square;
生成图1-33中间的图形。此时根据小面起点的透明度值设置小面的透明度,各小面的透明度不完全一样。
将FaceAlpha属性的值改为interp,即
patch('Faces',fac,'Vertices',vert,'FaceVertexCData',tcolor,'FaceVertexAlphaData',talpha,'FaceColor','flat','FaceAlpha', 'interp');
生成图1-33右图。此时小面上的透明度有渐变效果。
纹理映射
纹理映射技术通过变换颜色数据将二维图像映射到三维曲面上。它允许颜色数据数组的维数与定义曲面图的数据的不同。可以将图像映射到任意大小的曲面上。MATLAB会对纹理颜色数据进行插值,使它可以映射到整个曲面上。
下面的例子用sphere函数创建一个球面,然后将一个图片映射到这个曲面上。
>> C=imread('d:\pic.jpg');
>> [x,y,z]=sphere;
>> surface(x,y,z,'CData',flipud(C),'FaceColor','texturemap')
>> axis equal
>> view([65 30])
纹理映射效果如图1-34所示。
图1-34 球体的纹理映射效果
光照
添加光照使图形场景更加真实,这一点是通过模拟自然光下对象的明暗色调来实现的。这里,自然光也就是阳光。为了创建光照效果,MATLAB定义了一个名为Light的图形对象。MATLAB将光照应用于Surface对象和Patch对象。
Light对象
用light函数创建Light对象。该对象有3个重要的属性,即
Color—Light对象投射的光线的颜色。
Style—光线来自无穷远处(默认)还是附近。
Position—对于无穷远处的光源,表示光的方向;对于附近的光源,表示光的位置。
Color属性确定光的颜色。场景中对象的颜色由对象本身的颜色和光的颜色共同确定。
Style属性确定光源是点光源(Style属性值为local)还是放在无穷远处的光源(Style属性值设置为infinite)。点光源从指定点上向各个方向发射,而放在无穷远处的光源从指定位置上发射镜面平行光。
Position属性指定光源的位置,单位为坐标数据的单位。如果光源在无穷远处,则Position属性指定光源的方向。
光源会影响与Light对象同在一个坐标系中的Surface和Patch对象。这些对象有很多属性,利用这些属性,可以改变被光线照射时的外观显示。
MATLAB提供了几个用于设置光源位置和材质的命令,如表1-10中所示。
表1-10 设置光源位置和材质的命令
| 命 令 | 功 能 |
|---|---|
| camlight | 相对于相机位置创建或移动Light对象 |
| lightangle | 在球坐标中创建或放置一个Light对象 |
| light | 创建一个Light对象 |
| lighting | 选择一种光照方法 |
| material | 设置对象的材质 |
light函数在当前坐标系中创建一个光照对象。注意:光照对象只能用于Patch对象和Surface对象。光照对象本身是看不到的,但可以在Patch对象和Surface对象上看到光照效果。
下面的代码创建一个函数定义的曲面,然后给曲面添加光照。在命令窗口键入
>> x=@(u,v) cos(u).*sin(v);
>> y=@(u,v) sin(u).*sin(v);
>> z=@(u,v) cos(v)+log(tan(v./2))+0.2.*u;
>> fsurf(x,y,z,[0 12.4 0.1 2],'EdgeColor','none')
生成曲面如图1-35所示。
图1-35 函数定义的曲面 图1-36 曲面的光照效果
用平行光照射它,光的方向由向量[0 1 1]定义
>> light('Position',[0 1 1])
光照效果如图1-36所示。
lightangle函数在球面坐标系中创建一个光照对象。下面的代码创建一个动画,该动画给peaks曲面添加光照并变化光照对象的方位角。
>> surf(peaks)
>> axis vis3d
>> h=light;
>> for az=-50:50
lightangle(h,az,30)
drawnow
end
影响光照效果的属性
Light对象本身是不可见的,但是可以在包含Light对象的坐标系中任何Patch和Surface对象上看到光照的效果。有很多函数可以生成这些对象,包括surf,mesh,pcolor,fill,fill3,surface和patch函数等。
通过设置不同的Axes,Light,Patch和Surface对象属性,可以控制光照效果。所有属性都有默认值,可以生成需要的结果。但是,也可以通过调节这些属性值来获得指定的效果。这些属性及其控制效果如表1-11所示。
表1-11 控制光照效果的属性
| 属 性 | 效 果 |
|---|---|
| AmbientLightColor | Axes对象的属性,它指定场景中背景光的颜色。背景光没有方向,对所有对象的影响都是相同的。背景光效果只在坐标系中有可见光对象时才会出现 |
| AmbientStrength | Patch对象和Surface对象的属性,它确定从对象反射来的光中ambient组分(环境光)的强度 |
| DiffuseStrength | Patch对象和Surface对象的属性,它确定从对象反射来的光中diffuse组分(漫反射光)的强度 |
| SpecularStrength | Patch对象和Surface对象的属性,确定从对象反射来的光中specular组分(镜面光)的强度 |
| SpecularExponent | Patch对象和Surface对象的属性,确定指定镜面光大小的面片和曲面属性 |
| SpecularColorReflectance | Patch对象和Surface对象的属性,确定反射光被对象颜色或光源颜色着色的程度 |
| FaceLighting | Patch对象和Surface对象的属性,确定计算对象曲面上光照效果的方法,包括没有光照、刻面、Gouraud或Phong光照算法 |
| EdgeLighting | Patch对象和Surface对象的属性,确定用于计算对象边上光照效果的方法,包括没有光照、刻面、Gouraud或Phong光照算法 |
| BackFaceLighting | Patch对象和Surface对象的属性,确定顶点法向指向远离相机的一侧时曲面的颜色。这个属性对于区分对象的内表面和外表面很有用 |
| FaceColor | Patch对象和Surface对象的属性,指定对象小面的颜色 |
| EdgeColor | Patch对象和Surface对象的属性,指定对象边的颜色 |
| VertexNormals | Patch对象和Surface对象的属性,包含对象各顶点的法向量。MATLAB用法向量进行光照计算。MATLAB会自动计算这些数据,也可以自己指定顶点法向 |
| NormalMode | Patch对象和Surface对象的属性,确定如果改变对象数据或使用VertexNormals属性的当前值,是否重新计算顶点法向。如果指定VertexNormals的值,MATLAB将该属性设置为manual |
下面的代码演示位置为无穷远,方向由[1 0 1]定义的黄色光源在peaks数据定义的曲面上的光照效果。
clear;close all;
h=surf(peaks); %绘制曲面
h.EdgeColor="none"; %删除网格线
set(h,'FaceLighting','phong','FaceColor','interp', 'AmbientStrength',0.5) %曲面光照属性
light('Position',[1 0 1],'Style','infinite','Color','y'); %添加光照,黄色,无穷远
… %省略部分代码
运行代码生成图1-37。
图1-37 给曲面添加光照并设置光照属性
光照算法
给坐标系添加光照时,MATLAB确定坐标系中Patch和Surface对象上的光照效果。计算对象边和面的着色有不同的算法,算法的选择与想获得的光照效果有关。
对于光照计算,MATLAB提供了3种不同的算法。通过设置场景中每个Patch和Surface对象的FaceLighting和EdgeLighting属性可以进行选择。每个算法都会生成多少有些不同的结果:
刻面光照:对象的每个小面上生成均匀的颜色。
Gouraud光照:计算顶点处的颜色,然后插值计算整个小面上的颜色。
Phong光照:在每个小面上进行顶点法向的插值,并计算每个像素的反射。Phong光照生成的效果通常比Gouraud光照的好,但是更费时。
图1-38 应用几种不同光照方法时红球的显示效果
图1-38显示了应用几种光照方法时红球的显示效果。第1至第4个红球分别对应于没有光照、使用刻面光照、Gouraud光照和Phong光照时的显示效果。
利用lighting函数,可以方便地设置光照算法。该函数的调用格式为:
lighting flat 选择刻面光照。
lighting gouraud 选择gouraud光照。
lighting phong 选择phong光照。
lighting none 取消光照。
下面的代码使用不同的光照算法渲染同一曲面。
tiledlayout(2,2);
nexttile %第1个坐标系,不添加光照
h1=surf(peaks(20));
h1.EdgeColor="none";
title('None')
box on
nexttile %第2个坐标系
h2=surf(peaks(20));
h2.EdgeColor="none";
camlight
lighting flat %刻面光照
title('Flat')
box on
nexttile %第3个坐标系
h3=surf(peaks(20));
h3.EdgeColor="none";
camlight
lighting gouraud %Gouraud光照
title('Gouraud')
box on
nexttile %第4个坐标系
h4=surf(peaks(20));
h4.EdgeColor="none";
camlight
lighting phong %Phong光照
title('Phong')
box on
运行代码生成图1-39。
图1-39 用不同的光照算法渲染曲面
面的反射特性
可以修改Patch对象和Surface对象的反射特性,从而改变在场景中应用光照时对象的显示外观。这些特性包括:
镜面反射和漫反射
环境光
镜面反射指数
镜面反射光的颜色
背面光照
可以组合使用这几种特性来生成特殊的显示结果。可以通过设置SpecularStrength和DiffuseStrength属性来控制对象曲面镜面反射和漫反射的强度。图1-40演示了不同反射类型和强度下的设置效果。
图1-40设置效果一 图1-41 设置效果二
环境光不是镜面光,它均匀地洒在场景中的所有对象上。只有在坐标系中有Light对象时环境光才可见。有两个属性可以控制环境光:AmbientLightColor属性是一个用于坐标系的属性,设置颜色;AmbientStrength属性是一个用于面片和Surface对象的属性,确定特定对象上环境光的强度。
图1-41显示了3种不同颜色的环境光在不同强度下红球的显示效果。场景中有一个白光对象存在。
图1-41中,绿色([0 1 0])环境光对场景没有影响,因为绿光中没有红色组分。但是,RGB值[.5 0 1]定义的颜色有红色组分,所以它会影响红球的显示效果。但是它的影响效果没有白光[1 1 1]的强烈。
镜面高光的大小与Patch和Surface对象的SpecularExponent属性有关,该属性的值界于1和500之间,一般对象的值界于5和20之间。图1-42演示了SpecularExponent属性取3个不同的值时白光照射下红球的显示效果。
图1-42 镜面反射指数对光照效果的影响
镜面反射光的颜色可以有一个变化范围,即从对象颜色与光源颜色的组合色变到只有光源颜色。面片和Surface对象的SpecularColorReflectance属性控制这个颜色。图1-43显示了SpecularColorReflectance属性的值从0变到1时白光照射下红球的显示效果。0对应于对象和光源的组合色,1对应于光源的颜色。
图1-43 镜面反射光的颜色对显示效果的影响
背面光照可用于显示对象内表面和外表面的差别。图1-44中被切开的柱面演示了这种背面光照效果。
图1-44 背面光照对显示效果的影响
BackFaceLighting属性的默认值是reverselit。这个设置将顶点法向指向相机,使内表面将光线反射到相机。将BackFaceLighting属性设置为unlit,通过将顶点法向指向背离相机的方向来取消光照。
对于图1-35所示曲面,现在用lightangle命令添加光照,并进行更多设置。
x=@(u,v) cos(u).*sin(v);
y=@(u,v) sin(u).*sin(v);
z=@(u,v) cos(v)+log(tan(v./2))+0.2.*u;
fsurf(x,y,z,[0 12.4 0.1 2],'EdgeColor','none')
view(0,75)
lightangle(-45,30) %光照角度
set(gcf,'Renderer','zbuffer')
set(findobj(gca,'type','surface'),... %查找曲面对象设置属性
'FaceLighting',';phong',... %光照算法
'AmbientStrength',.3,'DiffuseStrength',.8,... %反射参数设置
'SpecularStrength',.9,'SpecularExponent',25,...
'BackFaceLighting','unlit')
效果如图1-45所示。
图1-45 对曲面进行更多设置
材质
使用material函数可以快速设置曲面或面片的材质。该函数的语法格式为:
material shiny 镜面反射光的强度比漫反射光和环境光的要高得多,镜面光的颜色只决定于光源的颜色。
material dull 主要进行漫反射,没有镜面反射,但是反射光的颜色只与光源有关。
material metal 镜面反射很强,环境光和漫反射光较弱,反射光的颜色与光源和对象的颜色都有关系。
material([ka kd ks]) 设置对象的环境光、漫反射光和镜面光的强度。
material([ka kd ks n]) 设置环境光、漫反射光和镜面光的强度,以及对象的镜面反射指数。
material([ka kd ks n sc]) 设置环境光、漫反射光和镜面光的强度,以及对象的镜面反射指数和镜面反射光的颜色。
material default 将环境光、漫反射光和镜面光的强度,以及对象的镜面反射指数和镜面反射光的颜色设置为默认值。
注意,material命令设置坐标系中所有Surface和Patch对象的AmbientStrength、DiffuseStrength、SpecularStrength、SpecularExponent和SpecularColorReflectance属性。坐标系中必须有一个可见的Light对象。
下面的代码将图1-35所示曲面的材质设置为金属材质。
x=@(u,v) cos(u).*sin(v);
y=@(u,v) sin(u).*sin(v);
z=@(u,v) cos(v)+log(tan(v./2))+0.2.*u;
fsurf(x,y,z,[0 12.4 0.1 2],'EdgeColor','none')
view(0,75)
lightangle(-45,30) %光照角度
material metal %金属材质
生成的图形效果如图1-46所示,曲面的金属质感比较明显。
图1-46 设置材质