Added terrain and basic terrain textures
This commit is contained in:
207
Assets/Filamented/UnityGlobalIllumination.cginc
Normal file
207
Assets/Filamented/UnityGlobalIllumination.cginc
Normal file
@ -0,0 +1,207 @@
|
||||
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
|
||||
|
||||
#ifndef UNITY_GLOBAL_ILLUMINATION_INCLUDED
|
||||
#define UNITY_GLOBAL_ILLUMINATION_INCLUDED
|
||||
|
||||
// Functions sampling light environment data (lightmaps, light probes, reflection probes), which is then returned as the UnityGI struct.
|
||||
|
||||
#include "UnityImageBasedLighting.cginc"
|
||||
#include "UnityStandardUtils.cginc"
|
||||
#include "UnityShadowLibrary.cginc"
|
||||
|
||||
inline half3 DecodeDirectionalSpecularLightmap (half3 color, half4 dirTex, half3 normalWorld, bool isRealtimeLightmap, fixed4 realtimeNormalTex, out UnityLight o_light)
|
||||
{
|
||||
o_light.color = color;
|
||||
o_light.dir = dirTex.xyz * 2 - 1;
|
||||
o_light.ndotl = 0; // Not use;
|
||||
|
||||
// The length of the direction vector is the light's "directionality", i.e. 1 for all light coming from this direction,
|
||||
// lower values for more spread out, ambient light.
|
||||
half directionality = max(0.001, length(o_light.dir));
|
||||
o_light.dir /= directionality;
|
||||
|
||||
#ifdef DYNAMICLIGHTMAP_ON
|
||||
if (isRealtimeLightmap)
|
||||
{
|
||||
// Realtime directional lightmaps' intensity needs to be divided by N.L
|
||||
// to get the incoming light intensity. Baked directional lightmaps are already
|
||||
// output like that (including the max() to prevent div by zero).
|
||||
half3 realtimeNormal = realtimeNormalTex.xyz * 2 - 1;
|
||||
o_light.color /= max(0.125, dot(realtimeNormal, o_light.dir));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Split light into the directional and ambient parts, according to the directionality factor.
|
||||
half3 ambient = o_light.color * (1 - directionality);
|
||||
o_light.color = o_light.color * directionality;
|
||||
|
||||
// Technically this is incorrect, but helps hide jagged light edge at the object silhouettes and
|
||||
// makes normalmaps show up.
|
||||
ambient *= saturate(dot(normalWorld, o_light.dir));
|
||||
return ambient;
|
||||
}
|
||||
|
||||
inline void ResetUnityLight(out UnityLight outLight)
|
||||
{
|
||||
outLight.color = half3(0, 0, 0);
|
||||
outLight.dir = half3(0, 1, 0); // Irrelevant direction, just not null
|
||||
outLight.ndotl = 0; // Not used
|
||||
}
|
||||
|
||||
inline half3 SubtractMainLightWithRealtimeAttenuationFromLightmap (half3 lightmap, half attenuation, half4 bakedColorTex, half3 normalWorld)
|
||||
{
|
||||
// Let's try to make realtime shadows work on a surface, which already contains
|
||||
// baked lighting and shadowing from the main sun light.
|
||||
half3 shadowColor = unity_ShadowColor.rgb;
|
||||
half shadowStrength = _LightShadowData.x;
|
||||
|
||||
// Summary:
|
||||
// 1) Calculate possible value in the shadow by subtracting estimated light contribution from the places occluded by realtime shadow:
|
||||
// a) preserves other baked lights and light bounces
|
||||
// b) eliminates shadows on the geometry facing away from the light
|
||||
// 2) Clamp against user defined ShadowColor.
|
||||
// 3) Pick original lightmap value, if it is the darkest one.
|
||||
|
||||
|
||||
// 1) Gives good estimate of illumination as if light would've been shadowed during the bake.
|
||||
// Preserves bounce and other baked lights
|
||||
// No shadows on the geometry facing away from the light
|
||||
half ndotl = LambertTerm (normalWorld, _WorldSpaceLightPos0.xyz);
|
||||
half3 estimatedLightContributionMaskedByInverseOfShadow = ndotl * (1- attenuation) * _LightColor0.rgb;
|
||||
half3 subtractedLightmap = lightmap - estimatedLightContributionMaskedByInverseOfShadow;
|
||||
|
||||
// 2) Allows user to define overall ambient of the scene and control situation when realtime shadow becomes too dark.
|
||||
half3 realtimeShadow = max(subtractedLightmap, shadowColor);
|
||||
realtimeShadow = lerp(realtimeShadow, lightmap, shadowStrength);
|
||||
|
||||
// 3) Pick darkest color
|
||||
return min(lightmap, realtimeShadow);
|
||||
}
|
||||
|
||||
inline void ResetUnityGI(out UnityGI outGI)
|
||||
{
|
||||
ResetUnityLight(outGI.light);
|
||||
outGI.indirect.diffuse = 0;
|
||||
outGI.indirect.specular = 0;
|
||||
}
|
||||
|
||||
inline UnityGI UnityGI_Base(UnityGIInput data, inout half occlusion, half3 normalWorld)
|
||||
{
|
||||
UnityGI o_gi;
|
||||
ResetUnityGI(o_gi);
|
||||
|
||||
// Base pass with Lightmap support is responsible for handling ShadowMask / blending here for performance reason
|
||||
#if defined(HANDLE_SHADOWS_BLENDING_IN_GI)
|
||||
half bakedAtten = UnitySampleBakedOcclusion(data.lightmapUV.xy, data.worldPos);
|
||||
float zDist = dot(_WorldSpaceCameraPos - data.worldPos, UNITY_MATRIX_V[2].xyz);
|
||||
float fadeDist = UnityComputeShadowFadeDistance(data.worldPos, zDist);
|
||||
data.atten = UnityMixRealtimeAndBakedShadows(data.atten, bakedAtten, UnityComputeShadowFade(fadeDist));
|
||||
#endif
|
||||
|
||||
o_gi.light = data.light;
|
||||
o_gi.light.color *= data.atten;
|
||||
|
||||
#if UNITY_SHOULD_SAMPLE_SH
|
||||
o_gi.indirect.diffuse = ShadeSHPerPixel(normalWorld, data.ambient, data.worldPos);
|
||||
#endif
|
||||
|
||||
#if defined(LIGHTMAP_ON)
|
||||
// Baked lightmaps
|
||||
half4 bakedColorTex = UNITY_SAMPLE_TEX2D(unity_Lightmap, data.lightmapUV.xy);
|
||||
half3 bakedColor = DecodeLightmap(bakedColorTex);
|
||||
|
||||
// Derive specular occlusion
|
||||
|
||||
half bakedOcclusion = saturate(dot(bakedColor * 3.0, 1.0));
|
||||
occlusion *= bakedOcclusion;
|
||||
|
||||
#ifdef DIRLIGHTMAP_COMBINED
|
||||
fixed4 bakedDirTex = UNITY_SAMPLE_TEX2D_SAMPLER (unity_LightmapInd, unity_Lightmap, data.lightmapUV.xy);
|
||||
o_gi.indirect.diffuse += DecodeDirectionalLightmap (bakedColor, bakedDirTex, normalWorld);
|
||||
|
||||
#if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN)
|
||||
ResetUnityLight(o_gi.light);
|
||||
o_gi.indirect.diffuse = SubtractMainLightWithRealtimeAttenuationFromLightmap (o_gi.indirect.diffuse, data.atten, bakedColorTex, normalWorld);
|
||||
#endif
|
||||
|
||||
#else // not directional lightmap
|
||||
o_gi.indirect.diffuse += bakedColor;
|
||||
|
||||
#if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN)
|
||||
ResetUnityLight(o_gi.light);
|
||||
o_gi.indirect.diffuse = SubtractMainLightWithRealtimeAttenuationFromLightmap(o_gi.indirect.diffuse, data.atten, bakedColorTex, normalWorld);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef DYNAMICLIGHTMAP_ON
|
||||
// Dynamic lightmaps
|
||||
fixed4 realtimeColorTex = UNITY_SAMPLE_TEX2D(unity_DynamicLightmap, data.lightmapUV.zw);
|
||||
half3 realtimeColor = DecodeRealtimeLightmap (realtimeColorTex);
|
||||
|
||||
#ifdef DIRLIGHTMAP_COMBINED
|
||||
half4 realtimeDirTex = UNITY_SAMPLE_TEX2D_SAMPLER(unity_DynamicDirectionality, unity_DynamicLightmap, data.lightmapUV.zw);
|
||||
o_gi.indirect.diffuse += DecodeDirectionalLightmap (realtimeColor, realtimeDirTex, normalWorld);
|
||||
#else
|
||||
o_gi.indirect.diffuse += realtimeColor;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
o_gi.indirect.diffuse *= occlusion;
|
||||
return o_gi;
|
||||
}
|
||||
|
||||
|
||||
inline half3 UnityGI_IndirectSpecular(UnityGIInput data, half occlusion, Unity_GlossyEnvironmentData glossIn)
|
||||
{
|
||||
half3 specular;
|
||||
|
||||
#ifdef UNITY_SPECCUBE_BOX_PROJECTION
|
||||
// we will tweak reflUVW in glossIn directly (as we pass it to Unity_GlossyEnvironment twice for probe0 and probe1), so keep original to pass into BoxProjectedCubemapDirection
|
||||
half3 originalReflUVW = glossIn.reflUVW;
|
||||
glossIn.reflUVW = BoxProjectedCubemapDirection (originalReflUVW, data.worldPos, data.probePosition[0], data.boxMin[0], data.boxMax[0]);
|
||||
#endif
|
||||
|
||||
#ifdef _GLOSSYREFLECTIONS_OFF
|
||||
specular = unity_IndirectSpecColor.rgb;
|
||||
#else
|
||||
half3 env0 = Unity_GlossyEnvironment (UNITY_PASS_TEXCUBE(unity_SpecCube0), data.probeHDR[0], glossIn);
|
||||
#ifdef UNITY_SPECCUBE_BLENDING
|
||||
const float kBlendFactor = 0.99999;
|
||||
float blendLerp = data.boxMin[0].w;
|
||||
UNITY_BRANCH
|
||||
if (blendLerp < kBlendFactor)
|
||||
{
|
||||
#ifdef UNITY_SPECCUBE_BOX_PROJECTION
|
||||
glossIn.reflUVW = BoxProjectedCubemapDirection (originalReflUVW, data.worldPos, data.probePosition[1], data.boxMin[1], data.boxMax[1]);
|
||||
#endif
|
||||
|
||||
half3 env1 = Unity_GlossyEnvironment (UNITY_PASS_TEXCUBE_SAMPLER(unity_SpecCube1,unity_SpecCube0), data.probeHDR[1], glossIn);
|
||||
specular = lerp(env1, env0, blendLerp);
|
||||
}
|
||||
else
|
||||
{
|
||||
specular = env0;
|
||||
}
|
||||
#else
|
||||
specular = env0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return specular * occlusion;
|
||||
}
|
||||
|
||||
inline UnityGI UnityGlobalIllumination (UnityGIInput data, half occlusion, half3 normalWorld)
|
||||
{
|
||||
return UnityGI_Base(data, occlusion, normalWorld);
|
||||
}
|
||||
|
||||
inline UnityGI UnityGlobalIllumination (UnityGIInput data, half occlusion, half3 normalWorld, Unity_GlossyEnvironmentData glossIn)
|
||||
{
|
||||
UnityGI o_gi = UnityGI_Base(data, occlusion, normalWorld);
|
||||
o_gi.indirect.specular = UnityGI_IndirectSpecular(data, occlusion, glossIn);
|
||||
return o_gi;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user