OpenGL ES 学习教程(七) 亮瞎狗眼的 Specular Lighting 镜面高光

2023-11-05 16:59

本文主要是介绍OpenGL ES 学习教程(七) 亮瞎狗眼的 Specular Lighting 镜面高光,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

来来来,拿起手机,站到镜子前面,对着镜子打开手机闪光灯,朝镜子看,是不是亮瞎狗眼啊!

又比如下面的房子,被太阳照的反光太厉害,就像镜子一样。

还有玩家口中的的 油腻的Unreal Engine ,各种YY的油腻的师姐。


上面举了这么多例子,就是引入这一节要讲的 Speculer Lighting 镜面高光  。

一张图来解释下镜面高光


左侧是灯泡,灯泡发出光,到达顶点片段,然后被反射出来为 R 。

我们站在右侧观察,如果眼睛正好位于 光 的反射 的方向,即 眼睛位于 R 方向上,那么这个时候我们看到的光肯定是最强的。

随着眼睛 和 反射光 R 的夹角越大,那我们观察到Speculer Lighting 镜面光强度越小。


和上一篇了解到的 Diffuse Lighting 漫反射光照 对比,Speculer Lighting 镜面高光需要添加一个新的变量 - 观察者的位置。

我们代码中观察者 就是 摄像机,所以就使用 摄像机 的位置坐标 替代 观察者的位置。


所以我们添加另一个 uniform 变量添加到 Fragment Shader 片段着色器中,然后把摄像机位置传过去。(GLProgram_Cube.h Line 82)

"uniform vec3 m_camerapos;"//观察者位置

然后计算 顶点片段 指向 观察者的向量(GLProgram_Cube.h Line 96)

"vec3 cameraDir=normalize(m_camerapos-out_fragpos);" //计算顶点片段指向观察者的向量

然后计算光的反射 向量 R (GLProgram_Cube.h Line 97)

"vec3 reflectDir=reflect(-lightdir,normal);" //计算光的反射 R reflect第一个参数是光源指向片段的向量,所以这里使用 -lightdir

然后通过 cameraDir 和 reflectDir 的点积,计算出来的数值,再去 进行 pow 运算,求出 镜面亮度 (GLProgram_Cube.h Line 98)

"float spec=pow(max(dot(cameraDir,reflectDir),0.0),256.0);" //计算镜面亮度,32是高光的发光值 Shininess,发光值越高,反射光越强,散射越小,高光点越集中。

然后指定一个镜面光 强度 (GLProgram_Cube.h Line 95)

"float specularStrength=0.5;" //镜面光 中等强度 Specular Intensity

然后 相乘得到镜面光 (GLProgram_Cube.h Line 102)

"vec3 specular=specularStrength * spec * m_lightcolor;"

最后用 Specular Lighting + Diffuse Lighting + Ambient Lighting 乘以顶点颜色,得到最终颜色 (GLProgram_Cube.h Line 102)

"vec3 result=(ambient+diffuse+specular) * m_color;" //(环境光+漫反射光) * 物体本身的颜色 

然后从代码中传入 观察者的位置 ( GLProgram_Cube.h Line 93)

//传入摄像机位置;
glUniform3f(m_programCube.m_camerapos, -2, 0, 10);

运行结果如下图

可以看到中间的高亮区域

在Fragment Shader中 计算镜面亮度的时候,进行了 pow 操作,操作数是指定的一个数,这个数叫 高光的发光值 Shininess 。

下图是不同的Shininess 值产生的效果,可以看到 高光的发光值 Shininess,发光值越高,反射光越强,散射越小,高光点越集中。


示例工程下载:

http://pan.baidu.com/s/1dDSdo3J


这篇关于OpenGL ES 学习教程(七) 亮瞎狗眼的 Specular Lighting 镜面高光的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/351232

相关文章

JAVA集成本地部署的DeepSeek的图文教程

《JAVA集成本地部署的DeepSeek的图文教程》本文主要介绍了JAVA集成本地部署的DeepSeek的图文教程,包含配置环境变量及下载DeepSeek-R1模型并启动,具有一定的参考价值,感兴趣的... 目录一、下载部署DeepSeek1.下载ollama2.下载DeepSeek-R1模型并启动 二、J

Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)

《Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)》文章介绍了如何使用dhtmlx-gantt组件来实现公司的甘特图需求,并提供了一个简单的Vue组件示例,文章还分享了一... 目录一、首先 npm 安装插件二、创建一个vue组件三、业务页面内 引用自定义组件:四、dhtmlx

MySQL zip安装包配置教程

《MySQLzip安装包配置教程》这篇文章详细介绍了如何使用zip安装包在Windows11上安装MySQL8.0,包括下载、解压、配置环境变量、初始化数据库、安装服务以及更改密码等步骤,感兴趣的朋... 目录mysql zip安装包配置教程1、下载zip安装包:2、安装2.1 解压zip包到安装目录2.2

Java使用Tesseract-OCR实战教程

《Java使用Tesseract-OCR实战教程》本文介绍了如何在Java中使用Tesseract-OCR进行文本提取,包括Tesseract-OCR的安装、中文训练库的配置、依赖库的引入以及具体的代... 目录Java使用Tesseract-OCRTesseract-OCR安装配置中文训练库引入依赖代码实

SpringBoot整合easy-es的详细过程

《SpringBoot整合easy-es的详细过程》本文介绍了EasyES,一个基于Elasticsearch的ORM框架,旨在简化开发流程并提高效率,EasyES支持SpringBoot框架,并提供... 目录一、easy-es简介二、实现基于Spring Boot框架的应用程序代码1.添加相关依赖2.添

Ubuntu固定虚拟机ip地址的方法教程

《Ubuntu固定虚拟机ip地址的方法教程》本文详细介绍了如何在Ubuntu虚拟机中固定IP地址,包括检查和编辑`/etc/apt/sources.list`文件、更新网络配置文件以及使用Networ... 1、由于虚拟机网络是桥接,所以ip地址会不停地变化,接下来我们就讲述ip如何固定 2、如果apt安

PyCharm 接入 DeepSeek最新完整教程

《PyCharm接入DeepSeek最新完整教程》文章介绍了DeepSeek-V3模型的性能提升以及如何在PyCharm中接入和使用DeepSeek进行代码开发,本文通过图文并茂的形式给大家介绍的... 目录DeepSeek-V3效果演示创建API Key在PyCharm中下载Continue插件配置Con

Deepseek R1模型本地化部署+API接口调用详细教程(释放AI生产力)

《DeepseekR1模型本地化部署+API接口调用详细教程(释放AI生产力)》本文介绍了本地部署DeepSeekR1模型和通过API调用将其集成到VSCode中的过程,作者详细步骤展示了如何下载和... 目录前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装oll

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

在不同系统间迁移Python程序的方法与教程

《在不同系统间迁移Python程序的方法与教程》本文介绍了几种将Windows上编写的Python程序迁移到Linux服务器上的方法,包括使用虚拟环境和依赖冻结、容器化技术(如Docker)、使用An... 目录使用虚拟环境和依赖冻结1. 创建虚拟环境2. 冻结依赖使用容器化技术(如 docker)1. 创