注册通行证 用户名 密码
  • 文章投稿
  • 博客
  • 论坛
  • 设为首页
  • 加入收藏
jztop.com网络技术
  • 首页
  • | iT新闻
  • | 操作系统
  • | 组网建网
  • | 网络安全
  • | 程序开发
  • | 办公一族
  • | 工具软件
  • | 网页制作
  • | 多媒体制作
  • | 网吧技术
  • | 服务器
  • | 专题教程
Vista | 软件评测 | 系统备份 | 优化 | 进程 | 聊天 | 病毒 | Linux | 黑客 | 防火墙 | 数据库 | Web开发 | Java | Word | 游戏 | 32位开发 | 移动开发
当前位置:首页 > 多媒体制作 > 3dmax > 内容正文

GIS三维地景仿真设计之建模及场景渲染

发布时间:2006-08-03 15:22:22 来源:天极开发 网友评论 0 条
  引言

  在上一篇文章中已经实现了对数字高程模型(DEM)的文件创建与数据读取。本文将根据已经读取的DEM数据完成建模及对场景的绘制渲染。主要的设计步骤为:首先通过计算获取法线向量,然后对地景的材质进行定义并初始化地景列表,最后对地景的不同建模方式进行介绍。

  法线向量的计算

  本系统的实现目标是通过计算机真实的再现指定真实场景的视觉效果。这显然要考虑到光照的影响,而一般的场景通常都是存在不同程度的起伏,通过抽取出来的DEM网格数据表现为大量不同朝向的小网格平面。由于这些网格平面的朝向不同,当同一光源发出的光线照到场景上时,反射出来的光线将反射到四面八方。仿真的一个重要思想就是在算法中应用真实世界中客观存在的物理定律、现象以及规律等。只有这样,才能制作出与逼真的效果。为了描述光线的反射方向,必须首先确定各网格平面的法线方向,在程序实现中通过法线向量来表示:

int x[2], y[2], z[2];
m_pNormals = new float [3 * m_nSumPointOfDem];
float normal[3], rate;
for (int i = 0; i < m_nDemY - 1; i++) {
 for (int j = 0; j < m_nDemX - 1; j++) {
  x[0] = m_pDemX[(i + 1) * m_nDemX + j] - m_pDemX[i * m_nDemX + j];
  x[1] = m_pDemX[i * m_nDemX + (j + 1)] - m_pDemX[i * m_nDemX + j];
  y[0] = m_pDemY[(i + 1) * m_nDemX + j] - m_pDemY[i * m_nDemX + j];
  y[1] = m_pDemY[i * m_nDemX + (j + 1)] - m_pDemY[i * m_nDemX + j];
  z[0] = m_pDemH[(i + 1) * m_nDemX + j] - m_pDemH[i * m_nDemX + j];
  z[1] = m_pDemH[i * m_nDemX + (j + 1)] - m_pDemH[i * m_nDemX + j];
  normal[0] = (float)(y[1] * z[0] - z[1] * y[0]);
  normal[1] = (float)(z[1] * x[0] - x[1] * z[0]);
  normal[2] = (float)(x[1] * y[0] - y[1] * x[0]);
  rate = (float)sqrt(normal[0] * normal[0] + normal[1] * normal[1] + normal[2] * normal[2]);
  normal[0] /= rate;
  normal[1] /= rate;
  normal[2] /= rate;
  m_pNormals[(i * m_nDemX + j) * 3 + 0] = normal[0];
  m_pNormals[(i * m_nDemX + j) * 3 + 1] = normal[1];
  m_pNormals[(i * m_nDemX + j) * 3 + 2] = normal[2];
 } 
}

  这段代码在GetVertexNormal()函数中实现,在读取完DEM数据后即被执行。具体的计算过程纯属一般的数学计算,在上一篇文章中已经将网格各节点的三维坐标存放在m_pDemX、m_pDemY和m_pDemH指向的缓冲区中。这里依次对组成网格平面的全部网格单元进行枚举,并计算由格网点(i,j)所组成的矩形格网上的向量(X0,Y0,Z0)、向量(X1,Y1,Z1),以便利用二者来求取顶点(i,j)的法向量。之后,通过求两个向量的叉积(X1,Y1,Z1)X(X0,Y0,Z0)确定出顶点(i,j)的法向量,并将其x、y、z分量保存到normal[0]、normal[1]和normal[2]中,该计算结果并不能直接在OpenGL中使用,需要做进一步的处理,将法向量单位标准化,然后按照x、y、z分量的次序将计算结果依次保存到m_pNormals所指向的缓冲区中备用。

  定义材质

  定义了法线向量仅仅能够控制光线的反射方向,而真实场景除了存在地形的起伏外,材质的不同也对视觉有很大的影响。例如,光滑的地表要比粗糙的地表镜面反射光更强,而漫反射光更弱。同一束白光照射到不同颜色的地表也将显现出不同的颜色。因此,除了定义法线向量外,还需要对地景的材质进行定义,通常需要定义的主要有材质的环境反射光、漫反射光、镜面反射光和反射光亮度等参数:

glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); // 定义材质的环境反射光
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); // 定义材质的漫反射光
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); // 定义材质镜面反射光
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); // 定义反射光亮度

  其中,mat_ambient、mat_diffuse、mat_specular和mat_shininess中定义了具体的参数取值:

// 定义材质镜面反射光
mat_shininess[0] = 50.0f;
// 定义材质的环境反射光
mat_ambient[0] = 0.3f;mat_ambient[1] = 0.3f;mat_ambient[2] = 0.3f; mat_ambient[3] = 1.0f; // 定义材质的漫反射光
mat_diffuse[0] = 0.9f;mat_diffuse[1] = 0.9f;mat_diffuse[2] = 0.7f;mat_diffuse[3] = 1.0f;
// 定义材质镜面反射光
mat_specular[0]=1.0f;mat_specular[1] = 1.0f;mat_specular[2] = 1.0f;mat_specular[3] = 1.0f;
即使初始定义了材质,在之后的执行过程中也随时可以更改材质设定:
if (dlg.m_bDiffuseColor){ // 定义材质的漫反射光
 RGBToGLfloatv(dlg.m_crDiffuseColor,r,g,b);
 mat_diffuse[0] = r; mat_diffuse[1] = g; mat_diffuse[2] = b; mat_diffuse[3] = 1.0f;
}
if (dlg.m_bAmbientColor) { // 定义材质的环境反射光
 RGBToGLfloatv(dlg.m_crAmbientColor,r,g,b);
 mat_ambient[0] = r;mat_ambient[1] = g;mat_ambient[2] = b;mat_ambient[3] = 1.0f;
}
if (dlg.m_bSpecularColor) { // 定义材质镜面反射光
 RGBToGLfloatv(dlg.m_crSpecularColor,r,g,b);
 mat_specular[0] = r;mat_specular[1] = g;mat_specular[2] = b;mat_specular[3] = 1.0f;
}
mat_shininess[0] = (GLfloat)dlg.m_nShininess; // 光亮度
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); // 定义材质的环境反射光
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); // 定义材质的漫反射光
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); // 定义材质镜面反射光
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); // 定义材质镜面反射光

  这里是通过对话框的交互由用户动态指定所需的颜色取值并以此来进行材质设定。由于通常多以COLORREF型变量来指定颜色,因此在设置材质之前要先通过RGBToGLfloatv()函数从中分离出R、G、B颜色分量:

BYTE r = (BYTE)(color & 0x000000FF); // 提取RGB各分量取值
BYTE g = (BYTE)((color & 0x0000FF00) >> 8);
BYTE b = (BYTE)((color & 0x00FF0000) >> 16);
rf = r / 255.0f; gf = g / 255.0f; bf = b / 255.0f;

