计算机图形学 | 实验八:Phong模型
计算机图形学 | 实验八:Phong模型
- 计算机图形学 | 实验八:Phong模型
- Phong模型
- 光源设置
- 光照计算
- 定向光
- 点光源
- 聚光
华中科技大学《计算机图形学》课程
MOOC地址:计算机图形学(HUST)
计算机图形学 | 实验八:Phong模型
Phong模型
接下来,我们来介绍一下Phong模型。
绘制效果如下,我们可以看到,中间的立方体是被照射的对象,有一个定向光源,六个点光源和一个聚光的光源。

我们的程序流程主体还是跟前面的课程相同。因此我们这节的重点部分就是主要在这两个方面,一个是光源的设置,一个是光照计算。
光源设置
首先是光源的设置,我们这里的光源种类主要有三种,定向光,点光源和聚光,三种光源的效果叠加形成了我们刚才看到的效果。
那么我们在代码中是如何实现的呢?首先我们来看定向光,定向光就是类似太阳这种,它的属性包括定向光的方向,以及环境光,漫反射光,镜面反射光的强度参数。由于定向光是光源处于无限远处的平行光,因此我们无需指定出定向光光源具体的位置,只需指定其指向的方向即可。
接下来是点光源,我们定义了六个点光源,点光源就是类似灯泡这种,每一个点光源的属性都包括点光源的位置,环境光,漫反射光,和镜面反射光的强度参数,这里每一个分量都要乘一个点光源的颜色。那么除此之外点光源与定向光有哪些不同呢?它与定向光不同的是它多了三个属性参数,这三个参数是用来计算衰减公式的三个系数,分别是constant常数项,linear一次项和quadratic二次项,它会使得光线强度随距离的增加不断减小并且衰减的幅度也逐渐减小,这样更接近现实生活中点光源的效果。
我们的第三种光源是聚光,聚光就是类似手电筒的这种效果,聚光的属性也包括聚光光源的位置,方向,这里我们是用摄像机的位置和朝向来指定的,还有环境光,漫反射光,和镜面反射光的强度参数以及三个衰减系数,那么除此之外聚光光源与点光源又有哪些不同呢?这里我们又多了两个参数分别表示我们聚光内外圆锥的内外切光角。聚光的效果就相当于是一个圆锥的光效,我们这里通过使用两个圆锥来使我们的聚光效果看起来更加平滑。
当我们已经知道了我们是如何设置光源的,并且已经了解了三种光源的属性时,接下来我们要做的就是计算光源的光照,这里我们使用的是Phong模型来计算光照。
光照计算
具体计算光照的过程,我们是在立方体的片段着色器中进行的。由于我们在考虑物体颜色时才会考虑光照到物体产生的颜色影响,因此我们在立方体的片段着色器中计算光照。
定向光
接下来就是具体的计算过程,首先是计算定向光源,根据之前Phong模型的公式,我们分别计算环境光、漫反射光和镜面光。
我们在计算环境光的时候用的是漫反射光下的物体颜色而非环境光下的,是因为通常情况下漫反射光和环境光下的物体效果几近相同,因此我们无需存取两遍。
计算漫反射时我们对法向量和光线方向向量进行点乘,计算光源对当前片段实际的漫发射影响,即L·N,结果值再乘以物体的材质颜色Kd和漫反射光因子Ip。
// 漫反射
vec3 lightDir = normalize(-light.direction);
float diff = max(dot(normal, lightDir), 0.0);
计算镜面反射时我们对视线方向与反射方向的点乘(R·V)(并确保它不是负值),然后取它的n次幂。这个n是高光的反光度(Shininess) ,结果值再乘以物体的材质颜色Ks和镜面光因子Ip。
// 镜面反射
vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
这里的高光的反光度n(shininess)我们程序中取值为32,那么为什么我们取32而不取其他的值呢?之所以选取这个值是因为我们不希望镜面光过于显眼,我们可以看到图中n取值不同时我们得出的光源效果,也可以自己尝试一下。
点光源
第二种光源效果是点光源,这里我们对于点光源的环境光、漫反射光和镜面光的计算同定向光相同,依然是根据Phong模型来计算,只不过我们引入了衰减这一属性。衰减与光源和物体的距离有关,它会使得光线强度随距离的增加不断减小并且衰减的幅度也逐渐减小。这里我们保留环境光,只考虑漫反射光和镜面光受到衰减的影响。
// 距离和衰减
float d = length(light.position - fragPos);
float attenuation = 1.0 / (light.c + light.l * d + light.q * d * d);
聚光
第三种光源效果是聚光光源,这里对于环境光、漫反射光和镜面光以及衰减的计算同点光源相同,不同点在于这里增加了聚光强度这一属性。
theta就是光线方向同光源方向的夹角。
Epsilon是内外圆锥之间的余弦差值,这里我们给出两个切光角,分别形成内外圆锥。
Intensity则是我们最终得到的聚光强度,它通过clamp()函数将theta值做了限制,在内圆锥内,强度大于1.0,在内外圆锥之间,强度在0.0-1.0之间,在外圆锥外,强度为负值。
// 聚光强度
float theta = dot(lightDir, normalize(-light.direction));
float epsilon = light.cutOff - light.outerCutOff;
float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);
我们同样保留环境光,对漫反射光和镜面反射增加聚光强度,就可以得到平滑的聚光效果。
最后我们对程序进行一个演示,我们这里设置了键盘响应事件,按1开启定向光,2~7开启点光源,8开启聚光效果。

