diff --git a/EditorPreview/Editor/ShadowcasterUpdaterPreview.cs b/EditorPreview/Editor/ShadowcasterUpdaterPreview.cs index 6c604c5..4403b87 100644 --- a/EditorPreview/Editor/ShadowcasterUpdaterPreview.cs +++ b/EditorPreview/Editor/ShadowcasterUpdaterPreview.cs @@ -1,141 +1,151 @@ #if UNITY_EDITOR +using System.Collections.Generic; using UnityEditor; using UnityEngine; -using System.Collections.Generic; [InitializeOnLoad] -public static class ShadowcasterUpdaterPreview +public static class ShadowcasterUpdaterEditorLoop { - const double kTickInterval = 0.1; // seconds - static double _nextTick; + private const double Interval = 0.1; + private const float Eps = 1e-6f; - // One shared MPB to avoid allocations each frame - static readonly MaterialPropertyBlock sMPB = new MaterialPropertyBlock(); + private static double _lastUpdateTime; + private static ShadowcasterUpdater[] _cached; + private static readonly MaterialPropertyBlock _mpb = new MaterialPropertyBlock(); - // Cache: component -> property ID, and renderer -> last applied matrix - static readonly Dictionary _propId = new Dictionary(); - static readonly Dictionary _lastW2L = new Dictionary(); - static readonly List _toRemove = new List(32); - - static ShadowcasterUpdaterPreview() + static ShadowcasterUpdaterEditorLoop() { + _lastUpdateTime = EditorApplication.timeSinceStartup; + EditorApplication.update += Update; - EditorApplication.hierarchyChanged += ForceTick; - Undo.undoRedoPerformed += ForceTick; - Selection.selectionChanged += ForceTick; - EditorApplication.playModeStateChanged += _ => ForceTick(); + EditorApplication.hierarchyChanged += RefreshCache; + AssemblyReloadEvents.afterAssemblyReload += RefreshCache; + + RefreshCache(); } - public static void ForceTick() => _nextTick = 0; - - static void Update() + private static void RefreshCache() { -#if UNITY_2019_1_OR_NEWER - if (EditorApplication.isPlayingOrWillChangePlaymode) return; + _cached = FindSceneUpdaters(); + } + + private static ShadowcasterUpdater[] FindSceneUpdaters() + { +#if UNITY_2020_1_OR_NEWER + return Object.FindObjectsOfType(true); #else - if (EditorApplication.isPlaying) return; -#endif - double now = EditorApplication.timeSinceStartup; - if (now < _nextTick) return; - _nextTick = now + kTickInterval; - - CleanupNullRenderers(); - - var behaviours = FindAllInScene(); - foreach (var b in behaviours) + // Unity 2019-compatible path: include inactive, filter out assets/prefabs not in a scene + var all = Resources.FindObjectsOfTypeAll(typeof(ShadowcasterUpdater)); + var list = new List(all.Length); + foreach (var o in all) { - if (b == null || !b.isActiveAndEnabled) continue; - if (EditorUtility.IsPersistent(b)) continue; // skip assets/prefabs - ApplyToBehaviour(b); + var c = o as ShadowcasterUpdater; + if (c == null) continue; + if (EditorUtility.IsPersistent(c)) continue; // skip assets + if (!c.gameObject.scene.IsValid()) continue; + list.Add(c); + } + return list.ToArray(); +#endif + } + + private static void Update() + { + if (EditorApplication.isPlayingOrWillChangePlaymode) return; + if (EditorApplication.isCompiling) return; + + var now = EditorApplication.timeSinceStartup; + if (now - _lastUpdateTime < Interval) return; + _lastUpdateTime = now; + + var arr = _cached; + if (arr == null || arr.Length == 0) return; + + for (int i = 0; i < arr.Length; i++) + { + var u = arr[i]; + if (u == null) continue; + TryUpdate(u); } + // Make changes visible in Scene/Game view without wiggling the mouse SceneView.RepaintAll(); } - static ShadowcasterUpdater[] FindAllInScene() + private static void TryUpdate(ShadowcasterUpdater u) { -#if UNITY_2023_1_OR_NEWER - return Object.FindObjectsByType(FindObjectsInactive.Exclude, FindObjectsSortMode.None); -#elif UNITY_2020_1_OR_NEWER - return Object.FindObjectsOfType(true); -#else - return Resources.FindObjectsOfTypeAll(); -#endif - } - - static void CleanupNullRenderers() - { - _toRemove.Clear(); - foreach (var kv in _lastW2L) - if (kv.Key == null) _toRemove.Add(kv.Key); - for (int i = 0; i < _toRemove.Count; i++) - _lastW2L.Remove(_toRemove[i]); - } - - static int GetPropertyId(ShadowcasterUpdater b) - { - string name = string.IsNullOrEmpty(b.propertyName) ? "_Udon_WorldToLocal" : b.propertyName; - - if (!_propId.TryGetValue(b, out int id)) + // If inspector values changed, make sure textures/colors/min brightness are pushed + try { - id = Shader.PropertyToID(name); - _propId[b] = id; - return id; + u.ApplyTextureData(); + } + catch + { + // UdonSharp can be touchy during certain editor states. Ignore and continue. } - // If user changed the property name in inspector, refresh the ID - int newId = Shader.PropertyToID(name); - if (newId != id) + var targets = u.rendererTargets; + if (targets == null || targets.Length == 0) return; + + // Match the runtime script's plane definition (0.5 half-size before scaling) + const float quadHalfWidth = 0.5f; + const float quadHalfHeight = 0.5f; + + Transform t = u.transform; + + // World-space basis from transform + Vector3 Udir = t.rotation * Vector3.right; // local +X + Vector3 Vdir = t.rotation * Vector3.up; // local +Y + + // Half extents after non-uniform scaling + float halfW = Mathf.Max(quadHalfWidth * t.lossyScale.x, Eps); + float halfH = Mathf.Max(quadHalfHeight * t.lossyScale.y, Eps); + + // Reciprocal axes so dot(r, Uinv/Vinv) -> [-0.5, 0.5] + Vector3 Uinv = Udir / (2.0f * halfW); + Vector3 Vinv = Vdir / (2.0f * halfH); + + // Unit normal + Vector3 N = Vector3.Normalize(Vector3.Cross(Udir, Vdir)); + + int idx = Mathf.Max(0, u.shadowcasterIndex); + string suf = "_" + idx.ToString(); + + int idShadowTex = Shader.PropertyToID("_Udon_shadowCasterTex" + suf); + int idShadowColor = Shader.PropertyToID("_Udon_shadowCasterColor" + suf); + int idOutsideColor = Shader.PropertyToID("_Udon_OutSideColor" + suf); + int idMinBrightness = Shader.PropertyToID("_Udon_MinBrightnessShadow" + suf); + + int idPlaneOrigin = Shader.PropertyToID("_Udon_Plane_Origin_" + idx.ToString()); + int idPlaneUinv = Shader.PropertyToID("_Udon_Plane_Uinv_" + idx.ToString()); + int idPlaneVinv = Shader.PropertyToID("_Udon_Plane_Vinv_" + idx.ToString()); + int idPlaneNormal = Shader.PropertyToID("_Udon_Plane_Normal_" + idx.ToString()); + + Vector4 origin = new Vector4(t.position.x, t.position.y, t.position.z, 0); + Vector4 uinv4 = new Vector4(Uinv.x, Uinv.y, Uinv.z, 0); + Vector4 vinv4 = new Vector4(Vinv.x, Vinv.y, Vinv.z, 0); + Vector4 n4 = new Vector4(N.x, N.y, N.z, 0); + + for (int r = 0; r < targets.Length; r++) { - _propId[b] = newId; - id = newId; - } - return id; - } + var ren = targets[r]; + if (ren == null) continue; - static void ApplyToBehaviour(ShadowcasterUpdater b) - { - var renderers = b.rendererTargets; - if (renderers == null || renderers.Length == 0) return; + ren.GetPropertyBlock(_mpb); - int id = GetPropertyId(b); - Matrix4x4 w2l = b.transform.worldToLocalMatrix; + // Also mirror texture/color in case ApplyTextureData couldn't run + if (u.ShadowcasterTexture != null) _mpb.SetTexture(idShadowTex, u.ShadowcasterTexture); + _mpb.SetColor(idShadowColor, u.TextureColor); + _mpb.SetColor(idOutsideColor, u.OutsideColor); + _mpb.SetFloat(idMinBrightness, u.MinBrightness); - for (int i = 0; i < renderers.Length; i++) - { - Renderer r = renderers[i]; - if (r == null) continue; + // Plane data + _mpb.SetVector(idPlaneOrigin, origin); + _mpb.SetVector(idPlaneUinv, uinv4); + _mpb.SetVector(idPlaneVinv, vinv4); + _mpb.SetVector(idPlaneNormal, n4); - if (_lastW2L.TryGetValue(r, out var last) && last == w2l) - continue; // nothing changed for this renderer - - r.GetPropertyBlock(sMPB); - sMPB.SetMatrix(id, w2l); - r.SetPropertyBlock(sMPB); - - _lastW2L[r] = w2l; - } - } -} - -[CustomEditor(typeof(ShadowcasterUpdater))] -public class ShadowcasterUpdaterInspector : Editor -{ - public override void OnInspectorGUI() - { - DrawDefaultInspector(); - GUILayout.Space(6); - using (new EditorGUI.DisabledScope(true)) - { - EditorGUILayout.LabelField("Edit-Mode Preview", EditorStyles.boldLabel); - EditorGUILayout.LabelField("Keeps the matrix property updated in the Scene View."); - } - - if (GUILayout.Button("Refresh Now")) - { - ShadowcasterUpdaterPreview.ForceTick(); - EditorApplication.QueuePlayerLoopUpdate(); - SceneView.RepaintAll(); + ren.SetPropertyBlock(_mpb); } } } diff --git a/Scripts/ShadowcasterUpdater.cs b/Scripts/ShadowcasterUpdater.cs index f688a92..14c11cb 100644 --- a/Scripts/ShadowcasterUpdater.cs +++ b/Scripts/ShadowcasterUpdater.cs @@ -16,7 +16,6 @@ public class ShadowcasterUpdater : UdonSharpBehaviour public int shadowcasterIndex = 1; - public string propertyName = "_Udon_WorldToLocal"; private MaterialPropertyBlock _mpb; @@ -32,23 +31,44 @@ public class ShadowcasterUpdater : UdonSharpBehaviour { if (mat == null) continue; mat.GetPropertyBlock(_mpb); - _mpb.SetTexture("_Udon_ShadowcasterTex" + "_" + (string)shadowcasterIndex, ShadowcasterTexture); - _mpb.SetColor("_Udon_shadowCasterColor" + "_" + (string)shadowcasterIndex, TextureColor); - _mpb.SetColor("_Udon_OutSideColor" + "_" + (string)shadowcasterIndex, OutsideColor); - _mpb.SetFloat("_Udon_MinBrightnessShadow" + "_" + (string)shadowcasterIndex, MinBrightness); + _mpb.SetTexture("_Udon_shadowCasterTex" + "_" + shadowcasterIndex.ToString(), ShadowcasterTexture); + _mpb.SetColor("_Udon_shadowCasterColor" + "_" + shadowcasterIndex.ToString(), TextureColor); + _mpb.SetColor("_Udon_OutSideColor" + "_" + shadowcasterIndex.ToString(), OutsideColor); + _mpb.SetFloat("_Udon_MinBrightnessShadow" + "_" + shadowcasterIndex.ToString(), MinBrightness); mat.SetPropertyBlock(_mpb); } } void LateUpdate() { - var w2l = transform.worldToLocalMatrix; - foreach (Renderer mat in rendererTargets) { if (mat == null) continue; mat.GetPropertyBlock(_mpb); - _mpb.SetMatrix(propertyName + "_" + (string)shadowcasterIndex, w2l); + + float quadHalfWidth = 0.5f; + float quadHalfHeight = 0.5f; + + // World-space basis directions from transform + Vector3 Udir = transform.rotation * Vector3.right; // plane local +X + Vector3 Vdir = transform.rotation * Vector3.up; // plane local +Y + + // World-space half extents after non-uniform scaling + float halfW = quadHalfWidth * transform.lossyScale.x; + float halfH = quadHalfHeight * transform.lossyScale.y; + + // Reciprocal axes so dot(r, Uinv/Vinv) -> [-0.5, 0.5] + Vector3 Uinv = Udir / (2.0f * Mathf.Max(halfW, 1e-6f)); + Vector3 Vinv = Vdir / (2.0f * Mathf.Max(halfH, 1e-6f)); + + // Unit normal + Vector3 N = Vector3.Normalize(Vector3.Cross(Udir, Vdir)); + + _mpb.SetVector("_Udon_Plane_Origin_" + shadowcasterIndex.ToString(), new Vector4(transform.position.x, transform.position.y, transform.position.z, 0)); + _mpb.SetVector("_Udon_Plane_Uinv_" + shadowcasterIndex.ToString(), new Vector4(Uinv.x, Uinv.y, Uinv.z, 0)); + _mpb.SetVector("_Udon_Plane_Vinv_" + shadowcasterIndex.ToString(), new Vector4(Vinv.x, Vinv.y, Vinv.z, 0)); + _mpb.SetVector("_Udon_Plane_Normal_" + shadowcasterIndex.ToString(), new Vector4(N.x, N.y, N.z, 0)); + mat.SetPropertyBlock(_mpb); } diff --git a/Shader/BlendinShader.shader b/Shader/BlendinShader.shader index 706ee4c..435939f 100644 --- a/Shader/BlendinShader.shader +++ b/Shader/BlendinShader.shader @@ -86,13 +86,22 @@ Shader "DeMuenu/World/Hoppou/RevealStandart" MoonlightGlobalVariables - float4x4 _Udon_WorldToLocal_1; + + float4 _Udon_Plane_Origin_1; // xyz = origin (world), w unused + float4 _Udon_Plane_Uinv_1; // xyz = Udir / (2*halfWidth) + float4 _Udon_Plane_Vinv_1; // xyz = Vdir / (2*halfHeight) + float4 _Udon_Plane_Normal_1; // xyz = unit normal + sampler2D _Udon_shadowCasterTex_1; float4 _Udon_shadowCasterColor_1; float4 _Udon_OutSideColor_1; float _Udon_MinBrightnessShadow_1; - float4x4 _Udon_WorldToLocal_2; + float4 _Udon_Plane_Origin_2; + float4 _Udon_Plane_Uinv_2; + float4 _Udon_Plane_Vinv_2; + float4 _Udon_Plane_Normal_2; + sampler2D _Udon_shadowCasterTex_2; float4 _Udon_shadowCasterColor_2; float4 _Udon_OutSideColor_2; @@ -152,20 +161,26 @@ Shader "DeMuenu/World/Hoppou/RevealStandart" Lambert(_Udon_LightPositions[LightCounter].xyz ,i, N); //defines NdotL LightTypeCalculations(_Udon_LightColors, LightCounter, i, NdotL, dIntensity, _Udon_LightPositions[LightCounter].a, _Udon_LightPositions[LightCounter].xyz); + + float4 ShadowCasterMult_1 = 1; + float4 ShadowCasterMult_2 = 1; - float4 ShadowCasterMult_1 = float4(1,1,1,1); - float4 ShadowCasterMult_2 = float4(1,1,1,1); - if (((_Udon_ShadowMapIndex[LightCounter] > 0.5) && (_Udon_ShadowMapIndex[LightCounter] < 1.5)) || (_Udon_ShadowMapIndex[LightCounter] > 2.5)) { - ShadowCasterMult_1 = SampleShadowcasterPlane(_Udon_WorldToLocal_1, _Udon_shadowCasterTex_1, _Udon_LightPositions[LightCounter].xyz, i.worldPos, _Udon_OutSideColor_1); - ShadowCasterMult_1 *= _Udon_shadowCasterColor_1; - ShadowCasterMult_1 = float4(ShadowCasterMult_1.rgb * (1-ShadowCasterMult_1.a), 1); - ShadowCasterMult_1 = max(ShadowCasterMult_1, _Udon_MinBrightnessShadow_1) + if (((_Udon_ShadowMapIndex[LightCounter] > 0.5) && (_Udon_ShadowMapIndex[LightCounter] < 1.5)) || (_Udon_ShadowMapIndex[LightCounter] > 2.5)) + { + float4 sc1 = SampleShadowcasterPlaneWS_Basis( + _Udon_LightPositions[LightCounter].xyz, i.worldPos, + _Udon_Plane_Origin_1.xyz, _Udon_Plane_Uinv_1.xyz, _Udon_Plane_Vinv_1.xyz, _Udon_Plane_Normal_1.xyz, + _Udon_shadowCasterTex_1, _Udon_OutSideColor_1, _Udon_shadowCasterColor_1); + ShadowCasterMult_1 = max(sc1, _Udon_MinBrightnessShadow_1); } - if (_Udon_ShadowMapIndex[LightCounter] > 1.5) { - ShadowCasterMult_2 = SampleShadowcasterPlane(_Udon_WorldToLocal_2, _Udon_shadowCasterTex_2, _Udon_LightPositions[LightCounter].xyz, i.worldPos, _Udon_OutSideColor_2); - ShadowCasterMult_2 *= _Udon_shadowCasterColor_2; - ShadowCasterMult_2 = float4(ShadowCasterMult_2.rgb * (1-ShadowCasterMult_2.a), 1); - ShadowCasterMult_2 = max(ShadowCasterMult_2, _Udon_MinBrightnessShadow_2) + + if (_Udon_ShadowMapIndex[LightCounter] > 1.5) + { + float4 sc2 = SampleShadowcasterPlaneWS_Basis( + _Udon_LightPositions[LightCounter].xyz, i.worldPos, + _Udon_Plane_Origin_2.xyz, _Udon_Plane_Uinv_2.xyz, _Udon_Plane_Vinv_2.xyz, _Udon_Plane_Normal_2.xyz, + _Udon_shadowCasterTex_2, _Udon_OutSideColor_2, _Udon_shadowCasterColor_2); + ShadowCasterMult_2 = max(sc2, _Udon_MinBrightnessShadow_2); } dmax = dmax + contrib * float4(LightColor, 1) * ShadowCasterMult_1 * ShadowCasterMult_2; diff --git a/Shader/Includes/Shadowcaster.cginc b/Shader/Includes/Shadowcaster.cginc index 0b062da..f5b2c7d 100644 --- a/Shader/Includes/Shadowcaster.cginc +++ b/Shader/Includes/Shadowcaster.cginc @@ -3,54 +3,30 @@ #include "UnityCG.cginc" // for tex2Dlod, etc. -static const float EPS = 1e-5; +static const float WS_EPS = 1e-5; -// Returns whether segment hits the unit plane quad in plane-local z=0. -// Outputs uv in [0,1] and t in [0,1] along A->B. -inline bool RaySegmentHitsPlaneQuad(float4x4 worldToLocal, float3 rayOrigin, float3 rayEnd, out float2 uv, out float t) +inline float4 SampleShadowcasterPlaneWS_Basis( + float3 A, float3 B, + float3 P0, float3 Uinv, float3 Vinv, float3 N, + sampler2D tex, float4 OutsideColor, float4 ShadowColor) { - float3 aP = mul(worldToLocal, float4(rayOrigin, 1)).xyz; - float3 bP = mul(worldToLocal, float4(rayEnd, 1)).xyz; + float3 d = B - A; + float dn = dot(N, d); + if (abs(dn) < WS_EPS) return OutsideColor; - float3 d = bP - aP; - float dz = d.z; + float t = dot(N, P0 - A) / dn; + if (t < 0.0 || t > 1.0) return OutsideColor; + float3 hit = A + d * t; + float3 r = hit - P0; - // Parallel-ish to plane? - if (abs(dz) < EPS) return false; + // u,v in [-0.5, 0.5] if inside quad + float u = dot(r, Uinv); + float v = dot(r, Vinv); + if (abs(u) > 0.5 || abs(v) > 0.5) return OutsideColor; - // Intersect z=0 - t = -aP.z / dz; - - // Segment only - if (t < 0.0 || t > 1.0) return false; - - float3 hit = aP + d * t; - - // Inside 1x1 centered quad? - if (abs(hit.x) > 0.5 || abs(hit.y) > 0.5) return false; - - uv = hit.xy + 0.5; // [-0.5,0.5] -> [0,1] - return true; -} - -// Fragment-shader version: uses proper filtering/mips via tex2D -inline float4 SampleShadowcasterPlane(float4x4 worldToLocal, sampler2D tex, float3 rayOrigin, float3 rayEnd, float4 OutsideColor) -{ - float2 uv; float t; - if (RaySegmentHitsPlaneQuad(worldToLocal, rayOrigin, rayEnd, uv, t)) - return tex2D(tex, uv); // full color - - return OutsideColor; -} - -// Anywhere (vertex/geom/compute/custom code) version: forces LOD 0 -inline float4 SampleShadowcasterPlaneLOD0(float4x4 worldToLocal, sampler2D tex, float3 rayOrigin, float3 rayEnd, float4 OutsideColor) -{ - float2 uv; float t; - if (RaySegmentHitsPlaneQuad(worldToLocal, rayOrigin, rayEnd, uv, t)) - return tex2Dlod(tex, float4(uv, 0, 0)); // full color at mip 0 - - return OutsideColor; + float4 returnColor = tex2D(tex, float2(u + 0.5, v + 0.5)) * ShadowColor; + returnColor = float4(returnColor.rgb * (1 - returnColor.a), 1); + return returnColor; } #endif diff --git a/Shader/LitParticles.shader b/Shader/LitParticles.shader index c8e7a02..ec82bce 100644 --- a/Shader/LitParticles.shader +++ b/Shader/LitParticles.shader @@ -79,18 +79,25 @@ Shader "DeMuenu/World/Hoppou/Particles/LitParticles" MoonlightGlobalVariables - float4x4 _Udon_WorldToLocal_1; + float4 _Udon_Plane_Origin_1; // xyz = origin (world), w unused + float4 _Udon_Plane_Uinv_1; // xyz = Udir / (2*halfWidth) + float4 _Udon_Plane_Vinv_1; // xyz = Vdir / (2*halfHeight) + float4 _Udon_Plane_Normal_1; // xyz = unit normal + sampler2D _Udon_shadowCasterTex_1; float4 _Udon_shadowCasterColor_1; float4 _Udon_OutSideColor_1; float _Udon_MinBrightnessShadow_1; - float4x4 _Udon_WorldToLocal_2; + float4 _Udon_Plane_Origin_2; + float4 _Udon_Plane_Uinv_2; + float4 _Udon_Plane_Vinv_2; + float4 _Udon_Plane_Normal_2; + sampler2D _Udon_shadowCasterTex_2; float4 _Udon_shadowCasterColor_2; float4 _Udon_OutSideColor_2; float _Udon_MinBrightnessShadow_2; - v2f vert (appdata v) { v2f o; @@ -129,22 +136,28 @@ Shader "DeMuenu/World/Hoppou/Particles/LitParticles" LightTypeCalculations(_Udon_LightColors, LightCounter, i, 1, dIntensity, _Udon_LightPositions[LightCounter].a, _Udon_LightPositions[LightCounter].xyz); - float4 ShadowCasterMult_1 = float4(1,1,1,1); - float4 ShadowCasterMult_2 = float4(1,1,1,1); - if (((_Udon_ShadowMapIndex[LightCounter] > 0.5) && (_Udon_ShadowMapIndex[LightCounter] < 1.5)) || (_Udon_ShadowMapIndex[LightCounter] > 2.5)) { - ShadowCasterMult_1 = SampleShadowcasterPlane(_Udon_WorldToLocal_1, _Udon_shadowCasterTex_1, _Udon_LightPositions[LightCounter].xyz, i.worldPos, _Udon_OutSideColor_1); - ShadowCasterMult_1 *= _Udon_shadowCasterColor_1; - ShadowCasterMult_1 = float4(ShadowCasterMult_1.rgb * (1-ShadowCasterMult_1.a), 1); - ShadowCasterMult_1 = max(ShadowCasterMult_1, _Udon_MinBrightnessShadow_1) - } - if (_Udon_ShadowMapIndex[LightCounter] > 1.5) { - ShadowCasterMult_2 = SampleShadowcasterPlane(_Udon_WorldToLocal_2, _Udon_shadowCasterTex_2, _Udon_LightPositions[LightCounter].xyz, i.worldPos, _Udon_OutSideColor_2); - ShadowCasterMult_2 *= _Udon_shadowCasterColor_2; - ShadowCasterMult_2 = float4(ShadowCasterMult_2.rgb * (1-ShadowCasterMult_2.a), 1); - ShadowCasterMult_2 = max(ShadowCasterMult_2, _Udon_MinBrightnessShadow_2) + float4 ShadowCasterMult_1 = 1; + float4 ShadowCasterMult_2 = 1; + + if (((_Udon_ShadowMapIndex[LightCounter] > 0.5) && (_Udon_ShadowMapIndex[LightCounter] < 1.5)) || (_Udon_ShadowMapIndex[LightCounter] > 2.5)) + { + float4 sc1 = SampleShadowcasterPlaneWS_Basis( + _Udon_LightPositions[LightCounter].xyz, i.worldPos, + _Udon_Plane_Origin_1.xyz, _Udon_Plane_Uinv_1.xyz, _Udon_Plane_Vinv_1.xyz, _Udon_Plane_Normal_1.xyz, + _Udon_shadowCasterTex_1, _Udon_OutSideColor_1, _Udon_shadowCasterColor_1); + ShadowCasterMult_1 = max(sc1, _Udon_MinBrightnessShadow_1); } - dmax = dmax + contrib * float4(LightColor, 1) * ShadowCasterMult1 * ShadowCasterMult_2; + if (_Udon_ShadowMapIndex[LightCounter] > 1.5) + { + float4 sc2 = SampleShadowcasterPlaneWS_Basis( + _Udon_LightPositions[LightCounter].xyz, i.worldPos, + _Udon_Plane_Origin_2.xyz, _Udon_Plane_Uinv_2.xyz, _Udon_Plane_Vinv_2.xyz, _Udon_Plane_Normal_2.xyz, + _Udon_shadowCasterTex_2, _Udon_OutSideColor_2, _Udon_shadowCasterColor_2); + ShadowCasterMult_2 = max(sc2, _Udon_MinBrightnessShadow_2); + } + + dmax = dmax + contrib * float4(LightColor, 1) * ShadowCasterMult_1 * ShadowCasterMult_2; }