mirror of
https://github.com/DeMuenu/MoonlightVRC.git
synced 2026-05-06 10:22:20 +00:00
optimisations from gemini (not tested)
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System;
|
||||
using UdonSharp;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
@@ -9,9 +10,6 @@ using VRC.SDK3.Rendering;
|
||||
public partial class LightUpdater : UdonSharpBehaviour
|
||||
{
|
||||
[Header("Lightsources")]
|
||||
[Tooltip("Place Transforms here which should also emit Light (attach LightdataStorage to them).")]
|
||||
public Transform[] otherLightSources;
|
||||
|
||||
|
||||
[Header("Strength")]
|
||||
[Tooltip("Local player light range")]
|
||||
@@ -68,6 +66,9 @@ public partial class LightUpdater : UdonSharpBehaviour
|
||||
private float[] _ShadowMapArray;
|
||||
private bool _ShadowMap_isDirty = false;
|
||||
|
||||
private LightdataStorage[] _sceneLights;
|
||||
private int _sceneLightCount = 0;
|
||||
|
||||
private VRCPlayerApi[] _players;
|
||||
|
||||
|
||||
@@ -91,6 +92,7 @@ public partial class LightUpdater : UdonSharpBehaviour
|
||||
_directions = new Vector4[maxLights];
|
||||
_TypeArray = new float[maxLights];
|
||||
_ShadowMapArray = new float[maxLights];
|
||||
_sceneLights = new LightdataStorage[maxLights];
|
||||
|
||||
_players = new VRCPlayerApi[maxLights];
|
||||
|
||||
@@ -101,11 +103,56 @@ public partial class LightUpdater : UdonSharpBehaviour
|
||||
UdonID_LightType = VRCShader.PropertyToID(typeProperty);
|
||||
UdonID_ShadowMapIndex = VRCShader.PropertyToID(shadowMapIndexProperty);
|
||||
|
||||
|
||||
UpdateData();
|
||||
PushToRenderers();
|
||||
}
|
||||
|
||||
public void RegisterLight(LightdataStorage light)
|
||||
{
|
||||
if (light == null) return;
|
||||
|
||||
// Prevent duplicates
|
||||
for (int i = 0; i < _sceneLightCount; i++)
|
||||
{
|
||||
if (_sceneLights[i] == light) return;
|
||||
}
|
||||
|
||||
if (_sceneLightCount < _sceneLights.Length)
|
||||
{
|
||||
_sceneLights[_sceneLightCount] = light;
|
||||
_sceneLightCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"[MoonlightVRC] Cannot register new light, scene light limit reached ({_sceneLights.Length})");
|
||||
}
|
||||
}
|
||||
|
||||
public void DeregisterLight(LightdataStorage light)
|
||||
{
|
||||
if (light == null) return;
|
||||
int foundIndex = -1;
|
||||
for (int i = 0; i < _sceneLightCount; i++)
|
||||
{
|
||||
if (_sceneLights[i] == light)
|
||||
{
|
||||
foundIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundIndex != -1)
|
||||
{
|
||||
// Shift elements down to fill the gap
|
||||
for (int i = foundIndex; i < _sceneLightCount - 1; i++)
|
||||
{
|
||||
_sceneLights[i] = _sceneLights[i + 1];
|
||||
}
|
||||
_sceneLightCount--;
|
||||
_sceneLights[_sceneLightCount] = null; // Clear the last element
|
||||
}
|
||||
}
|
||||
|
||||
void LateUpdate()
|
||||
{
|
||||
if (Time.time < _nextUpdate) return;
|
||||
@@ -154,6 +201,7 @@ public partial class LightUpdater : UdonSharpBehaviour
|
||||
if (_directions[i] != TempDir)
|
||||
{
|
||||
_directions[i] = new Vector4(TempDir.x, TempDir.y, TempDir.z, 10f);
|
||||
_directions[i] = TempDir;
|
||||
_directions_isDirty = true;
|
||||
}
|
||||
|
||||
@@ -201,14 +249,13 @@ public partial class LightUpdater : UdonSharpBehaviour
|
||||
}
|
||||
|
||||
// --- Scene light sources ---
|
||||
if (otherLightSources != null)
|
||||
if (_sceneLights != null)
|
||||
{
|
||||
for (int j = 0; j < otherLightSources.Length && currentCount < maxLights; j++)
|
||||
for (int j = 0; j < _sceneLightCount && currentCount < maxLights; j++)
|
||||
{
|
||||
Transform t = otherLightSources[j];
|
||||
if (t == null || !t.gameObject.activeInHierarchy) continue;
|
||||
|
||||
LightdataStorage data = t.GetComponent<LightdataStorage>();
|
||||
LightdataStorage data = _sceneLights[j];
|
||||
if (data == null || !data.gameObject.activeInHierarchy) continue;
|
||||
Transform t = data.transform;
|
||||
|
||||
Vector3 pos = t.position;
|
||||
float range = (data != null) ? data.range * t.localScale.x: t.localScale.x;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using UdonSharp;
|
||||
using UdonSharp;
|
||||
using UnityEngine;
|
||||
using VRC.SDKBase;
|
||||
using VRC.Udon;
|
||||
@@ -10,6 +10,10 @@ public enum LightType { Sphere, Spot }
|
||||
[UdonBehaviourSyncMode(BehaviourSyncMode.None)]
|
||||
public class LightdataStorage : UdonSharpBehaviour
|
||||
{
|
||||
[Header("System")]
|
||||
[Tooltip("The main LightUpdater in the scene. This is required for dynamic lights.")]
|
||||
public LightUpdater lightUpdater;
|
||||
|
||||
|
||||
[Header("Type")]
|
||||
[Tooltip("Select the logical light type for this source.")]
|
||||
@@ -36,6 +40,22 @@ public class LightdataStorage : UdonSharpBehaviour
|
||||
[Tooltip("0 = no shadows, 1-4 = shadow map index")]
|
||||
public float shadowMapIndex = 0f; // 0 = no shadows, 1-4 = shadow map index
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
if (lightUpdater != null)
|
||||
{
|
||||
lightUpdater.RegisterLight(this);
|
||||
}
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
if (lightUpdater != null)
|
||||
{
|
||||
lightUpdater.DeregisterLight(this);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert to a Vector4 for your shader upload
|
||||
public Vector4 GetFinalColor()
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
using System.Security.Permissions;
|
||||
using UdonSharp;
|
||||
using UnityEngine;
|
||||
@@ -18,10 +18,30 @@ public class ShadowcasterUpdater : UdonSharpBehaviour
|
||||
|
||||
private MaterialPropertyBlock _mpb;
|
||||
|
||||
private int _propShadowTex;
|
||||
private int _propShadowColor;
|
||||
private int _propOutsideColor;
|
||||
private int _propMinBrightness;
|
||||
private int _propPlaneOrigin;
|
||||
private int _propPlaneUinv;
|
||||
private int _propPlaneVinv;
|
||||
private int _propPlaneNormal;
|
||||
|
||||
void Start()
|
||||
{
|
||||
_mpb = new MaterialPropertyBlock();
|
||||
|
||||
string suf = "_" + shadowcasterIndex.ToString();
|
||||
_propShadowTex = VRCShader.PropertyToID("_Udon_shadowCasterTex" + suf);
|
||||
_propShadowColor = VRCShader.PropertyToID("_Udon_shadowCasterColor" + suf);
|
||||
_propOutsideColor = VRCShader.PropertyToID("_Udon_OutSideColor" + suf);
|
||||
_propMinBrightness = VRCShader.PropertyToID("_Udon_MinBrightnessShadow" + suf);
|
||||
|
||||
_propPlaneOrigin = VRCShader.PropertyToID("_Udon_Plane_Origin" + suf);
|
||||
_propPlaneUinv = VRCShader.PropertyToID("_Udon_Plane_Uinv" + suf);
|
||||
_propPlaneVinv = VRCShader.PropertyToID("_Udon_Plane_Vinv" + suf);
|
||||
_propPlaneNormal = VRCShader.PropertyToID("_Udon_Plane_Normal" + suf);
|
||||
|
||||
ApplyTextureData();
|
||||
}
|
||||
|
||||
@@ -31,43 +51,47 @@ public class ShadowcasterUpdater : UdonSharpBehaviour
|
||||
{
|
||||
if (mat == null) continue;
|
||||
mat.GetPropertyBlock(_mpb);
|
||||
_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);
|
||||
if (ShadowcasterTexture != null) _mpb.SetTexture(_propShadowTex, ShadowcasterTexture);
|
||||
_mpb.SetColor(_propShadowColor, TextureColor);
|
||||
_mpb.SetColor(_propOutsideColor, OutsideColor);
|
||||
_mpb.SetFloat(_propMinBrightness, MinBrightness);
|
||||
mat.SetPropertyBlock(_mpb);
|
||||
}
|
||||
}
|
||||
void LateUpdate()
|
||||
{
|
||||
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));
|
||||
|
||||
Vector4 originVec = new Vector4(transform.position.x, transform.position.y, transform.position.z, 0);
|
||||
Vector4 uinvVec = new Vector4(Uinv.x, Uinv.y, Uinv.z, 0);
|
||||
Vector4 vinvVec = new Vector4(Vinv.x, Vinv.y, Vinv.z, 0);
|
||||
Vector4 nVec = new Vector4(N.x, N.y, N.z, 0);
|
||||
|
||||
foreach (Renderer mat in rendererTargets)
|
||||
{
|
||||
if (mat == null) continue;
|
||||
mat.GetPropertyBlock(_mpb);
|
||||
|
||||
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));
|
||||
_mpb.SetVector(_propPlaneOrigin, originVec);
|
||||
_mpb.SetVector(_propPlaneUinv, uinvVec);
|
||||
_mpb.SetVector(_propPlaneVinv, vinvVec);
|
||||
_mpb.SetVector(_propPlaneNormal, nVec);
|
||||
|
||||
mat.SetPropertyBlock(_mpb);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user