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
|
#ifndef __PBR_INC__
#define __PBR_INC__
#include "AutoLight.cginc"
#include "eyes_data.cginc"
#include "UnityPBSLighting.cginc"
float _Enable_Custom_Cubemap;
UNITY_DECLARE_TEXCUBE(_Custom_Cubemap);
sampler2D _Matcap;
float _Matcap_Str;
float _Enable_Matcap;
float _Matcap_Mode;
UnityIndirect GetIndirect(v2f i, float3 view_dir, float smoothness) {
UnityIndirect indirect;
indirect.diffuse = 0;
indirect.specular = 0;
#if defined(VERTEXLIGHT_ON)
indirect.diffuse = i.vertexLightColor;
#endif
#if defined(FORWARD_BASE_PASS)
indirect.diffuse += max(0, ShadeSH9(float4(i.normal, 1)));
float3 reflect_dir = reflect(-view_dir, i.normal);
// There's a nonlinear relationship between mipmap level and roughness.
float roughness = 1 - smoothness;
roughness *= 1.7 - .7 * roughness;
float3 env_sample;
if (_Enable_Custom_Cubemap) {
env_sample = UNITY_SAMPLE_TEXCUBE_LOD(
_Custom_Cubemap,
reflect_dir,
roughness * UNITY_SPECCUBE_LOD_STEPS);
} else {
env_sample = UNITY_SAMPLE_TEXCUBE_LOD(
unity_SpecCube0,
reflect_dir,
roughness * UNITY_SPECCUBE_LOD_STEPS);
}
if (_Enable_Matcap) {
// identity: (a, b, c) and (c, c, -(a +b)) are perpendicular to each other
float3 ortho_1 = normalize(float3(view_dir.z, view_dir.z, -(view_dir.y + view_dir.x)));
float3 ortho_2 = cross(view_dir, ortho_1);
float2 matcap_uv = (float2(dot(i.normal, ortho_1), dot(i.normal, ortho_2)) + 1) * .43;
float iddx = ddx(i.uv.x);
float iddy = ddy(i.uv.y);
float3 matcap = tex2Dgrad(_Matcap, matcap_uv, iddx, iddy) * _Matcap_Str;
int mode = round(_Matcap_Mode);
switch (mode) {
case 1:
indirect.specular = clamp(env_sample + matcap, 0, 1);
break;
case 2:
indirect.specular = clamp(env_sample * matcap, 0, 1);
break;
case 3:
indirect.specular = clamp(matcap, 0, 1);
break;
case 4:
indirect.specular = clamp(env_sample - matcap, 0, 1);
break;
}
} else {
indirect.specular = env_sample;
}
#endif
return indirect;
}
UnityLight GetLight(v2f i)
{
UNITY_LIGHT_ATTENUATION(attenuation, 0, i.worldPos.xyz);
float3 light_color = _LightColor0.rgb * attenuation;
UnityLight light;
light.color = light_color;
#if defined(POINT) || defined(POINT_COOKIE) || defined(SPOT)
light.dir = normalize(_WorldSpaceLightPos0.xyz - i.worldPos);
#else
light.dir = _WorldSpaceLightPos0.xyz;
#endif
light.ndotl = DotClamped(i.normal, light.dir);
return light;
}
void initNormal(inout v2f i)
{
i.normal = normalize(i.normal);
}
float4 light(inout v2f i,
float4 albedo,
float metallic,
float smoothness)
{
initNormal(i);
float3 specular_tint;
float one_minus_reflectivity;
albedo.rgb = DiffuseAndSpecularFromMetallic(
albedo, metallic, specular_tint, one_minus_reflectivity);
float3 view_dir = normalize(_WorldSpaceCameraPos - i.worldPos);
float3 pbr = UNITY_BRDF_PBS(albedo,
specular_tint,
one_minus_reflectivity,
smoothness,
i.normal,
view_dir,
GetLight(i),
GetIndirect(i, view_dir, smoothness)).rgb;
return float4(saturate(pbr), albedo.a);
}
float getWorldSpaceDepth(in float4 world_pos)
{
float4 clip_pos = mul(UNITY_MATRIX_VP, world_pos);
return LinearEyeDepth(clip_pos.z / clip_pos.w);
}
sampler2D _CameraDepthTexture;
// Return depth buffer at coordinate, on [0, 1].
float getDepthBufferAt(in float4 world_pos)
{
float4 clip_pos = mul(UNITY_MATRIX_VP, world_pos);
float4 uv = ComputeGrabScreenPos(clip_pos);
return LinearEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv.xy / uv.w));
}
#endif // __PBR_INC__
|