From b26c189b89d2391453b4afd87f5c3d226e10fafd Mon Sep 17 00:00:00 2001 From: DeMuenu <96650288+DeMuenu@users.noreply.github.com> Date: Thu, 2 Oct 2025 20:25:59 +0200 Subject: [PATCH 1/3] Rename PlayerPositionsToShader to LightUpdater Renamed all references, scripts, and editor helpers from PlayerPositionsToShader to LightUpdater for improved clarity and consistency. Updated README and editor preview documentation to reflect the new naming. Added new shader Standard_Lightmap_2SP for enhanced lighting and shadow support. --- ...haderPreview.cs => LightupdaterPreview.cs} | 26 +- ...ew.cs.meta => LightupdaterPreview.cs.meta} | 0 ...hader.Editor.cs => LightUpdater.Editor.cs} | 4 +- ...or.cs.meta => LightUpdater.Editor.cs.meta} | 0 README.md | 8 +- ...erPositionsToShader.cs => LightUpdater.cs} | 2 +- ...sToShader.cs.meta => LightUpdater.cs.meta} | 0 Shader/Standard_Lightmap_2SP.shader | 237 ++++++++++++++++++ Shader/Standard_Lightmap_2SP.shader.meta | 9 + 9 files changed, 266 insertions(+), 20 deletions(-) rename EditorPreview/Editor/{PlayerPositionsToShaderPreview.cs => LightupdaterPreview.cs} (86%) rename EditorPreview/Editor/{PlayerPositionsToShaderPreview.cs.meta => LightupdaterPreview.cs.meta} (100%) rename EditorPreview/{PlayerPositionsToShader.Editor.cs => LightUpdater.Editor.cs} (95%) rename EditorPreview/{PlayerPositionsToShader.Editor.cs.meta => LightUpdater.Editor.cs.meta} (100%) rename Scripts/{PlayerPositionsToShader.cs => LightUpdater.cs} (99%) rename Scripts/{PlayerPositionsToShader.cs.meta => LightUpdater.cs.meta} (100%) create mode 100644 Shader/Standard_Lightmap_2SP.shader create mode 100644 Shader/Standard_Lightmap_2SP.shader.meta diff --git a/EditorPreview/Editor/PlayerPositionsToShaderPreview.cs b/EditorPreview/Editor/LightupdaterPreview.cs similarity index 86% rename from EditorPreview/Editor/PlayerPositionsToShaderPreview.cs rename to EditorPreview/Editor/LightupdaterPreview.cs index 716a6f1..e24f677 100644 --- a/EditorPreview/Editor/PlayerPositionsToShaderPreview.cs +++ b/EditorPreview/Editor/LightupdaterPreview.cs @@ -1,15 +1,15 @@ -// Assets/Editor/PlayerPositionsToShaderPreview.cs +// Assets/Editor/LightUpdaterPreview.cs #if UNITY_EDITOR using UnityEditor; using UnityEngine; using System.Collections.Generic; [InitializeOnLoad] -public static class PlayerPositionsToShaderPreview +public static class LightUpdaterPreview { const double kTickInterval = 0.1; // seconds static double _nextTick; - static readonly Dictionary _cache = new Dictionary(); + static readonly Dictionary _cache = new Dictionary(); struct Cache { @@ -21,7 +21,7 @@ public static class PlayerPositionsToShaderPreview public int size; } - static PlayerPositionsToShaderPreview() + static LightUpdaterPreview() { EditorApplication.update += Update; EditorApplication.hierarchyChanged += ForceTick; @@ -53,18 +53,18 @@ public static class PlayerPositionsToShaderPreview SceneView.RepaintAll(); } - static PlayerPositionsToShader[] FindAllInScene() + static LightUpdater[] FindAllInScene() { #if UNITY_2023_1_OR_NEWER - return Object.FindObjectsByType(FindObjectsInactive.Exclude, FindObjectsSortMode.None); + return Object.FindObjectsByType(FindObjectsInactive.Exclude, FindObjectsSortMode.None); #elif UNITY_2020_1_OR_NEWER - return Object.FindObjectsOfType(true); + return Object.FindObjectsOfType(true); #else - return Resources.FindObjectsOfTypeAll(); + return Resources.FindObjectsOfTypeAll(); #endif } - static void EnsureArrays(PlayerPositionsToShader src, int required) + static void EnsureArrays(LightUpdater src, int required) { if (!_cache.TryGetValue(src, out var c) || c.positions == null || c.colors == null || c.directions == null || c.types == null || c.shadowMapIndices == null || @@ -83,7 +83,7 @@ public static class PlayerPositionsToShaderPreview } } - static void PushFromBehaviour(PlayerPositionsToShader src) + static void PushFromBehaviour(LightUpdater src) { int max = Mathf.Max(1, src.maxLights); EnsureArrays(src, max); @@ -171,8 +171,8 @@ public static class PlayerPositionsToShaderPreview } } -[CustomEditor(typeof(PlayerPositionsToShader))] -public class PlayerPositionsToShaderInspector : Editor +[CustomEditor(typeof(LightUpdater))] +public class LightUpdaterInspector : Editor { public override void OnInspectorGUI() { @@ -186,7 +186,7 @@ public class PlayerPositionsToShaderInspector : Editor if (GUILayout.Button("Refresh Now")) { - PlayerPositionsToShaderPreview.ForceTick(); + LightUpdaterPreview.ForceTick(); EditorApplication.QueuePlayerLoopUpdate(); SceneView.RepaintAll(); } diff --git a/EditorPreview/Editor/PlayerPositionsToShaderPreview.cs.meta b/EditorPreview/Editor/LightupdaterPreview.cs.meta similarity index 100% rename from EditorPreview/Editor/PlayerPositionsToShaderPreview.cs.meta rename to EditorPreview/Editor/LightupdaterPreview.cs.meta diff --git a/EditorPreview/PlayerPositionsToShader.Editor.cs b/EditorPreview/LightUpdater.Editor.cs similarity index 95% rename from EditorPreview/PlayerPositionsToShader.Editor.cs rename to EditorPreview/LightUpdater.Editor.cs index bb57b34..9dc7024 100644 --- a/EditorPreview/PlayerPositionsToShader.Editor.cs +++ b/EditorPreview/LightUpdater.Editor.cs @@ -1,8 +1,8 @@ -// Assets/Lighting/Scripts/PlayerPositionsToShader.Editor.cs +// Assets/Lighting/Scripts/LightUpdater.Editor.cs #if UNITY_EDITOR using UnityEngine; -public partial class PlayerPositionsToShader +public partial class LightUpdater { public void Editor_BuildPreview( out Vector4[] positions, diff --git a/EditorPreview/PlayerPositionsToShader.Editor.cs.meta b/EditorPreview/LightUpdater.Editor.cs.meta similarity index 100% rename from EditorPreview/PlayerPositionsToShader.Editor.cs.meta rename to EditorPreview/LightUpdater.Editor.cs.meta diff --git a/README.md b/README.md index 85745de..05017f3 100644 --- a/README.md +++ b/README.md @@ -30,13 +30,13 @@ On PC, I haven't encountered any frame drops in the editor at all, even with 400 1. Clone the code into your project. -2. Add the `PlayerPositionsToShader` component to a GameObject in your scene: +2. Add the `LightUpdater` component to a GameObject in your scene: - Tweak strength/intensity of the local and remote player if you want them to have an attached light. 3. For lights, attach `LightdataStorage` to a Transform and configure: - `range`, `type`, `color`, `intensity`, and `spotAngleDeg`. -4. Add the light transform to your `PlayerPositionsToShader` component's `otherLightSources` array. +4. Add the light transform to your `LightUpdater` component's `otherLightSources` array. 5. Use one of the premade shaders on your material. Or, if you feel like it, use the provided .hlsl/.cginc in your own shader. You just need to copy everything surrounded by Moonlight comments, and apply it at the end of your shader. @@ -44,8 +44,8 @@ On PC, I haven't encountered any frame drops in the editor at all, even with 400 ## Editor preview -- While not in play mode, the editor helper `PlayerPositionsToShaderPreview` (EditorPreview/Editor/PlayerPositionsToShaderPreview.cs) and `ShadowcasterUpdaterPreview` (EditorPreview/Editor/ShadowcasterUpdaterPreview.cs) write the same property blocks to assigned Renderers so you can preview lighting effects in the Scene view. Those update 10 times a second. -- The editor partial helper for building preview arrays is in `EditorPreview/PlayerPositionsToShader.Editor.cs`. +- While not in play mode, the editor helper `LightUpdaterPreview` (EditorPreview/Editor/LightUpdaterPreview.cs) and `ShadowcasterUpdaterPreview` (EditorPreview/Editor/ShadowcasterUpdaterPreview.cs) write the same property blocks to assigned Renderers so you can preview lighting effects in the Scene view. Those update 10 times a second. +- The editor partial helper for building preview arrays is in `EditorPreview/LightUpdater.Editor.cs`. --- diff --git a/Scripts/PlayerPositionsToShader.cs b/Scripts/LightUpdater.cs similarity index 99% rename from Scripts/PlayerPositionsToShader.cs rename to Scripts/LightUpdater.cs index 5b8b2e5..b9ad5be 100644 --- a/Scripts/PlayerPositionsToShader.cs +++ b/Scripts/LightUpdater.cs @@ -6,7 +6,7 @@ using VRC.SDKBase; using VRC.Udon; using VRC.SDK3.Rendering; -public partial class PlayerPositionsToShader : UdonSharpBehaviour +public partial class LightUpdater : UdonSharpBehaviour { [Header("Lightsources")] [Tooltip("Place Transforms here which should also emit Light (attach LightdataStorage to them).")] diff --git a/Scripts/PlayerPositionsToShader.cs.meta b/Scripts/LightUpdater.cs.meta similarity index 100% rename from Scripts/PlayerPositionsToShader.cs.meta rename to Scripts/LightUpdater.cs.meta diff --git a/Shader/Standard_Lightmap_2SP.shader b/Shader/Standard_Lightmap_2SP.shader new file mode 100644 index 0000000..51048fe --- /dev/null +++ b/Shader/Standard_Lightmap_2SP.shader @@ -0,0 +1,237 @@ +Shader "DeMuenu/World/Hoppou/Standard_Lightmap_2SP" +{ + Properties + { + _MainTex ("Texture", 2D) = "white" {} + _NormalMap ("Normal Map", 2D) = "bump" {} + _NormalMapStrength ("Normal Map Strength", Range(0,1)) = 1 + _Color ("Color", Color) = (1,1,1,1) + + _EmmisiveText ("Emmissive Texture", 2D) = "white" {} + _EmmissiveColor ("Emmissive Color", Color) = (1,1,1,1) + _EmmissiveStrength ("Emmissive Strength", Range(0,10)) = 0 + + + //Moonlight + _InverseSqareMultiplier ("Inverse Square Multiplier", Float) = 1 + _LightCutoffDistance ("Light Cutoff Distance", Float) = 100 + + _EnableShadowCasting ("Enable Shadowcasting", Float) = 0 + _BlurPixels ("Shadowcaster Blur Pixels", Float) = 0 + //Moonlight END + + [Enum(UnityEngine.Rendering.CullMode)] _Cull ("Cull Mode", Float) = 2 + + + + } + SubShader + { + Tags { "RenderType"="Opaque" } + LOD 100 + Cull[_Cull] + + Pass + { + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ DIRLIGHTMAP_COMBINED + + #include "UnityCG.cginc" + #include "Includes/LightStrength.hlsl" + #include "Includes/Lambert.hlsl" + #include "Includes/DefaultSetup.hlsl" + #include "Includes/Variables.hlsl" + #include "Includes/Shadowcaster.cginc" + + //Moonlight Defines + #define MAX_LIGHTS 80 // >= maxPlayers in script + //Moonlight Defines END + + struct appdata + { + float4 vertex : POSITION; + float2 uv : TEXCOORD0; + float3 normal : NORMAL; + float4 tangent : TANGENT; + float2 uv2 : TEXCOORD1; // Lightmap UV + }; + + struct v2f + { + float2 uv : TEXCOORD0; + float2 uv2 : TEXCOORD1; + float2 uvEmmis : TEXCOORD4; + float4 vertex : SV_POSITION; + float2 normUV : TEXCOORD5; + float3 worldTangent : TEXCOORD6; + float3 worldBitangent : TEXCOORD7; + + //Moonlight + float3 worldPos : TEXCOORD2; + float3 worldNormal: TEXCOORD3; + //Moonlight END + + + #ifdef LIGHTMAP_ON + float2 lmuv : TEXCOORD8; + #endif + + + }; + + sampler2D _MainTex; + float4 _MainTex_ST; + sampler2D _NormalMap; + float4 _NormalMap_ST; + float4 _Color; + float _NormalMapStrength; + + + + sampler2D _EmmisiveText; + float4 _EmmisiveText_ST; + float4 _EmmissiveColor; + float _EmmissiveStrength; + + + MoonlightGlobalVariables + + + 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; + + 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; + + float _BlurPixels; + float4 _Udon_shadowCasterTex_1_TexelSize; // xy = 1/width, 1/height + float4 _Udon_shadowCasterTex_2_TexelSize; + + bool _EnableShadowCasting; + + + + v2f vert (appdata v) + { + v2f o; + o.vertex = UnityObjectToClipPos(v.vertex); + o.uv = TRANSFORM_TEX(v.uv, _MainTex); + o.normUV = TRANSFORM_TEX(v.uv, _NormalMap); + o.uvEmmis = TRANSFORM_TEX(v.uv, _EmmisiveText); + + float3 nWS = UnityObjectToWorldNormal(v.normal); + float3 tWS = normalize(UnityObjectToWorldDir(v.tangent.xyz)); + float3 bWS = normalize(cross(nWS, tWS) * v.tangent.w); + + o.worldNormal = nWS; + o.worldTangent = tWS; + o.worldBitangent= bWS; + + + //Moonlight Vertex + float4 wp = mul(unity_ObjectToWorld, v.vertex); + o.worldPos = wp.xyz; + //o.worldNormal = UnityObjectToWorldNormal(v.normal); + //Moonlight Vertex END + + #ifdef LIGHTMAP_ON + o.lmuv = v.uv2 * unity_LightmapST.xy + unity_LightmapST.zw; + #endif + + return o; + } + + fixed4 frag (v2f i) : SV_Target + { + // sample the texture + fixed4 col = tex2D(_MainTex, i.uv); + fixed4 norm = tex2D(_NormalMap, i.normUV); + + fixed4 emmis = tex2D(_EmmisiveText, i.uvEmmis); + + + //Moonlight + float3 nTS = UnpackNormal(norm); + float3 NmapWS = normalize(i.worldTangent * nTS.x + + i.worldBitangent * nTS.y + + i.worldNormal * nTS.z); + float3 N = normalize(lerp(normalize(i.worldNormal), NmapWS, saturate(_NormalMapStrength))); + + OutLoopSetup(i, _Udon_PlayerCount) //defines count, N, dmax, dIntensity + + [loop] + for (int LightCounter = 0; LightCounter < MAX_LIGHTS; LightCounter++) + { + InLoopSetup(_Udon_LightPositions, LightCounter, count, i); //defines distanceFromLight, contrib + + + //Lambertian diffuse + 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; + + if (((_Udon_ShadowMapIndex[LightCounter] > 0.5) && (_Udon_ShadowMapIndex[LightCounter] < 1.5) && (_EnableShadowCasting > 0.5)) || (_Udon_ShadowMapIndex[LightCounter] > 2.5 && _EnableShadowCasting)) + { + 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, _BlurPixels, _Udon_shadowCasterTex_1_TexelSize.xy); + ShadowCasterMult_1 = max(sc1, _Udon_MinBrightnessShadow_1); + } + if (_Udon_ShadowMapIndex[LightCounter] > 1.5 && (_EnableShadowCasting > 0.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, _BlurPixels, _Udon_shadowCasterTex_2_TexelSize.xy); + ShadowCasterMult_2 = max(sc2, _Udon_MinBrightnessShadow_2); + } + + dmax = dmax + contrib * float4(LightColor, 1) * NdotL * ShadowCasterMult_1 * ShadowCasterMult_2; + + } + //dmax.xyz = min(dmax * dIntensity, 1.0); + dmax.w = 1.0; + + //Moonlight END + + fixed3 lm = 0; + #ifdef LIGHTMAP_ON + // Decode handles RGBM/DoubleLDR and linear/gamma differences for you. + lm = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, i.lmuv)); + + #ifdef DIRLIGHTMAP_COMBINED + // Directional lightmaps add dominant direction; improves shading on normal-mapped/curved surfaces + half4 dirTex = UNITY_SAMPLE_TEX2D_SAMPLER(unity_LightmapInd,unity_Lightmap, i.lmuv); + lm = DecodeDirectionalLightmap(lm, dirTex, normalize(i.worldNormal)); + #endif + #endif + + return col * _Color * (dmax + float4(lm, 1)) + emmis * _EmmissiveStrength * _EmmissiveColor; + } + ENDCG + } + } + + FallBack "Diffuse" +} \ No newline at end of file diff --git a/Shader/Standard_Lightmap_2SP.shader.meta b/Shader/Standard_Lightmap_2SP.shader.meta new file mode 100644 index 0000000..b03f2c2 --- /dev/null +++ b/Shader/Standard_Lightmap_2SP.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: dcd9aab68ad0b484f8382cdb61ef0cb9 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: From bb31145e4d1b6ae464e3d0558245b14260679cef Mon Sep 17 00:00:00 2001 From: DeMuenu <96650288+DeMuenu@users.noreply.github.com> Date: Fri, 3 Oct 2025 23:27:27 +0200 Subject: [PATCH 2/3] smooth falloff, but not correct angles Replaced usage of GetCosHalfAngle() with spotAngleDeg for spot light calculations in both editor and runtime scripts. Updated shader logic to use smoothstep for light contribution falloff, improving spot light edge smoothness. --- EditorPreview/LightUpdater.Editor.cs | 2 +- Scripts/LightUpdater.cs | 4 ++-- Shader/Includes/LightStrength.hlsl | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/EditorPreview/LightUpdater.Editor.cs b/EditorPreview/LightUpdater.Editor.cs index 9dc7024..41543d8 100644 --- a/EditorPreview/LightUpdater.Editor.cs +++ b/EditorPreview/LightUpdater.Editor.cs @@ -38,7 +38,7 @@ public partial class LightUpdater float intensity = (data != null) ? data.intensity * t.localScale.x : 1f; // w = cosHalfAngle (0 for omni) - float cosHalf = (data != null) ? data.GetCosHalfAngle() : 0f; + float cosHalf = (data != null) ? data.spotAngleDeg : 0f; // 0=Omni, 1=Spot, 2=Directional (your custom enum) int typeId = (data != null) ? data.GetTypeId() : 0; diff --git a/Scripts/LightUpdater.cs b/Scripts/LightUpdater.cs index b9ad5be..372a024 100644 --- a/Scripts/LightUpdater.cs +++ b/Scripts/LightUpdater.cs @@ -221,7 +221,7 @@ public partial class LightUpdater : UdonSharpBehaviour Vector3 fwd = rot * Vector3.down; - float cosHalf = (data != null) ? data.GetCosHalfAngle() : 0f; + float Lightangle = (data != null) ? data.spotAngleDeg : 0f; Vector4 posTemp = new Vector4(pos.x, pos.y, pos.z, range); if (_positions[currentCount] != posTemp) @@ -235,7 +235,7 @@ public partial class LightUpdater : UdonSharpBehaviour _lightColors[currentCount] = colorTemp; _lightColors_isDirty = true; } - Vector4 dirTemp = new Vector4(fwd.x, fwd.y, fwd.z, cosHalf); + Vector4 dirTemp = new Vector4(fwd.x, fwd.y, fwd.z, Lightangle); if (_directions[currentCount] != dirTemp) { _directions[currentCount] = dirTemp; diff --git a/Shader/Includes/LightStrength.hlsl b/Shader/Includes/LightStrength.hlsl index d9119d0..d858403 100644 --- a/Shader/Includes/LightStrength.hlsl +++ b/Shader/Includes/LightStrength.hlsl @@ -14,7 +14,7 @@ float threshold = (-1 + _Udon_LightDirections[LightCounter].w / 180); \ \ contrib = min(dot(normalize(i.worldPos - Lightposition), -normalize(_Udon_LightDirections[LightCounter].xyz)), 0); \ - contrib= 1 - step(threshold, contrib); \ + contrib= 1 - smoothstep(threshold, threshold + radius / 180, contrib); \ \ contrib = contrib * invSq; \ dIntensity += contrib; \ From 65c34d2ddf897da0860d6ef24f0ea49ad5f2dfa4 Mon Sep 17 00:00:00 2001 From: DeMuenu <96650288+DeMuenu@users.noreply.github.com> Date: Sat, 4 Oct 2025 04:10:43 +0200 Subject: [PATCH 3/3] Refactor light range and angle calculations Updated how light range and spot angle are calculated and packed for both editor and runtime scripts, distinguishing between sphere and non-sphere lights. Adjusted shader logic to use new packing for spot light contribution, improving consistency between CPU and GPU representations. --- EditorPreview/LightUpdater.Editor.cs | 15 ++++++++++++--- Scripts/LightUpdater.cs | 18 +++++++++++++----- Shader/Includes/LightStrength.hlsl | 5 ++--- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/EditorPreview/LightUpdater.Editor.cs b/EditorPreview/LightUpdater.Editor.cs index 41543d8..3161938 100644 --- a/EditorPreview/LightUpdater.Editor.cs +++ b/EditorPreview/LightUpdater.Editor.cs @@ -30,15 +30,24 @@ public partial class LightUpdater LightdataStorage data = t.GetComponent(); + // w = cosHalfAngle (0 for omni) + float cosHalf = (data != null) ? data.GetCosHalfAngle() : 0f; + Vector3 pos = t.position; - float range = (data != null) ? data.range * t.localScale.x : t.localScale.x; + float range = 0; + if (data.lightType == LightType.Sphere) + { + range = (data != null) ? data.range * t.localScale.x : t.localScale.x; + } + else + { + range = (data != null) ? Mathf.Cos(Mathf.Deg2Rad * ((data.spotAngleDeg * 0.5f) + Mathf.Max(data.range, 0))): 0f; + } // rgb = color, a = intensity (packed to match runtime/shader) Vector4 col = (data != null) ? data.GetFinalColor() : new Vector4(1f, 1f, 1f, 1f); float intensity = (data != null) ? data.intensity * t.localScale.x : 1f; - // w = cosHalfAngle (0 for omni) - float cosHalf = (data != null) ? data.spotAngleDeg : 0f; // 0=Omni, 1=Spot, 2=Directional (your custom enum) int typeId = (data != null) ? data.GetTypeId() : 0; diff --git a/Scripts/LightUpdater.cs b/Scripts/LightUpdater.cs index 372a024..bcecd95 100644 --- a/Scripts/LightUpdater.cs +++ b/Scripts/LightUpdater.cs @@ -221,14 +221,22 @@ public partial class LightUpdater : UdonSharpBehaviour Vector3 fwd = rot * Vector3.down; - float Lightangle = (data != null) ? data.spotAngleDeg : 0f; + float Lightangle = (data != null) ? data.GetCosHalfAngle() : 0f; - Vector4 posTemp = new Vector4(pos.x, pos.y, pos.z, range); - if (_positions[currentCount] != posTemp) + Vector4 posTemp = Vector4.zero; + if (data.lightType == LightType.Sphere) { - _positions[currentCount] = posTemp; - _positons_isDirty = true; + posTemp = new Vector4(pos.x, pos.y, pos.z, range); } + else + { + posTemp = new Vector4(pos.x, pos.y, pos.z, Mathf.Cos(Mathf.Deg2Rad * ((data.spotAngleDeg * 0.5f) + Mathf.Max(data.range, 0)))); + } + if (_positions[currentCount] != posTemp) + { + _positions[currentCount] = posTemp; + _positons_isDirty = true; + } Vector4 colorTemp = new Vector4(col.x, col.y, col.z, intensity); if (_lightColors[currentCount] != colorTemp) { diff --git a/Shader/Includes/LightStrength.hlsl b/Shader/Includes/LightStrength.hlsl index d858403..cd53b39 100644 --- a/Shader/Includes/LightStrength.hlsl +++ b/Shader/Includes/LightStrength.hlsl @@ -11,10 +11,9 @@ else if (_Udon_LightType[LightCounter] == 1) \ { \ float invSq = _Udon_LightColors[LightCounter].a / max(1e-4, (distanceFromLight * invSqMul) * (distanceFromLight * invSqMul)); \ - float threshold = (-1 + _Udon_LightDirections[LightCounter].w / 180); \ \ - contrib = min(dot(normalize(i.worldPos - Lightposition), -normalize(_Udon_LightDirections[LightCounter].xyz)), 0); \ - contrib= 1 - smoothstep(threshold, threshold + radius / 180, contrib); \ + contrib = dot(normalize(i.worldPos - Lightposition), normalize(_Udon_LightDirections[LightCounter].xyz)); \ + contrib = smoothstep(radius,_Udon_LightDirections[LightCounter].w, contrib); \ \ contrib = contrib * invSq; \ dIntensity += contrib; \