关于 GIS三维 场景渲染 的新闻
  • GIS三维地景仿真设计之数字高程模型
【评论】【收藏本文】【打印】【关闭】
上一篇文章:续写辉煌:Autodesk隆重发布MAYA8.0
下一篇文章:用Vue设计三维造型的雕刻家Adam Websper
讨论区
查看
已有 0 位对此新闻感兴趣的网友发表了看法
匿名发表
注册通行证 登陆
图文阅读推荐
3DsMax打造精致珍珠狮头手镯首饰
3DsMax打造精致珍珠狮头手镯首饰
3D MAX打造宇宙中遥望美丽的地球
3D MAX打造宇宙中遥望美丽的地球
3DsMAX打造柔美丝巾送给MM作节日礼物
3DsMAX打造柔美丝巾送给MM作节日礼物
为爱人制作情人节三维玫瑰花田
为爱人制作情人节三维玫瑰花田
全站资源
  • 微软官方入门教程19:轻松掌握Vista系统的快
  • 微软2008大冲击,预借Vista SP1力促Vista市
  • 在收件箱中获得 Windows Vista 的最新更新
  • 微软官方Vista入门教程全集19篇(Vista学院
  • Windows Vista 的成功将势不可挡
  • 快快抛弃Vista,拥抱XP SP3!你觉得呢?
  • 浅谈Vista系统关闭虚拟内存与使用内存盘加速
  • 嘿嘿,按下键盘上面的三个键,马上让你的Vi
  • Windows Vista的盗版率只有Windows XP的一半
  • 3DMark和PCMark Vantage新版将只支持Vista系
阅读排行
  • 3D教程:主持凳制作的简单方法
  • 用3Ds MAX体积光制作光芒片头特效
  • 3DsMAX实例制作:三维玻璃灯泡
  • 在3DS MAX中打造巍巍雪山
  • 3Ds MAX制作简单光芒特效文字片头
  • 3DsMAX打造叶片上的精致三维蜻蜓
  • 制作一个简单的三维片头包装
  • 为爱人制作情人节三维玫瑰花田
  • 续写辉煌:Autodesk隆重发布MAYA8.0
  • 春节添喜庆 3DsMAX绘制立体大红灯笼
最新技术文档
  • 教AutoCAD初学者有效提高绘图速度
  • 3DsMAX打造叶片上的精致三维蜻蜓
  • 3DsMax打造精致珍珠狮头手镯首饰
  • Shift键在AUTOCAD中的几招妙用
  • 制作一个简单的三维片头包装
  • 用3DS MAX打造三维虚拟跑车
  • GIS三维地景仿真设计之最后的话
  • Guitta Bertaud的Vue作品:三维乡村景色
  • GIS三维地景仿真设计之雾化和纹理
  • 官方视频教程演示 3DS Max 9 新特性
专题教程
  • 大话G游 专题:手机病毒揭密
  • ARP攻击防范与解决方案 路由故障处理手册
  • Picasa中文版_Picasa教程 专题:清除流氓软件
  • Firefox专题 seo搜索引擎优化专区
  • 重装Windows必知的事情 装机之必备软件大行动
病毒专杀栏
  • 杀毒软件反被病毒杀 连"救命"都不能喊
  • 金山ARP防火墙
  • 还原卡神话破灭“机器狗”病毒来势汹汹
  • cctv经济半小时:你的手机现在安全吗?
  • 新挂马方式开始流行 ARP挂马称雄局域网
  • 木马和病毒清除的通用解法
  • IP地址不再冲突 查找ARP攻击者元凶
  • 教你几招识别和防御Web网页木马
  • 分析:封杀BT只是暂时的止痛药
  • QQ爆危险漏洞,“QQ游戏邀请大盗”邀请你玩病
关于我们 | 诚聘英才 | 联系我们 | 版权声明 | 网站大事 | 网站地图 | 意见建议
CopyRight 2005-2007 Jztop.Com 版权所有 未经许可 请勿转载