title: unity-shader-光照相关
categories: Unity3d
tags: [unity, shader, 光照模型]
date: 2019-03-19 10:05:18
comments: false
把之前记录到 unity-shader相关 中的笔记抽出单独一个文件记录. 因为光照部分也是比较大的内容.
参考内容: 《Real-Time Rendering 3rd》 提炼总结 – https://zhuanlan.zhihu.com/p/34207965
菲涅尔反射
- 菲涅耳效应 – https://zhuanlan.zhihu.com/p/19988903
- Fresnel Effect (8) – https://zhuanlan.zhihu.com/p/26611183
- 菲涅尔 Fresnel – https://www.jianshu.com/p/a63bee519e3e
- 菲涅尔反射是什么- https://www.zhihu.com/question/53022233
- 用 C 语言画光(六):菲涅耳方程 ( 叶大 ) – https://zhuanlan.zhihu.com/p/31534769
- 实时渲染中的菲涅尔效应 – http://www.selfgleam.com/fresnel_effect.html
什么是菲涅耳效应/p>
简要地说,物体在不同角度观察下,表面的反射率是不一样的。菲涅耳效应模拟的就是物体材质反射率随角度改变的效果。如下图左所示,肥皂泡在边缘处,即视线与表面夹角处比较小时,反射效果更强烈;在肥皂泡中心附近,即视线与表面夹角近乎垂直时,看起来更透明一些。下图右中,池塘远处的水面看上去像镜面一样,近处的水面则更透彻,这同样是由于菲涅耳效应——在不同视角观察下物体材质反射率不同。如果你家里的地板是光滑的大理石材质,或者是打蜡过的木地板的话,可以很容易自己观察到这样的现象。
shader中的使用 ( 参考: Illustrative-Rendering-with-Unity 工程, git : https://github.com/SilangQuan/Illustrative-Rendering-with-Unity )
光照衰减&阴影
参考 : 笔记十——光照衰减&阴影 – https://zhuanlan.zhihu.com/p/31805436
Unity中的阴影
Unity中可以使一个物体向其他物体投射阴影,以及让一个物体接收其他物体的阴影,从而使场景看起来更加真实。Unity的实时渲染中,使用一种Shadow Map技术,这种技术将摄像机放在光源位置,场景中的阴影区域即为摄像机看不到的区域。阴影映射纹理本质上是一张深度图,记录从光源位置出发,能看到的场景中距离距离它最近的表面位置的深度信息。Unity使用一个额外的Pass专门用于更新光源的阴影映射纹理,该Pass为 LightMode标签设置为 ShadowCaster的Pass。当使用屏幕空间阴影映射时,Unity先调用 LightMode为 ShadowCaster的Pass来得到可投射阴影的光源的阴影映射纹理以及摄像机的深度纹理。根据光源的阴影映射纹理和深度纹理得到屏幕空间的阴影图,一个物体若想接收其他物体的阴影,则需要在Shader中对阴影进行采样。阴影图是屏幕空间下的,先对表面坐标从模型空间变换到屏幕空间,再对阴影图进行采样。完整的过程为:
在 unity 中, 只有 平行光 会产生 阴影投射 , 而 点光源 和 聚光灯 都不会. 所以一般都是以平行光作为主光源, 而其他光源只是作为辅助光.
主要计算公式
Half Lambert(半兰伯特)
Blinn Phong
参考 :
- 【Unity Shader】 Blinn-phong光照模型 – https://blog.csdn.net/v_xchen_v/article/details/79433399
相比较Phong模型,Blinn-phong模型只适用N?H替换了V?R,但却获得了明显的提高,它能提供比Phong更柔和、更平滑的高光,而且由于Blinn-phong的光照模型省去了计算反射光线方向向量的两个乘法运算速度上也更快,因此成为很多CG软件中默认的光照渲染方法,同时也被集成到大多数的图形芯片中,在OpenGL和Direct3D渲染管线中,Blinn-Phong就是默认的渲染模型。
Blinn-phong光照模型中,用N?H的值取代了V?R。Blinn-phong光照模型的光强因子为:
(N?H)n
即H 越靠近N,光照越强。
由于这两个光照模型公式基本相同,所以只解释一下N?H:
N与前面相同,是顶点的单位法向量,而H则是入射光L和顶点到视点的单位向量的角平分线单位向量,通常也成为 半向量。其计算方法为:
H = (L + V) / (|L + V|)
逐顶点 与 逐像素
参考 :
- Unity Shader 逐顶点/像素漫反射光照 – https://www.cnblogs.com/isayes/p/6532598.html
漫反射光照符合兰伯特定律 : 反射光线的强度 与 表面法线 和 光源方向 之间的夹角的余弦值成正比 .
计算机图形第一定律 : 如果它看起来是对的 , 那么它就是对的 .
逐顶点光照的计算量往往要小于逐像素光照 .
逐顶点光照依赖于线性插值来得到像素光照 , 当光照模型中有非线性的计算的时候 , 逐顶点光照就会出问题 , 例如计算高光反射 .
逐顶点光照会在渲染图元内部对顶点进行插值 , 渲染图元内部的颜色总是暗于顶点处的最高颜色 , 在某些情况下会产生明显的棱角现象 .
光照计算方式
-
兰伯特 无高光, 参考 : Lambert(兰伯特)
-
兰伯特 + blin-phong, 参考 : Blinn-phong
-
有阴影和光照
总结
-
无阴影
-
有阴影
最终颜色 = [(漫反射系数 x 纹理颜色 x RGB颜色)+ 高光] * atten + 环境光 + 自发光颜色 + [边缘色]
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!