镜面高光
上节学习了漫反射,这节我们来探索下镜面反射(高光),镜面反射可以让物体看起来是有光泽的,比如金属材质。
通过上图我们可以清楚的看到,镜面反射和入射光,法向量,反射光方向,视角方向这几个因素有关, 很明显我们可以通过反射光的方向和视角方向的夹角来计算镜面反射强度,如果夹角越小,那么镜面反射光的强度就越大。
计算公式:
在CG中,我们可以通过
reflect(I,n)
函数来计算反射光方向,
I
代表入射光方向,
n
代表法向量。
更多常用函数可以参考
这篇文章
shader代码:
//高光反射(Specular)
Shader
"lcl/005_Specular_fargment"
{
Properties
{
//主纹理
_MainTex
(
"Texture"
,
2D
)
=
"white"
{
}
//整体颜色
_Color
(
"Diffuse Color"
,
Color
)
=
(
1
,
1
,
1
,
1
)
// 高光颜色
_Specular
(
"_Specular Color"
,
Color
)
=
(
1
,
1
,
1
,
1
)
// 高光强度
_Gloss
(
"Gloss"
,
Range
(
8
,
200
)
)
=
10
}
SubShader
{
Pass
{
Tags
{
"LightMode"
=
"ForwardBase"
}
CGPROGRAM
#include
"Lighting.cginc"
#
pragma
vertex vert
#
pragma
fragment frag
// 变量定义
sampler2D
_MainTex
;
fixed4
_Color
;
half
_Gloss
;
fixed4
_Specular
;
//CPU传输到顶点着色器的数据
struct
a2v
{
// 顶点坐标
float4
vertex
:
POSITION
;
// 法向量
float3
normal
:
NORMAL
;
// 纹理坐标
float3
texcoord
:
TEXCOORD0
;
}
;
//顶点传输到片元着色器的数据
struct
v2f
{
//顶点坐标
float4
position
:
SV_POSITION
;
// 世界空间下的法向量
float3
worldNormal
:
TEXCOORD0
;
// 世界空间下坐标
float3
worldVertex
:
TEXCOORD1
;
// 纹理坐标
float3
texcoord
:
TEXCOORD2
;
}
;
//顶点着色
v2f
vert
(
a2v
v
)
{
v2f
f
;
f
.
position
=
UnityObjectToClipPos
(
v
.
vertex
)
;
f
.
worldNormal
=
mul
(
v
.
normal
,
(
float3x3
)
unity_WorldToObject
)
;
f
.
worldVertex
=
mul
(
v
.
vertex
,
unity_WorldToObject
)
.
xyz
;
f
.
texcoord
=
v
.
texcoord
;
return
f
;
}
;
// 片元着色器
fixed4
frag
(
v2f
f
)
:
SV_TARGET
{
//纹理颜色
float4
texColor
=
tex2D
(
_MainTex
,
f
.
texcoord
)
;
// 环境光
fixed3
ambient
=
UNITY_LIGHTMODEL_AMBIENT
.
rgb
;
//法向量
fixed3
normalDir
=
normalize
(
f
.
worldNormal
)
;
// 光源方向
fixed3
lightDir
=
normalize
(
_WorldSpaceLightPos0
.
xyz
)
;
//漫反射
fixed3
diffuse
=
_LightColor0
.
rgb
*
max
(
dot
(
normalDir
,
lightDir
)
,
0
)
*
_Color
.
rgb
;
//反射光计算
fixed3
reflectDir
=
reflect
(
-
lightDir
,
normalDir
)
;
//计算视角方向
fixed3
viewDir
=
normalize
(
_WorldSpaceCameraPos
.
xyz
-
f
.
worldVertex
)
;
//计算高光反射
fixed3
specular
=
_LightColor0
.
rgb
*
pow
(
max
(
0
,
dot
(
viewDir
,
reflectDir
)
)
,
_Gloss
)
*
_Specular
;
//合并漫反射,环境光,高光反射
fixed3
tempColor
=
diffuse
+
ambient
+
specular
;
//融合纹理颜色
return
fixed4
(
tempColor
*
texColor
.
rgb
,
1
)
;
}
;
ENDCG
}
}
FallBack
"VertexLit"
}
效果颜色;
镜面高光的CG实现
本文探讨了镜面反射(高光)在计算机图形学中的应用,详细讲解了如何利用反射光方向和视角方向的夹角计算镜面反射强度,并提供了一段Shader代码实例,展示了如何在实际项目中实现这一效果。
6270

被折叠的 条评论
为什么被折叠?



