在Unity中,场景渲染是构建高质量游戏和动画的关键环节。其中,光照模型是影响场景真实感的重要因素之一。通过掌握不同的光照模型,我们可以为场景增添丰富的光影效果,让游戏世界更加生动。本文将为您详细介绍Unity中的光照模型,帮助您轻松打造真实光影效果。
一、光照模型概述
光照模型是描述光在场景中传播、反射、折射等现象的数学模型。在Unity中,常见的光照模型包括:
- Lambert光照模型:适用于模拟漫反射,如纸张、石头等。
- Blinn-Phong光照模型:结合了Lambert和Phong模型的特点,适用于大多数场景。
- Physically Based Rendering (PBR)光照模型:基于物理的光照模型,能够更真实地模拟光在场景中的传播和反射。
二、Lambert光照模型
Lambert光照模型是最简单也是最常用的光照模型之一。它假设光线在物体表面均匀反射,适用于模拟漫反射。
1. Lambert光照模型公式
Lambert光照模型公式如下:
[ I = I_d \cdot L \cdot (N \cdot L) ]
其中:
- ( I ) 为场景中的光照强度。
- ( I_d ) 为物体表面反射的光照强度。
- ( L ) 为光源方向向量。
- ( N ) 为物体表面法线向量。
2. 应用示例
以下是一个使用Lambert光照模型的Unity Shader代码示例:
Shader "Custom/LambertShader"
{
Properties
{
_Color ("Base Color", Color) = (1,1,1,1)
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float3 worldNormal : NORMAL;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _Color;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.worldNormal = normalize(mul(unity_ObjectToWorld, float4(v.vertex.xyz, 1.0)).xyz);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed3 color = tex2D(_MainTex, i.uv).rgb;
fixed3 normal = normalize(i.worldNormal);
fixed3 lightDir = normalize(-lightData.direction);
fixed NdotL = dot(normal, lightDir);
return fixed4(color, 1.0) * _Color * NdotL;
}
ENDCG
}
}
}
三、Blinn-Phong光照模型
Blinn-Phong光照模型结合了Lambert和Phong模型的特点,适用于大多数场景。它通过模拟光线在物体表面的反射和折射,为场景增添丰富的光影效果。
1. Blinn-Phong光照模型公式
Blinn-Phong光照模型公式如下:
[ I = I_d \cdot L \cdot (N \cdot L) + I_s \cdot (R \cdot V) ]
其中:
- ( I ) 为场景中的光照强度。
- ( I_d ) 为物体表面反射的光照强度。
- ( I_s ) 为物体表面高光强度。
- ( L ) 为光源方向向量。
- ( N ) 为物体表面法线向量。
- ( R ) 为反射向量。
- ( V ) 为观察者方向向量。
2. 应用示例
以下是一个使用Blinn-Phong光照模型的Unity Shader代码示例:
Shader "Custom/BlinnPhongShader"
{
Properties
{
_Color ("Base Color", Color) = (1,1,1,1)
_SpecColor ("Specular Color", Color) = (1,1,1,1)
_Gloss ("Gloss", Range(0, 256)) = 50
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float3 worldNormal : NORMAL;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _Color;
float4 _SpecColor;
float _Gloss;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.worldNormal = normalize(mul(unity_ObjectToWorld, float4(v.vertex.xyz, 1.0)).xyz);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed3 color = tex2D(_MainTex, i.uv).rgb;
fixed3 normal = normalize(i.worldNormal);
fixed3 lightDir = normalize(-lightData.direction);
fixed3 viewDir = normalize(eyePos - worldPos);
fixed3 halfDir = normalize(lightDir + viewDir);
fixed NdotL = dot(normal, lightDir);
fixed NdotH = dot(normal, halfDir);
fixed3 specColor = tex2D(_SpecColor, NdotH * _Gloss);
return fixed4(color, 1.0) * _Color * NdotL + specColor;
}
ENDCG
}
}
}
四、PBR光照模型
PBR光照模型基于物理的光照模型,能够更真实地模拟光在场景中的传播和反射。它通过考虑材料的光谱、粗糙度和透明度等因素,为场景增添逼真的光影效果。
1. PBR光照模型原理
PBR光照模型主要基于以下原理:
- 材料的光谱:不同材料具有不同的光谱特性,如金属、塑料、木材等。
- 材料的粗糙度:粗糙度会影响光线在物体表面的反射和折射。
- 材料的透明度:透明度会影响光线在物体内部的传播。
2. 应用示例
以下是一个使用PBR光照模型的Unity Shader代码示例:
Shader "Custom/PBRShader"
{
Properties
{
_Color ("Base Color", Color) = (1,1,1,1)
_Metallic ("Metallic", Range(0, 1)) = 0.5
_Roughness ("Roughness", Range(0, 1)) = 0.5
_Emission ("Emission", Color) = (0,0,0,0)
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float3 worldNormal : NORMAL;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _Color;
float _Metallic;
float _Roughness;
float4 _Emission;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.worldNormal = normalize(mul(unity_ObjectToWorld, float4(v.vertex.xyz, 1.0)).xyz);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed3 color = tex2D(_MainTex, i.uv).rgb;
fixed3 normal = normalize(i.worldNormal);
fixed3 lightDir = normalize(-lightData.direction);
fixed3 viewDir = normalize(eyePos - worldPos);
fixed3 halfDir = normalize(lightDir + viewDir);
fixed NdotL = dot(normal, lightDir);
fixed NdotH = dot(normal, halfDir);
fixed3 specColor = tex2D(_SpecColor, NdotH * _Gloss);
return fixed4(color, 1.0) * _Color * NdotL + specColor;
}
ENDCG
}
}
}
五、总结
掌握不同的光照模型,可以帮助我们在Unity中打造真实、生动的光影效果。本文介绍了Lambert光照模型、Blinn-Phong光照模型和PBR光照模型,并提供了相应的Shader代码示例。希望这些内容能对您的Unity场景渲染工作有所帮助。
