更多渲染

图表的渲染,除了着色外,还有设置透明度、纹理映射、添加光照和设置材质等内容。本节进一步进行介绍。

透明度

将图形对象设置为半透明在三维可视化中是一个很有用的技巧。它使用户不仅能看到对象的外观,还能看到对象内部的结构特征。支持透明性的对象有图像、面片和曲面。

透明度值常用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函数可以指定曲面的透明度。

下面的代码绘制球面坐标系函数的图形。在命令窗口键入:

code.matlab
>> 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左图。

code.matlab
>> camlight
>> alpha(.5)

添加光照并设置为半透明,生成图1-32右图。

Document Image
\[\]

图1-32 将曲面设置为半透明

给Patch对象的FaceAlpha属性赋值,可以设置面片的透明度。跟曲面着色类似,透明度也可以设置为单值、刻面和插值等几种效果。

下面用patch函数生成一个立方体。立方体各小面的颜色用刻面着色,FaceAlpha属性的值设置为0.3。此时所有小面的透明度都设置为0.3。

code.matlab
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左图。

Document Image
\[\]

图1-33 透明度设置为单值、刻面和插值的效果

下面将面片的FaceAlpha属性值设置为flat。注意,设置为flat或interp时,必须指定各小面或各顶点的透明度值,并赋给FaceVertexAlphaData属性。

code.matlab
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,即

code.matlab
patch('Faces',fac,'Vertices',vert,'FaceVertexCData',tcolor,'FaceVertexAlphaData',talpha,'FaceColor','flat','FaceAlpha', 'interp');

生成图1-33右图。此时小面上的透明度有渐变效果。

纹理映射

纹理映射技术通过变换颜色数据将二维图像映射到三维曲面上。它允许颜色数据数组的维数与定义曲面图的数据的不同。可以将图像映射到任意大小的曲面上。MATLAB会对纹理颜色数据进行插值,使它可以映射到整个曲面上。

下面的例子用sphere函数创建一个球面,然后将一个图片映射到这个曲面上。

code.matlab
>> 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所示。

Document Image
\[\]

图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对象上看到光照效果。

下面的代码创建一个函数定义的曲面,然后给曲面添加光照。在命令窗口键入

code.matlab
>> 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所示。

Document Image Document Image
\[\]

图1-35 函数定义的曲面 图1-36 曲面的光照效果

用平行光照射它,光的方向由向量[0 1 1]定义

code.matlab
>> light('Position',[0 1 1])

光照效果如图1-36所示。

lightangle函数在球面坐标系中创建一个光照对象。下面的代码创建一个动画,该动画给peaks曲面添加光照并变化光照对象的方位角。

code.matlab
>> 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数据定义的曲面上的光照效果。

code.matlab
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。

Document Image
\[\]

图1-37 给曲面添加光照并设置光照属性

光照算法

给坐标系添加光照时,MATLAB确定坐标系中Patch和Surface对象上的光照效果。计算对象边和面的着色有不同的算法,算法的选择与想获得的光照效果有关。

对于光照计算,MATLAB提供了3种不同的算法。通过设置场景中每个Patch和Surface对象的FaceLighting和EdgeLighting属性可以进行选择。每个算法都会生成多少有些不同的结果:

刻面光照:对象的每个小面上生成均匀的颜色。

Gouraud光照:计算顶点处的颜色,然后插值计算整个小面上的颜色。

Phong光照:在每个小面上进行顶点法向的插值,并计算每个像素的反射。Phong光照生成的效果通常比Gouraud光照的好,但是更费时。

Document Image
\[\]

图1-38 应用几种不同光照方法时红球的显示效果

图1-38显示了应用几种光照方法时红球的显示效果。第1至第4个红球分别对应于没有光照、使用刻面光照、Gouraud光照和Phong光照时的显示效果。

利用lighting函数,可以方便地设置光照算法。该函数的调用格式为:

lighting flat 选择刻面光照。

lighting gouraud 选择gouraud光照。

lighting phong 选择phong光照。

lighting none 取消光照。

下面的代码使用不同的光照算法渲染同一曲面。

code.matlab
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。

Document Image
\[\]

图1-39 用不同的光照算法渲染曲面

面的反射特性

可以修改Patch对象和Surface对象的反射特性,从而改变在场景中应用光照时对象的显示外观。这些特性包括:

镜面反射和漫反射

环境光

镜面反射指数

镜面反射光的颜色

背面光照

可以组合使用这几种特性来生成特殊的显示结果。可以通过设置SpecularStrength和DiffuseStrength属性来控制对象曲面镜面反射和漫反射的强度。图1-40演示了不同反射类型和强度下的设置效果。

Document Image Document Image
\[\]

图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个不同的值时白光照射下红球的显示效果。

Document Image
\[\]

图1-42 镜面反射指数对光照效果的影响

镜面反射光的颜色可以有一个变化范围,即从对象颜色与光源颜色的组合色变到只有光源颜色。面片和Surface对象的SpecularColorReflectance属性控制这个颜色。图1-43显示了SpecularColorReflectance属性的值从0变到1时白光照射下红球的显示效果。0对应于对象和光源的组合色,1对应于光源的颜色。

Document Image
\[\]

图1-43 镜面反射光的颜色对显示效果的影响

背面光照可用于显示对象内表面和外表面的差别。图1-44中被切开的柱面演示了这种背面光照效果。

Document Image
\[\]

图1-44 背面光照对显示效果的影响

BackFaceLighting属性的默认值是reverselit。这个设置将顶点法向指向相机,使内表面将光线反射到相机。将BackFaceLighting属性设置为unlit,通过将顶点法向指向背离相机的方向来取消光照。

对于图1-35所示曲面,现在用lightangle命令添加光照,并进行更多设置。

code.matlab
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所示。

Document Image
\[\]

图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所示曲面的材质设置为金属材质。

code.matlab
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所示,曲面的金属质感比较明显。

Document Image
\[\]

图1-46 设置材质