-
Notifications
You must be signed in to change notification settings - Fork 393
/
UnityDeferredLibrary.cginc
212 lines (162 loc) · 6.45 KB
/
UnityDeferredLibrary.cginc
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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
#ifndef UNITY_DEFERRED_LIBRARY_INCLUDED
#define UNITY_DEFERRED_LIBRARY_INCLUDED
// Deferred lighting / shading helpers
// --------------------------------------------------------
// Vertex shader
struct unity_v2f_deferred {
float4 pos : SV_POSITION;
float4 uv : TEXCOORD0;
float3 ray : TEXCOORD1;
};
float _LightAsQuad;
unity_v2f_deferred vert_deferred (float4 vertex : POSITION, float3 normal : NORMAL)
{
unity_v2f_deferred o;
o.pos = UnityObjectToClipPos(vertex);
o.uv = ComputeScreenPos(o.pos);
o.ray = UnityObjectToViewPos(vertex) * float3(-1,-1,1);
// normal contains a ray pointing from the camera to one of near plane's
// corners in camera space when we are drawing a full screen quad.
// Otherwise, when rendering 3D shapes, use the ray calculated here.
o.ray = lerp(o.ray, normal, _LightAsQuad);
return o;
}
// --------------------------------------------------------
// Shared uniforms
UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
float4 _LightDir;
float4 _LightPos;
float4 _LightColor;
float4 unity_LightmapFade;
float4x4 unity_WorldToLight;
sampler2D_float _LightTextureB0;
#if defined (POINT_COOKIE)
samplerCUBE_float _LightTexture0;
#else
sampler2D_float _LightTexture0;
#endif
#if defined (SHADOWS_SCREEN)
sampler2D _ShadowMapTexture;
#endif
#if defined (SHADOWS_SHADOWMASK)
sampler2D _CameraGBufferTexture4;
#endif
// --------------------------------------------------------
// Shadow/fade helpers
// Receiver plane depth bias create artifacts when depth is retrieved from
// the depth buffer. see UnityGetReceiverPlaneDepthBias in UnityShadowLibrary.cginc
#ifdef UNITY_USE_RECEIVER_PLANE_BIAS
#undef UNITY_USE_RECEIVER_PLANE_BIAS
#endif
#include "UnityShadowLibrary.cginc"
//Note :
// SHADOWS_SHADOWMASK + LIGHTMAP_SHADOW_MIXING -> ShadowMask mode
// SHADOWS_SHADOWMASK only -> Distance shadowmask mode
// --------------------------------------------------------
half UnityDeferredSampleShadowMask(float2 uv)
{
half shadowMaskAttenuation = 1.0f;
#if defined (SHADOWS_SHADOWMASK)
half4 shadowMask = tex2D(_CameraGBufferTexture4, uv);
shadowMaskAttenuation = saturate(dot(shadowMask, unity_OcclusionMaskSelector));
#endif
return shadowMaskAttenuation;
}
// --------------------------------------------------------
half UnityDeferredSampleRealtimeShadow(half fade, float3 vec, float2 uv)
{
half shadowAttenuation = 1.0f;
#if defined (DIRECTIONAL) || defined (DIRECTIONAL_COOKIE)
#if defined(SHADOWS_SCREEN)
shadowAttenuation = tex2D(_ShadowMapTexture, uv).r;
#endif
#endif
#if defined(UNITY_FAST_COHERENT_DYNAMIC_BRANCHING) && defined(SHADOWS_SOFT) && !defined(LIGHTMAP_SHADOW_MIXING)
//avoid expensive shadows fetches in the distance where coherency will be good
UNITY_BRANCH
if (fade < (1.0f - 1e-2f))
{
#endif
#if defined(SPOT)
#if defined(SHADOWS_DEPTH)
float4 shadowCoord = mul(unity_WorldToShadow[0], float4(vec, 1));
shadowAttenuation = UnitySampleShadowmap(shadowCoord);
#endif
#endif
#if defined (POINT) || defined (POINT_COOKIE)
#if defined(SHADOWS_CUBE)
shadowAttenuation = UnitySampleShadowmap(vec);
#endif
#endif
#if defined(UNITY_FAST_COHERENT_DYNAMIC_BRANCHING) && defined(SHADOWS_SOFT) && !defined(LIGHTMAP_SHADOW_MIXING)
}
#endif
return shadowAttenuation;
}
// --------------------------------------------------------
half UnityDeferredComputeShadow(float3 vec, float fadeDist, float2 uv)
{
half fade = UnityComputeShadowFade(fadeDist);
half shadowMaskAttenuation = UnityDeferredSampleShadowMask(uv);
half realtimeShadowAttenuation = UnityDeferredSampleRealtimeShadow(fade, vec, uv);
return UnityMixRealtimeAndBakedShadows(realtimeShadowAttenuation, shadowMaskAttenuation, fade);
}
// --------------------------------------------------------
// Common lighting data calculation (direction, attenuation, ...)
void UnityDeferredCalculateLightParams (
unity_v2f_deferred i,
out float3 outWorldPos,
out float2 outUV,
out half3 outLightDir,
out float outAtten,
out float outFadeDist)
{
i.ray = i.ray * (_ProjectionParams.z / i.ray.z);
float2 uv = i.uv.xy / i.uv.w;
// read depth and reconstruct world position
float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv);
depth = Linear01Depth (depth);
float4 vpos = float4(i.ray * depth,1);
float3 wpos = mul (unity_CameraToWorld, vpos).xyz;
float fadeDist = UnityComputeShadowFadeDistance(wpos, vpos.z);
// spot light case
#if defined (SPOT)
float3 tolight = _LightPos.xyz - wpos;
half3 lightDir = normalize (tolight);
float4 uvCookie = mul (unity_WorldToLight, float4(wpos,1));
// negative bias because http://aras-p.info/blog/2010/01/07/screenspace-vs-mip-mapping/
float atten = tex2Dbias (_LightTexture0, float4(uvCookie.xy / uvCookie.w, 0, -8)).w;
atten *= uvCookie.w < 0;
float att = dot(tolight, tolight) * _LightPos.w;
atten *= tex2D (_LightTextureB0, att.rr).r;
atten *= UnityDeferredComputeShadow (wpos, fadeDist, uv);
// directional light case
#elif defined (DIRECTIONAL) || defined (DIRECTIONAL_COOKIE)
half3 lightDir = -_LightDir.xyz;
float atten = 1.0;
atten *= UnityDeferredComputeShadow (wpos, fadeDist, uv);
#if defined (DIRECTIONAL_COOKIE)
atten *= tex2Dbias (_LightTexture0, float4(mul(unity_WorldToLight, half4(wpos,1)).xy, 0, -8)).w;
#endif //DIRECTIONAL_COOKIE
// point light case
#elif defined (POINT) || defined (POINT_COOKIE)
float3 tolight = wpos - _LightPos.xyz;
half3 lightDir = -normalize (tolight);
float att = dot(tolight, tolight) * _LightPos.w;
float atten = tex2D (_LightTextureB0, att.rr).r;
atten *= UnityDeferredComputeShadow (tolight, fadeDist, uv);
#if defined (POINT_COOKIE)
atten *= texCUBEbias(_LightTexture0, float4(mul(unity_WorldToLight, half4(wpos,1)).xyz, -8)).w;
#endif //POINT_COOKIE
#else
half3 lightDir = 0;
float atten = 0;
#endif
outWorldPos = wpos;
outUV = uv;
outLightDir = lightDir;
outAtten = atten;
outFadeDist = fadeDist;
}
#endif // UNITY_DEFERRED_LIBRARY_INCLUDED