事实上,我们在前面所有的章节所做的操作都没涉及到光照模型。
我们只是给他赋予了某种颜色,没有接受来自外界光照的这种干涉。这和现实情况是背离的是吧。也不算,比如我们的灯泡就不受其它干扰,这种光照叫做自发光
Emissive
其实举个最简单的例子:
我无论怎么变化平行光属性,
对应的效果都不会有变化。
这就是没加光照的。
那么这一章我们要考虑光照。
我们所看到的物体 = 物体的漫反射+环境光。
而根据计算物体光照的位置不同,有逐顶点光照和逐像素光照。
差别不大,就是放在顶点着色器和片元着色器的区别。
来看一下怎么获取漫反射:
漫反射颜色值 = (光源的rgb*定义的漫反射强度rgb)*max(0,dot(基于世界坐标系的模型法线,光源在世界空间坐标系下的位置))
接下来介绍怎么获取上述公式中的一些相关参数。
1.光源的rgb
我们在Scnene定义的光源,产生的rgb都可以通过Unity内置的函数库
去获取。
当我们引入该函数库后,shader自动编译,现在你可以通过
_LightColor0.rgb
获取光源的rgb。
2.光照强度,这个是你自己定义的Properties属性,具体操作请看前面的教程。
3.max函数
saturate(x,y)
4.模型法线
你可以通过在定义顶点着色器的传入结构体通过
NORMAL语义
获取
5.光源位置
这个库的这个
_WorldSpaceLightPos0.xyz
获取。
来做一个实验吧:
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
Shader "Unlit/Mesh7"
{
Properties
{
_Color("Color",Color) = (1,1,1,1)
_MainTex("Texture", 2D) = "white" {}
}
SubShader
{
Tags {"LightModel" = "ForwardBase" }
LOD 100
Pass
{
//ZWrite Off
//Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vertex
#pragma fragment fragment
// make fog work
// #pragma multi_compile_fog
#include "UnityCG.cginc"
#include "Lighting.cginc"
struct fromCpu
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal:NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : POSITION;
float4 color: COLOR0;
float3 normal:TEXCOORD1;
float3 wPos :TEXCOORD2;
};
sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _Color;
half4 c1;
v2f vertex(fromCpu v)
{
v2f o;
float3 objectNormal = UnityObjectToWorldNormal(v.normal);
float3 lightPos = _WorldSpaceLightPos0.xyz;
float3 lightColor = _LightColor0.rgb;
float3 colorPower = _Color.rgb;
objectNormal = normalize(objectNormal);
lightPos = normalize(lightPos);
float3 reColor = (lightColor*colorPower)*dot(objectNormal, lightPos);
o.normal = UnityObjectToWorldNormal(v.normal);
o.vertex = UnityObjectToClipPos(v.vertex);
o.color.rgb = reColor;
return o;
}
fixed4 fragment(v2f i) : SV_Target
{
return i.color;
}
ENDCG
}
}
}
2.获取环境光
效果没差多少
这是逐顶点光照,逐像素光照差不多,就是计算放在片元,没啥东西,不讲了。