冯氏光照模型

想要模拟真实世界的光照效果是比较困难的,我们使用一种叫做冯氏光照模型(Phong Lighting Model)的模型来实现近似的效果。冯氏光照模型的主要结构由3个分量组成:环境(Ambient)、漫反射(Diffuse)和镜面(Specular)光照。下面这张图展示了这些光照分量看起来的:

  • 环境光照(Ambient Lighting):即使在黑暗的情况下,世界上通常也仍然有一些光亮(月亮、远处的光),所以物体几乎永远不会是完全黑暗的。为了模拟这个,我们会使用一个环境光照常量,它永远会给物体一些颜色。
  • 漫反射光照(Diffuse Lighting):模拟光源对物体的方向性影响(Directional Impact)。它是冯氏光照模型中视觉上最显著的分量。物体的某一部分越是正对着光源,它就会越亮。
  • 镜面光照(Specular Lighting):模拟有光泽物体上面出现的亮点。镜面光照的颜色相比于物体的颜色会更倾向于光的颜色。

环境光照

环境光照比较简单,定义一个常量环境因子,乘以光的颜色,再乘以物体的颜色,然后将最终结果作为片段的颜色即可。为了方便分辨每个面,我们定义每个面的颜色不同。修改后的着色器代码如下:

        vertexShaderCode ="uniform mat4 uMVPMatrix;" +"attribute vec3 aPosition;" +"attribute vec3 objectColor;" +"varying vec4 aColor;" +"void main() {" +" vec3 lightColor = vec3(1.0, 1.0, 1.0);" +// ambient" float ambientStrength = 0.3;" +" vec3 ambient = ambientStrength * lightColor;" +" aColor = vec4(ambient * objectColor, 1.0);" +" gl_Position = uMVPMatrix * vec4(aPosition, 1.0);" +"}";fragmentShaderCode ="precision mediump float;" +"varying vec4 aColor;" +"void main() {" +" gl_FragColor = aColor;" +"}";

显示效果如下:

当增加ambientStrength的值时,物体就会变亮;反之减小时就会变暗。

漫反射光照

环境光照并不能体现现实世界的光照效果,但是漫反射光照可以体现显著的视觉效果了。漫反射光照使物体上与光线方向越接近的片段能从光源处获得更多的亮度。为了能够更好的理解漫反射光照,请看下图:

不难看出,当夹角越小时,照射的点会越亮,反之则越暗。我们定义一个向量叫法向量,垂直于当前的平面,因为我们的顶点构成了面,我们定义顶点坐标时,同时定义法向量,计算连接光源点和顶点与法向量的夹角。关于更详细的介绍请参考文档https://learnopengl-cn.github.io/02%20Lighting/02%20Basic%20Lighting/。看下修改后的着色器代码:

        vertexShaderCode ="uniform mat4 uMVMatrix;" +"uniform mat4 uMVPMatrix;" +// 光源坐标"uniform vec3 aLightPos;" +"attribute vec4 aPosition;" +// 法向量"attribute vec3 aNormal;" +"attribute vec3 objectColor;" +// 结果"varying vec4 aColor;" +"void main() {" +" vec3 lightColor = vec3(1.0, 1.0, 1.0);" +// 环境光照" float ambientStrength = 0.3;" +" vec3 ambient = ambientStrength * lightColor;" +// 转换坐标" vec3 fragPos = vec3(uMVMatrix * aPosition);" +// 漫反射光照// 归一化法向量" vec3 modelViewNormal = vec3(uMVMatrix * vec4(aNormal, 0.0));" +// 归一化光源线" vec3 lightDir = normalize(aLightPos - fragPos);" +" float diff = max(dot(modelViewNormal, lightDir), 0.0);" +" vec3 diffuse = diff * lightColor;" +" vec3 result = (ambient + diffuse) * objectColor;" +" aColor = vec4(result, 1.0);" +" gl_Position = uMVPMatrix * aPosition;" +"}";fragmentShaderCode ="precision mediump float;" +"varying vec4 aColor;" +"void main() {" +" gl_FragColor = aColor;" +"}";

需要传入的数据:光源点的坐标;法向量。首先光源点的坐标必须是经过变换的,计算中用到了normalize内置方法,这个方法主要是用来归一化的,如果你的顶点和光源都经过了位移或缩放之类的变换,那么它可能变长或变短,而法向量定义的却是1,用这个方法是为了防止计算错误。dot方法用来计算向量两个向量之间的点积。max防止数值小于0时也会计算。

显示效果如下:

我们看到面向光源的面亮度高,背面和侧面亮度低或无亮度。

镜面光照

最后的一项和漫反射光照类似,某个点的颜色不光和光源点的距离有关,还和观察点的位置有关,参考下图:

当观察位置在R线上时,看到那个点的亮度最高,会看到一个高光的区域。首先我们需要定义一个观察点,这里我们就设置为我们摄像机的坐标位置,那么在观察空间之内转换之后观察点坐标永远是(0,0,0)。使用reflect计算反射方向之后再计算点积。关键代码:
// 镜面光照 " float specularStrength = 0.5;" + " vec3 viewDir = normalize(-fragPos);" + " vec3 reflectDir = reflect(-lightDir, modelViewNormal);" + " float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32.0);" + " vec3 specular = specularStrength * spec * lightColor;" + // 结果 " vec3 result = (ambient + diffuse + specular) * objectColor;"复制代码
我们先看镜面光照的单独的效果:

