shader篇-高光反射模型


  • shader篇-高光反射模型
  • 背景
  • 逐顶点光照
  • 逐像素光照
  • Blinn-Phong光照模型

背景

这里的高光反射模型,并不是现实意义上的高光反射,而是只是用来计算物理上那些沿着完全镜面反射方向被反射的光线,让物体看起来有光泽,例如金属材质
高光反射计算公式如下

Cdiffuse=(Clight∗Mdiffuse)∗max(0,v⃗ ∗r⃗ )Mgloss

C_{diffuse}=(C_{light}*M_{diffuse})*max(0,\vec{v}*\vec{r})^{M_{gloss}}
v是视角方向,r是反射方向

Mgloss

M_{gloss}是高光反射系数
反射方向可用表面法线n和光照方向l计算

r⃗ =l⃗ −2∗(n⃗ ∗l⃗ )∗n⃗ 

\vec{r}=\vec{l}-2*(\vec{n}*\vec{l})*\vec{n}

逐顶点光照

Shader "Test Shader/SpecularVertexLevel{
Properties
{_Diffuse ("Diffuse", Color) = (1, 1, 1, 1)//控制高光反射颜色_Specular ("Specular", Color) = (1, 1, 1, 1)//控制高光区域大小_Gloss ("Gloss", Range(8.0, 256)) = 20
}
SubShader
{Pass{Tags { "LightMode"="ForwardBase" }CGPROGRAM#pragma vertex vert#pragma fragment frag#include "Lighting.cginc"fixed4 _Diffuse;fixed4 _Specular;float _Gloss;struct a2v{//模型空间的顶点坐标float4 vertex:POSITION;//模型空间的法线方向float3 normal:NORMAL;};struct v2f{//输出的是裁剪空间的顶点坐标float4 pos:SV_POSITION;float3 color:COLOR;};v2f vert(a2v v){v2f o;//利用unity内置的模型-观察-投影矩阵将顶点坐标转换到裁剪空间o.pos=UnityObjectToClipPos(v.vertex);//通过内置变量获取环境光fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;//法线转换到世界坐标//unity_WorldToObject为模型空间到世界空间的变换矩阵的逆矩阵fixed3 worldNormal=normalize(mul(v.normal,(float3x3)unity_WorldToObject));//获取光源方向fixed3 worldLight=normalize(_WorldSpaceLightPos0.xyz);//利用漫反射光照公式计算漫反射fixed3 diffuse=_LightColor0.rgb*_Diffuse.rgb*max(0,dot(worldNormal,worldLight));//利用Cg内置反射光线方向计算函数计算反射光线fixed3 reflectDir = normalize(reflect(-worldLight, worldNormal));//mul(unity_ObjectToWorld, v.vertex)将顶点坐标转换为世界坐标//视角方向=摄像头位置-顶点位置fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - mul(unity_ObjectToWorld, v.vertex).xyz);//根据公式计算高光反射fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir, viewDir)), _Gloss);o.color=ambient+diffuse+specular;return o;}fixed4 frag(v2f i):SV_Target{return fixed4(i.color,1.0);}ENDCG}
}
FallBack "Specular"}

这里高光部分明显不平滑,这是因为高光反射的计算是非线性的,而在顶点着色器中计算光照再进行差值的过程是线性的,破坏了原有的视觉问题

