您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
203 行
5.7 KiB
203 行
5.7 KiB
#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 _LightTexture0;
|
|
#else
|
|
sampler2D _LightTexture0;
|
|
#endif
|
|
|
|
#if defined (SHADOWS_SCREEN)
|
|
sampler2D _ShadowMapTexture;
|
|
#endif
|
|
|
|
#if defined (SHADOWS_SHADOWMASK)
|
|
sampler2D _CameraGBufferTexture4;
|
|
#endif
|
|
|
|
// --------------------------------------------------------
|
|
// Shadow/fade helpers
|
|
|
|
#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).UNITY_ATTEN_CHANNEL;
|
|
|
|
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).UNITY_ATTEN_CHANNEL;
|
|
|
|
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
|