shaderforge Specular通道

一、官方介绍


这是材质的高光的颜色。值越高越亮,如果高光值为黑色则完全不会影响shader的表现。

二、通道的输入

1. Specular

可以是高光贴图也可以是高光颜色

2. Gloss

默认值为0.5
gloss用来调制亮斑的大小,一般来讲,gloss越大,光斑越细小,gloss越大,光斑分布越广泛

三、镜面反射简介

对于许多物体,漫反射不够真实,比如擦亮的金属、光滑的塑料。要模拟光滑表面,还需要添加镜面高光反射的颜色,。在金属这样的光滑表现上,能模拟出光泽

1. 理想镜面反射

一束平行光射到平面镜上,入射光严格遵循光的反射定律平行的反射出去,这种反射叫做镜面反射。

2. 非理想镜面反射

现实中的物体表面都不是完全光滑的。在微观上物体的表面面元是由许多朝向的微小平面组成,其镜面反射光分布于物体镜面反射方向的周围。

3. 镜面反射光特点

  • 跟入射方向有关
  • 跟观察的角度有关

黑暗的房间中,手电筒的光射向一面镜子,只有眼睛与光线平行的时候才能看到光,改变观察的角度看到不到光。

四、光照模型

1. Phong光照模型

Phong光照模型属于经验模型,它在Lambert模型(纯漫反射模型)的基础上考虑了镜面反射的效果,该模型只考虑物体对方向光的镜面反射作用,不考虑环境光的镜面反射(认为环境光只发生漫反射),主要用来模拟光滑物体表面的光照现象。

此模型假设物体表面为非理想镜面反射体(既会发生漫反射也会发生镜面发射,且镜面反射为非理想的镜面反射),场景中存在两种光,一种为环境光,一种为方向光,然后我们分别计算这两种光照射到物体表面所产生的光照现象(注意:phong不考虑环境光的镜面反射,也就是说我们要考虑到环境光的漫反射和方向光的漫反射和镜面反射),最后再将两个结果相加,得出反射后的光强值。

首先是计算环境光的公式:

I_inDirectionDiffuse = K_d * I_a;

其中,K_d为粗糙物体表面材质对光的反射系数,这个系数由程序编写者在宿主程序中给出,I_a为环境光的光强,也就是环境光的颜色数值,一般是一个float3型的变量

然后是计算方向光的公式:

I_direction = I_directionDiffuse + I_directionSpecular;
I_directionDiffuse = K_d * I_l * max(0,dot(N, L)); //方向光漫反射强度
I_directionSpecular = K_d * I_l * pow( max(0, dot(R,V)), n); //方向光镜面射强度

其中I_l为方向光的光强,也就是其颜色值;N为顶点的单位法向量;L为入射光的单位法向量(注意,光照向量是从顶点指向光源的向量;也就是,它与线的传播方向正好相反)。R表示反射光的单位向量,V为顶点到视点的向量。

我们知道,在理想状况下,镜面反射后的光之集中在一条线上,因此我们的视线离这条线的距离越近,射入我们眼中的光线就越多,我们看到的光强也就越强。同时,镜面反射也与物体表面的高光指数(物体表面光泽程度)有关,其数值越大,反射后的光线越集中,反之则越分散。方向光的镜面反射光照强度遵循Phong余弦定理。

综上,得出漫反射和镜面反射叠加后的光强为:

I_diff = K_d * I_a + K_d * I_l * max(0,dot(N, L)) + K_d * I_l * pow( max(0, dot(R,V)), n);

反射方向的计算


L为入射光(顶点到光源)的单位法向量,N为顶点的单位法向量,R为反射光的单位法向量,V是观察方向。

推导过程:
L在N方向上的投影是|Lcosθ|=cosθ,那么投影矢量N’=Ncosθ
L+S = N’ = Ncosθ
R = L+2S = L+2(Ncosθ-L) = 2Ncosθ-L

结果:

R=2(N•L)N-L

Phong余弦定理

反射光的明亮度直接取决于反射光向量(R)和视角向量(V)两个向量将夹角的余弦值。

