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.
This commit is contained in:
DeMuenu
2025-10-02 20:25:59 +02:00
parent fe4503a876
commit b26c189b89
9 changed files with 266 additions and 20 deletions

View File

@@ -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<PlayerPositionsToShader, Cache> _cache = new Dictionary<PlayerPositionsToShader, Cache>();
static readonly Dictionary<LightUpdater, Cache> _cache = new Dictionary<LightUpdater, Cache>();
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<PlayerPositionsToShader>(FindObjectsInactive.Exclude, FindObjectsSortMode.None);
return Object.FindObjectsByType<LightUpdater>(FindObjectsInactive.Exclude, FindObjectsSortMode.None);
#elif UNITY_2020_1_OR_NEWER
return Object.FindObjectsOfType<PlayerPositionsToShader>(true);
return Object.FindObjectsOfType<LightUpdater>(true);
#else
return Resources.FindObjectsOfTypeAll<PlayerPositionsToShader>();
return Resources.FindObjectsOfTypeAll<LightUpdater>();
#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();
}

View File

@@ -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,

View File

@@ -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`.
---

View File

@@ -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).")]

View File

@@ -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"
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: dcd9aab68ad0b484f8382cdb61ef0cb9
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant: