445 lines
11 KiB
HLSL
445 lines
11 KiB
HLSL
#ifndef ALLIN13DSHADER_HELPER_BIRP_INCLUDED
|
|
#define ALLIN13DSHADER_HELPER_BIRP_INCLUDED
|
|
|
|
#include "AutoLight.cginc"
|
|
|
|
#define OBJECT_TO_WORLD_MATRIX unity_ObjectToWorld
|
|
|
|
//#if !defined(LIGHTMAP_ON) && defined(SHADOWS_SCREEN)
|
|
// #if defined(SHADOWS_SHADOWMASK) && !defined(UNITY_NO_SCREENSPACE_SHADOWS)
|
|
// #define ADDITIONAL_MASKED_DIRECTIONAL_SHADOWS 1
|
|
// #endif
|
|
//#endif
|
|
|
|
#ifdef REQUIRE_SCENE_DEPTH
|
|
|
|
UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
|
|
|
|
float GetRawDepth(float4 projPos)
|
|
{
|
|
//float res = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(projPos));
|
|
float res = tex2Dproj(_CameraDepthTexture, projPos);
|
|
return res;
|
|
}
|
|
|
|
float GetLinearDepth01(float4 projPos)
|
|
{
|
|
float rawDepth = GetRawDepth(projPos);
|
|
float res = Linear01Depth (rawDepth);
|
|
|
|
return res;
|
|
}
|
|
|
|
float GetSceneDepthDiff(float4 projPos)
|
|
{
|
|
float rawDepth = GetRawDepth(projPos);
|
|
float res = LinearEyeDepth(rawDepth) - projPos.z;
|
|
return res;
|
|
}
|
|
|
|
#endif
|
|
|
|
float3 GetNormalWS(float3 normalOS)
|
|
{
|
|
float3 normalWS = UnityObjectToWorldNormal(normalOS);
|
|
return normalWS;
|
|
}
|
|
|
|
float3 GetViewDirWS(float3 vertexWS)
|
|
{
|
|
float3 res = UnityWorldSpaceViewDir(vertexWS);
|
|
return res;
|
|
}
|
|
|
|
float3 GetPositionVS(float3 positionOS)
|
|
{
|
|
float3 res = UnityObjectToViewPos(positionOS);
|
|
return res;
|
|
}
|
|
|
|
float3 GetPositionWS(float4 positionOS)
|
|
{
|
|
return mul(unity_ObjectToWorld, positionOS).xyz;
|
|
}
|
|
|
|
float3 GetPositionOS(float4 positionWS)
|
|
{
|
|
return mul(unity_WorldToObject, positionWS);
|
|
}
|
|
|
|
float3 GetDirWS(float4 dirOS)
|
|
{
|
|
return mul(unity_ObjectToWorld, float4(dirOS.xyz, 0));
|
|
}
|
|
|
|
float3 GetDirOSFloat3(float3 dirOS)
|
|
{
|
|
return mul(unity_WorldToObject, float4(dirOS.xyz, 0));
|
|
}
|
|
|
|
float3 GetDirOS(float4 dirOS)
|
|
{
|
|
return mul(unity_WorldToObject, dirOS);
|
|
}
|
|
|
|
float3 GetMainLightDir(float3 vertexWS)
|
|
{
|
|
#ifdef _LIGHTMODEL_FASTLIGHTING
|
|
float3 mainLightDir = global_lightDirection;
|
|
#else
|
|
float3 mainLightDir = normalize(_WorldSpaceLightPos0.xyz - vertexWS * _WorldSpaceLightPos0.w);
|
|
#endif
|
|
|
|
return mainLightDir;
|
|
}
|
|
|
|
float3 GetMainLightColorRGB()
|
|
{
|
|
#ifdef _LIGHTMODEL_FASTLIGHTING
|
|
float3 res = global_lightColor.rgb;
|
|
#else
|
|
float3 res = _LightColor0.rgb;
|
|
#endif
|
|
|
|
return res;
|
|
}
|
|
|
|
float2 GetSSAO(float2 normalizedScreenSpaceUV, float alpha)
|
|
{
|
|
float2 res = float2(1, 1);
|
|
return res;
|
|
}
|
|
|
|
float FadeShadows (float3 worldPos, float shadowAtten, AllIn1GI gi)
|
|
{
|
|
float res = shadowAtten;
|
|
#if defined(SHADOWS_SHADOWMASK)
|
|
float bakedAttenuation = UnitySampleBakedOcclusion(gi.uvLightmap, worldPos);
|
|
float zDist = dot(_WorldSpaceCameraPos.xyz - worldPos, UNITY_MATRIX_V[2].xyz);
|
|
float shadowFadeDistance = UnityComputeShadowFadeDistance(worldPos, zDist);
|
|
float shadowFade = UnityComputeShadowFade(shadowFadeDistance);
|
|
|
|
res = UnityMixRealtimeAndBakedShadows(shadowAtten, bakedAttenuation, shadowFade);
|
|
#endif
|
|
|
|
return res;
|
|
}
|
|
|
|
float GetShadowAttenuation(EffectsData effectsData, AllIn1GI gi)
|
|
{
|
|
float res = 1;
|
|
|
|
#if !defined(_LIGHTMODEL_FASTLIGHTING)
|
|
UNITY_LIGHT_ATTENUATION(attenuation, effectsData, effectsData.vertexWS);
|
|
#if !defined(FORWARD_ADD_PASS)
|
|
attenuation = FadeShadows(effectsData.vertexWS, attenuation, gi);
|
|
#endif
|
|
|
|
res = attenuation;
|
|
#endif
|
|
|
|
return res;
|
|
}
|
|
|
|
AllIn1LightData GetPointLightData(float3 vertexWS, float3 normalWS, float3 lightPositionWS, float3 lightColor, float pointLightAtten, EffectsData effectsData, AllIn1GI gi)
|
|
{
|
|
AllIn1LightData lightData;
|
|
|
|
float3 lightVec = lightPositionWS - vertexWS;
|
|
float3 lightDir = normalize(lightVec);
|
|
|
|
float atten = 1 / (1 + dot(lightVec, lightVec) * pointLightAtten);
|
|
|
|
lightData.lightColor = lightColor;
|
|
lightData.lightDir = lightDir;
|
|
|
|
#ifdef _RECEIVE_SHADOWS_ON
|
|
lightData.realtimeShadow = GetShadowAttenuation(effectsData, gi);
|
|
#else
|
|
lightData.realtimeShadow = 1.0;
|
|
#endif
|
|
lightData.distanceAttenuation = atten;
|
|
|
|
lightData.shadowColor = /*lerp(0, 1.0, lightData.realtimeShadow * lightData.distanceAttenuation)*/lightData.realtimeShadow;
|
|
lightData.layerMask = 1.0;
|
|
|
|
return lightData;
|
|
}
|
|
|
|
AllIn1LightData GetMainLightData(float3 vertexWS, EffectsData effectsData, AllIn1GI gi)
|
|
{
|
|
AllIn1LightData lightData;
|
|
|
|
#if defined(SUBTRACTIVE_LIGHTING)
|
|
lightData.lightColor = 0;
|
|
lightData.lightDir = GetMainLightDir(vertexWS);
|
|
lightData.realtimeShadow = 1.0;
|
|
lightData.distanceAttenuation = 1.0;
|
|
lightData.shadowColor = 1.0;
|
|
#else
|
|
lightData.lightColor = GetMainLightColorRGB();
|
|
lightData.lightDir = GetMainLightDir(vertexWS);
|
|
|
|
#if defined(_LIGHTMODEL_NONE)
|
|
lightData.realtimeShadow = 1.0;
|
|
#else
|
|
#ifdef _RECEIVE_SHADOWS_ON
|
|
lightData.realtimeShadow = GetShadowAttenuation(effectsData, gi);
|
|
#if defined(_RECEIVEDSHADOWSTYPE_STYLIZED) && !defined(FORWARD_ADD_PASS)
|
|
lightData.realtimeShadow = AntiAliasing(lightData.realtimeShadow, ACCESS_PROP_FLOAT(_ShadowCutoff));
|
|
#endif
|
|
#else
|
|
lightData.realtimeShadow = 1.0;
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef _LIGHTMODEL_FASTLIGHTING
|
|
lightData.shadowColor = 1.0;
|
|
#else
|
|
#ifdef FORWARD_ADD_PASS
|
|
lightData.shadowColor = lightData.realtimeShadow;
|
|
#else
|
|
lightData.shadowColor = lerp(SHADOW_COLOR, 1.0, lightData.realtimeShadow);
|
|
#endif
|
|
#endif
|
|
|
|
lightData.distanceAttenuation = 1.0;
|
|
#endif
|
|
|
|
lightData.layerMask = 1.0;
|
|
|
|
return lightData;
|
|
}
|
|
|
|
float3 GetPointLightPosition(int index)
|
|
{
|
|
float3 pointLightPosition = float3(unity_4LightPosX0[index], unity_4LightPosY0[index], unity_4LightPosZ0[index]);
|
|
return pointLightPosition;
|
|
}
|
|
|
|
AllIn1LightData GetPointLightData(int index, float3 vertexWS, float3 normalWS, EffectsData effectsData, AllIn1GI gi)
|
|
{
|
|
return GetPointLightData(vertexWS, normalWS, GetPointLightPosition(index), unity_LightColor[index], unity_4LightAtten0[index], effectsData, gi);
|
|
}
|
|
|
|
FragmentDataShadowCaster GetClipPosShadowCaster( /*VertexData v*/VertexData v, FragmentDataShadowCaster o)
|
|
{
|
|
//float4 res = 0;
|
|
//#if defined(SHADOWS_CUBE) && !defined(SHADOWS_CUBE_IN_DEPTH_TEX)
|
|
// // Rendering into point light (cubemap) shadows
|
|
// //#define TRANSFER_SHADOW_CASTER_NOPOS(o,opos) o.vec = mul(unity_ObjectToWorld, v.vertex).xyz - _LightPositionRange.xyz; opos = UnityObjectToClipPos(v.vertex);
|
|
// //#define SHADOW_CASTER_FRAGMENT(i) return UnityEncodeCubeShadowDepth ((length(i.vec) + unity_LightShadowBias.x) * _LightPositionRange.w);
|
|
|
|
// float3 vec = mul(unity_ObjectToWorld, v.vertex).xyz - _LightPositionRange.xyz;
|
|
// res = UnityObjectToClipPos(v.vertex);
|
|
//#else
|
|
// // Rendering into directional or spot light shadows
|
|
// res = UnityClipSpaceShadowCasterPos(v.vertex, v.normal);
|
|
// res = UnityApplyLinearShadowBias(res);
|
|
// #endif
|
|
|
|
//res = UnityClipSpaceShadowCasterPos(v.vertex.xyz, v.normal);
|
|
//res = UnityApplyLinearShadowBias(res);
|
|
|
|
TRANSFER_SHADOW_CASTER_NORMALOFFSET(o);
|
|
return o;
|
|
|
|
//return res;
|
|
}
|
|
|
|
//float GetShadowAttenuation(FragmentData i, float3 vertexWS)
|
|
//{
|
|
// //float shadowAttenuation = UNITY_SHADOW_ATTENUATION(i, vertexWS);
|
|
|
|
// //float3 lightCoord = mul(unity_WorldToLight, float4(vertexWS, 1)).xyz;
|
|
// // fixed shadow = UNITY_SHADOW_ATTENUATION(i, vertexWS);
|
|
// // float res = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).r * shadow;
|
|
|
|
// /*TODO: Fix this*/
|
|
// //shadowAttenuation = 1.0;
|
|
|
|
// UNITY_LIGHT_ATTENUATION(attenuation, i, vertexWS);
|
|
|
|
// return attenuation;
|
|
//}
|
|
|
|
ShadowCoordStruct GetShadowCoords(VertexData v, float4 clipPos, float3 vertexWS, float2 uvLightmap)
|
|
{
|
|
ShadowCoordStruct res;
|
|
|
|
res.pos = clipPos;
|
|
res._ShadowCoord = 0;
|
|
|
|
UNITY_TRANSFER_SHADOW(res, uvLightmap);
|
|
|
|
return res;
|
|
}
|
|
|
|
float3 GetLightmap(float2 uvLightmap, EffectsData data)
|
|
{
|
|
float3 res = 0.0;
|
|
#if defined(_AFFECTED_BY_LIGHTMAPS_ON) && defined(LIGHTMAP_ON)
|
|
res = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, uvLightmap));
|
|
#ifdef SUBTRACTIVE_LIGHTING
|
|
float attenuation = GetShadowAttenuation(data);
|
|
float ndotl = saturate(dot(data.normalWS, _WorldSpaceLightPos0.xyz));
|
|
float3 shadowedLightEstimate =
|
|
ndotl * (1 - attenuation) * _LightColor0.rgb;
|
|
float3 subtractedLight = res - shadowedLightEstimate;
|
|
subtractedLight = max(subtractedLight, unity_ShadowColor.rgb);
|
|
subtractedLight = lerp(subtractedLight, res, _LightShadowData.x);
|
|
|
|
res = subtractedLight;
|
|
#endif
|
|
#endif
|
|
|
|
return res;
|
|
}
|
|
|
|
float3 GetAmbientColor(EffectsData data)
|
|
{
|
|
float3 res = float3(0, 0, 0);
|
|
|
|
#ifdef _CUSTOM_AMBIENT_LIGHT_ON
|
|
res = ACCESS_PROP_FLOAT4(_CustomAmbientColor).rgb;
|
|
#else
|
|
res = ShadeSH9(float4(data.normalWS, 1.0));
|
|
#endif
|
|
|
|
return res;
|
|
}
|
|
|
|
AllIn1GI CalculateGI(float2 uvLightmap, EffectsData data)
|
|
{
|
|
AllIn1GI res;
|
|
INIT_GI(res);
|
|
|
|
#if defined(LIGHTMAP_ON)
|
|
res.diffuse = GetLightmap(uvLightmap, data);
|
|
#else
|
|
res.diffuse = GetAmbientColor(data);
|
|
#endif
|
|
|
|
#if defined(SHADOWS_SHADOWMASK)
|
|
res.shadowMask = UnitySampleBakedOcclusion(uvLightmap, data.vertexWS);
|
|
#endif
|
|
|
|
res.uvLightmap = uvLightmap;
|
|
|
|
return res;
|
|
}
|
|
|
|
//float GetFogFactor(FragmentData fragmentData)
|
|
//{
|
|
// float res = 0;
|
|
|
|
//#if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2)
|
|
// UNITY_TRANSFER_FOG(fragmentData, fragmentData.pos);
|
|
// res = fragmentData.fogCoord;
|
|
//#endif
|
|
|
|
// return res;
|
|
//}
|
|
|
|
float GetFogFactor(float4 clipPos)
|
|
{
|
|
float res = 0;
|
|
#if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2)
|
|
FogStruct fogStruct;
|
|
UNITY_TRANSFER_FOG(fogStruct, clipPos);
|
|
res = fogStruct.fogCoord;
|
|
#endif
|
|
|
|
return res;
|
|
}
|
|
|
|
|
|
#if defined(FOG_ENABLED)
|
|
float4 CustomMixFog(float fogFactor, float4 col)
|
|
{
|
|
float4 res = col;
|
|
UNITY_APPLY_FOG(fogFactor, res);
|
|
return res;
|
|
}
|
|
#endif
|
|
|
|
#ifdef REFLECTIONS_ON
|
|
|
|
float3 BoxProjection (
|
|
float3 direction, float3 position,
|
|
float4 cubemapPosition, float3 boxMin, float3 boxMax
|
|
) {
|
|
#if UNITY_SPECCUBE_BOX_PROJECTION
|
|
UNITY_BRANCH
|
|
if (cubemapPosition.w > 0) {
|
|
float3 factors =
|
|
((direction > 0 ? boxMax : boxMin) - position) / direction;
|
|
float scalar = min(min(factors.x, factors.y), factors.z);
|
|
direction = direction * scalar + (position - cubemapPosition);
|
|
}
|
|
#endif
|
|
return direction;
|
|
}
|
|
|
|
float3 GetReflectionsSimple(float3 worldRefl, float cubeLod, float3 positionWS)
|
|
{
|
|
float3 reflUV0 = BoxProjection(worldRefl, positionWS, unity_SpecCube0_ProbePosition, unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax);
|
|
float4 probe0HDR = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, reflUV0, cubeLod);
|
|
float3 probe0 = DecodeHDR(probe0HDR, unity_SpecCube0_HDR);
|
|
|
|
|
|
float3 res = probe0;
|
|
#if UNITY_SPECCUBE_BLENDING
|
|
float interpolator = unity_SpecCube0_BoxMin.w;
|
|
|
|
if(interpolator < 0.99999)
|
|
{
|
|
float3 reflUV1 = BoxProjection(worldRefl, positionWS, unity_SpecCube1_ProbePosition, unity_SpecCube1_BoxMin, unity_SpecCube1_BoxMax);
|
|
float4 probe1HDR = UNITY_SAMPLE_TEXCUBE_SAMPLER_LOD(unity_SpecCube1, unity_SpecCube0, reflUV1, cubeLod);
|
|
float3 probe1 = DecodeHDR(probe1HDR, unity_SpecCube1_HDR);
|
|
|
|
res = lerp(probe1, probe0, interpolator);
|
|
}
|
|
else
|
|
{
|
|
res = probe0;
|
|
}
|
|
#endif
|
|
|
|
return res;
|
|
}
|
|
|
|
float3 GetSkyColor(float3 positionWS, float2 normalizedScreenSpaceUV,
|
|
float3 normalWS, float3 viewDirWS, float cubeLod)
|
|
{
|
|
float3 worldRefl = normalize(reflect(-viewDirWS, normalWS));
|
|
|
|
float3 res = GetReflectionsSimple(worldRefl, cubeLod, positionWS);
|
|
|
|
#ifdef _REFLECTIONS_TOON
|
|
float posterizationLevel = lerp(2, 20, ACCESS_PROP_FLOAT(_ToonFactor));
|
|
res = floor(res * posterizationLevel) / posterizationLevel;
|
|
#endif
|
|
|
|
res *= ACCESS_PROP_FLOAT(_ReflectionsAtten);
|
|
|
|
return res;
|
|
}
|
|
#endif
|
|
|
|
float3 ShadeSH(float4 normalWS)
|
|
{
|
|
float3 res = ShadeSH9(normalWS);
|
|
return res;
|
|
}
|
|
|
|
|
|
#define NUM_ADDITIONAL_LIGHTS 4;
|
|
|
|
#define OBJECT_TO_CLIP_SPACE(v) UnityObjectToClipPos(v.vertex)
|
|
#define OBJECT_TO_CLIP_SPACE_FLOAT4(pos) UnityObjectToClipPos(pos)
|
|
#define ALLIN1_APPLY_CROSSFADE(input) \
|
|
float2 __vpos = i.projPos.xy / i.projPos.w * _ScreenParams.xy; \
|
|
UNITY_APPLY_DITHER_CROSSFADE(__vpos);
|
|
|
|
#endif |