[6.837]A3:OpenG应用和Phong着色模型
任务概述
本次作业中,我们将向场景中添加实时交互预览,同时为之前的光线追踪器增加Phong着色模型。为了达到交互显示,我们将使用OpenGLAPI在显卡上快速渲染三维多边形。我们将能够实时预览场景并且改变视点,接下来用光线追踪器来渲染高质量的图像。许多基础结构在之前的作业中已经构建好,我们只需要向API传递正确的三角形绘制指令或者绘制各种Object3D类的图元。在OpenGL中,API接受所有的透视投影和几何变换,并且将多边形光栅化,并且为每个多边形绘制正确的像素点。除此之外,我们的架构提供了用户界面和鼠标控制摄像机。
实现细节
1.为光线追踪器添加一个可视化预览窗口,使用glCanvas类。在主程序中创建一个实例,调用如下函数初始化:
void glCanvas::initialize(SceneParser *_scene, void (*_renderFunction)(void));
初始化程序输入两个参数,第一个是全局场景指针,第二个是执行光线追踪的函数。glCanvas类建立的目的是使绘制函数没有参数输入并且返回void。从实时界面中,我们可以通过按下键盘r键进行绘制。一旦初始化程序调用,glCanvas将会控制整个应用程序并且监听所有的键盘鼠标消息。通过按下键盘q退出。
2.修改Camera类来控制交互摄像机。
3.绘制三角形的方法
4.绘制平面的方法
OpenGL中并不能存储一个无限延展的平面,由于长度限制,数字最多不能超过10610^6。因此对于平面的绘制,我们将其当作一个很大的长方形,长方形的边长可以任意大,只要不超过表达长度限制即可。计算长方形顶点的方法如下:
平面方程为:Ax+By+Cz+D=0Ax+By+Cz+D=0,法向量N⃗ =(A,B,C)\vec{N}=(A,B,C),由于空间中只有这个平面上的向量垂直于法向量,因此我们可以任取空间中一个向量V⃗ \vec{V},计算其与法向量的叉乘得到向量b1→=V⃗ N⃗ \vec{b1}=\vec{V}\vec{N},再将b1叉乘N得到b2,这样b1b2作为平面上的一组正交基,即可表示平面上的所有点。方便起见,取V⃗ =(1,0,0)\vec{V}=(1,0,0),如果VN平行,则取V=(0,1,0)。
5.绘制球的方法
在之前的光线追踪算法中,球被表达为一个隐式方程x2+y2+z2=R2x^2+y^2+z^2=R^2,而在OpenGL绘制管线中,所有的集合元素都被表达为顶点、法线的组合。这里使用了tessellation细分曲面方法,将球细分为多边形。在程序命令行中,我们通过参数-tessellation <thetastep phistep>
来控制球在水平和垂直两个维度的细分程度。其中θ,ϕ\theta,\phi是球面坐标中的角度。
6.球的着色方法
通过细分,我们已经把球转化为了多边形。其中顶点法线的计算决定了不同的着色方法。FlatShading表示将每个四边形的顶点法向都设定为该四边形的法向,结果如下:
7.specular lobe fix 高光边界修补
在OpenGL固定渲染管线中,Phong局部光照模型可以通过以下代码定义:
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);//漫反射glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, diffuse);//环境光glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);//镜面反射光glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &glexponent);//镜面反射指数
样例渲染结果如下:
我们会发现当高光系数n趋向于0的时候,高光部分与背光部分之间有一道明显的分界线。根据Blinn- Phong镜面反射公式:Cspecular=ks∗(H⋅N)n∗LC_{specular}=k_s*(H·N)^n*L,我们发现小的高光系数会使(H⋅N)n(H·N)^n一项趋近为1,问题在边界部分尤为明显,因为光接近于平行入射,人眼可见的反光度事实上非常小。为了解决这个问题,提出了高光边界修补方法,具体方案是将镜面反射项再乘以N⋅LN·L,这样就可以达到边界部分到高光部分的平滑过渡。在OpenGL中,通过三次传递完成这一修补过程,具体代码为:
if (SPECULAR_FIX_WHICH_PASS == 0) {// First pass, draw only the specular highlightsglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, zero);glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &glexponent);}else if (SPECULAR_FIX_WHICH_PASS == 1) {// Second pass, compute normal dot light glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, one);glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, zero);glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);}else {// Third pass, add ambient & diffuse termsassert(SPECULAR_FIX_WHICH_PASS == 2);glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, diffuse);glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);}
三次pass对应的效果为:
在我们自己的光线追踪器中,也将镜面反射一项乘以法线与光源的点乘,注意最终求得的结果Clamp到[0,1]区间。
实验结果
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
[6.837]A3:OpenG应用和Phong着色模型相关推荐
- flat着色、gourand着色、phong着色
逐多边形着色:flat 逐顶点着色 : gourand 逐像素着色 :phong flat着色和Gourand着色 若渲染速度并不重要,我们可以逐像素地计算光照和雾化.(对于光照,这项技术称作 ...
- Unity3D-RayMarch-几何图元1-添加基本着色模型
效果图: 使用phong着色模型,将环境光.物体的漫反射光.镜面光三种光效加合而得到上图的效果 raymarch 的shader代码: // Upgrade NOTE: replaced '_Obje ...
- openGL中Phong 着色
openGL系列文章目录 前言 Bui Tuong Phong 在犹他大学的研究生期间开发了一种平滑的着色算法,在1973 年的论文[PH73]中对其进行了描述,并在[PH75]中发表.该算法的结构类 ...
- 问题六十八:Phong反射模型的C++实现
1 Phong反射模型 这一章节,我们将实现Phong反射模型. 环境光的部分:先不解释,后面来填这个坑: 漫反射光和高光反射光部分: 入射光(光源)的辐射率: 入射光和表面法向量的夹角的余弦值: 可 ...
- 问题六十八:着色模型(shading model)(1)——反射模型(reflection model)(2.2)——高光反射(specular reflection)
和diffuse reflection对应的是specular reflection.一直以来,本人都将"specular reflection"理解为"镜面反射&quo ...
- 计算机图形学(七)-深度缓存、着色shadding、着色模型、着色频率、渲染管线
shadding-着色 1 深度缓存 1.1 从画家算法到深度缓存 1.2 深度缓存 1.2.1 深度缓存深度缓存的实现方法 1.2.2 深度缓存注意事项 2 着色shadding 2.1 着色模型 ...
- Games101--现代计算机图形学入门 作业3笔记(渲染管线、着色模型、双线性插值)
一.渲染管线 一.作业要求 在这次编程任务中,我们会进一步模拟现代图形技术.我们在代码中添加了ObjectLoader(用于加载三维模型),VertexShader与FragmentShader,并且 ...
- Q99:当Bezier曲面(Utah Teapot)同时遇上“噪声纹理”和“Phong反射模型”
1,理论介绍 完整标题应该是:当"三角形网格细分后的"Bezier曲面(Utah Teapot)同时遇上"噪声纹理"和"Phong反射模型" ...
- 虚幻引擎之自定义着色模型(ShadingModel)
虚幻引擎之自定义着色模型(ShadingModel) 文章目录 虚幻引擎之自定义着色模型(ShadingModel) 一.前言 二.着色模型 2.1 材质输入 2.2 模型浅析 2.2.1 Defau ...
- 着色模型简介和实现(上)
摘要 着色模型(shading model)描述的是材质表面对光线的作用,它的输入是光线.入射角.反射角.材质的属性(例如粗糙度.金属度等),输出是材质的颜色.前面提到的BRDF模型就是shading ...
最新文章
- Tomcat自定义Http错误信息
- WinForm下ComboBox获取绑定对象集的SelectedValue补充
- HTML基础知识个人总结
- 人工智能:第五章 计算智能(2)
- JZOJ5906 传送门
- SpringBoot_数据访问-整合MyBatis(一)-基础环境搭建
- 【RK3399Pro学习笔记】四、ROS 创建工作空间与功能包
- linux批量过去5小时前文件名,Linux批量修改文件名
- getResource().getColor() 过时
- 如何快速上手一个项目
- Linux资源监控工具
- (转)Fabric 1.0 读写集
- mysql 的基本用法_mysql的基本用法
- uniapp App权限开启
- WebService接口的生成和调用(WebService接口)
- 360极速浏览器打不开国内网站的一种解决方法
- 关于马克思《青年在选择职业时的考虑》的读书报告
- 程序的本质之一程序编译的详细过程
- c语言编程怎么样,C语言怎么样,好学吗?
- 运动蓝牙耳机怎么选、几款适合运动的运动耳机