逐像素光照

 Shader "Test Shader/SpecularPixelLevel"{
Properties
{_Diffuse ("Diffuse", Color) = (1, 1, 1, 1)//控制高光反射颜色_Specular ("Specular", Color) = (1, 1, 1, 1)//控制高光区域大小_Gloss ("Gloss", Range(8.0, 256)) = 20
}
SubShader
{Pass{Tags { "LightMode"="ForwardBase" }CGPROGRAM#pragma vertex vert#pragma fragment frag#include "Lighting.cginc"fixed4 _Diffuse;fixed4 _Specular;float _Gloss;struct a2v{//模型空间的顶点坐标float4 vertex:POSITION;//模型空间的法线方向float3 normal:NORMAL;};struct v2f{//输出的是裁剪空间的顶点坐标float4 pos:SV_POSITION;float3 worldNormal:TEXCOORD0;float3 worldPos:TEXCOORD1; };v2f vert(a2v v){v2f o;//利用unity内置的模型-观察-投影矩阵将顶点坐标转换到裁剪空间o.pos=UnityObjectToClipPos(v.vertex);//法线转换到世界坐标//unity_WorldToObject为模型空间到世界空间的变换矩阵的逆矩阵o.worldNormal=normalize(mul(v.normal,(float3x3)unity_WorldToObject));o.worldPos=mul(unity_ObjectToWorld, v.vertex).xyz;return o;}fixed4 frag(v2f i):SV_Target{//通过内置变量获取环境光fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;fixed3 worldNormal=normalize(i.worldNormal);//获取光源方向fixed3 worldLight=normalize(_WorldSpaceLightPos0.xyz);//利用漫反射光照公式计算漫反射fixed3 diffuse=_LightColor0.rgb*_Diffuse.rgb*max(0,dot(worldNormal,worldLight));//利用Cg内置反射光线方向计算函数计算反射光线fixed3 reflectDir = normalize(reflect(-worldLight, worldNormal));//mul(unity_ObjectToWorld, v.vertex)将顶点坐标转换为世界坐标//视角方向=摄像头位置-顶点位置fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);//根据公式计算高光反射fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir, viewDir)), _Gloss);return fixed4(ambient+diffuse+specular,1.0);}ENDCG}
}
FallBack "Specular"}

这样的光照反射模型更平滑,而这一光照模型就是著名的phong光照模型

Blinn-Phong光照模型

blinn模型没有使用反射方向。而是引入了矢量h

h⃗ =(v⃗ +l⃗ )|v⃗ +l⃗ |

\vec{h}=\frac{(\vec{v}+\vec{l})}{|\vec{v}+\vec{l}|}
blinn模型光照公式如下

Cdiffuse=(Clight∗Mdiffuse)∗max(0,n⃗ ∗h⃗ )Mgloss

C_{diffuse}=(C_{light}*M_{diffuse})*max(0,\vec{n}*\vec{h})^{M_{gloss}}

Shader "Test Shader/BlinnPhone"{
Properties
{_Diffuse ("Diffuse", Color) = (1, 1, 1, 1)//控制高光反射颜色_Specular ("Specular", Color) = (1, 1, 1, 1)//控制高光区域大小_Gloss ("Gloss", Range(8.0, 256)) = 20
}
SubShader
{Pass{Tags { "LightMode"="ForwardBase" }CGPROGRAM#pragma vertex vert#pragma fragment frag#include "Lighting.cginc"fixed4 _Diffuse;fixed4 _Specular;float _Gloss;struct a2v{//模型空间的顶点坐标float4 vertex:POSITION;//模型空间的法线方向float3 normal:NORMAL;};struct v2f{//输出的是裁剪空间的顶点坐标float4 pos:SV_POSITION;float3 worldNormal:TEXCOORD0;float3 worldPos:TEXCOORD1; };v2f vert(a2v v){v2f o;//利用unity内置的模型-观察-投影矩阵将顶点坐标转换到裁剪空间o.pos=UnityObjectToClipPos(v.vertex);//法线转换到世界坐标//unity_WorldToObject为模型空间到世界空间的变换矩阵的逆矩阵o.worldNormal=normalize(mul(v.normal,(float3x3)unity_WorldToObject));o.worldPos=mul(unity_ObjectToWorld, v.vertex).xyz;return o;}fixed4 frag(v2f i):SV_Target{//通过内置变量获取环境光fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;fixed3 worldNormal=normalize(i.worldNormal);//获取光源方向fixed3 worldLight=normalize(_WorldSpaceLightPos0.xyz);//利用漫反射光照公式计算漫反射fixed3 diffuse=_LightColor0.rgb*_Diffuse.rgb*max(0,dot(worldNormal,worldLight));//mul(unity_ObjectToWorld, v.vertex)将顶点坐标转换为世界坐标//视角方向=摄像头位置-顶点位置fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);//计算矢量hfixed3 h=normalize(worldLight+viewDir);//根据公式计算高光反射fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(worldNormal, h)), _Gloss);return fixed4(ambient+diffuse+specular,1.0);}ENDCG}
}
FallBack "Specular"}

这样的高光反射模型反射部分更大更亮些,大多数情况下,我们都会选择这一高光反射模型
最后结果如下

从右到左分别是逐顶点光照,逐像素光照phong模型,blinn模型

shader篇-高光反射模型相关推荐

  1. Unity Shader学习-高光反射

    Unity Shader学习-高光反射 高光反射计算公式 高光反射 = 光源的色彩和强度 * 材质的高光反射系数 * pow(max(0,视角方向 · 反射方向),_Gloss) 视角方向 = ref ...

  2. Shader实现高光反射

    高光反射又叫做镜面反射:用于模拟有光泽物体的上面出现的光点.高光反射的颜色相比于物体的颜色会更倾向与光的颜色.(漫反射:模拟光源对物体的方向性影响.) 首先是Phong光照模型: 公式: v是视角方向 ...

  3. Shader编程——高光漫反射模型

    在实现该模型之前,我对shader和计算机图形学的知识可谓是空白,但是立志成为伟大游戏设计师的我又怎么能放弃对梦想的探寻,在网上寻找相应的课程,恰好看到一篇关于Shader入门的教程,学完之后觉得有所 ...

  4. Unity Shader知识点(三)高光反射Shader

    前言 此文及专栏系是以Shader入门精要为基础整理的Unity Shader学习笔记,尽量以初学者视角还原(其实半年前我就是初学者),错误还需指正. 本篇是实操部分的第三个Shader,即高光反射S ...

  5. 问题六十八:着色模型(shading model)(1)——反射模型(reflection model)(2.2)——高光反射(specular reflection)

    和diffuse reflection对应的是specular reflection.一直以来,本人都将"specular reflection"理解为"镜面反射&quo ...

  6. Q87:间接光照(Indirect Illumination)的高光反射(Glossy Reflcetion)

    87.1 建立模型 接下来就是采样啦! 之前,我们遇到过的采样一般都是对撞击点处的上半球面进行采样,比如: 这是因为cos分布对应的夹角是光线和法向量的夹角. 但是,我们这里对应的夹角是光线和镜面反射 ...

  7. Q85:对比“直接光照”和“间接光照”的反射模型

    这里只是罗列"直接光照"和"间接光照"的反射模型的示意图.这一章节的作用主要是:联系之前学过的反射模型(漫反射模型.高光反射模型)和接下来将要学习的反射模型. ...

  8. 问题六十八:着色模型(shading model)(1)——反射模型(reflection model)(3.1)——辐射学(Radiometry)

    前面,我们已经学习了各种反射模型.罗列如下. 漫反射模型: 高光反射模型: 根据这些模型,我们已经可以进行编程,然后生成图形.但是,为了加强这些模型的数学基础,我们引入辐射学(Radiometry)的 ...

  9. 着色 Shading,漫反射,高光,环境光,Blinn-Phong 反射模型,Flat Shading,Gouraud Shading,图形管线 Graphics Pipeline渲染总结

    着色 Shading shading:The darkening or coloring of an illustration or diagram with parrel lines or a bl ...

  10. shader基础学习摘要(三)高光反射

    高光反射 理论推导 代码实践 Phone光照模型 逐顶点 逐像素 Blinn-Phong光照模型 内置函数 理论推导 在6.2.4节中,我们给出了基本光照模型中高光反射部分的计算公式 高光反射求的夹角 ...

最新文章

  1. Review meeting还开不开?
  2. 北京昌平计算机职业高中学校,北京职业学校2021中专
  3. Uvaoj 10048 - Audiophobia(Floyd算法变形)
  4. vue04-components
  5. Javascript特效:不断在页面跑的星星
  6. oracle、mysql、sqlserver、pg数据库去重实现方案总结
  7. 王阳明:志不立,天下无可成之事
  8. 微信支付系列(三)之二维码扫码支付
  9. 矩阵论(四)——矩阵的广义逆
  10. Mac 使用brew 安装工具报错 Your CLT does not support macOS 11
  11. 《Cocos Creator游戏实战》游戏转场时如何保留节点信息
  12. Prediction of Multidrug-Resistant TB from CT Pulmonary Images Based on Deep Learning Techniques论文总结
  13. 毕业设计-基于SpringBoot小区物业管理系统
  14. vscode运行Live Server报错:Windows找不到文件‘chrome‘,请确定文件名是否正确后,再试一次。
  15. 户外顶级装备---安全套和卫生巾!(转载)
  16. 聊天室 1.0 (TCP协议)客户端
  17. 35岁前成功的黄金法则(1)-一个目标
  18. 深度学习——Face Verificaton(人脸验证)与Face Recognition(人脸识别)在FaceNet的应用案例
  19. 计算机任务驱动法教学应用,中职计算机教学中应用任务驱动法的途径
  20. mysql 中的删除列_如何从MySQL中的表中删除列?

热门文章

  1. 剑指 Offer(C++版本)系列:剑指 Offer 10- I 斐波那契数列
  2. PVR个人视频录像机 - XBMC 12.0(Frodo)新功能
  3. java的datasource_JAVA创建DataSource
  4. [dp][思维]Paranoid String CF1694B
  5. Mantis 安装与配置及使用
  6. Qt随机数生成器:QRandomGenerator
  7. mysql导出的身份证格式错误
  8. 《生命科学50讲》课程笔记9--自我
  9. EOJ 1864 二分图匹配
  10. LVS配合piranha安装使用