计算机图形学实验报告-实验5Phong光照模型

合集下载

计算机图形学上机实验报告

计算机图形学上机实验报告

计算机图形学实验报告姓名:学号:班级:目录实验一OpenGL程序结构练习 (3)实验二基本图形生成 (6)实验三交互式控制 (9)实验四图形基本变换 (12)实验五三维图形生成及显示 (15)实验六三维图形生成及显示 (19)实验一OpenGL程序结构练习【实验目的】1.熟悉C语言环境下OpenGL的使用方法;2.了解OpenGL程序的基本结构。

【实验原理】绝大多数OpenGL程序具有类似的结构,包含下述函数main():定义回调函数,打开一个或多个具有指定属性的窗口,进入事件循环(最后一条可执行语句)init():设置状态变量、视图、属性、回调、显示函数、输入和窗口函数#include <GL/glut.h> // glut.h includes gl.h and glu.hvoid display(){ ……}void init(){ ……}int main( intargc, char **argv){ ……}【实验内容】1.了解程序中各个结构的功能;2.用OpenGL生成三角形。

【实验步骤及结果】1.导入OpenGL的glut32.lib和glut.h文件:将.lib文件存放到C 语言程序文件夹的Library下,.h文件放到Include下;导入应用程序扩展文件glut32.dll,存放到system文件夹下。

2.打开VC 6.0,新建工程,并命名为text1,如图1.图 13.在工程text1下新建源文件,并命名为text1.cpp。

4.编写代码并编译链接,如图2所示。

图 25.运行,结果如图3所示。

图 3实验二基本图形生成【实验目的】1.熟悉OpenGL的程序结构,并了解各部分的功能。

2.学会应用OpenGL语言绘制出点,线,多边形。

【实验原理】1.GLUT函数glutInit使得应用程序可以获取命令行参数并初始化系统。

glutInitDisplayMode设置窗口的属性、RGB颜色、单缓冲区、属性按照逻辑或组合在一起。

计算机图形学中的光照模型

计算机图形学中的光照模型

计算机图形学中的光照模型在计算机图形学中,光照模型是模拟现实世界中光线与物体之间相互作用的模型。

通过使用光照模型,计算机可以在虚拟场景中模拟光线的传播和反射,从而创建出真实感和逼真感的图像。

因此,光照模型是计算机图形学中非常重要的一个组成部分。

光照模型的基本原理是从光源发出的光线经过物体表面的反射、折射和透射等变换,最终到达观察者的眼睛,从而形成人们所看到的图像。

在光照模型中,光源可以是点光源、定向光源和面光源等不同类型的光源,而物体的材质属性和表面形状也会对光线的传播和反射产生影响。

常见的光照模型包括冯氏光照模型、布林-菲菲(Blinn-Phong)光照模型、库克-托伯汉姆(Cook-Torrance)光照模型等。

下面,我们分别对这三种光照模型进行介绍。

冯氏光照模型是最早被提出的光照模型之一,它是由斯特恩伯格(Phong)在上世纪70年代提出的。

冯氏光照模型假设物体表面的亮度与其漫反射和镜面反射成分的线性组合有关。

其中,漫反射成分是从各个方向均匀地反射出来的光线,而镜面反射成分则是由光源直接反射回观察者的光线。

冯氏光照模型还考虑了环境光的影响,该影响是由光源外发射的光线在场景中反射和折射,并最终到达物体表面的。

布林-菲菲光照模型是另一种常用的光照模型,它是由布林(Blinn)和菲菲(Phong)在上世纪80年代提出的。

相比于冯氏光照模型,布林-菲菲光照模型增加了一个半角向量的概念。

半角向量是入射光线和出射光线的平均方向,它可以更加准确地描述物体表面的反射特性。

此外,布林-菲菲光照模型还加入了柔光和高光衰减等特性,从而使得被渲染的图像更加真实。

库克-托伯汉姆光照模型是一种物理模拟的光照模型,它是由库克(Cook)和托伯汉姆(Torrance)在上世纪80年代提出的。

该光照模型基于微观的物理原理,考虑了光线与物体表面微观结构之间的相互作用。

库克-托伯汉姆光照模型因其真实感和准确性而被广泛应用于计算机图形学、计算机游戏等领域。

phong光照模型

phong光照模型

05
Phong光照模型的优缺 点
优点
真实感强
Phong光照模型能够模拟出较为真实的光照效果,通过计算不同表 面的反射特性,能够呈现出较为逼真的材质质感。
灵活性高
Phong光照模型提供了多种光照参数,如环境光、漫反射光和镜面 光等,允许开发者根据需求调整光照效果,以适应不同的场景和需 求。
易于实现

编写着色器
Unity使用着色器来实现光照模型,需要编写相应的Phong 着色器代码。
渲染图像
将着色器代码应用到物体上,并根据光源和材质属性计算 出物体的光照强度,最终渲染出具有真实感的3D图像。
THANKS FOR WATCHING
感谢您的观看
沉浸式体验
Phong光照模型能够提供逼真的光照效果,使虚拟现实场景更加 真实、自然,提高用户的沉浸感。
交互式探索
通过Phong光照模型,虚拟现实开发者可以为用户提供更加丰富的 交互体验,如实时调整光照、观察物体表面的反射等。
教育与培训
Phong光照模型在虚拟现实中的教育应用也很广泛,如模拟实验、 历史场景重建等,有助于提高学习效果和培训质量。
04
Phong光照模型的应用
游戏开发
逼真渲染
Phong光照模型能够提供 逼真的光照效果,使游戏 场景更加真实、生动。
细节表现
通过Phong光照模型,游 戏开发者可以更好地表现 物体的细节和纹理,提升 游戏的视觉体验。
交互性增强
Phong光照模型能够根据 玩家的视角和动作实时调 整光照效果,增强游戏的 交互性和沉浸感。
折射光
折射光的概念
折射光是指光线在穿过透明物体时发生折射后形成的影像。在Phong光照模型中,折射光的计也是实现逼真光照效 果的重要一环。

计算机图形学第五次实验报告

计算机图形学第五次实验报告

《计算机图形学》实验报告实验十一真实感图形一、实验教学目标与基本要求初步实现真实感图形, 并实践图形的造型与变换等。

二、理论基础运用几何造型, 几何、投影及透视变换、真实感图形效果(消隐、纹理、光照等)有关知识实现。

1.用给定地形高程数据绘制出地形图;2.绘制一(套)房间,参数自定。

三. 算法设计与分析真实感图形绘制过程中, 由于投影变换失去了深度信息, 往往导致图形的二义性。

要消除这类二义性, 就必须在绘制时消除被遮挡的不可见的线或面, 习惯上称之为消除隐藏线和隐藏面, 或简称为消隐, 经过消隐得到的投影图称为物体的真实图形。

消隐处理是计算机绘图中一个引人注目的问题, 目前已提出多种算法, 基本上可以分为两大类:即物体空间方法和图象空间方法。

物体空间方法是通过比较物体和物体的相对关系来决定可见与不可见的;而图象空间方法则是根据在图象象素点上各投影点之间的关系来确定可见与否的。

用这两类方法就可以消除凸型模型、凹形模型和多个模型同时存在时的隐藏面。

1).消隐算法的实现1.物体空间的消隐算法物体空间法是在三维坐标系中, 通过分析物体模型间的几何关系, 如物体的几何位置、与观察点的相对位置等, 来进行隐藏面判断的消隐算法。

世界坐标系是描述物体的原始坐标系, 物体的世界坐标描述了物体的基本形状。

