6. Vertex Shaders
30. Turning a box into a sphere
Now we’re working in 3D,means we need to change our camera from orthographic camera to perspective camera.
From 42,Change shading mode to sahded Wireframe.
30.1 The Unity Uniform _SinTime
_SinTime.x = sin(time/8)
y = sin(time/4)
z = sin(time/2)
w = sin(time)
30.2 Using position to define a sphere
v.vertex
——square
normalize(v.vertex.xyz)*_Radius*0.01,v.vertex.w
——sphere
这里乘以0.01是因为square 的scale是100
use lerp to change
v2f vert (appdata_base v)
{
v2f o;
float delta = (_SinTime.w + 1)/2;
float4 s = float4(normalize(v.vertex.xyz)*_Radius*0.01, v.vertex.w);
float4 pos = lerp(v.vertex, s, delta);
o.vertex = UnityObjectToClipPos(pos);
return o;
}
31. Using the Unity lighting-Lambert
31.1 Real-time 3D lighting
- Physically correct lighting
- Phong lighting
- Binn-Phong lighting
- Lambert lighting
31.2 Lambert lighting
漫反射是指入射光线被物体表面反射到各个角度,所以反射角度是不确定的,重要的是入射角度。通过入射角度可以确定反射光线的强度。
漫反射光照符合兰伯特定律(Lambert’s law):反射光线的强度与表面法线和光源方向之间夹角的余弦值成正比。因此,漫反射部分的计算如下:
c
d
i
f
f
u
s
e
=
(
c
l
i
g
h
t
⋅
m
d
i
f
f
u
s
e
)
m
a
x
(
0
,
n
⋅
I
)
c_{diffuse}= (c_{light}\cdot m_{diffuse} )max(0,n\cdot I)
cdiffuse=(clight⋅mdiffuse)max(0,n⋅I)
n是表面法线,I是指向光源的单位矢量,
m
d
i
f
f
u
s
e
m_{diffuse}
mdiffuse 是漫反射材质颜色,
c
l
i
g
h
t
c_{light}
clight是光源颜色。防止点乘为负(被来自后面的物体照亮),所以要截取到0。
这里是n到I的投影。
Shader45:
Shader "NiksShaders/Shader45Lit"
{
Properties
{
_Radius("Radius", Float) = 1.0
}
SubShader
{
Tags { "LightMode"="ForwardBase" }//开启前向渲染
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "UnityLightingCommon.cginc"
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 diff : COLOR0; // diffuse lighting color
};
float _Radius;
float _Delta;
v2f vert (appdata_base v)
{
v2f o;
float delta = (_SinTime.w + 1.0)/2.0;
float3 normal = normalize(v.vertex.xyz);
float4 s = float4(normal * _Radius * 0.01, v.vertex.w);
float4 pos = lerp(v.vertex, s, delta);
float3 dnormal = lerp(v.normal,normal,delta);//用来替代v.normal
o.vertex = UnityObjectToClipPos(pos);
//顶点法线变换到世界坐标系,由于光照方向就在世界空间,所以法线也要转换到相同空间
half3 worldNormal = UnityObjectToWorldNormal(dnormal);
half nl = max(0,dot(worldNormal,_WorldSpaceLightPos0.xyz));//光源坐标,点乘后得到标量计算光强,这里叫nl可能是因为noraml*lightDir
o.diff = nl * _LightColor0;//光强*颜色
return o;
}
float4 frag (v2f i) : COLOR
{
fixed4 color = 1;
// multiply by lighting
color *= i.diff;
return color;
}
ENDCG
}
}
}