Unity Shader URP 学习 基础光照
首先是几种常见的基础光照模型的简单说�?/p>
简�?/span> 用于模拟漫反射的光照模型,相关的维基百科
光照公式
Diffuse = max(0,dot(nDir, LightDir))
关于HalfLambert(半兰伯特)光照模型
光照公式
Diffuse = dot(nDir, LightDir)*0.5+0.5
关于Phong(冯氏)光照模型
光照公式
最终片段颜色:环境颜色+漫反射颜�?镜面反射颜色
环境颜色 = 光源的环境光颜色 × 物体的环境材质颜�?
漫反射颜�?= 光源的漫反射光颜�?× 物体的漫反射材质颜色 × 漫反射因�?/p>
镜面反射颜色 = 光源的镜面光颜色 × 物体的镜面材质颜�?× 镜面反射因子
镜面反射最终颜�?= 直射光颜�?* 反射光颜�?* pow(max(0, dot(反射光方�? 视野方向)), 光泽�?gloss)) + 漫反射颜�?+ 环境光颜�?/p>

关于BlinnPhong光照模型
参考:
光照公式
最终颜�?= 直射光颜�?* 反射光颜�?* pow(max(0, dot(法线方向, 视野与光线中间向�?), 光泽�?gloss)) + 漫反射颜�?+ 环境光颜�?/p>
关于Fresnel Reflection/Term
https://www.scratchapixel.com/lessons/3d-basic-rendering/introduction-to-shading/reflection-refraction-fresnel
-
光照公式
Fresnel = pow((1-dot(法线方向, 视方�?),系数);
关于URP
官方关于URP的文�?/a>
URP下的基础光照模型Shader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
Shader "Costom/StandardBlinnPhong"
{
Properties{
[MainColor]_DiffuseColor("Diffuse", Color) = (1, 1, 1, 1)
[MainTexture]_MainTex("Main Tex", 2D) = "white"{}
[Normal]_NormalMap("Normal Map",2D) = "bump"{}
_NormalScale("NormalScale",Range(0,1)) = 0
[Toggle] _UseCubMap("Use Cub Map", Int) = 0
_CubMap("Env Map",CUBE) = ""{}
_Metallic("Metallic",Range(0,1)) = 0
_Smoothness("Smoothness",Range(0,1)) = 0
_Fresnel("Fresnel",Range(0,100)) = 4
}
SubShader
{
Tags{"RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
HLSLINCLUDE
struct a2v
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
float4 tangent : TANGENT;
};
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float3 posWS : TEXCOORD1;
float3 nDirWS : TEXCOORD2;
float3 tDirWS : TEXCOORD3;
float3 bDirWS : TEXCOORD4;
float4 shadowCoord : TEXCOORD5;
};
CBUFFER_START(UnityPerMaterial)
float4 _DiffuseColor;
real4 _MainTex_ST;
real _NormalScale;
float _Metallic;
float _Smoothness;
float _Fresnel;
CBUFFER_END
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
TEXTURE2D(_NormalMap);
SAMPLER(sampler_NormalMap);
TEXTURECUBE(_CubMap);
SAMPLER(sampler_CubMap);
ENDHLSL
Pass
{
Tags{"LightMode" = "UniversalForward"}
HLSLPROGRAM
v2f vert(a2v i)
{
v2f o;
o.posWS = TransformObjectToWorld(i.vertex.xyz);
o.pos = TransformWorldToHClip(o.posWS);
o.uv = TRANSFORM_TEX(i.uv, _MainTex);
o.nDirWS = TransformObjectToWorldNormal(i.normal);
o.tDirWS = normalize(TransformObjectToWorldDir(i.tangent.xyz));
o.bDirWS = normalize(cross(o.nDirWS,o.tDirWS)*i.tangent.w);
o.shadowCoord = TransformWorldToShadowCoord(o.posWS);
return o;
}
half4 frag(v2f i) : SV_Target
{
float3x3 TBN = float3x3(i.tDirWS,i.bDirWS,i.nDirWS);
float3 nDirWS = normalize(i.nDirWS);
float4 normalMap = SAMPLE_TEXTURE2D(_NormalMap,sampler_NormalMap,i.uv);
float3 normal = UnpackNormal(normalMap);
normal.z = sqrt(1.0 - saturate(dot(normal.xy,normal.xy)));
normal = TransformTangentToWorld(normal,TBN);
normal = normalize(normal);
nDirWS = lerp(nDirWS,normal,_NormalScale);
Light mainLight = GetMainLight(TransformWorldToShadowCoord(i.posWS));
Light mainLight = GetMainLight();
real4 lightColor = real4(mainLight.color, 1);
float3 lightDir = mainLight.direction;
half shadow = mainLight.shadowAttenuation;
half3 vDirWS = normalize(_WorldSpaceCameraPos.xyz - i.posWS);
float3 refWS = normalize(reflect(-vDirWS,nDirWS));
float nDotL = dot(nDirWS, lightDir);
float nDotV = dot(nDirWS, vDirWS);
float lambert = max(0.0,nDotL);
float fresnel = pow((1-nDotV),_Fresnel);
float3 halfVec = normalize(lightDir+vDirWS);
float blinnPhong = saturate(dot(nDirWS, halfVec));
float3 reflectDir = normalize(reflect(-lightDir,nDirWS));
float phong = max(0.0,dot(reflectDir,vDirWS));
half4 ambientLight = half4(SampleSH(nDirWS),1);
ambientLight = SAMPLE_TEXTURECUBE_LOD(_CubMap,sampler_CubMap,refWS,(255-_Smoothness*255)*8/255);
_DiffuseColor = pow(max(0.02,_DiffuseColor),1.1);
half4 mainColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv);
float4 ambient = ambientLight*_DiffuseColor*_Metallic;
float4 diffuse = ((lightColor*lambert*shadow+half4(SampleSH(nDirWS),1))*mainColor*_DiffuseColor)*(1-(_Metallic+_Smoothness)*0.5);
float4 specular = lightColor*lerp(smoothstep(0,0.9,pow(blinnPhong,_Smoothness*255)),float4(0,0,0,0),(1-_Smoothness))*shadow;
specular = lerp(specular,_DiffuseColor*specular,_Metallic)+fresnel*ambientLight*_Smoothness;
float4 result= (ambient+diffuse+specular);
return result;
}
ENDHLSL
}
pass
{
Tags
{
"LightMode"="ShadowCaster"
}
HLSLPROGRAM
v2f vertshadow(a2v i)
{
v2f o;
Light MainLight=GetMainLight();
float3 posWS=TransformObjectToWorld(i.vertex.xyz);
float3 nDirWS=TransformObjectToWorldNormal(i.normal.xyz);
o.pos=TransformWorldToHClip(ApplyShadowBias(posWS,nDirWS,MainLight.direction));
o.pos.z=min(o.pos.z,o.pos.w*UNITY_NEAR_CLIP_VALUE);
o.pos.z=max(o.pos.z,o.pos.w*UNITY_NEAR_CLIP_VALUE);
return o;
}
half4 fragshadow(v2f i):SV_TARGET{
return 0;
}
ENDHLSL
}
}
}
光照公式
Diffuse = max(0,dot(nDir, LightDir))
光照公式
Diffuse = dot(nDir, LightDir)*0.5+0.5
光照公式
最终片段颜色:环境颜色+漫反射颜�?镜面反射颜色
环境颜色 = 光源的环境光颜色 × 物体的环境材质颜�?
漫反射颜�?= 光源的漫反射光颜�?× 物体的漫反射材质颜色 × 漫反射因�?/p>
镜面反射颜色 = 光源的镜面光颜色 × 物体的镜面材质颜�?× 镜面反射因子
镜面反射最终颜�?= 直射光颜�?* 反射光颜�?* pow(max(0, dot(反射光方�? 视野方向)), 光泽�?gloss)) + 漫反射颜�?+ 环境光颜�?/p>

参考:
光照公式
最终颜�?= 直射光颜�?* 反射光颜�?* pow(max(0, dot(法线方向, 视野与光线中间向�?), 光泽�?gloss)) + 漫反射颜�?+ 环境光颜�?/p>
https://www.scratchapixel.com/lessons/3d-basic-rendering/introduction-to-shading/reflection-refraction-fresnel
光照公式
Fresnel = pow((1-dot(法线方向, 视方�?),系数);
官方关于URP的文�?/a>
URP下的基础光照模型Shader
1 | Shader "Costom/StandardBlinnPhong" |
关于本文
本文作�?Master Gong Sheng, 许可�?CC BY-NC 4.0.