//------------------------------------ // OmniShade // Copyright© 2025 OmniShade //------------------------------------ #include "OmniShadeURP.cginc" ////////////////////////////////////////////////////////////////////////////////////////// // PROPERTY DECLARATIONS ////////////////////////////////////////////////////////////////////////////////////////// CBUFFER_START(UnityPerMaterial) half _TriplanarSharpness; sampler2D _MainTex; half4 _MainTex_ST; half4 _Color; half _Brightness; half _Contrast; half _Saturation; half _IgnoreMainTexAlpha; sampler2D _TopTex; half4 _TopTex_ST; half4 _TopColor; half _TopBrightness; half _DiffuseWrap; half _DiffuseBrightness; half _DiffuseContrast; sampler2D _SpecularTex; half4 _SpecularTex_ST; half4 _SpecularColor; half _SpecularBrightness; half _SpecularSmoothness; half4 _RimColor; half _RimAmount; half _RimContrast; half _RimInverse; half3 _RimDirection; samplerCUBE _ReflectionTex; half4 _ReflectionTex_HDR; half _ReflectionAmount; half4 _ReflectionColor; sampler2D _NormalTex; half4 _NormalTex_ST; half _NormalStrength; sampler2D _NormalTex2; half4 _NormalTex2_ST; half _Normal2Strength; sampler2D _NormalTopTex; half4 _NormalTopTex_ST; half _NormalTopStrength; sampler2D _LightmapTex; half4 _LightmapTex_ST; half4 _LightmapTex_HDR; half4 _LightmapColor; half _LightmapBrightness; half4 _Emissive; sampler2D _EmissiveTex; half4 _EmissiveTex_ST; sampler2D _MatCapTex; half4 _MatCapTex_ST; half4 _MatCapColor; half _MatCapBrightness; half _MatCapContrast; half3 _MatCapRot; half _VertexColorsAmount; half _VertexColorsContrast; sampler2D _DetailTex; half4 _DetailTex_ST; half4 _DetailColor; half _DetailBrightness; half _DetailContrast; sampler2D _Layer1Tex; half4 _Layer1Tex_ST; half4 _Layer1Color; half _Layer1Brightness; half _Layer1Alpha; half _Layer1VertexColor; sampler2D _Layer2Tex; half4 _Layer2Tex_ST; half4 _Layer2Color; half _Layer2Brightness; half _Layer2Alpha; half _Layer2VertexColor; sampler2D _Layer3Tex; half4 _Layer3Tex_ST; half4 _Layer3Color; half _Layer3Brightness; half _Layer3Alpha; half _Layer3VertexColor; sampler2D _TransparencyMaskTex; half4 _TransparencyMaskTex_ST; half _TransparencyMaskAmount; half _TransparencyMaskContrast; half4 _HeightColorsColor; half _HeightColorsAlpha; half _HeightColorsHeight; half _HeightColorsEdgeThickness; half _HeightColorsThickness; half _HeightColorsSpace; sampler2D _HeightColorsTex; half4 _HeightColorsTex_ST; sampler2D _ShadowOverlayTex; half4 _ShadowOverlayTex_ST; half _ShadowOverlayBrightness; half _ShadowOverlaySpeedU; half _ShadowOverlaySpeedV; half _ShadowOverlaySwayAmount; half _PlantSwayAmount; half _PlantSwaySpeed; half _PlantPhaseVariation; half _PlantBaseHeight; float _OutlineWidth; half4 _OutlineColor; float _OutlineZPos; half _AnimeThreshold1; half4 _AnimeColor1; half _AnimeThreshold2; half4 _AnimeColor2; half4 _AnimeColor3; half _AnimeSoftness; half _CameraFadeStart; half _CameraFadeEnd; half _CameraFadeInvert; half _UVTileDiscardUV; half _UVTileV3U0; half _UVTileV3U1; half _UVTileV3U2; half _UVTileV3U3; half _UVTileV2U0; half _UVTileV2U1; half _UVTileV2U2; half _UVTileV2U3; half _UVTileV1U0; half _UVTileV1U1; half _UVTileV1U2; half _UVTileV1U3; half _UVTileV0U0; half _UVTileV0U1; half _UVTileV0U2; half _UVTileV0U3; half _AmbientBrightness; half4 _ShadowColor; half _ZOffset; half _CutoutCutoff; CBUFFER_END ////////////////////////////////////////////////////////////////////////////////////////// // VERTEX STRUCTURE OUTPUT ////////////////////////////////////////////////////////////////////////////////////////// #if !TRIPLANAR struct v2f { float4 pos : SV_POSITION; float4 uv : TEXCOORD0; #if VERTEX_COLORS || LAYER1 || LAYER2 || LAYER3 || DETAIL_VERTEX_COLORS half4 color : COLOR; #endif float3 pos_world : TEXCOORD1; float3 nor_world : TEXCOORD2; #if SPECULAR && !(NORMAL_MAP || NORMAL_MAP2) && !(DIRLIGHTMAP_COMBINED && LIGHTMAP_ON) && !FLAT float3 specReflectDir : TEXCOORD3; #endif #if RIM || SPECULAR || REFLECTION float3 viewDir_world : TEXCOORD4; #endif #if MATCAP #if MATCAP_STATIC float3 nor_view : TEXCOORD5; #elif MATCAP_PERSPECTIVE float3 viewDir_view : TEXCOORD5; #endif #endif #if REFLECTION && !(NORMAL_MAP || NORMAL_MAP2) && !FLAT float3 viewReflectDir : TEXCOORD6; #endif #if (NORMAL_MAP || NORMAL_MAP2) && ((DIFFUSE && (!LIGHTMAP_ON || MIXED_LIGHTING)) || RIM || SPECULAR || MATCAP || (DIRLIGHTMAP_COMBINED && LIGHTMAP_ON) || REFLECTION) || SPECULAR_HAIR float4 tan_world : TEXCOORD7; #endif #if HEIGHT_COLORS half heightColorsHeight : TEXCOORD8; #endif #if SHADOW_OVERLAY float2 shadowOverlayUV : TEXCOORD9; #endif #if FOG #if FALLBACK_PASS float fogCoord : TEXCOORD7; #else float fogCoord : TEXCOORD10; #endif #endif #if DIFFUSE && (!DIFFUSE_PER_PIXEL && !(USE_FORWARD_PLUS || USE_CLUSTER_LIGHT_LOOP)) && !FLAT && !(NORMAL_MAP || NORMAL_MAP2) && (!LIGHTMAP_ON || MIXED_LIGHTING) && (VERTEXLIGHT_ON || _ADDITIONAL_LIGHTS || MIXED_LIGHTING) half3 col_diffuse_add : TEXCOORD11; #endif #if CAMERA_FADE half fade : TEXCOORD12; #endif #if (SHADOWS_SCREEN || SHADOWS_SHADOWMASK || LIGHTMAP_SHADOW_MIXING) && SHADOWS_ENABLED UNITY_SHADOW_COORDS(13) #endif UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO }; #endif ////////////////////////////////////////////////////////////////////////////////////////// // FUNCTIONS ////////////////////////////////////////////////////////////////////////////////////////// float3 PlantSway(appdata_full v) { float3 pos = v.vertex.xyz; #if PLANT_SWAY #if !PLANT_SWAY_LOCAL // Do computation in world space so rotation don't affect it pos = mul((float3x3)GetObjectToWorldMatrix(), pos); #endif // Semi-random phase based on world position of this mesh float3 worldPosCenter = TransformObjectToWorld(float3(0, 0, 0)).xyz; half posBasedRandom = dot(worldPosCenter, 1); half phase = _PlantPhaseVariation * posBasedRandom; // Base sway amount #if _PLANTTYPE_LEAF // Constant for leaves half swayAmount = 0.15; #elif _PLANTTYPE_PLANT // Based on height for plants half swayAmount = max(0, pos.y - _PlantBaseHeight); #elif _PLANTTYPE_VERTEX_COLOR_ALPHA // Based on alpha half swayAmount = 0.15 * v.color.a; #endif swayAmount *= _PlantSwayAmount; // Sway XZ positions // Sway Y at double-speed and sync phase to match XY half swayXZ = sin(_PlantSwaySpeed * _Time.y + phase) * swayAmount; pos.xz += swayXZ; pos.y += -(sin(_PlantSwaySpeed * _Time.z + phase*2 - UNITY_PI/2) * 0.5 + 0.5) * swayAmount * 0.5; #if !PLANT_SWAY_LOCAL // Change back to object space pos = mul((float3x3)GetWorldToObjectMatrix(), pos); #endif #endif return pos; } bool UVTileDiscard(float2 uv) { uv /= 4.0; return ((_UVTileV0U0 && uv.y < 0.25 && uv.x < 0.25) || (_UVTileV0U1 && uv.y < 0.25 && uv.x >= 0.25 && uv.x < 0.5) || (_UVTileV0U2 && uv.y < 0.25 && uv.x >= 0.5 && uv.x < 0.75) || (_UVTileV0U3 && uv.y < 0.25 && uv.x >= 0.75) || (_UVTileV1U0 && uv.y >= 0.25 && uv.y < 0.5 && uv.x < 0.25) || (_UVTileV1U1 && uv.y >= 0.25 && uv.y < 0.5 && uv.x >= 0.25 && uv.x < 0.5) || (_UVTileV1U2 && uv.y >= 0.25 && uv.y < 0.5 && uv.x >= 0.5 && uv.x < 0.75) || (_UVTileV1U3 && uv.y >= 0.25 && uv.y < 0.5 && uv.x >= 0.75) || (_UVTileV2U0 && uv.y >= 0.5 && uv.y < 0.75 && uv.x < 0.25) || (_UVTileV2U1 && uv.y >= 0.5 && uv.y < 0.75 && uv.x >= 0.25 && uv.x < 0.5) || (_UVTileV2U2 && uv.y >= 0.5 && uv.y < 0.75 && uv.x >= 0.5 && uv.x < 0.75) || (_UVTileV2U3 && uv.y >= 0.5 && uv.y < 0.75 && uv.x >= 0.75) || (_UVTileV3U0 && uv.y >= 0.75 && uv.x < 0.25) || (_UVTileV3U1 && uv.y >= 0.75 && uv.x >= 0.25 && uv.x < 0.5) || (_UVTileV3U2 && uv.y >= 0.75 && uv.x >= 0.5 && uv.x < 0.75) || (_UVTileV3U3 && uv.y >= 0.75 && uv.x >= 0.75)); } half4 ColorBrightness(half4 base, half brightness, half4 color) { base.rgb *= brightness; return base * color; } float3 TangentSpaceNormalToWorldSpaceNormal(float3 nor_world, float4 tan_world, float3 nor_tan) { float3 bin_world = cross(nor_world, tan_world.xyz) * tan_world.w; float3 ts0 = float3(tan_world.x, bin_world.x, nor_world.x); float3 ts1 = float3(tan_world.y, bin_world.y, nor_world.y); float3 ts2 = float3(tan_world.z, bin_world.z, nor_world.z); return normalize(float3(dot(ts0, nor_tan), dot(ts1, nor_tan), dot(ts2, nor_tan))); } bool IsLitMainLight(float3 unityLightData, uint meshRenderingLayers, bool isSpecular) { // Hack to prevent flickering in Forward+ #if (USE_FORWARD_PLUS || USE_CLUSTER_LIGHT_LOOP) return true; #endif // For dir baked lights, just default Specular to on #if (DIRLIGHTMAP_COMBINED && LIGHTMAP_ON) if (isSpecular) return true; #endif bool cullingMask = unityLightData.z == 1; #if URP && (_LIGHT_LAYERS && UNITY_VERSION >= 202102) bool layerMask = IsMatchingLightLayer(_MainLightLayerMask, meshRenderingLayers); return cullingMask && layerMask; #else return cullingMask; #endif } float FadeShadows(float3 pos_world, float3 nor_world, float atten) { // Fade shadows if needed #if HANDLE_SHADOWS_BLENDING_IN_GI float viewZ = dot(_WorldSpaceCameraPos - pos_world, UNITY_MATRIX_V[2].xyz); float shadowFadeDistance = UnityComputeShadowFadeDistance(pos_world, viewZ); float shadowFade = UnityComputeShadowFade(shadowFadeDistance); atten = saturate(atten + shadowFade); #endif // Mixed lighting - Hide non-lightfacing shadows #if LIGHTMAP_ON float ndotl = step(0, dot(_WorldSpaceLightPos0.xyz, nor_world)); atten = lerp(1, atten, ndotl); #endif return atten; } // BLENDING FUNCTIONS //////////////////////////////////////////////////////////////////////// half3 BlendDetail(half3 col, half3 col_blend, float blendAlpha) { #if _DETAILBLEND_ALPHA_BLEND col = lerp(col, col_blend, blendAlpha); #else half3 col_blend_alphaed = col_blend * blendAlpha; #if _DETAILBLEND_ADDITIVE col += col_blend_alphaed; #elif _DETAILBLEND_MULTIPLY col *= col_blend_alphaed; #elif _DETAILBLEND_MULTIPLY_LIGHTEN col *= 1 + col_blend_alphaed; #endif #endif return col; } half3 BlendMatCap(half3 col, half3 col_blend) { #if _MATCAPBLEND_MULTIPLY col *= col_blend; #elif _MATCAPBLEND_MULTIPLY_LIGHTEN col *= 1 + col_blend; #endif return col; } half3 BlendRim(half3 col, half3 col_blend, float blendAlpha) { #if _RIMBLEND_ALPHA_BLEND col = lerp(col, col_blend, blendAlpha); #else half3 col_blend_alphaed = col_blend * blendAlpha; #if _RIMBLEND_ADDITIVE col += col_blend_alphaed; #elif _RIMBLEND_MULTIPLY col *= col_blend_alphaed; #elif _RIMBLEND_MULTIPLY_LIGHTEN col *= 1 + col_blend_alphaed; #endif #endif return col; } half4 BlendLayer1(half4 col, half4 col_blend, float blendAlpha) { #if _LAYER1BLEND_ALPHA_BLEND col = lerp(col, col_blend, blendAlpha); #else half3 col_blend_alphaed = col_blend.rgb * blendAlpha; #if _LAYER1BLEND_ADDITIVE col.rgb += col_blend_alphaed; #elif _LAYER1BLEND_MULTIPLY col.rgb *= col_blend_alphaed; #elif _LAYER1BLEND_MULTIPLY_LIGHTEN col.rgb *= 1 + col_blend_alphaed; #endif #endif return col; } half4 BlendLayer2(half4 col, half4 col_blend, float blendAlpha) { #if _LAYER2BLEND_ALPHA_BLEND col = lerp(col, col_blend, blendAlpha); #else half3 col_blend_alphaed = col_blend.rgb * blendAlpha; #if _LAYER2BLEND_ADDITIVE col.rgb += col_blend_alphaed; #elif _LAYER2BLEND_MULTIPLY col.rgb *= col_blend_alphaed; #elif _LAYER2BLEND_MULTIPLY_LIGHTEN col.rgb *= 1 + col_blend_alphaed; #endif #endif return col; } half4 BlendLayer3(half4 col, half4 col_blend, float blendAlpha) { #if _LAYER3BLEND_ALPHA_BLEND col = lerp(col, col_blend, blendAlpha); #else half3 col_blend_alphaed = col_blend.rgb * blendAlpha; #if _LAYER3BLEND_ADDITIVE col.rgb += col_blend_alphaed; #elif _LAYER3BLEND_MULTIPLY col.rgb *= col_blend_alphaed; #elif _LAYER3BLEND_MULTIPLY_LIGHTEN col.rgb *= 1 + col_blend_alphaed; #endif #endif return col; } half4 BlendHeightColors(half4 col, half4 col_blend, float blendAlpha) { #if _HEIGHTCOLORSBLEND_ALPHA_BLEND || _HEIGHTCOLORSBLEND_LIT col = lerp(col, col_blend, blendAlpha); #else half3 col_blend_alphaed = col_blend.rgb * blendAlpha; #if _HEIGHTCOLORSBLEND_ADDITIVE col.rgb += col_blend_alphaed; #endif #endif return col; } // LAYER FUNCTIONS //////////////////////////////////////////////////////////////////////// #if LAYER1 half4 Layer1(half4 col, float2 uv, half4 vertexColor, float2 uvX, float2 uvY, float2 uvZ, half4 blend) { #if !TRIPLANAR half4 layer = tex2D(_Layer1Tex, TRANSFORM_TEX(uv, _Layer1Tex)); #else half4 layerX = tex2D(_Layer1Tex, TRANSFORM_TEX(uvX, _Layer1Tex)); half4 layerY = tex2D(_Layer1Tex, TRANSFORM_TEX(uvY, _Layer1Tex)); half4 layerZ = tex2D(_Layer1Tex, TRANSFORM_TEX(uvZ, _Layer1Tex)); half4 layer = layerX * blend.x + layerY * (blend.y + blend.w) + layerZ * blend.z; #endif layer = ColorBrightness(layer, _Layer1Brightness, _Layer1Color); half mask = layer.a; mask *= _Layer1VertexColor == 0 ? 1 : vertexColor.r; mask = min(1, mask * _Layer1Alpha); return BlendLayer1(col, layer, mask); } #endif #if LAYER2 half4 Layer2(half4 col, float2 uv, half4 vertexColor, float2 uvX, float2 uvY, float2 uvZ, half4 blend) { #if !TRIPLANAR half4 layer = tex2D(_Layer2Tex, TRANSFORM_TEX(uv, _Layer2Tex)); #else half4 layerX = tex2D(_Layer2Tex, TRANSFORM_TEX(uvX, _Layer2Tex)); half4 layerY = tex2D(_Layer2Tex, TRANSFORM_TEX(uvY, _Layer2Tex)); half4 layerZ = tex2D(_Layer2Tex, TRANSFORM_TEX(uvZ, _Layer2Tex)); half4 layer = layerX * blend.x + layerY * (blend.y + blend.w) + layerZ * blend.z; #endif layer = ColorBrightness(layer, _Layer2Brightness, _Layer2Color); half mask = layer.a; mask *= _Layer2VertexColor == 0 ? 1 : vertexColor.g; mask = min(1, mask * _Layer2Alpha); return BlendLayer2(col, layer, mask); } #endif #if LAYER3 half4 Layer3(half4 col, float2 uv, half4 vertexColor, float2 uvX, float2 uvY, float2 uvZ, half4 blend) { #if !TRIPLANAR half4 layer = tex2D(_Layer3Tex, TRANSFORM_TEX(uv, _Layer3Tex)); #else half4 layerX = tex2D(_Layer3Tex, TRANSFORM_TEX(uvX, _Layer3Tex)); half4 layerY = tex2D(_Layer3Tex, TRANSFORM_TEX(uvY, _Layer3Tex)); half4 layerZ = tex2D(_Layer3Tex, TRANSFORM_TEX(uvZ, _Layer3Tex)); half4 layer = layerX * blend.x + layerY * (blend.y + blend.w) + layerZ * blend.z; #endif layer = ColorBrightness(layer, _Layer3Brightness, _Layer3Color); half mask = layer.a; mask *= _Layer3VertexColor == 0 ? 1 : vertexColor.b; mask = min(1, mask * _Layer3Alpha); return BlendLayer3(col, layer, mask); } #endif #if HEIGHT_COLORS half4 HeightColors(half4 col, half waterHeight, float2 uv) { half4 heightCol = 1; #if HEIGHT_COLORS_TEX heightCol = tex2D(_HeightColorsTex, TRANSFORM_TEX(uv, _HeightColorsTex)); #endif heightCol *= _HeightColorsColor; half mask = 1 - saturate((abs(waterHeight) - _HeightColorsThickness) / _HeightColorsEdgeThickness); mask = min(1, mask * _HeightColorsAlpha); return BlendHeightColors(col, heightCol, mask); } #endif ////////////////////////////////////////////////////////////////////////////////////////// // VERTEX SHADER ////////////////////////////////////////////////////////////////////////////////////////// v2f vert (appdata_full v) { v2f o; UNITY_INITIALIZE_OUTPUT(v2f, o); UNITY_SETUP_INSTANCE_ID(v); UNITY_TRANSFER_INSTANCE_ID(v, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); // Vertex manipulations #if OUTLINE_PASS #if OUTLINE float outlineWidth = _OutlineWidth; half objDepth = -UnityObjectToViewPos(float3(0, 0, 0)).z; #if OUTLINE_WIDTH_INDEPENDENT half objDepthLog = objDepth; if (objDepthLog > 1) objDepthLog = 1 + log(objDepthLog); outlineWidth *= objDepthLog; #endif v.vertex.xyz += outlineWidth * normalize(v.normal); #else o.pos = 0; return o; #endif #endif #if !TRIPLANAR v.vertex.xyz = PlantSway(v); o.pos_world = TransformObjectToWorld(v.vertex.xyz); #else // TRIPLANAR Sway after pos_world and nor_world are set to avoid shifting texture o.pos_world = TransformObjectToWorld(v.vertex.xyz); v.vertex.xyz = PlantSway(v); #endif // UV Tile discard #if UVTILE float2 uv = v.texcoord; if (_UVTileDiscardUV == 2) uv = v.texcoord1; else if (_UVTileDiscardUV == 3) uv = v.texcoord2; else if (_UVTileDiscardUV == 4) uv = v.texcoord3; if (UVTileDiscard(uv)) v.vertex = asfloat(0x7fc00000); #endif // Clip pos #if ZOFFSET || CAMERA_FADE float3 pos_view = UnityObjectToViewPos(v.vertex.xyz); #endif #if ZOFFSET pos_view.z += _ZOffset; o.pos = mul(UNITY_MATRIX_P, float4(pos_view, 1)); #else o.pos = UnityObjectToClipPos(v.vertex.xyz); #endif #if OUTLINE_PASS && OUTLINE float outlineOffset = _OutlineZPos / -100 / objDepth; #if !UNITY_REVERSED_Z outlineOffset = -outlineOffset; #endif o.pos.z += outlineOffset; #endif #if TRIPLANAR_LOCAL o.pos_local = v.vertex.xyz; #endif #if CAMERA_FADE o.fade = saturate((-pos_view.z - _CameraFadeStart) / (_CameraFadeEnd - _CameraFadeStart)); if (_CameraFadeInvert) o.fade = 1 - o.fade; #endif // Fragment data o.uv.xy = v.texcoord.xy; o.uv.zw = v.texcoord1.xy; #if VERTEX_COLORS || LAYER1 || LAYER2 || LAYER3 || DETAIL_VERTEX_COLORS o.color = v.color; #endif o.nor_world = UnityObjectToWorldNormal(v.normal); #if (!TRIPLANAR && \ (NORMAL_MAP || NORMAL_MAP2) && ((DIFFUSE && (!LIGHTMAP_ON || MIXED_LIGHTING)) || RIM || SPECULAR || MATCAP || (DIRLIGHTMAP_COMBINED && LIGHTMAP_ON) || REFLECTION)) \ || SPECULAR_HAIR o.tan_world = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w); #endif #if DIFFUSE && (!DIFFUSE_PER_PIXEL && !(USE_FORWARD_PLUS || USE_CLUSTER_LIGHT_LOOP)) && !_LIGHT_COOKIES && !FLAT && !(NORMAL_MAP || NORMAL_MAP2 || NORMAL_MAP_TOP) && (!LIGHTMAP_ON || MIXED_LIGHTING) && (VERTEXLIGHT_ON || _ADDITIONAL_LIGHTS || MIXED_LIGHTING) uint meshRenderingLayers = GetMeshRenderingLightLayerCustom(); o.col_diffuse_add = AdditionalLightsVert(o.pos_world, o.nor_world, _DiffuseWrap, _DiffuseBrightness, _DiffuseContrast, meshRenderingLayers, _ShadowColor.rgb); #endif #if SPECULAR && !(NORMAL_MAP || NORMAL_MAP2 || NORMAL_MAP_TOP) && !(DIRLIGHTMAP_COMBINED && LIGHTMAP_ON) && !FLAT && !SPECULAR_HAIR o.specReflectDir = normalize(reflect(-_WorldSpaceLightPos0.rgb, o.nor_world)); #endif #if RIM || SPECULAR || REFLECTION o.viewDir_world = WorldSpaceViewDir(v.vertex); #endif #if MATCAP #if MATCAP_STATIC float3 worldNorm = UnityObjectToWorldNormal(v.normal); float3x3 viewMat = ((float3x3)UNITY_MATRIX_V); // Remove view rotation viewMat[0] = float3(1, 0, 0); viewMat[1] = float3(0, 1, 0); viewMat[2] = float3(0, 0, 1); // Add custom direction rotation float3 cosRot = cos(_MatCapRot); float3 sinRot = sin(_MatCapRot); float3x3 rotX = float3x3(1, 0, 0, 0, cosRot.x, -sinRot.x, 0, sinRot.x, cosRot.x); float3x3 rotY = float3x3(cosRot.y, 0, sinRot.y, 0, 1, 0, -sinRot.y, 0, cosRot.y); float3x3 rotZ = float3x3(cosRot.z, -sinRot.z, 0, sinRot.z, cosRot.z, 0, 0, 0, 1); worldNorm = mul(rotX, mul(rotY, mul(rotZ, worldNorm))); o.nor_view = mul(viewMat, worldNorm); #elif MATCAP_PERSPECTIVE o.viewDir_view = UnityObjectToViewPos(v.vertex.xyz); #endif #endif #if REFLECTION && !(NORMAL_MAP || NORMAL_MAP2 || NORMAL_MAP_TOP) && !FLAT o.viewReflectDir = reflect(-o.viewDir_world, o.nor_world); #endif #if HEIGHT_COLORS // World or local space height o.heightColorsHeight = _HeightColorsSpace == 0 ? o.pos_world.y : v.vertex.y; o.heightColorsHeight -= _HeightColorsHeight; #endif #if SHADOW_OVERLAY o.shadowOverlayUV = float2(o.pos_world.x, o.pos_world.z) / 80; float2 shadowAnim = (_Time.x % 60) * float2(_ShadowOverlaySpeedU, _ShadowOverlaySpeedV); #if _SHADOWOVERLAYANIMATION_SWAY shadowAnim = sin(shadowAnim * 500) * _ShadowOverlaySwayAmount; #endif o.shadowOverlayUV += shadowAnim; o.shadowOverlayUV *= 2; #endif // Unity system #if FOG UNITY_TRANSFER_FOG(o, o.pos); #endif #if (SHADOWS_SCREEN || SHADOWS_SHADOWMASK || LIGHTMAP_SHADOW_MIXING) && SHADOWS_ENABLED UNITY_TRANSFER_SHADOW(o, o.uv.zw); #endif #if SHADOW_CASTER TRANSFER_SHADOW_CAST(o, v) #endif #if META o.pos = UnityMetaVertexPosition(v.vertex, v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST); #endif return o; } ////////////////////////////////////////////////////////////////////////////////////////// // FRAGMENT SHADER ////////////////////////////////////////////////////////////////////////////////////////// half4 frag (v2f i) : COLOR { float2 uv = i.uv.xy; float2 uv2 = i.uv.zw; UNITY_SETUP_INSTANCE_ID(i); UNITY_LIGHTDATA #if META UnityMetaInput meta; UNITY_INITIALIZE_OUTPUT(UnityMetaInput, meta); #endif #if TRIPLANAR // Scale UVs to more reasonable size for world texturing float TEX_SCALE = 32; #if !TRIPLANAR_BASE_UV _MainTex_ST /= TEX_SCALE; #if NORMAL_MAP _NormalTex_ST /= TEX_SCALE; #endif #if NORMAL_MAP2 _NormalTex2_ST /= TEX_SCALE; #endif #if DETAIL _DetailTex_ST /= TEX_SCALE; #endif #if LAYER1 _Layer1Tex_ST /= TEX_SCALE; #endif #if LAYER2 _Layer2Tex_ST /= TEX_SCALE; #endif #if LAYER3 _Layer3Tex_ST /= TEX_SCALE; #endif #endif #if TOP_TEX _TopTex_ST /= TEX_SCALE; #endif #if NORMAL_MAP_TOP _NormalTopTex_ST /= TEX_SCALE; #endif #endif // Normalize vectors #if FLAT i.nor_world = cross(ddy(i.pos_world), ddx(i.pos_world)); #if UNITY_REVERSED_Z i.nor_world *= -_ProjectionParams.x; #endif #endif i.nor_world = normalize(i.nor_world); #if (!TRIPLANAR && (NORMAL_MAP || NORMAL_MAP2) && ((DIFFUSE && (!LIGHTMAP_ON || MIXED_LIGHTING)) || RIM || SPECULAR || MATCAP || (DIRLIGHTMAP_COMBINED && LIGHTMAP_ON) || REFLECTION)) || SPECULAR_HAIR i.tan_world.xyz = normalize(i.tan_world.xyz); #endif #if SPECULAR && !(NORMAL_MAP || NORMAL_MAP2 || NORMAL_MAP_TOP) && !(DIRLIGHTMAP_COMBINED && LIGHTMAP_ON) && !FLAT && !SPECULAR_HAIR i.specReflectDir = normalize(i.specReflectDir); #endif #if RIM || SPECULAR || (REFLECTION && ((NORMAL_MAP || NORMAL_MAP2 || NORMAL_MAP_TOP) || FLAT)) i.viewDir_world = normalize(i.viewDir_world); #endif #if MATCAP && (!MATCAP_STATIC && MATCAP_PERSPECTIVE) i.viewDir_view = normalize(i.viewDir_view); #endif #if REFLECTION && !(NORMAL_MAP || NORMAL_MAP2 || NORMAL_MAP_TOP) && !FLAT i.viewReflectDir = normalize(i.viewReflectDir); #endif #if TRIPLANAR // Calculate blend weights #if TRIPLANAR_LOCAL float3 triPos = i.pos_local; #else float3 triPos = i.pos_world.xyz; #endif #if TRIPLANAR_BASE_UV float2 uvX = uv; float2 uvZ = uv; #else float2 uvX = triPos.zy; float2 uvZ = triPos.xy; #endif float2 uvY = triPos.xz; float4 blend; blend.xyz = i.nor_world; blend.xz = abs(i.nor_world.xz); blend.y = max(0, i.nor_world.y); blend.w = -min(0, i.nor_world.y); #if TRIPLANAR_SHARPNESS blend = pow(blend, _TriplanarSharpness); #endif blend /= (blend.x + blend.y + blend.z + blend.w); #elif LAYER1 || LAYER2 || LAYER3 float2 uvX = 0, uvY = 0, uvZ = 0; half4 blend = 0; #endif // Calculate intermediate vectors uint meshRenderingLayers = GetMeshRenderingLightLayerCustom(); #if !TRIPLANAR #if (NORMAL_MAP || NORMAL_MAP2) // Calculate tangent-space normal float2 normalUV = uv; #if _NORMALUV_UV2 normalUV = uv2; #endif float2 normalUV2 = uv; #if _NORMALUV2_UV2 normalUV2 = uv2; #endif float3 nor_tan = 0; #if NORMAL_MAP nor_tan = UnpackNormal(tex2D(_NormalTex, TRANSFORM_TEX(normalUV, _NormalTex))); nor_tan.xy *= _NormalStrength; #endif #if NORMAL_MAP2 nor_tan += UnpackNormal(tex2D(_NormalTex2, TRANSFORM_TEX(normalUV2, _NormalTex2))); nor_tan.xy *= _Normal2Strength; #endif nor_tan = normalize(nor_tan); #else float3 nor_tan = float3(0, 0, 1); #endif #if (NORMAL_MAP || NORMAL_MAP2) && ((DIFFUSE && (!LIGHTMAP_ON || MIXED_LIGHTING)) || RIM || SPECULAR || MATCAP || (DIRLIGHTMAP_COMBINED && LIGHTMAP_ON) || REFLECTION) float3 bumpNor_world = TangentSpaceNormalToWorldSpaceNormal(i.nor_world, i.tan_world, nor_tan); #endif #else #if (NORMAL_MAP || NORMAL_MAP2 || NORMAL_MAP_TOP) #if NORMAL_MAP float3 norX = UnpackNormal(tex2D(_NormalTex, TRANSFORM_TEX(uvX, _NormalTex))) * _NormalStrength; float3 norYbottom = UnpackNormal(tex2D(_NormalTex, TRANSFORM_TEX(uvY, _NormalTex))) * _NormalStrength; float3 norZ = UnpackNormal(tex2D(_NormalTex, TRANSFORM_TEX(uvZ, _NormalTex))) * _NormalStrength; #else // Not using normal map - just use vector pointing outwards float3 norX = float3(0, 0, 1); float3 norYbottom = float3(0, 0, 1); float3 norZ = float3(0, 0, 1); #endif #if NORMAL_MAP2 norX += UnpackNormal(tex2D(_NormalTex2, TRANSFORM_TEX(uvX, _NormalTex2))) * _Normal2Strength; norYbottom += UnpackNormal(tex2D(_NormalTex2, TRANSFORM_TEX(uvY, _NormalTex2))) * _Normal2Strength; norZ += UnpackNormal(tex2D(_NormalTex2, TRANSFORM_TEX(uvZ, _NormalTex2))) * _Normal2Strength; #endif norX = float3(norX.xy + i.nor_world.zy, i.nor_world.x); norYbottom = float3(norYbottom.xy + i.nor_world.xz, i.nor_world.y); norZ = float3(norZ.xy + i.nor_world.xy, i.nor_world.z); #if NORMAL_MAP_TOP float3 norYtop = UnpackNormal(tex2D(_NormalTopTex, TRANSFORM_TEX(uvY, _NormalTopTex))) * _NormalTopStrength; norYtop = float3(norYtop.xy + i.nor_world.xz, i.nor_world.y); #else float3 norYtop = norYbottom; #endif #if (DIFFUSE && (!LIGHTMAP_ON || MIXED_LIGHTING)) || RIM || SPECULAR || MATCAP || (DIRLIGHTMAP_COMBINED && LIGHTMAP_ON) || REFLECTION float3 bumpNor_world = normalize(norX.zyx * blend.x + norYtop.xzy * blend.y + norZ.xyz * blend.z + norYbottom.xzy * blend.w); #endif #endif #endif #if (DIFFUSE && (!LIGHTMAP_ON || MIXED_LIGHTING)) || RIM || SPECULAR || MATCAP || REFLECTION #if (NORMAL_MAP || NORMAL_MAP2 || NORMAL_MAP_TOP) float3 adjNor_world = bumpNor_world; #else // Not using normal map - just use nor_world from vertex shader float3 adjNor_world = i.nor_world; #endif #endif #if LIGHT_MAP // Lightmap UV float2 lightmapUV = uv; #if _LIGHTMAPUV_UV2 lightmapUV = uv2; #endif lightmapUV = TRANSFORM_TEX(lightmapUV, _LightmapTex); #endif #if LIGHTMAP_ON float2 lightmapUnityUV = uv2 * unity_LightmapST.xy + unity_LightmapST.zw; #endif #if ((NORMAL_MAP || NORMAL_MAP2 || NORMAL_MAP_TOP) || SPECULAR) && (DIRLIGHTMAP_COMBINED && LIGHTMAP_ON) half4 lightmapDir = UNITY_SAMPLE_TEX2D_SAMPLER(unity_LightmapInd, unity_Lightmap, lightmapUnityUV); #endif #if SPECULAR_MAP && (SPECULAR || REFLECTION_SPECULAR) float2 specUV = uv; #if _SPECULARUV_UV2 specUV = uv2; #endif half4 specTex = tex2D(_SpecularTex, TRANSFORM_TEX(specUV, _SpecularTex)); #endif // BASE #if !TRIPLANAR float4 col_base = tex2D(_MainTex, TRANSFORM_TEX(uv, _MainTex)); col_base.a = _IgnoreMainTexAlpha == 0 ? saturate(col_base.a) : 1; #if BASE_CONTRAST col_base.rgb = pow(col_base.rgb, _Contrast); #endif col_base = ColorBrightness(col_base, _Brightness, _Color); #else // TRIPLANAR half4 colX = tex2D(_MainTex, TRANSFORM_TEX(uvX, _MainTex)); #if TOP_TEX || TRIPLANAR_TOP half4 colYtop = tex2D(_TopTex, TRANSFORM_TEX(uvY, _TopTex)); #else half4 colYtop = tex2D(_MainTex, TRANSFORM_TEX(uvY, _MainTex)); #endif #if !(TOP_TEX || TRIPLANAR_TOP) // Same as top half4 colYbottom = colYtop; #else half4 colYbottom = tex2D(_MainTex, TRANSFORM_TEX(uvY, _MainTex)); #endif half4 colZ = tex2D(_MainTex, TRANSFORM_TEX(uvZ, _MainTex)); float4 col_base = colX * blend.x + colZ * blend.z + colYbottom * blend.w; col_base = ColorBrightness(col_base, _Brightness, _Color); // BASE TOP half4 col_base_top = colYtop * blend.y; #if TRIPLANAR_TOP || TOP_TEX col_base_top = ColorBrightness(col_base_top, _TopBrightness, _TopColor); #else col_base_top = ColorBrightness(col_base_top, _Brightness, _Color); #endif col_base += col_base_top; col_base.a = _IgnoreMainTexAlpha == 0 ? saturate(col_base.a) : 1; #if BASE_CONTRAST // Triplanar apply contrast after top added col_base.rgb = pow(col_base.rgb, _Contrast); #endif #endif #if VERTEX_COLORS #if VERTEX_COLORS_CONTRAST i.color = pow(i.color, _VertexColorsContrast); #endif col_base = lerp(col_base, col_base * i.color, _VertexColorsAmount); #endif #if DETAIL #if !TRIPLANAR float2 detailUV = uv; #if _DETAILUV_UV2 detailUV = uv2; #endif half4 col_detail = tex2D(_DetailTex, TRANSFORM_TEX(detailUV, _DetailTex)); #else half4 col_detailX = tex2D(_DetailTex, TRANSFORM_TEX(uvX, _DetailTex)); half4 col_detailY = tex2D(_DetailTex, TRANSFORM_TEX(uvY, _DetailTex)); half4 col_detailZ = tex2D(_DetailTex, TRANSFORM_TEX(uvZ, _DetailTex)); half4 col_detail = col_detailX * blend.x + col_detailY * (blend.y + blend.w) + col_detailZ * blend.z; #endif #if DETAIL_CONTRAST col_detail.rgb = pow(col_detail.rgb, _DetailContrast); #endif col_detail = ColorBrightness(col_detail, _DetailBrightness, _DetailColor); #if DETAIL_VERTEX_COLORS col_detail.a *= i.color.a; #endif #if !DETAIL_LIGHTING col_base.rgb = BlendDetail(col_base.rgb, col_detail.rgb, col_detail.a); #endif #endif #if LAYER1 float2 layer1UV = uv; #if _LAYER1UV_UV2 layer1UV = uv2; #endif col_base = Layer1(col_base, layer1UV, i.color, uvX, uvY, uvZ, blend); #endif #if LAYER2 float2 layer2UV = uv; #if _LAYER2UV_UV2 layer2UV = uv2; #endif col_base = Layer2(col_base, layer2UV, i.color, uvX, uvY, uvZ, blend); #endif #if LAYER3 float2 layer3UV = uv; #if _LAYER3UV_UV2 layer3UV = uv2; #endif col_base = Layer3(col_base, layer3UV, i.color, uvX, uvY, uvZ, blend); #endif #if !TRIPLANAR #if TRANSPARENCY_MASK half4 maskColor = tex2D(_TransparencyMaskTex, TRANSFORM_TEX(uv, _TransparencyMaskTex)); half mask = min(maskColor.r, maskColor.a); // Supports either RGB or RGBA mask #if TRANSPARENCY_MASK_CONTRAST mask = pow(mask, _TransparencyMaskContrast); #endif half alphaMask = min(1, mask * _TransparencyMaskAmount); col_base.a *= alphaMask; #endif #endif #if HEIGHT_COLORS && _HEIGHTCOLORSBLEND_LIT col_base = HeightColors(col_base, i.heightColorsHeight, uv); #endif #if RIM half4 col_rim = _RimColor; half rim = max(0, dot(i.viewDir_world.xyz, adjNor_world)); rim = _RimInverse == 0 ? 1 - rim : rim; rim = min(1, pow(rim, _RimContrast) * _RimAmount) * col_rim.a; #if RIM_DIRECTION rim *= max(0, dot(adjNor_world, normalize(_RimDirection))); #endif #if !REFLECTION_RIM && _RIMBLEND_TRANSPARENCY col_base.a *= 1 - rim; #endif #endif #if REFLECTION #if (NORMAL_MAP || NORMAL_MAP2 || NORMAL_MAP_TOP) || FLAT float3 viewReflectDir = reflect(-i.viewDir_world, adjNor_world); #else float3 viewReflectDir = i.viewReflectDir; #endif #if REFLECTION_TEX half3 col_reflect = DecodeHDR(texCUBE(_ReflectionTex, viewReflectDir), _ReflectionTex_HDR); #else half3 col_reflect = DecodeHDR(unity_SpecCube0.Sample(samplerunity_SpecCube0, viewReflectDir), unity_SpecCube0_HDR); #endif col_reflect *= _ReflectionColor; half reflectAmount = _ReflectionAmount; #if REFLECTION_RIM && RIM // Mask reflection with rim col_reflect *= col_rim.rgb; reflectAmount *= rim; #endif #if REFLECTION_SPECULAR && SPECULAR_MAP reflectAmount *= specTex.r; #endif col_base.rgb = lerp(col_base.rgb, col_reflect.rgb, reflectAmount); #endif #if CAMERA_FADE col_base.a *= i.fade; #endif // LIGHTING #if !ANIME half3 col = col_base.rgb; #else // Anime lighting slightly less accurate, mostly multiplicative lighting half3 col = 1; #endif #if DIFFUSE && (!LIGHTMAP_ON || MIXED_LIGHTING) half3 col_diffuse = 0; #if LIGHTMAP_ON && MIXED_LIGHTING col_diffuse = 1; #else if (IsLitMainLight(unity_LightData, meshRenderingLayers, false)) { float ndotl = max(0, dot(_WorldSpaceLightPos0.xyz, adjNor_world)); ndotl = max(0, lerp(ndotl, 1, _DiffuseWrap)); ndotl = pow(ndotl, _DiffuseContrast) * _DiffuseBrightness; col_diffuse = ndotl * _LightColor0.rgb; #if URP && _LIGHT_COOKIES real3 cookieColor = SampleMainLightCookie(i.pos_world); col_diffuse *= cookieColor; #endif } #endif #if (VERTEXLIGHT_ON || _ADDITIONAL_LIGHTS || MIXED_LIGHTING) #if (!DIFFUSE_PER_PIXEL && !(USE_FORWARD_PLUS || USE_CLUSTER_LIGHT_LOOP)) && !FLAT && !_LIGHT_COOKIES && !(NORMAL_MAP || NORMAL_MAP2 || NORMAL_MAP_TOP) col_diffuse += i.col_diffuse_add; #else col_diffuse += AdditionalLightsFrag(i.pos_world, adjNor_world, i.pos, _DiffuseWrap, _DiffuseBrightness, _DiffuseContrast, meshRenderingLayers, _ShadowColor.rgb); #endif #endif #if DETAIL && DETAIL_LIGHTING col_diffuse = BlendDetail(col_diffuse, col_detail.rgb, col_detail.a); #endif col *= col_diffuse; #endif #if LIGHT_MAP half3 col_light = tex2D(_LightmapTex, lightmapUV).rgb; col_light = max(0, 1 - _LightmapBrightness) + col_light * _LightmapBrightness; col_light *= _LightmapColor.rgb; col *= col_light; #endif #if LIGHTMAP_ON float3 col_light2 = SampleUnityLightmap(lightmapUnityUV); #if DIRLIGHTMAP_COMBINED && (NORMAL_MAP || NORMAL_MAP2 || NORMAL_MAP_TOP) col_light2 = DecodeDirectionalLightmap(col_light2, lightmapDir, bumpNor_world); #endif col *= col_light2; #endif #if MATCAP // Calculate view-space normal #if MATCAP_STATIC // Use simplified matcap calculation without normal map float2 nor_view = i.nor_view.xy; #else float3 nor_view = normalize(mul((float3x3)UNITY_MATRIX_V, adjNor_world)); #if MATCAP_PERSPECTIVE float3 viewCross = cross(i.viewDir_view, nor_view); nor_view = float3(-viewCross.y, viewCross.x, 0.0); #endif #endif float2 matCapUV = nor_view.xy * 0.5 + 0.5; half3 col_matcap = tex2D(_MatCapTex, TRANSFORM_TEX(matCapUV, _MatCapTex)).rgb; #if MATCAP_CONTRAST col_matcap = pow(col_matcap, _MatCapContrast); #endif col_matcap = col_matcap * _MatCapColor.rgb * _MatCapBrightness; #if DETAIL && DETAIL_LIGHTING col_matcap = BlendDetail(col_matcap, col_detail.rgb, col_detail.a); #endif col = BlendMatCap(col.rgb, col_matcap); #endif #if SPECULAR if (IsLitMainLight(unity_LightData, meshRenderingLayers, true)) { #if !(DIRLIGHTMAP_COMBINED && LIGHTMAP_ON) float3 specLightDir = _WorldSpaceLightPos0.xyz; #else float3 specLightDir = (lightmapDir.xyz - 0.5) * 2; specLightDir /= max(0.000001, lightmapDir.w); #endif #if !TRIPLANAR && SPECULAR_MAP half specBrightness = _SpecularBrightness * specTex.r; half specSmoothness = max(1, _SpecularSmoothness * specTex.a); half shiftTex = specTex.r - 0.5; #else half specBrightness = _SpecularBrightness; half specSmoothness = _SpecularSmoothness; half shiftTex = 0; #endif #if !SPECULAR_HAIR #if (NORMAL_MAP || NORMAL_MAP2 || NORMAL_MAP_TOP) || (DIRLIGHTMAP_COMBINED && LIGHTMAP_ON) || FLAT float3 specReflectDir = reflect(-specLightDir, adjNor_world); #else float3 specReflectDir = i.specReflectDir; #endif half glare = max(0, dot(i.viewDir_world, specReflectDir)); #else float3 tanShift = normalize(i.tan_world.xyz + adjNor_world * shiftTex); float3 halfVec = normalize(specLightDir + i.viewDir_world); float dotTH = dot(tanShift, halfVec); half glare = sqrt(1 - dotTH * dotTH); #endif glare = pow(glare, specSmoothness); #if SPECULAR_HAIR glare *= smoothstep(-1, 0, dot(specLightDir, adjNor_world)); #endif #if LIGHTMAP_ON half3 specColor = col_light2; #else half3 specColor = _LightColor0.rgb; #endif if (dot(_SpecularColor.rgb, 1) != 3) // Specular Color override specColor = _SpecularColor.rgb; half3 col_specular = glare * specBrightness * specColor; col += col_specular; } #endif #if RIM && !REFLECTION_RIM && !_RIMBLEND_TRANSPARENCY col = BlendRim(col, col_rim.rgb, rim); #endif // Shadows #if (SHADOWS_SCREEN || SHADOWS_SHADOWMASK || LIGHTMAP_SHADOW_MIXING || _MAIN_LIGHT_SHADOWS || _MAIN_LIGHT_SHADOWS_CASCADE || _MAIN_LIGHT_SHADOWS_SCREEN) && SHADOWS_ENABLED UNITY_LIGHT_ATTENUATION(atten, i, i.pos_world) atten = FadeShadows(i.pos_world, i.nor_world, atten); #if LIGHTMAP_ON half3 col_shadow = max(0.000001, lerp(unity_ShadowColor.rgb, 1, atten)); float3 subtractShadow = min(1, max(0, col_light2 - col_shadow) / col_shadow); col_shadow = lerp(1, col_shadow, subtractShadow); #else half3 col_shadow = lerp(_ShadowColor.rgb, 1, atten); #endif col *= col_shadow; #endif #if SHADOW_OVERLAY half4 col_shadowOverlay = tex2D(_ShadowOverlayTex, TRANSFORM_TEX(i.shadowOverlayUV, _ShadowOverlayTex)); half shadowMask = min(col_shadowOverlay.r, col_shadowOverlay.a); shadowMask = saturate(shadowMask + (_ShadowOverlayBrightness - 1)); half topFactor = max(0, dot(float3(0, 1, 0), i.nor_world)); col *= lerp(1, shadowMask, topFactor); #endif #if _SCREEN_SPACE_OCCLUSION float2 normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(i.pos.xy); AmbientOcclusionFactor ao = GetScreenSpaceAmbientOcclusion(normalizedScreenSpaceUV); float aoFactor = ao.indirectAmbientOcclusion * ao.directAmbientOcclusion; col *= aoFactor; #endif #if ANIME half3 animeColor; half lum = Luminance(col); #if ANIME_SOFT half thresLower1 = _AnimeThreshold1 - _AnimeSoftness; half thresUpper1 = _AnimeThreshold1 + _AnimeSoftness; half thresLower2 = _AnimeThreshold2 - _AnimeSoftness; half thresUpper2 = _AnimeThreshold2 + _AnimeSoftness; #else half thresLower1 = _AnimeThreshold1; half thresLower2 = _AnimeThreshold2; #endif if (lum < thresLower1) animeColor = _AnimeColor1.rgb; #if ANIME_SOFT else if (lum < thresUpper1) animeColor = lerp(_AnimeColor1.rgb, _AnimeColor2.rgb, (lum - thresLower1) / (_AnimeSoftness * 2)); #endif else if (lum < thresLower2) animeColor = _AnimeColor2.rgb; #if ANIME_SOFT else if (lum < thresUpper2) animeColor = lerp(_AnimeColor2.rgb, _AnimeColor3.rgb, (lum - thresLower2) / (_AnimeSoftness * 2)); #endif else animeColor = _AnimeColor3.rgb; if (dot(col, 1) > 0.001) animeColor *= normalize(col); else animeColor = 0; // Blend light to base col = animeColor * col_base.rgb; #endif // Additives half3 col_emissive = _Emissive.rgb; #if EMISSIVE_MAP col_emissive *= tex2D(_EmissiveTex, TRANSFORM_TEX(uv, _EmissiveTex)).rgb; #endif #if META meta.Emission = col_emissive; #else col += col_emissive; #endif #if AMBIENT && !LIGHTMAP_ON half3 col_ambient = ShadeSH9(float4(i.nor_world, 1.0)).rgb * _AmbientBrightness; col += col_base.rgb * col_ambient; #endif // Overlays #if HEIGHT_COLORS && !_HEIGHTCOLORSBLEND_LIT half4 heightCol = HeightColors(half4(col, col_base.a), i.heightColorsHeight, uv); col = heightCol.rgb; col_base.a = heightCol.a; #endif #if BASE_SATURATION half3 col_desat = Luminance(col); col = lerp(col_desat, col, _Saturation); #endif #if FOG UNITY_APPLY_FOG(i.fogCoord, col); #endif #if CUTOUT if (col_base.a < _CutoutCutoff) discard; else col_base.a = 1; #endif // Special handling of passes #if SHADOW_CASTER return 0; #elif DEPTH return 0; #elif DEPTH_NORMALS return float4(i.nor_world, 0); #elif OUTLINE_PASS #if OUTLINE return _OutlineColor; #else return 0; #endif #endif #if META meta.Albedo = col; return UnityMetaFragment(meta); #else return half4(col, col_base.a); #endif }