为了更好地观察和描述物体, 经常需要对其世界坐标进行平移和旋转, 而得到物体的观察坐标。

物体的观察坐标能得到描述物体的更好视角, 所以物体空间法通常都是在观察坐标系中进行的。

观察坐标系的原点一般即是观察点。

物体空间法消隐包括两个基本步骤, 即三维坐标变换和选取适当的隐藏面判断算法。

选择合适的观察坐标系不但可以更好地描述物体, 而且可以大大简化和降低消隐算法的运算。

因此, 利用物体空间法进行消隐的第一步往往是将物体所处的坐标系转换为适当的观察坐标系。

这需要对物体进行三维旋转和平移变换。

常用的物体空间消隐算法包括平面公式法、径向预排序法、径向排序法、隔离平面法、深度排序法、光线投射法和区域子分法。

哈工大威海 计算机图形学实验报告

哈工大威海 计算机图形学实验报告

计算机图形学实验报告实验一、二技术之三维变换计算机图形学基础知识-三维变换变换是计算机图形学中重要概念,包括最基本的三维变换,即几何变换、投影变换、裁剪变换、视口变换。

1.从三维空间到二维平面1.1 相机模拟在真实世界里,所有的物体都是三维的。

但是,这些三维物体在计算机世界中却必须以二维平面物体的形式表现出来。

那么,这些物体是怎样从三维变换到二维的呢?下面我们采用相机(Camera)模拟的方式来讲述这个概念。

实际上,从三维空间到二维平面,就如同用相机拍照一样,通常都要经历以下几个步骤(括号内表示的是相应的图形学概念):第一步,将相机置于三角架上,让它对准三维景物(视点变换,Viewing Transformation)。

第二步,将三维物体放在适当的位置(模型变换,Modeling Transformation)。

第三步,选择相机镜头并调焦,使三维物体投影在二维胶片上(投影变换,Projection Transformation)。

第四步,决定二维像片的大小(视口变换,Viewport Transformation)。

这样,一个三维空间里的物体就可以用相应的二维平面物体表示了,也就能在二维的电脑屏幕上正确显示了。

1.2 三维图形显示流程运用相机模拟的方式比较通俗地讲解了三维图形显示的基本过程,但在具体编程时,还必须了解三维图形世界中的几个特殊坐标系的概念,以及用这些概念表达的三维图形显示流程。

计算机本身只能处理数字,图形在计算机内也是以数字的形式进行加工和处理的。

大家都知道,坐标建立了图形和数字之间的联系。

为了使被显示的物体数字化,要在被显示的物体所在的空间中定义一个坐标系。

这个坐标系的长度单位和坐标轴的方向要适合对被显示物体的描述,这个坐标系称为世界坐标系。

计算机对数字化的显示物体作了加工处理后,要在图形显示器上显示,这就要在图形显示器屏幕上定义一个二维直角坐标系,这个坐标系称为屏幕坐标系。

这个坐标系坐标轴的方向通常取成平行于屏幕的边缘,坐标原点取在左下角,长度单位常取成一个象素的长度,大小可以是整型数。

计算机图形学实验报告-实验5Phong光照模型

计算机图形学实验报告-实验5Phong光照模型

计算机图形学实验报告班级计算机工硕班学号 **********姓名王泽晶实验五: Phong光照模型实验目的通过本次试验,学生可以掌握简单光照明模型的计算,以及真实感绘制中三维场景搭建的初步知识。

实验内容:对给定的光源、相机状态,对球进行Phong光照明模型绘制。

搭建三维场景:a)在三维空间中摆放1个球,半径为R,默认为50 ,摆放位置为(0,0,0)b)球的材质默认值为Ka = (0.1,0.1,0.1), Kd = (0,0,0.8), Ks = 0.2, n = 10c)视点方向初始为(0,0,1),光源方向初始为(1,1,1)d)视口设置为x0 = -100, y0 = -75, w = 200, h = 150使用phong模型绘制场景试验步骤:添加成员函数,编写成员数代码为override public function computeIntersection( viewStart:Vec3, viewDir:Vec3):Boolean {// See /geometry/sphereline/var viewEnd:Vec3 = viewStart.add(viewDir);var A:Number = Math.pow(viewEnd.getVec(0) - viewStart.getVec(0), 2)+Math.pow(viewEnd.getVec(1) - viewStart.getVec(1), 2) +Math.pow(viewEnd.getVec(2) - viewStart.getVec(2), 2);var B:Number =((viewEnd.getVec(0) - viewStart.getVec(0)) * (viewStart.getVec(0) - _position.getVec(0)) +(viewEnd.getVec(1) - viewStart.getVec(1)) * (viewStart.getVec(1) -_position.getVec(1)) +(viewEnd.getVec(2) - viewStart.getVec(2)) * (viewStart.getVec(2) -_position.getVec(2))) * 2.0;var C:Number = Math.pow(_position.getVec(0) - viewStart.getVec(0), 2) + Math.pow(_position.getVec(1) - viewStart.getVec(1), 2) +Math.pow(_position.getVec(2) - viewStart.getVec(2), 2) - _radius*_radius;// Solve C + Bt + At^2 = 0var delta:Number = B*B - 4*A*C;if ( delta<0.0 || A==0.0 ) return false;// We don't consider whether 0<t<1 here because real viewer is at infinite place var t1:Number = (-B + Math.sqrt(delta)) / (2*A);var t2:Number = (-B - Math.sqrt(delta)) / (2*A);if ( t1<t2 )point = viewStart.multiplyk(1.0 - t1).add(viewEnd.multiplyk(t1));elsepoint = viewStart.multiplyk(1.0 - t2).add(viewEnd.multiplyk(t2));normal = Vec3.normalize(point.minus(_position));return true;}public var _width :Number =0.0;public var _height:Number = 0.0;public var data:Array = new Array();protected function group1_creationCompleteHandler(event:FlexEvent):void{draw();}public function draw():void{graphics.clear();if(txtViewDir.text == "")return;var ary:Array = txtViewDir.text.split(",");var flag:Boolean = false;for(var i:int= 0;i<ary.length;i++){if(ary[i] == "" || isNaN(ary[i])){flag = true;break;}}if(flag)txtViewDir.setStyle("color",0xff0000);return;}txtViewDir.setStyle("color",0x000000);var viewDir:Vec3 = new Vec3(Number(ary[0]), Number(ary[1]), Number(ary[2]));ary = txtLight.text.split(",");flag = false;for(i= 0;i<ary.length;i++){if(ary[i] == "" || isNaN(ary[i])){flag = true;break;}}if(flag){txtLight.setStyle("color",0xff0000);return;}txtLight.setStyle("color",0x000000);var light:Light = new Light();light.direction = new Vec3(Number(ary[0]), Number(ary[1]),Number(ary[2])).negative();light.ambient = new Vec3(Number(ary[0]), Number(ary[1]), Number(ary[2]));light.intensity = new Vec3(Number(ary[0]), Number(ary[1]), Number(ary[2]));var material:Material = new Material();material.diffuse =new Vec3(0.0, 0.0, 0.8);material.specular =new Vec3(0.2, 0.2, 0.2);material.ambient =new Vec3(0.1, 0.1, 0.1);data = createSceneImage( 200, 150, viewDir, light, material );drawImg();}public function drawImg():void{for(var y:int = 0 ;y<150;y++)for(var x:int =0;x<200;x++){var index:int = (y*200 + x) * 3;var r:Number = data[index+0];var g:Number = data[index+1];var b:Number = data[index+2];var cl:uint =(r << 16) | (g << 8) | b;this.graphics.beginFill(cl)this.graphics.drawCircle(x,y,1);this.graphics.endFill();}}}public function allocateBuffer( width:int,height: int ):Array{var data:Array = new Array();data.length = width * height * 3;_width = width;_height = heightreturn data;}public function createSceneImage( width:int,height: int ,viewDir:Vec3, light:Light, material:Material ):Array{var data:Array = new Array();var sphere:SphereObject = new SphereObject(50.0);sphere.setPosition(new Vec3(0.0, 0.0, 0.0) );sphere.setMaterial( material );var halfW:int = width / 2var halfH:int = height / 2;for ( var y:int=0; y<height; ++y ){for ( var x:int=0; x<width; ++x ){var viewStart:Vec3 = new Vec3(Number(x - halfW), Number(y - halfH), 0.0);if ( puteIntersection(viewStart, viewDir) )sphere.color = puteColor(light, viewDir, sphere.normal);elsesphere.color = new Vec3(0.1, 0.1, 0.1);var index:int = (y*width + x) * 3;data[index+0] = (sphere.color.getVec(0) * 255.0);data[index+1] = (sphere.color.getVec(1) * 255.0);data[index+2] = (sphere.color.getVec(2) * 255.0);}}return data;}protected function button1_clickHandler(event:MouseEvent):void {// TODO Auto-generated method stubdraw();}编译运行得到如下结果:。

《计算机图形学》实验报告

《计算机图形学》实验报告

《计算机图形学》实验报告一、实验目的计算机图形学是一门研究如何利用计算机生成、处理和显示图形的学科。

通过本次实验,旨在深入理解计算机图形学的基本原理和算法,掌握图形的生成、变换、渲染等技术,并能够运用所学知识解决实际问题,提高对图形学的应用能力和编程实践能力。

二、实验环境本次实验使用的编程语言为 Python,使用的图形库为 Pygame。

开发环境为 PyCharm。

三、实验内容1、直线的生成算法DDA 算法(Digital Differential Analyzer)Bresenham 算法DDA 算法是通过计算直线的斜率来确定每个像素点的位置。

它的基本思想是根据直线的斜率和起始点的坐标,逐步计算出直线上的每个像素点的坐标。

Bresenham 算法则是一种基于误差的直线生成算法。

它通过比较误差值来决定下一个像素点的位置,从而减少了计算量,提高了效率。

在实验中,我们分别实现了这两种算法,并比较了它们的性能和效果。

2、圆的生成算法中点画圆算法中点画圆算法的核心思想是通过判断中点的位置来确定圆上的像素点。

通过不断迭代计算中点的位置,逐步生成整个圆。

在实现过程中,需要注意边界条件的处理和误差的计算。

3、图形的变换平移变换旋转变换缩放变换平移变换是将图形在平面上沿着指定的方向移动一定的距离。

旋转变换是围绕一个中心点将图形旋转一定的角度。

缩放变换则是改变图形的大小。

通过矩阵运算来实现这些变换,可以方便地对图形进行各种操作。

4、图形的填充种子填充算法扫描线填充算法种子填充算法是从指定的种子点开始,将相邻的具有相同颜色或属性的像素点填充为指定的颜色。

扫描线填充算法则是通过扫描图形的每一行,确定需要填充的区间,然后进行填充。

在实验中,我们对不同形状的图形进行了填充,并比较了两种算法的适用情况。

四、实验步骤1、直线生成算法的实现定义直线的起点和终点坐标。

根据所选的算法(DDA 或Bresenham)计算直线上的像素点坐标。

计算机图形学实验报告

计算机图形学实验报告

实验结果与结论
• 在本次实验中,我们成功地实现了复杂场景的渲染,得到了具有较高真实感和视觉效果的图像。通过对比 实验前后的效果,我们发现光线追踪和着色器的运用对于提高渲染质量和效率具有重要作用。同时,我们 也发现场景图的构建和渲染脚本的编写对于实现复杂场景的渲染至关重要。此次实验不仅提高了我们对计 算机图形学原理的理解和实践能力,也为我们后续深入研究渲染引擎的实现提供了宝贵经验。
2. 通过属性设置和变换操作,实现了对图形的定 制和调整,加深了对图形属性的理解。
4. 实验的不足之处:由于时间限制,实验只涉及 了基本图形的绘制和变换,未涉及更复杂的图形 处理算法和技术,如光照、纹理映射等。需要在 后续实验中进一步学习和探索。
02
实验二:实现动画效果
实验目的
掌握动画的基本原 理和实现方法
04
实验四:渲染复杂场景
实验目的
掌握渲染复杂场景的基本流程和方法 理解光线追踪和着色器在渲染过程中的作用
熟悉渲染引擎的实现原理和技巧 提高解决实际问题的能力
实验步骤
• 准备场景文件 • 使用3D建模软件(如Blender)创建或导入场景模型,导出为常用的3D格式(如.obj或.fbx)。 • 导入场景文件 • 在渲染引擎(如Unity或Unreal Engine)中导入准备好的场景文件。 • 构建场景图 • 根据场景的层次结构和光照需求,构建场景图(Scene Graph)。 • 设置光照和材质属性 • 为场景中的物体设置光照和材质属性(如漫反射、镜面反射、透明度等)。 • 编写渲染脚本 • 使用编程语言(如C或JavaScript)编写渲染脚本,控制场景中物体的渲染顺序和逻辑。 • 运行渲染程序 • 运行渲染程序,观察渲染结果。根据效果调整光照、材质和渲染逻辑。 • 导出渲染图像 • 将渲染结果导出为图像文件(如JPEG或PNG),进行后续分析和展示。

计算机形学的光照模型

计算机形学的光照模型

计算机形学的光照模型计算机形学是计算机图形学的一个重要分支,主要研究计算机生成和处理图像的方法和技术。

在计算机形学中,光照模型起着至关重要的作用。

光照模型是描述物体如何与光源相互作用的数学模型,它用于计算物体表面的光照效果,使得计算机生成的图像更加逼真和真实。

一、光照模型的基本原理光照模型通常包括三个主要组成部分:环境光、漫反射和镜面反射。

环境光是指自然光照射到物体表面后经过多次反射而产生的来自无特定方向的散射光,它对于整体的光照效果起到了一定的调整作用。

漫反射是指光线照射到物体表面后均匀地反射到各个方向,这种反射使物体呈现出柔和的光照效果。

镜面反射是指光线照射到物体表面后以等角反射的方式反射出去,形成明亮的高光点,使物体呈现出明亮的高光效果。

二、经典的光照模型1. Lambert光照模型Lambert光照模型是一种最基本的光照模型,它假设光线与物体表面成直角入射,并且光线均匀地散射到各个方向。

它的计算公式为:I = Ia * Ka + Ip * Kd * (L · N)其中,I表示最终的光照强度,Ia表示环境光的强度,Ka表示环境光的反射系数,Ip表示光源的强度,Kd表示物体的漫反射系数,L表示光线的方向向量,N表示物体表面的法向量。

2. Phong光照模型Phong光照模型是一种基于镜面反射的光照模型,它综合考虑了环境光、漫反射和镜面反射三个方面的光照效果。

它的计算公式为:I = Ia * Ka + Ip * Kd * (L · N) + Ip * Ks * ((R · V) ^ s)其中,Ks表示物体的镜面反射系数,R表示镜面反射方向向量,V表示观察者的视线方向向量,s表示镜面反射的强度指数。

三、实时光照模型传统的光照模型在计算效果上非常准确,但是计算量较大,难以在实时渲染中使用。

因此,为了满足实时渲染的需求,研究人员提出了一些实时光照模型。

常见的实时光照模型有:1. Gouraud光照模型Gouraud光照模型是一种基于顶点的实时光照模型,它通过给顶点设置颜色值来模拟光照效果。

计算机图形学实验报告

计算机图形学实验报告

计算机图形学实验报告引言计算机图形学是计算机科学中一个重要的研究领域,它涉及了计算机图像的生成、处理和显示等方面的技术。

本次实验旨在通过实际操作学习计算机图形学的相关知识,并利用图形学算法实现一些有趣的效果。

实验目的1. 了解计算机图形学的基本概念和发展历程;2. 掌握图形学中的基本几何变换,如平移、旋转和缩放等;3. 实现一些常见的图形学算法,如光照模型、三角形剪裁和绘制等。

实验准备在开始实验之前,我们需要准备一些实验所需的工具和环境。

首先,确保计算机上安装了图形学相关的软件,如OpenGL或DirectX等。

其次,为了编写和运行图形学程序,我们需要掌握基本的编程技巧,如C++或Python语言,并了解相关的图形库和API。

实验过程1. 实现平移、旋转和缩放首先,我们需要掌握图形学中的基本几何变换,如平移、旋转和缩放。

通过矩阵运算,我们可以很方便地实现这些变换。

例如,对于一个二维点P(x, y),我们可以通过以下公式实现平移:P' = T * P其中,P'是平移后的点,T是平移矩阵。

类似地,我们可以用旋转矩阵和缩放矩阵来实现旋转和缩放效果。

2. 实现光照模型光照模型是指在计算机图形学中模拟现实光照效果的一种方法。

它可以提供更真实的视觉效果,让计算机生成的图像更加逼真。

其中,常用的光照模型有环境光照、漫反射光照和镜面光照等。

通过计算每个像素的光照强度,我们可以实现阴影效果和光源反射等功能。

3. 实现三角形剪裁三角形剪裁是计算机图形学中一种常用的几何算法,用于确定哪些像素需要绘制,哪些像素需要剔除。

通过对三角形的边界和视口进行比较,我们可以快速计算出剪裁后的三角形顶点,以提高图形渲染的效率。

4. 实现图形绘制图形绘制是计算机图形学中的核心内容,它包括了点、线和面的绘制等。

通过设定顶点坐标和属性(如颜色、纹理等),我们可以使用算法绘制出各种形状的图像。

其中,常用的绘制算法有Bresenham算法和扫描线算法等。

球体Phong光照模型课程设计报告

球体Phong光照模型课程设计报告

计算机图形学课程设计课程设计球体Phong光照模型一、实验目的(1)掌握双线性法矢插值模型;(2)掌握ZBuffer算法的思想;(3)掌握有效边表填充算法;二、实验要求1、建立三维坐标系Oxyz,原点位于屏幕客户区中心,x轴水平向右为正,y轴垂直向上为正,z轴垂直于屏幕指向观察者。

2、绘制体心和坐标系中心重合的球体表面,使用Z-Buffer消隐算法进行消隐。

3、使用单点光源对球体进行照射生成Phong光照模型,光源位置位于球体右上方。

4、背景色设置为RGB(128,0,0)。

5、使用键盘方向键旋转球体。

6、使用鼠标左击缩小球体、右击增大球体。

三、实验步骤建立球体的网格模型,使用地理划分法将球体北极和南极划分为三角形面片,其余部分划分为四边形面片,先对球体网格模型进行背面剔除,然后使用深度缓冲算法进行消隐。

计算面片各顶点的平均法矢量,然后采用双线性法失插值计算面片内各点的法矢量。

最终根据每点的法矢量对光源的朝向,通过简单光照模型计算所获得的光强。

面片使用有效边表算法填1、Phong双线性法矢插值模型Gouraud双线性光强插值模型解决了相邻多边形之间的颜色突变问题,产生的真实感图形颜色过渡均匀,图形显得非常光滑,这是它的优点,但是,由于采用光强插值,其镜面反射光效果不太理想,而且相邻多边形边界处的马赫带效应并不能完全消除。

Phong 模型提出的双线性法矢插值模型可以有效的解决上述问题,产生正确的高光区域。

Phong 模型在进行光强插值的时候,需要先对面片的每一个顶点计算平均法矢量,然后通过双线性法矢插值计算面片内每个点的法矢量,最后根据简单光照模型计算面片上各点的颜色值。

基本算法如下。

(1)计算面片顶点的平均法矢量。

∑∑===ni ini iNN N 11由于球心位于三维坐标系原点,所以球面上任意面片的顶点平均法矢量就是该点的位置矢量。

(2)计算面片内部各点的法矢量。

在图中,三角形面片的顶点坐标为),(000y x P ,法矢量为0N ;),,(111y x P 法矢量是1N ;。

计算机图形学实验报告

计算机图形学实验报告

计算机图形学实验报告计算机图形学实验报告引言计算机图形学是研究计算机生成和处理图像的学科,它在现代科技和娱乐产业中扮演着重要的角色。

本实验报告旨在总结和分享我在计算机图形学实验中的经验和收获。

一、实验背景计算机图形学实验是计算机科学与技术专业的一门重要课程,通过实践操作和编程,学生可以深入了解图形学的基本原理和算法。

本次实验主要涉及三维图形的建模、渲染和动画。

二、实验内容1. 三维图形建模在实验中,我们学习了三维图形的表示和建模方法。

通过使用OpenGL或其他图形库,我们可以创建基本的几何体,如立方体、球体和圆柱体,并进行变换操作,如平移、旋转和缩放。

这些基本操作为后续的图形处理和渲染打下了基础。

2. 光照和着色光照和着色是图形学中重要的概念。

我们学习了不同的光照模型,如环境光、漫反射和镜面反射,并了解了如何在三维场景中模拟光照效果。

通过设置材质属性和光源参数,我们可以实现逼真的光照效果,使物体看起来更加真实。

3. 纹理映射纹理映射是一种将二维图像映射到三维物体表面的技术。

通过将纹理图像与物体的顶点坐标相对应,我们可以实现更加细致的渲染效果。

在实验中,我们学习了纹理坐标的计算和纹理映射的应用,使物体表面呈现出具有纹理和细节的效果。

4. 动画和交互动画和交互是计算机图形学的重要应用领域。

在实验中,我们学习了基本的动画原理和算法,如关键帧动画和插值技术。

通过设置动画参数和交互控制,我们可以实现物体的平滑移动和变形效果,提升用户体验。

三、实验过程在实验过程中,我们首先熟悉了图形库的使用和基本的编程技巧。

然后,我们按照实验指导书的要求,逐步完成了三维图形建模、光照和着色、纹理映射以及动画和交互等任务。

在实验过程中,我们遇到了许多挑战和问题,但通过不断的尝试和调试,最终成功实现了预期的效果。

四、实验结果通过实验,我们成功实现了三维图形的建模、渲染和动画效果。

我们可以通过键盘和鼠标控制物体的移动和变形,同时观察到真实的光照效果和纹理映射效果。

了解计算机图形学中的光照模型与渲染算法

了解计算机图形学中的光照模型与渲染算法

了解计算机图形学中的光照模型与渲染算法计算机图形学是研究计算机图形及其渲染技术的学科,其中光照模型与渲染算法是实现真实感图形渲染的关键。

本文将介绍光照模型与渲染算法的基本概念,以及常见的光照模型和渲染算法。

一、光照模型光照模型是计算机图形学中用于模拟光线的传播和反射过程的数学模型。

它描述了光照对物体表面的影响,从而确定了物体表面的明暗、反射特性和颜色。

1. 环境光照环境光照是场景中无方向性的散射光,它均匀地照亮物体的所有部分。

它是全局光照的一部分,不受物体表面法线和材质属性的影响。

常用的环境光照模型有恒定环境光照模型和环境光照颜色模型。

2. 漫反射光照漫反射光照是指光线照射到物体表面后,按照光线方向和物体表面法线之间的夹角决定反射的光强。

漫反射光照模型考虑了物体的表面法线、光线方向和光线颜色等因素,常用的漫反射光照模型有Lambert光照模型和Blinn-Phong光照模型。

3. 高光反射光照高光反射光照是指光线照射到物体表面后,根据光线方向、表面法线和视线方向的夹角计算的反射光强。

它主要用于模拟物体的镜面反射,使物体表面产生亮点或高光。

常用的高光反射光照模型有Phong光照模型和Blinn-Phong光照模型。

二、渲染算法渲染算法是将三维场景转化为二维图像的过程,在光照模型的基础上计算物体表面的颜色,并在屏幕上绘制出最终的图像。

常见的渲染算法有光线追踪算法和光栅化算法。

1. 光线追踪算法光线追踪算法通过模拟光线从观察者发射、经过场景中的物体反射、折射和散射等过程,最终计算每个像素点的颜色值。

它可以实现逼真的光照效果,但计算复杂度较高。

常见的光线追踪算法有Whitted光线追踪算法、路径追踪算法和辐射度估计算法等。

2. 光栅化算法光栅化算法是将场景中的三维物体转化为屏幕上的二维像素的算法。

它通过将三维物体投影到屏幕平面,并根据光照模型和材质属性计算每个像素点的颜色值。

常见的光栅化算法有扫描线光栅化算法和三角形光栅化算法等。

phong光照模型公式

phong光照模型公式

phong光照模型公式Phong光照模型公式介绍•光照模型是计算计算机图形学中的重要概念之一,它描述了光照在物体表面的作用。

•Phong光照模型是计算机图形学中最常用的光照模型之一,由Bui Tuong Phong提出。

•本文将详细介绍Phong光照模型的公式及其各个组成部分。

Phong光照模型公式Phong光照模型可以分为三个独立的部分:环境光照、漫反射光照和镜面光照。

它们的组合就是物体的最终光照效果。

环境光照•环境光照是来自周围环境的无方向光,对物体的作用均匀而全局。

•环境光照的计算公式为:Ia = ka * La•其中,Ia是环境光照的强度,ka是环境光照系数,La是环境光颜色。

漫反射光照•漫反射光照是来自光源的有方向光,对物体表面的不同区域有不同的作用。

•漫反射光照的计算公式为:Id = kd * Ld * max(0, N · L)•其中,Id是漫反射光照的强度,kd是漫反射系数,Ld是光源颜色,N是物体表面法向量,L是光源方向向量。

镜面光照•镜面光照是来自光源的有方向光,对物体表面的特定区域产生高光效果。

•镜面光照的计算公式为:Is = ks * Ls * max(0, R · V)^s •其中,Is是镜面光照的强度,ks是镜面反射系数,Ls是光源颜色,R是光的反射方向向量,V是视线方向向量,s是镜面光照的反射指数。

光照模型的应用•Phong光照模型通常用于计算机图形学中的渲染算法,用于模拟真实世界中的光照效果。

•光照模型的计算可以应用于三维模型的表面上,使其在渲染过程中呈现出真实感和立体感。

总结•Phong光照模型通过组合环境光照、漫反射光照和镜面光照三个部分,可以模拟真实世界中的光照效果。

•光照模型在计算机图形学中有着广泛的应用,能够提升渲染效果和真实感。

•了解Phong光照模型的公式及其组成部分,对于研究和应用计算机图形学具有重要意义。

以上是对Phong光照模型公式的介绍和解析。

Phong光照模型

Phong光照模型

Phong光照模型简介在3D计算机图形学中,Phong着⾊是计算机图形学先驱Bui Tuong Phong发明的⼀种⽤于表⾯着⾊的插值技术。

也称为Phong插值或法向⽮量插值阴影。

它会在栅格化的多边形上内插表⾯法线,并根据内插法线和反射模型计算像素颜⾊。

Phong阴影也可以指Phong插值和Phong反射模型的特定组合。

主要过程:计算多边形顶点的法向量双线性插值计算每个像素点的法向量通过每个像素的法向量计算光强根据光强绘制像素历史:在1975年,由Phong提出,以他的名字冠名,是⼀种局部光照的模型。

Phong着⾊法与Gouraud着⾊法⽐较Phong着⾊法与Gouraud着⾊法类似,区别在于进⾏双线性插值的不是光照强度本⾝,⽽是顶点的法线。

因此使⽤这种着⾊法计算出的⾼光⽐Gouraud着⾊更精确。

Phong着⾊法与Gouraud著⾊法⽐较,Phong著⾊法的效果更逼真,能够提供更好的光滑曲⾯的近似值。

Phong著⾊法假设⼀个平滑变化的曲⾯为⼀⽮量。

在对于有较⼩的⾼光曲线区的反射模型,例如Phong模型时,Phong著⾊法⽐Gouraud著⾊法更优。

但运算程序也⽐前者为复杂。

Gouraud著⾊法在遇到在较⼤的多边形模型中央有⾼光曲线区时会产⽣严重的问题。

因为这些⾼光曲线区在多边形的顶点处会产⽣缺失⽽Gouraud著⾊法是基于顶点的颜⾊的,这些⾼光曲线区会从多边形的内部缺失。

这个问题在Phong著⾊法中得到了解决。

不同于通过多边形差值的Gouraud著⾊法,Phong著⾊法中⼀个⽮量是从多边形顶点的法线到多边形表⾯进⾏差值的。

为了或得到最后的像素颜⾊,⾯的法线被差值,应⽤于⼀个反射模型。

由于Phong著⾊法需要逐像素点进⾏计算,因此运算量远⼤于Gouraud著⾊法。

Phong光照模型是真实图形学中提出的第⼀个有影响的光照明模型,该模型只考虑物体对直接光照的反射作⽤,认为环境光是常量,没有考虑物体之间相互的反射光,物体间的反射光只⽤环境光表⽰。

phong模型公式

phong模型公式

phong模型公式Phong模型公式导言Phong模型公式是计算机图形学中一种重要的光照模型,用于模拟真实世界中的光照效果。

本文将介绍Phong模型公式的原理、应用以及一些注意事项。

Phong模型公式的原理Phong模型公式由Bui-Tuong Phong于1973年提出,它分为三个主要的部分:环境光反射、漫反射和镜面反射。

通过计算三者的叠加效果,可以得到物体表面的光照强度。

环境光反射环境光反射是指光源照射到物体表面后被散射到周围环境中的光线。

它与物体表面的材质属性无关,通常可视为均匀的柔和光照。

环境光反射的计算公式为:I_a = k_a * I其中,I_a为环境光强度,k_a为环境光系数,I为光源强度。

漫反射是指当光线照射到物体表面时,被物体材质粗糙度所散射的光线。

漫反射的强度取决于入射光线的角度和物体表面的法向量。

漫反射的计算公式为:I_d = k_d * I * (L · N)其中,I_d为漫反射强度,k_d为漫反射系数,I为光源强度,L 为光线方向向量,N为法向量。

镜面反射镜面反射是指光线照射到物体表面时,在光线方向上镜面反射的现象。

镜面反射主要与物体表面的镜面反射特性相关,如光线的反射方向和视角。

镜面反射的强度取决于视角、反射方向和光源的位置。

镜面反射的计算公式为:I_s = k_s * I * (R · V)^n其中,I_s为镜面反射强度,k_s为镜面反射系数,I为光源强度,R为反射方向向量,V为视角方向向量,n为反射系数。

Phong模型公式的应用Phong模型公式广泛应用于三维计算机图形学中的渲染引擎,用于计算物体表面的光照效果。

通过调整环境光系数、漫反射系数和镜面反射系数等参数,可以获得不同材质和光照条件下的逼真图像。

在使用Phong模型公式时,需要注意以下几个问题:•光源位置的选择对光照效果有重要影响,应根据实际场景进行调整。

•光照计算是基于像素级别的,因此需要进行光照插值以获得平滑的效果。

计算机图形学中的光照模型与材质渲染算法实现

计算机图形学中的光照模型与材质渲染算法实现

计算机图形学中的光照模型与材质渲染算法实现导言:计算机图形学是研究如何使用计算机生成、处理和呈现图像的学科。

在计算机图形学中,一个重要的问题是如何实现真实感的图像渲染。

光照模型和材质渲染算法是实现真实感图像的关键。

本文将介绍光照模型和材质渲染算法的基本概念和实现方法。

一、光照模型光照模型用于模拟光照在物体表面的影响,通过模拟光照效果,使渲染出的图像更加逼真。

常用的光照模型有冯氏光照模型、Lambertian光照模型和Blinn-Phong光照模型等。

1.冯氏光照模型冯氏光照模型是最早提出的光照模型之一,它将光照效果分为三个部分:环境光、漫反射光和镜面光。

环境光是由周围环境中的间接光照射到物体表面而产生的,它对物体的光照效果起到整体性的作用。

漫反射光是指物体表面吸收了光能量后,在不同方向上均匀地散射出去的光能,它决定了物体表面的亮度。

镜面光是指物体表面光能量经过反射后聚焦到一定方向上的光能,它决定了物体表面的高光效果。

2. Lambertian光照模型Lambertian光照模型是一种简化的光照模型,它只考虑物体的漫反射光。

根据兰伯特定律,漫反射光的亮度与光源和物体表面法线的夹角成正比。

3. Blinn-Phong光照模型Blinn-Phong光照模型是一种介于冯氏光照模型和Lambertian光照模型之间的模型。

它在计算镜面光时使用了一种近似的方法,使计算更加高效。

二、材质渲染算法材质渲染算法用于将光照模型应用到物体表面的材质上,从而实现真实感的渲染效果。

常用的材质渲染算法有平均法向量法、纹理映射法和高光纹理法等。

1.平均法向量法平均法向量法是一种常用的材质渲染算法。

它通过对网格模型上的顶点法向量进行插值计算,获得表面上每个点的法向量。

然后再使用光照模型计算光照效果。

2.纹理映射法纹理映射法是一种常用的材质渲染算法。

它将一个二维图像(纹理)映射到物体表面上,在渲染过程中,根据纹理映射的坐标值,获取纹理上对应点的颜色值,再结合光照模型计算光照效果。

计算机图形学实验Phong模型

计算机图形学实验Phong模型

实验七10-11一、实验题目将公式(10-38)的国际象棋棋盘纹理函数映射到球面上,绘制图10-80所示的动态旋转单光源光照纹理球面,明暗处理要求使用Phong模型。

二、实验思想先计算多边形网格的每个顶点的平均法矢量,然后使用双线性插值计算多边形内部各点的法矢量。

最后才使用多边形网格上各点的法矢量调用简单光照模型计算其所获得的光强。

Phong明暗处理的实现步骤如下:⑴计算多边形顶点的平均法矢量。

⑵线性插值计算多边形内部各点的法矢量。

双线性法矢插值的计算公式与光强插值的类似,只是将其中的光强项用法矢项代替。

⑶对多边形内的每一点使用法矢量调用简单光照模型计算光强,然后再将光强分解为该点的RGB颜色。

三、实验代码void CZBuffer::SetPoint(CPi3 *p,CVector *vn,double *u1,double *v1,int m){P=new CPi3[m];u=new double[m];v=new double[m];VN=new CVector[m];for(int i=0;i<m;i++){P[i]=p[i];u[i]=u1[i];v[i]=v1[i];VN[i]=vn[i];}PNum=m;}void CZBuffer::CreateBucket()//创建桶表{int yMin,yMax;yMin=yMax=P[0].y;for(int i=0;i<PNum;i++)//查找多边形所覆盖的最小和最大扫描线{if(P[i].y<yMin){yMin=P[i].y;//扫描线的最小值}if(P[i].y>yMax){yMax=P[i].y;//扫描线的最大值}}for(int y=yMin;y<=yMax;y++){if(yMin==y)//建立桶头结点{HeadB=new CBucket;//建立桶的头结点CurrentB=HeadB;//CurrentB为CBucket当前结点指针CurrentB->ScanLine=yMin;CurrentB->pET=NULL;//没有连接边链表CurrentB->next=NULL;}else//建立桶的其它结点{CurrentB->next=new CBucket;CurrentB=CurrentB->next;CurrentB->ScanLine=y;CurrentB->pET=NULL;CurrentB->next=NULL;}}}void CZBuffer::CreateEdge()//创建边表{for(int i=0;i<PNum;i++){CurrentB=HeadB;int j=(i+1)%PNum;//边的第二个顶点,P[i]和P[j]构成边if(P[i].y<P[j].y)//边的终点比起点高{Edge=new CAET;Edge->x=P[i].x;//计算ET表的值Edge->yMax=P[j].y;Edge->k=(P[j].x-P[i].x)/(P[j].y-P[i].y);//代表1/kEdge->pb=P[i];//绑定顶点和颜色Edge->pe=P[j];Edge->ub=u[i];Edge->ue=u[j];Edge->vb=v[i];Edge->ve=v[j];Edge->vNb=VN[i];//绑定顶点法矢量Edge->vNe=VN[j];Edge->next=NULL;while(CurrentB->ScanLine!=P[i].y)//在桶内寻找该边的yMin{CurrentB=CurrentB->next;//移到yMin所在的桶结点}}if(P[j].y<P[i].y)//边的终点比起点低{Edge=new CAET;Edge->x=P[j].x;Edge->yMax=P[i].y;Edge->k=(P[i].x-P[j].x)/(P[i].y-P[j].y);Edge->pb=P[i];Edge->pe=P[j];Edge->ub=u[i];Edge->ue=u[j];Edge->vb=v[i];Edge->ve=v[j];Edge->vNb=VN[i];//绑定顶点法矢量Edge->vNe=VN[j];Edge->next=NULL;while(CurrentB->ScanLine!=P[j].y){CurrentB=CurrentB->next;}}if(P[j].y!=P[i].y){CurrentE=CurrentB->pET;if(CurrentE==NULL){CurrentE=Edge;CurrentB->pET=CurrentE;}else{while(CurrentE->next!=NULL){CurrentE=CurrentE->next;}CurrentE->next=Edge;}}}}void CZBuffer::Fill(CDC *pDC,CP3 ViewPoint,CLighting *pLight,CMaterial *pMaterial)//填充面片{double z=0.0;//当前扫描线的zdouble zStep=0.0;//当前扫描线随着x增长的z步长double A,B,C,D;//平面方程Ax+By+Cz+D=0的系数CVector V21(P[1],P[2]),V10(P[0],P[1]);CVector VN=V21*V10;A=VN.X();B=VN.Y();C=VN.Z();D=-A*P[1].x-B*P[1].y-C*P[1].z;//计算curDeep;从x=xMin开始计算,此时针对yizStep=-A/C;//计算直线z增量CAET *T1,*T2;HeadE=NULL;for(CurrentB=HeadB;CurrentB!=NULL;CurrentB=CurrentB->next){for(CurrentE=CurrentB->pET;CurrentE!=NULL;CurrentE=CurrentE->next) {Edge=new CAET;Edge->x=CurrentE->x;Edge->yMax=CurrentE->yMax;Edge->k=CurrentE->k;Edge->pb=CurrentE->pb;Edge->pe=CurrentE->pe;Edge->ub=CurrentE->ub;Edge->ue=CurrentE->ue;Edge->vb=CurrentE->vb;Edge->ve=CurrentE->ve;Edge->vNb=CurrentE->vNb;Edge->vNe=CurrentE->vNe;Edge->next=NULL;AddEt(Edge);}EtOrder();T1=HeadE;if(T1==NULL){return;}while(CurrentB->ScanLine>=T1->yMax)//下闭上开{T1=T1->next;HeadE=T1;if(HeadE==NULL)return;}if(T1->next!=NULL){T2=T1;T1=T2->next;}while(T1!=NULL){if(CurrentB->ScanLine>=T1->yMax)//下闭上开{T2->next=T1->next;T1=T2->next;}else{T2=T1;T1=T2->next;}}double ua,ub,uf,va,vb,vf;//ua和ub,va和vb代边上任意点的纹理,uf和vf代表面上任意点的纹理ua=Interpolation(CurrentB->ScanLine,HeadE->pb.y,HeadE->pe.y,HeadE->ub,HeadE->ue);ub=Interpolation(CurrentB->ScanLine,HeadE->next->pb.y,HeadE->next->pe.y,HeadE->next-> ub,HeadE->next->ue);va=Interpolation(CurrentB->ScanLine,HeadE->pb.y,HeadE->pe.y,HeadE->vb,HeadE->ve);vb=Interpolation(CurrentB->ScanLine,HeadE->next->pb.y,HeadE->next->pe.y,HeadE->next->v b,HeadE->next->ve);CVector na,nb,nf;//na和nb代表边上任意点的法矢量,nf代表面上任意点的法矢量na=Interpolation(CurrentB->ScanLine,HeadE->pb.y,HeadE->pe.y,HeadE->vNb,HeadE->vNe);nb=Interpolation(CurrentB->ScanLine,HeadE->next->pb.y,HeadE->next->pe.y,HeadE->next-> vNb,HeadE->next->vNe);BOOL Flag=FALSE;double xb,xe;//扫描线的起点和终点坐标for(T1=HeadE;T1!=NULL;T1=T1->next){if(Flag==FALSE){xb=T1->x;z=-(xb*A+CurrentB->ScanLine*B+D)/C;//z=-(Ax+By-D)/CFlag=TRUE;}else{xe=T1->x;for(double x=xb;x<xe;x++)//左闭右开{uf=((Interpolation(x,xb,xe,ua,ub)>1)?1:(Interpolation(x,xb,xe,ua,ub)));vf=((Interpolation(x,xb,xe,va,vb)>1)?1:(Interpolation(x,xb,xe,va,vb)));nf=Interpolation(x,xb,xe,na,nb);CRGB Textureclr=GetTextureColor(uf,vf);pMaterial->SetDiffuse(Textureclr);//用纹理的颜色值作为材质对漫反射光和环境光的反射率pMaterial->SetAmbient(Textureclr);CRGBColor=pLight->Lighting(ViewPoint,CP3(ROUND(x),CurrentB->ScanLine,z),nf,pMaterial);CP3 Point(x,CurrentB->ScanLine,z);COLORREF Pointc=RGB(Color.red*255,Color.green*255,Color.blue*255);pDC->SetPixel(ROUND(Point.x),ROUND(Point.y),Pointc);z+=zStep;}Flag=FALSE;}}for(T1=HeadE;T1!=NULL;T1=T1->next)//边的连续性{T1->x=T1->x+T1->k;}}delete HeadB;delete HeadE;delete CurrentE;delete CurrentB;delete Edge;}void CZBuffer::AddEt(CAET *NewEdge)//合并ET表{CAET *CE;CE=HeadE;if(CE==NULL){HeadE=NewEdge;CE=HeadE;}else{while(CE->next!=NULL){CE=CE->next;}CE->next=NewEdge;}}void CZBuffer::EtOrder()//边表的冒泡排序算法{CAET *T1,*T2;int Count=1;T1=HeadE;if(T1==NULL){return;}if(T1->next==NULL)//如果该ET表没有再连ET表{return;//桶结点只有一条边,不需要排序}while(T1->next!=NULL)//统计结点的个数{Count++;T1=T1->next;}for(int i=1;i<Count;i++)//冒泡排序{T1=HeadE;if(T1->x>T1->next->x)//按x由小到大排序{T2=T1->next;T1->next=T1->next->next;T2->next=T1;HeadE=T2;}else{if(T1->x==T1->next->x){if(T1->k>T1->next->k)//按斜率由小到大排序{T2=T1->next;T1->next=T1->next->next;T2->next=T1;HeadE=T2;}}}T1=HeadE;while(T1->next->next!=NULL){T2=T1;T1=T1->next;if(T1->x>T1->next->x)//按x由小到大排序{T2->next=T1->next;T1->next=T1->next->next;T2->next->next=T1;T1=T2->next;}else{if(T1->x==T1->next->x){if(T1->k>T1->next->k)//按斜率由小到大排序{T2->next=T1->next;T1->next=T1->next->next;T2->next->next=T1;T1=T2->next;}}}}}}double CZBuffer::Interpolation(double t,double t1,double t2,double n1,double n2)//双线性插值{double n;n=n1*(t-t2)/(t1-t2)+n2*(t-t1)/(t2-t1);return n;}CVector CZBuffer::Interpolation(double t,double t1,double t2,CVector v1,CVector v2)//矢量线性插值{CVector v;v=v1*(t-t2)/(t1-t2)+v2*(t-t1)/(t2-t1);return v;}CRGB CZBuffer::GetTextureColor(double u,double v)//获得纹理颜色{if((int(floor(u*16.0))+int(floor(v*8.0)))%2==0)return CRGB(0.1,0.1,0.1);elsereturn CRGB(0.9,0.9,0.9);}四、实验结果截图。

实验:Phong模型(详细)

实验:Phong模型(详细)

计算机图形学课程实验:Phong模型目录1 Phong模型 (1)1.1 光源设置 (1)2 光照计算 (3)2.1 定向光 (3)2.2 点光源 (4)2.3 聚光 (4)1 Phong模型接下来,我们来介绍一下Phong模型。

绘制效果如下,我们可以看到,中间的立方体是被照射的对象,有一个定向光源,六个点光源和一个聚光的光源。

图1 效果图我们的程序流程主体还是跟前面的课程相同。

因此我们这节的重点部分就是主要在这两个方面,一个是光源的设置,一个是光照计算。

1.1 光源设置首先是光源的设置,我们这里的光源种类主要有三种,定向光,点光源和聚光,三种光源的效果叠加形成了我们刚才看到的效果。

那么我们在代码中是如何实现的呢?首先我们来看定向光,定向光就是类似太阳这种,它的属性包括定向光的方向,以及环境光,漫反射光,镜面反射光的强度参数。

由于定向光是光源处于无限远处的平行光,因此我们无需指定出定向光光源具体的位置,只需指定其指向的方向即可。

接下来是点光源,我们定义了六个点光源,点光源就是类似灯泡这种,每一个点光源的属性都包括点光源的位置,环境光,漫反射光,和镜面反射光的1强度参数,这里每一个分量都要乘一个点光源的颜色。

那么除此之外点光源与定向光有哪些不同呢?它与定向光不同的是它多了三个属性参数,这三个参数是用来计算衰减公式的三个系数,分别是constant常数项,linear一次项和quadratic二次项,它会使得光线强度随距离的增加不断减小并且衰减的幅度也逐渐减小,这样更接近现实生活中点光源的效果。

我们的第三种光源是聚光,聚光就是类似手电筒的这种效果,聚光的属性也包括聚光光源的位置,方向,这里我们是用摄像机的位置和朝向来指定的,还有环境光,漫反射光,和镜面反射光的强度参数以及三个衰减系数,那么除此之外聚光光源与点光源又有哪些不同呢?这里我们又多了两个参数分别表示我们聚光内外圆锥的内外切光角。

聚光的效果就相当于是一个圆锥的光效,我们这里通过使用两个圆锥来使我们的聚光效果看起来更加平滑。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

计算机图形学实验报告班级计算机工硕班学号 **********姓名王泽晶实验五: Phong光照模型实验目的通过本次试验,学生可以掌握简单光照明模型的计算,以及真实感绘制中三维场景搭建的初步知识。

实验内容:对给定的光源、相机状态,对球进行Phong光照明模型绘制。

搭建三维场景:a)在三维空间中摆放1个球,半径为R,默认为50 ,摆放位置为(0,0,0)b)球的材质默认值为Ka = (0.1,0.1,0.1), Kd = (0,0,0.8), Ks = 0.2, n = 10c)视点方向初始为(0,0,1),光源方向初始为(1,1,1)d)视口设置为x0 = -100, y0 = -75, w = 200, h = 150使用phong模型绘制场景试验步骤:添加成员函数,编写成员数代码为override public function computeIntersection( viewStart:Vec3, viewDir:Vec3):Boolean {// See /geometry/sphereline/var viewEnd:Vec3 = viewStart.add(viewDir);var A:Number = Math.pow(viewEnd.getVec(0) - viewStart.getVec(0), 2)+Math.pow(viewEnd.getVec(1) - viewStart.getVec(1), 2) +Math.pow(viewEnd.getVec(2) - viewStart.getVec(2), 2);var B:Number =((viewEnd.getVec(0) - viewStart.getVec(0)) * (viewStart.getVec(0) - _position.getVec(0)) +(viewEnd.getVec(1) - viewStart.getVec(1)) * (viewStart.getVec(1) -_position.getVec(1)) +(viewEnd.getVec(2) - viewStart.getVec(2)) * (viewStart.getVec(2) -_position.getVec(2))) * 2.0;var C:Number = Math.pow(_position.getVec(0) - viewStart.getVec(0), 2) + Math.pow(_position.getVec(1) - viewStart.getVec(1), 2) +Math.pow(_position.getVec(2) - viewStart.getVec(2), 2) - _radius*_radius;// Solve C + Bt + At^2 = 0var delta:Number = B*B - 4*A*C;if ( delta<0.0 || A==0.0 ) return false;// We don't consider whether 0<t<1 here because real viewer is at infinite place var t1:Number = (-B + Math.sqrt(delta)) / (2*A);var t2:Number = (-B - Math.sqrt(delta)) / (2*A);if ( t1<t2 )point = viewStart.multiplyk(1.0 - t1).add(viewEnd.multiplyk(t1));elsepoint = viewStart.multiplyk(1.0 - t2).add(viewEnd.multiplyk(t2));normal = Vec3.normalize(point.minus(_position));return true;}public var _width :Number =0.0;public var _height:Number = 0.0;public var data:Array = new Array();protected function group1_creationCompleteHandler(event:FlexEvent):void{draw();}public function draw():void{graphics.clear();if(txtViewDir.text == "")return;var ary:Array = txtViewDir.text.split(",");var flag:Boolean = false;for(var i:int= 0;i<ary.length;i++){if(ary[i] == "" || isNaN(ary[i])){flag = true;break;}}if(flag)txtViewDir.setStyle("color",0xff0000);return;}txtViewDir.setStyle("color",0x000000);var viewDir:Vec3 = new Vec3(Number(ary[0]), Number(ary[1]), Number(ary[2]));ary = txtLight.text.split(",");flag = false;for(i= 0;i<ary.length;i++){if(ary[i] == "" || isNaN(ary[i])){flag = true;break;}}if(flag){txtLight.setStyle("color",0xff0000);return;}txtLight.setStyle("color",0x000000);var light:Light = new Light();light.direction = new Vec3(Number(ary[0]), Number(ary[1]),Number(ary[2])).negative();light.ambient = new Vec3(Number(ary[0]), Number(ary[1]), Number(ary[2]));light.intensity = new Vec3(Number(ary[0]), Number(ary[1]), Number(ary[2]));var material:Material = new Material();material.diffuse =new Vec3(0.0, 0.0, 0.8);material.specular =new Vec3(0.2, 0.2, 0.2);material.ambient =new Vec3(0.1, 0.1, 0.1);data = createSceneImage( 200, 150, viewDir, light, material );drawImg();}public function drawImg():void{for(var y:int = 0 ;y<150;y++)for(var x:int =0;x<200;x++){var index:int = (y*200 + x) * 3;var r:Number = data[index+0];var g:Number = data[index+1];var b:Number = data[index+2];var cl:uint =(r << 16) | (g << 8) | b;this.graphics.beginFill(cl)this.graphics.drawCircle(x,y,1);this.graphics.endFill();}}}public function allocateBuffer( width:int,height: int ):Array{var data:Array = new Array();data.length = width * height * 3;_width = width;_height = heightreturn data;}public function createSceneImage( width:int,height: int ,viewDir:Vec3, light:Light, material:Material ):Array{var data:Array = new Array();var sphere:SphereObject = new SphereObject(50.0);sphere.setPosition(new Vec3(0.0, 0.0, 0.0) );sphere.setMaterial( material );var halfW:int = width / 2var halfH:int = height / 2;for ( var y:int=0; y<height; ++y ){for ( var x:int=0; x<width; ++x ){var viewStart:Vec3 = new Vec3(Number(x - halfW), Number(y - halfH), 0.0);if ( puteIntersection(viewStart, viewDir) )sphere.color = puteColor(light, viewDir, sphere.normal);elsesphere.color = new Vec3(0.1, 0.1, 0.1);var index:int = (y*width + x) * 3;data[index+0] = (sphere.color.getVec(0) * 255.0);data[index+1] = (sphere.color.getVec(1) * 255.0);data[index+2] = (sphere.color.getVec(2) * 255.0);}}return data;}protected function button1_clickHandler(event:MouseEvent):void {// TODO Auto-generated method stubdraw();}编译运行得到如下结果:。

相关文档
最新文档