一步步学Metal图形引擎9-《Blinn-Phong光照模型》

Posted Mr_厚厚

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一步步学Metal图形引擎9-《Blinn-Phong光照模型》相关的知识,希望对你有一定的参考价值。

教程 9

Blinn-Phong光照模型

教程源码下载地址: https://github.com/jiangxh1992/MetalTutorialDemos

CSDN完整版专栏: https://blog.csdn.net/cordova/category_9734156.html

一、原理

前面的教程我们完成了漫反射、镜面反射和环境光的计算,基于Phong光照模型组合三者得到不错的光照效果,这里我们对其中的镜面反射做了调整修正,也就是这篇教程中要实现的Blinn-Phong光照模型。

Blinn-Phong光照模型是对Phong模型的改进修正,高光部分的计算做了调整,加入了计算更简单且具有特殊物理意义的半角向量H,使得计算速度上更加高效,高光效果比Phong更加柔和平滑。

半角向量H指的是光的入射方向L和视线方向V的中间向量,计算方法很简单:


半角向量在各类光照模型中应用很广泛,一方面是它的计算很简单高效,另一方面它具有特殊的信息含义,在基于物理的渲染中,它具有表达D项法线分布的作用,可以表示微表面理论中微小表面能反射到视角的法线比例,是光照计算中一个重要的中间变量。

在高光强度分量的计算中,相比于之前的Phong模型,Blinn-Phong中用N · H取代了V · R,这样高光部分的计算公式变为:


其中N是表面法线向量,H是半角向量,IL是光源强度,ks是镜面反射系数(0~1),n是高光指数。

所以这里源码中的实现很简单,只要计算出半角向量H,修改下shader中高光部分的计算即可。

二、源码分析

2.1 Shaders.metal

// ...
// 半角向量
float3 H = normalize(L + V);
// ...

片段着色器中根据已有的入射光方向L和视线方向V直接计算出半角向量H。

// ...
// Specular(Blinn-Phong)
float specular = uniforms.IL * uniforms.Ks * pow(fmax(dot(N, H), 0), uniforms.shininess);
// ...

高光部分将V和R的点积替换为N和H的点积即可。

三、运行效果

效果上只是高光部分有所不同。

Blinn-Phong只是经验模型的另一种方案,和Phong模型相比各有优劣,都和现实光照有着很大差异,都是简单高效的基础光照模型。

相比来看,Phong光照比Blinn-Phong更加真实,而Blinn-Phong光照更加柔和,同样高光系数下,Blinn-Phong高光区域范围更大,明暗界限相对不明显。

以上是关于一步步学Metal图形引擎9-《Blinn-Phong光照模型》的主要内容,如果未能解决你的问题,请参考以下文章

一步步学Metal图形引擎2-《纹理贴图》

一步步学Metal图形引擎2-《纹理贴图》

一步步学Metal图形引擎3-《MTLVertexDescriptor》

一步步学Metal图形引擎3-《MTLVertexDescriptor》

一步步学Metal图形引擎5-《Uniform Buffer》

一步步学Metal图形引擎5-《Uniform Buffer》