f(θ) = max(cosθ,0) = max(R•V,0)

对材质表面粗糙程度对反射光强的影响

非理想镜面的表面并非完全光滑,也就是说会发生散射,其镜面反射光分布于物体镜面反射方向的周围,物体表面粗糙程度越大,散射越大。

理想镜面的反射光照强度为:R dot V

非理想镜面的反射光照强度为:(R dot V)^n
n为镜面放射指数,也称高光指数,反映物体表面的粗糙程度。n越大高光亮度随α的增大衰减的越快。

n的取值于表面粗糙程度有关,
- n越大,表面越光滑(散射现象小,稍一偏离,明暗亮度急剧下降)
- n越小,表面越毛躁(散射现象严重)

2. Blinn-phong光照模型

相比较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|)

Blinn-phong余弦定理

反射光的明亮度直接取决于入射光和视角向量的半角(H)和法线向量(N)两个向量将夹角的余弦值。

f(θ) = max(cosθ,0) = max(H•N,0)

五、自定义UnityShader实现Blinn-phong光照模型

写法

Shader "Hidden/NewImageEffectShader"
{Properties{_MainTex ("Texture", 2D) = "white" {}_DiffusePower("Diffuse Power", Float) = 1.0//_SpecularTex("Specular Tex", 2D) = "white"{}_Gloss("Specular Gloss", Float) = 0.5_SpecularColor("Specular Color", Color) = (1,1,1,1)}SubShader{Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"#include "Lighting.cginc"#include "AutoLight.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;float3 normal : NORMAL;};struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;float3 normalDir : TEXCOORD1;float4 posWorld : TEXCOORD2;};v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = v.uv;// 将物体法线从物体坐标系转换到世界坐标系o.normalDir = UnityObjectToWorldNormal(v.normal);o.posWorld = mul(unity_ObjectToWorld, v.vertex);return o;}sampler2D _MainTex;float _DiffusePower;// sampler2D _SpecularTex; // 这里我们直接用viewDirection和lightDirection的点积来计算反射光强度而不是使用高光图float _Gloss;float4 _SpecularColor;fixed4 frag (v2f i) : SV_Target{// 法线方向float3 normalDirection = normalize(i.normalDir);// 灯光方向float lightDirection = normalize(_WorldSpaceLightPos0.xyz);// 灯光颜色float3 lightColor = _LightColor0.rgb;// 视线方向float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);// 视线方先与法线方向的中间向量float3 halfDirection = normalize(viewDirection+lightDirection);// 计算灯光衰减float attenuation = LIGHT_ATTENUATION(i);float3 attenColor = attenuation * _LightColor0.xyz;// 基于兰伯特模型计算漫反射灯光float NdotL = max(0,dot(normalDirection,lightDirection));// 方向光float3 directionDiffuse = pow(NdotL, _DiffusePower) * attenColor;// 环境光  float3 inDirectionDiffuse = float3(0,0,0)+UNITY_LIGHTMODEL_AMBIENT.rgb;// 基于Blinn Phong计算镜面反射灯光float specPow = exp2( _Gloss * 10.0 + 1.0 );float3 directionSpecular = attenColor*  _SpecularColor*(pow(max(0,dot(halfDirection,normalDirection)),specPow));// 灯光与材质球表面颜色进行作用float3 texColor = tex2D(_MainTex, i.uv).rgb;float3 diffuseColor = texColor *(directionDiffuse+inDirectionDiffuse);float3 specularColor = directionSpecular;float4 finalColor = float4(diffuseColor+specularColor,1);return finalColor;}ENDCG}}
}

效果展示

参考

Phong光照模型、Blinn-phong光照模型归纳
光照模型PPT
光照模型
PBR Step by Step( 五)Phong反射模型

【shaderforge学习笔记】 Specular(高光)通道相关推荐

  1. opencv 学习笔记6:通道的拆分与合并

    python + opencv 通道拆分 原始方法 import cv2 img=cv2.imread('图像名') b=img[:,:,0] g=img[:,:,`1] r=img[:,:,2] 新 ...

  2. 【shaderforge学习笔记】 Parallax节点(视差节点)

    shaderforge Parallax节点 一.官方说明 Parallax节点输出的uv是输入的uv经过视差偏移的得到结果,其中视差偏移程由[Hei]指定,[Hei]在计算偏移量时有两个相关参数:深 ...

  3. 【shaderforge学习笔记】 Vector Operations(向量运算)

    shaderforge 向量运算 Append数据维度的附加 Component Mask数据维度的分解 Channel Blend通道混合 Cross Product叉积 Desaturate去色 ...

  4. 【shaderforge学习笔记】 Hue节点(色相节点)

    shaderforge 色相节点 一.官方说明 根据Hue值输出RGB值,换句话说Hue节点的作用是,将Hue值转为相应的RGB值. 二.节点输入 Hue值 Hue节点输入值的[0,1]对应色相轮的[ ...

  5. Java学习笔记:文件通道(FileChannel)

    文章目录 一.文件通道 (一)概述 (二)继承关系 (三)常用方法 二.案例演示 1.创建Java项目 - FileChannelDemo 2.创建FileChannelDemo类 (1)编写test ...

  6. 【shaderforge学习笔记】 Rotator节点

    ShaderForge Rotator节点 一.节点介绍 旋转器 输出的是输入的uv以[piv]为锚点旋转后[ang] (单位为弧度)的uv信息.如果ang没有连线,或者ang连线到time节点上,那 ...

  7. 【shaderforge学习笔记】 UVTile节点

    shaderforge UVTile节点 一. 介绍 UVTile UVTile可以用来以uv坐标为基准在一个纹理中取到其中一块的贴图. [UV]是整个贴图的UV值 [Wid]指定沿tilemap的x ...

  8. CCC3.0学习笔记_SCP03安全通道

    1. 在安全通道建立的情况下,数据安全交互的应答流程图如下所示,具体步骤解释如下: 1> 避免SCP03安全通道协议中的CMAC与C-MAC的混淆,CMAC是计算C-MAC校验值的一       ...

  9. go语言学习笔记 — 并发编程 — 通道channel(3):各种各样的通道

    3.1 单向通道 在声明通道时,我们可以设置只发送或只接收.这种被约束操作方向的通道称为单向通道. 声明单向通道 只发送:chan<-,只接收:<-chan var 通道实例 chan&l ...

最新文章

  1. 4个计算机视觉领域用作迁移学习的模型
  2. [AX]AX2012 纪录缓存
  3. Toolbar-5.0新特性
  4. java中对于异常的处理,代码简单描述
  5. jzoj3302-[集训队互测2013]供电网络【上下界网络流,费用流,动态加边】
  6. Java:伪造工厂的闭包以创建域对象
  7. git@github.com:Permission denied(publickey).fatal: Could not read form remote repository错误
  8. linux切换到字符界面stemctl,CentOS7两种模式
  9. 程序猿永远就是程序员的命么?
  10. 在windows上搭建redis集群(主从复制)
  11. leetcode448-Find All Numbers Disappeared in an Array
  12. Java抽象类、接口和内部类
  13. DOM注册事件的三种方式~满满的干货哦
  14. tensorflow学习笔记(1)如何高效地学习TensorFlow(附链接)
  15. 无线网络通信技术介绍
  16. 数学建模一:层次分析法 附代码详解
  17. 软件测试培训之十个无脚本测试方案
  18. 前端大屏适配几种方案
  19. 回车符,换行符与'\0'
  20. java spark 二进制_spark数据源操作

热门文章

  1. ECharts数据可视化(第三章实训)
  2. 用NPOI操作EXCEL-NPOI计算公式-通过NPOI获得公式的返回值
  3. 软件开发成本太高,怎么办?
  4. startuml动态模型工具_StarUML建模工具
  5. 传统PC和云桌面的五大差异
  6. MySQL ERROR:1153 的解决方法
  7. bem什么意思_BEM是什么?
  8. 有无SSL证书,网站安全大不同
  9. 6.4下周黄金最新行情走势分析及开盘交易策略
  10. 捷径系列:Notification