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] 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; \