相关文章:
计算机图形学 | 实验八:Phong模型
计算机图形学 | 实验八:Phong模型 计算机图形学 | 实验八:Phong模型Phong模型光源设置 光照计算定向光点光源聚光 华中科技大学《计算机图形学》课程 MOOC地址:计算机图形学(HUST) 计算机图形学 | 实验八:…...
第三十一回:GestureDetector Widget
文章目录 概念介绍使用方法示例代码 我们在上一章回中介绍了ListView响应事件的内容t,本章回中将介绍 GestureDetector Widget.闲话休提,让我们一起Talk Flutter吧。 概念介绍 我们在这里介绍的GestureDetector是一个事件响应Widget,它可以响应双击事件࿰…...
Java面试知识点(全)-Java并发-多线程JUC三- JUC集合/线程池
Java面试知识点(全) 导航: https://nanxiang.blog.csdn.net/article/details/130640392 注:随时更新 JUC集合类 为什么HashTable慢? 它的并发度是什么? 那么ConcurrentHashMap并发度是什么? Hashtable之所以效率低下主要是因为其实现使用了synchro…...
Android 如何获取有效的DeviceId
目录 前言官方唯一标识符建议使用广告 ID使用实例 ID 和 GUID不要使用 MAC 地址标识符特性常见用例和适用的标识符 解决方案DeviceIdANDROID_IDMac地址UUID补充 总结 前言 从 Android 10 开始,应用必须具有 READ_PRIVILEGED_PHONE_STATE 特许权限才能访问设备的不可…...
<SQL>《SQL命令(含例句)精心整理版(2)》
《SQL命令(含例句)精心整理版(2)》 跳转《SQL命令(含例句)精心整理版(1)8 函数8.1 文本处理函数8.2 数值处理函数8.3 时间处理函数8.3.1 时间戳转化为自定义格式from_unixtime8.3.2 …...
完全自主研发,聚芯微发布3D dToF图像传感器芯片!
日前,由中国半导体行业协会IC设计分会(ICCAD)、芯原股份、松山湖管委会主办的主题为“AR/VR/XR元宇宙”的“2023松山湖中国IC创新高峰论坛”正式在广东东莞松山湖召开。武汉市聚芯微电子有限责任公司发布了完全自主知识产权的3D dToF图像传感…...
MySQL 事物(w字)
目录 事物 首先我们来看一个简单的问题 什么是事务 为什么会出现事务 事务的版本支持 事务提交方式 事务常见操作方式 设置隔离级别 事物操作 事物结论 事务隔离级别 理解隔离性 隔离级别 查看与设置隔离性 注意可重复读【Repeatable Read】的可能问题ÿ…...
字节跳动测试岗四面总结....
字节一面 1、 简单做一下自我介绍 2、 简要介绍一下项目/你负责的模块/选一个模块说一下你设计的用例 3 、get请求和post请求的区别 4、 如何判断前后端bug/3xx是什么意思 5、 说一下XXX项目中你做的接口测试/做了多少次 6、 http和https的区别 7、 考了几个ADB命令/查看…...
基于.NetCore开源的Windows的GIF录屏工具
推荐一个Github上Start超过20K的超火、好用的屏幕截图转换为 GIF 动图开源项目。 项目简介 这是基于.Net Core WPF 开发的、开源项目,可将屏幕截图转为 GIF 动画。它的核心功能是能够简单、快速地截取整个屏幕或者选定区域,并将其转为 GIF动画&#x…...
PCB 基础~典型的PCB设计流程,典型的PCB制造流程
典型的PCB设计流程 典型的PCB制造流程 • 从客户手中拿到Gerber, Drill以及其它PCB相关文件 • 准备PCB基片和薄片 – 铜箔的底片会被粘合在基材上 • 内层图像蚀刻 – 抗腐蚀的化学药水会涂在需要保留的铜箔上(例如走线和过孔) – 其他药水…...
Python logging使用
目录 logging模块 logging核心组件 logger handler StreamHandler:把日志内容在控制台中输出 FileHandler:把日志内容写入到文件中 filter formatter 注意日志级别的继承问题 logger.exception 上述样例的整体代码 日志的配置文件及其模板 lo…...
红黑树的实现原理和应用场景
红黑树的实现原理和应用场景; 有如图所示的表,现在希望查询的结果将列成行 建表语句如下: CREATE TABLE TEST_TB_GRADE2 ( ID int(10) NOT NULL AUTO_INCREMENT, USER_NAME varchar(20) DEFAULT NULL, CN_SCORE float DEFAULT NU…...
idea插件完成junit代码生成,和springboot代码示例
在idea环境下,可以用过插件的方式自动生成juint模板代码。不过具体要需要自己手动编写。 1、安装插件 打开idea,file–settings–plugins,搜索和安装插件(JunitGenerator V2.0和JUnit),安装后,后…...
【Redis面试点总结】
1、缓存 1.1、穿透 查询一个空数据,mysql也查不到也不会写入缓存可能导致多次请求数据库 方案一:缓存设空即可(可能发生数据不一致就是这条数据有了但此时缓存是空,消耗内存) 方案二:布隆过滤器&#x…...
打卡智能中国(五):博士都去哪儿了?
《打卡智能中国》系列更新了几期,有读者表示,很爱看这类接地气的真实故事,也有读者反映,不是电工,就是文员、农民、治沙人,人工智能不是高精尖学科吗?那些学历很高的博士都去哪儿了?…...
[Nacos] Nacos Client获取调用服务的提供者列表 (四)
文章目录 1.Nacos Client获取调用服务的提供者列表1.1 从Ribbon的负载均衡入手到Nacos Client获取调用服务的提高者列表1.2 getServers方法返回分析1.3 通过selectInstances方法查找Instances实例1.4 获取到要调用服务的serviceInfo Nacos Client 从Ribbon负载均衡调用服务。 …...
gcc编译一个程序的步骤(嵌入式学习)
1.预处理(Preprocessing): 在这个步骤中,预处理器将处理与#相关的代码,包括展开头文件、删除无用定义和替换宏定义。预处理器会生成一个经过宏替换和条件编译处理的中间文件。 gcc -E xxx.c -o xxx.i2.编译࿰…...
邹检验,结构变化识别及其R语言实现
在描述多维数据的维度关系时,线性模型无疑应用最多。然而某些情况下,我们关心随着时间变化或随着样本分组,线性关系的具体参数是否发生了变化,即是否发生结构变化Structural break。邹检验Chow test提供了最基本的一种结构变化显著…...
腾讯云,物联网开发平台产品,动态注册步骤
1. 下载后解压,qcloud_iot_mqtt_sign-master.zip GitHub - tencentyun/qcloud_iot_mqtt_signContribute to tencentyun/qcloud_iot_mqtt_sign development by creating an account on GitHub.https://github.com/tencentyun/qcloud_iot_mqtt_sign 2. 按照readme文…...
Padding, Spacer, Initializer 的使用
1. Padding 的使用 1.1 样式一 1) 实现 func testText1()-> some View{Text("Hello, World!").background(Color.yellow) // 背景颜色//.padding() // 默认间距.padding(.all, 10) // 所有的间距.padding(.leading, 20) // 开始的间距.ba…...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
