实现BlinnPhong 光照的原理
2016-01-25 00:47
246 查看
引言:
在Shader中实现BlinnPhong光照时,会用到一些代码,这些代码令人费解,下面是BlinnPhong 在Unity里内置的函数:
在文件Lighting.cginc里面
windows系统下位于:
…Unity\Editor\Data\CGIncludes\
这个是实现BlinnPhong 的函数
忽然给了这么一段代码,学过CG 的人也会感到一些迷惑,下面我们从图形学的角度来看这些代码的含义.
我们先来了解一下光照的计算。
光照是由发射光,环境光,漫反射光以及镜面高光组成的,这四个部分先单独运算,然后再累积起来组成最终的效果。
一 发射光:
openGL 中物体材质设置发射颜色来模拟发射光的
发射颜色 = 物体发射材质颜色
二 漫反射:
漫反射颜色 = 光源的漫反射光颜色x物体的漫反射材质颜色x diff
其中漫反射因子diff是光线与定点法线向量的点积:
diff = max(0,dot(N,L))
PS: dot() 为两个向量之间的的cos值.很直观的展示的漫反射的规律.在正对着入射光线时光照最强,在大于等于90度时候,没有反射的效果.
三 环境光:
环境颜色 = 光源的环境光颜色 x 物体的环境材质颜色
四 镜面反射:
镜面反射颜色 = 光源的镜面光颜色x物体的镜面材质颜色 x spec
spec =power(max(0,dot(s.Normal, h)),shininess)
这里的shininess是128
h = normalize (lightDir + viewDir)
h向量是视线向量viewDir 与光线向量lightDir的半向量,几何意义就是视线与光线夹角的平分线.
这里的normalize()函数用于获取lightDir + viewDir 坐标转化为单位向量,且方向不变.
光照的终极公式:
光照颜色 = 反射颜色 +全局环境颜色 +(环境颜色 + 漫反射颜色 +镜面反射颜色) x 聚光灯效果 x 衰弱因子
这里给的物体是不发光的,没有反射颜色这的部分.
在Shader中实现BlinnPhong光照时,会用到一些代码,这些代码令人费解,下面是BlinnPhong 在Unity里内置的函数:
在文件Lighting.cginc里面
windows系统下位于:
…Unity\Editor\Data\CGIncludes\
这个是实现BlinnPhong 的函数
inline fixed4 LightingBlinnPhong (SurfaceOutput s, fixed3 lightDir, half3 viewDir, fixed atten) { half3 h = normalize (lightDir + viewDir); fixed diff = max (0, dot (s.Normal, lightDir)); float nh = max (0, dot (s.Normal, h)); float spec = pow (nh, s.Specular*128.0) * s.Gloss; fixed4 c; c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * _SpecColor.rgb * spec) * (atten * 2); c.a = s.Alpha + _LightColor0.a * _SpecColor.a * spec * atten; return c; }
忽然给了这么一段代码,学过CG 的人也会感到一些迷惑,下面我们从图形学的角度来看这些代码的含义.
我们先来了解一下光照的计算。
光照是由发射光,环境光,漫反射光以及镜面高光组成的,这四个部分先单独运算,然后再累积起来组成最终的效果。
一 发射光:
openGL 中物体材质设置发射颜色来模拟发射光的
发射颜色 = 物体发射材质颜色
二 漫反射:
漫反射颜色 = 光源的漫反射光颜色x物体的漫反射材质颜色x diff
其中漫反射因子diff是光线与定点法线向量的点积:
diff = max(0,dot(N,L))
PS: dot() 为两个向量之间的的cos值.很直观的展示的漫反射的规律.在正对着入射光线时光照最强,在大于等于90度时候,没有反射的效果.
三 环境光:
环境颜色 = 光源的环境光颜色 x 物体的环境材质颜色
四 镜面反射:
镜面反射颜色 = 光源的镜面光颜色x物体的镜面材质颜色 x spec
spec =power(max(0,dot(s.Normal, h)),shininess)
这里的shininess是128
h = normalize (lightDir + viewDir)
h向量是视线向量viewDir 与光线向量lightDir的半向量,几何意义就是视线与光线夹角的平分线.
这里的normalize()函数用于获取lightDir + viewDir 坐标转化为单位向量,且方向不变.
光照的终极公式:
光照颜色 = 反射颜色 +全局环境颜色 +(环境颜色 + 漫反射颜色 +镜面反射颜色) x 聚光灯效果 x 衰弱因子
这里给的物体是不发光的,没有反射颜色这的部分.
half3 h = normalize (lightDir + viewDir); //h向量是视线向量viewDir 与光线向量lightDir的半向量,几何意义就是视线与光线夹角的平分线. fixed diff = max (0, dot (s.Normal, lightDir)); //漫反射因子diff是光线与定点法线向量的点积,大于等于90度,没有反射的效果. float nh = max (0, dot (s.Normal, h)) //nh 是h向量与定点法线向量的点积 float spec = pow (nh, s.Specular*128.0) * s.Gloss; //得到nh 向量进行s.Specular*128.0 次乘方计算 fixed4 c; // 光照颜色 = 反射颜色 +全局环境颜色 +(环境颜色 + 漫反射颜色 +镜面反射颜色) x 聚光灯效果 x 衰弱因子 c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * _SpecColor.rgb * spec) * (atten * 2);//漫反射 + 镜面反射 c.a = s.Alpha + _LightColor0.a * _SpecColor.a * spec * atten;
相关文章推荐
- ALTERA系列FPGA时序分析(一)
- Git常用命令
- MySql效率问题
- 20160124集训Day3-数学
- 让Windows下的应用程序在崩溃的时候写dump文件的代码
- 再见,大一上;大一下,我来了
- Java DataInputStream和DataOutputStream 使用例子
- 为Fedora20安装内核
- LeetCode 61. Rotate List
- 到底该如何入门Keras、Theano呢?(浅谈)
- Android自定义控件——ExpandTextView
- Swift: 用UserDefaults保存复杂对象
- linux系统常规安全优化
- 2013年第四届蓝桥杯C/C++程序设计本科B组省赛
- LinearLayout/RelativeLayout/FrameLayout实例,以及Activity跳转
- nyoj61 传纸条(一) (双线dp)
- $.ajax里面不识别ajax传参data里面的键是一个变量的情况
- Swift: 用UserDefaults保存复杂对象
- 使用hexo和github pages搭建个人博客
- 2013年第四届蓝桥杯C/C++程序设计本科B组省赛 连号区间数(编程大题)