三种效果叠加如下:

然后我们让光源进行旋转,可以观察到物体的亮度在不断的变化。

请简述gouraud光照模型_OpenGL ES for Android(冯氏光照)相关推荐

  1. 请简述gouraud光照模型_《计算机图形学》试卷及答案

    一.填空题(每空0.5分,共 1 0 分) 1. 计算机图形学中的图形是指由点.线.面.体等 和明暗.灰度(亮度).色 彩等 构成的,从现实世界中抽象出来的带有灰度.色彩及形状的图或形. 2. 一个计 ...

  2. 请简述gouraud光照模型_光照模型汇总

    1. Lambert模型 理想漫反射模型,各个方向一样. Lambert光照模型是一个非常简单的模型,由Lambert在200多年前提出,当光照射到粗糙的表面时,它将向四周均匀的反射.这种各向同性 的 ...

  3. 南邮——计算机图像学——光照、冯氏光照模型

    颜色可以数字化的由红色(Red).绿色(Green)和蓝色(Blue)三个分量组成,它们通常被缩写为RGB.这三个不同的分量组合在一起几乎可以表示存在的任何一种颜色. (一)观察物体 (1)物体的片段 ...

  4. 适用于Android的OpenSL ES指南-OpenSL ES的Android扩展

    翻译自Android Extensions 针对Android的OpenSL ES扩展了参考OpenSL ES规范,使其与Android兼容,并利用Android平台的强大功能和灵活性. Androi ...

  5. OpenGL.ES在Android上的简单实践:11-全景(索引-深度测试)

    OpenGL.ES在Android上的简单实践:11-全景(正方体-索引-深度测试) 0.全景图要怎么看? What is 全景?可能很多人单看这名字不太清楚.但看到下面的图的时候就噢的一声~瞬间廓然 ...

  6. OpenGL.ES在Android上的简单实践:10-曲棍球(拖动物体、碰撞测试)

    OpenGL.ES在Android上的简单实践:10-曲棍球(拖动物体.碰撞测试) 1.让木槌跟随手指移动 继续上一篇文章9的内容.既然可以测试木槌是否被触碰了,我们将继续努力下去:当我们来回拖动木槌 ...

  7. OpenGL.ES在Android上的简单实践:23-水印录制(FBO离屏渲染,解决透明冲突,画中画)

    OpenGL.ES在Android上的简单实践:23-水印录制(FBO离屏录制,解决透明冲突) 1.水印签名罢工了? 不知道大家有没注意到,之前我们使用MediaCodec录制的视频,水印签名那部分区 ...

  8. OpenGL.ES在Android上的简单实践:21-水印录制(MediaCodec输出h264+MediaMuxer合成mp4 上)

    OpenGL.ES在Android上的简单实践:21-水印录制(MediaCodec输出h264+MediaMuxer合成mp4 上) 1.录制视频需要什么? 在上篇文章,我们已经成功的满足了需求,在 ...

  9. OpenSL ES for Android

    OpenSL ES for Android 原英文文档地址:http://mobilepearls.com/labs/native-android-api/ndk/docs/opensles/ Ope ...

最新文章

  1. RuntimeError: Expected object of device type cuda but got device type cpu for argument pytorch数据位置
  2. 宝塔建站 mysql在哪_宝塔面板建站教程,越详细越好纯小白! - 搜外问答
  3. hdu 4738 2013杭州赛区网络赛 桥+重边+连通判断 ***
  4. Lua 5.1.1 源代码阅读笔记
  5. python基础之循环与迭代器
  6. 使用Scala,Play和Akka连接到RabbitMQ(AMQP)
  7. 实战Spring Boot 2.0系列(一) - 使用Gradle构建Docker镜像
  8. 什么是浏览器同源策略?
  9. xcorr函数_相关函数xcorr的用法及实例
  10. 阿里云边缘计算三年,都为开发者带来了什么?
  11. JAVA + LR实现apache流媒体的性能测试
  12. 计算机截图工具无法运行,win7系统打开截图工具提示“截图工具当前未在计算机上运行”的解决方法...
  13. 将一个自然数拆分为N个自然数
  14. 深度学习建模预测全流程(Python)!
  15. 支付沙箱环境测试和验签
  16. pc模拟器运行多个Android,低配电脑如何强制开50个安卓模拟器挂机
  17. POJ 1635 Subway tree systems 树的Hash 或 树的最小表示法
  18. 基于ssm智能仓库(进销存)管理系统获取(java毕业设计)
  19. 【Shader】拷贝ShaderToy系列——蝴蝶
  20. (6)打鸡儿教你Vue.js

热门文章

  1. Springboot 关于日期时间格式化处理方式总结
  2. php接口下载图片,php图片下载方法
  3. MyBatis--工具类模板
  4. centos7 rpm 安装 rabbitMQ 最新版
  5. 结对-贪吃蛇-最终程序
  6. Java核心类库——内部类那点事儿
  7. 【深入】java 单例模式
  8. .NET Timer控件
  9. 华硕a501lb5200加内存和固盘并装上win7系统并设置固盘为第一启动
  10. pygame的最小系统