您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

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