Compare commits

2 Commits

Author SHA1 Message Date
DeMuenu
a412ae2dc6 Merge branch 'main' of https://github.com/DeMuenu/MoonlightVRC 2026-03-26 22:04:56 +01:00
DeMuenu
9401c47631 Klammer fix oder so 2026-03-26 22:04:52 +01:00
14 changed files with 275 additions and 295 deletions

View File

@@ -21,37 +21,38 @@ public partial class LightUpdater
shadowMapIndices = new float[max]; shadowMapIndices = new float[max];
count = 0; count = 0;
LightdataStorage[] sceneLights = Object.FindObjectsOfType<LightdataStorage>(); if (otherLightSources == null) return;
for (int i = 0; i < sceneLights.Length && count < max; i++) for (int i = 0; i < otherLightSources.Length && count < max; i++)
{ {
LightdataStorage data = sceneLights[i]; Transform t = otherLightSources[i];
if (data == null || !data.gameObject.activeInHierarchy) continue; if (t == null || !t.gameObject.activeInHierarchy) continue;
Transform t = data.transform; LightdataStorage data = t.GetComponent<LightdataStorage>();
// w = cosHalfAngle (0 for omni) // w = cosHalfAngle (0 for omni)
float cosHalf = data.GetCosHalfAngle(); float cosHalf = (data != null) ? data.GetCosHalfAngle() : 0f;
Vector3 pos = t.position; Vector3 pos = t.position;
float range = 0; float range = 0;
if (data.lightType == LightType.Sphere) if (data.lightType == LightType.Sphere)
{ {
range = data.range * t.localScale.x; range = (data != null) ? data.range * t.localScale.x : t.localScale.x;
} }
else else
{ {
range = Mathf.Cos(Mathf.Deg2Rad * ((data.spotAngleDeg * 0.5f) + Mathf.Max(data.range, 0))); 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) // rgb = color, a = intensity (packed to match runtime/shader)
Vector4 col = data.GetFinalColor(); Vector4 col = (data != null) ? data.GetFinalColor() : new Vector4(1f, 1f, 1f, 1f);
float intensity = data.intensity * t.localScale.x; float intensity = (data != null) ? data.intensity * t.localScale.x : 1f;
// 0=Omni, 1=Spot, 2=Directional (your custom enum) // 0=Omni, 1=Spot, 2=Directional (your custom enum)
int typeId = data.GetTypeId(); int typeId = (data != null) ? data.GetTypeId() : 0;
float shIndex = data.shadowMapIndex; float shIndex = (data != null) ? data.shadowMapIndex : 0f;
Quaternion rot = t.rotation; Quaternion rot = t.rotation;
Vector3 fwd = rot * Vector3.down; Vector3 fwd = rot * Vector3.down;

View File

@@ -12,13 +12,12 @@ What this includes:
- Point/spotlights editable at runtime. - Point/spotlights editable at runtime.
- A couple of premade shaders (standard, particle). - A couple of premade shaders (standard, particle).
- Premade code handling lights, normals and a Lambertian diffuse. - Premade code handling lights, normals and a Lambertian diffuse.
- Shadow caster planes
Work in progress: Work in progress:
- Water shader - Water shader
- Documentation - Documentation
- More performance testing/improvements - More performance testing/improvements
- Shadow caster planes
Planned: Planned:
- Support for additive baked light maps and ambient lighting in the standard shader. - Support for additive baked light maps and ambient lighting in the standard shader.
@@ -37,12 +36,11 @@ On PC, I haven't encountered any frame drops in the editor at all, even with 400
2. Add the `LightUpdater` 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. - Tweak strength/intensity of the local and remote player if you want them to have an attached light.
- Configure the `PlayerShadowMapIndex` if you want players to interact with shadows.
3. For lights, attach `LightdataStorage` to a Transform and configure: 3. For lights, attach `LightdataStorage` to a Transform and configure:
- `range`, `lightType`, `color`, `intensity`, `spotAngleDeg`, and `shadowMapIndex`. - `range`, `type`, `color`, `intensity`, and `spotAngleDeg`.
4. On your light's `LightdataStorage` component, assign your scene's `LightUpdater` to the `Light Updater` field. This allows lights to be added or removed dynamically at runtime. 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. 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.
@@ -64,4 +62,4 @@ On PC, I haven't encountered any frame drops in the editor at all, even with 400
## Contributing ## Contributing
If you want to help with development, please contact me on Discord (@demuenu) so we can coordinate our efforts. If you want to help with development, please contact me on Discord (@demuenu) so we can coordinate our efforts.
If your somebody with a education in Computer graphics, I would be even more thankful for your help. As right now, it's just me with ~1.5 years of messing around in Shaderlab and ChatGPT as my advisor. So I'm sure that there are serious flaws in the codebase :-) If your somebody with a education in Computer graphics, I would be even more thankfull for your help. As right now, it's just me with ~1.5 years of messing around in Shaderlab and ChatGPT as my advisor. So I'm sure that there are serious flaws in the codebase :-)

View File

@@ -1,5 +1,4 @@
using System; using System;
using System;
using UdonSharp; using UdonSharp;
using Unity.Mathematics; using Unity.Mathematics;
using UnityEngine; using UnityEngine;
@@ -10,6 +9,9 @@ using VRC.SDK3.Rendering;
public partial class LightUpdater : UdonSharpBehaviour public partial class LightUpdater : UdonSharpBehaviour
{ {
[Header("Lightsources")] [Header("Lightsources")]
[Tooltip("Place Transforms here which should also emit Light (attach LightdataStorage to them).")]
public Transform[] otherLightSources;
[Header("Strength")] [Header("Strength")]
[Tooltip("Local player light range")] [Tooltip("Local player light range")]
@@ -66,9 +68,6 @@ public partial class LightUpdater : UdonSharpBehaviour
private float[] _ShadowMapArray; private float[] _ShadowMapArray;
private bool _ShadowMap_isDirty = false; private bool _ShadowMap_isDirty = false;
private LightdataStorage[] _sceneLights;
private int _sceneLightCount = 0;
private VRCPlayerApi[] _players; private VRCPlayerApi[] _players;
@@ -92,7 +91,6 @@ public partial class LightUpdater : UdonSharpBehaviour
_directions = new Vector4[maxLights]; _directions = new Vector4[maxLights];
_TypeArray = new float[maxLights]; _TypeArray = new float[maxLights];
_ShadowMapArray = new float[maxLights]; _ShadowMapArray = new float[maxLights];
_sceneLights = new LightdataStorage[maxLights];
_players = new VRCPlayerApi[maxLights]; _players = new VRCPlayerApi[maxLights];
@@ -103,56 +101,11 @@ public partial class LightUpdater : UdonSharpBehaviour
UdonID_LightType = VRCShader.PropertyToID(typeProperty); UdonID_LightType = VRCShader.PropertyToID(typeProperty);
UdonID_ShadowMapIndex = VRCShader.PropertyToID(shadowMapIndexProperty); UdonID_ShadowMapIndex = VRCShader.PropertyToID(shadowMapIndexProperty);
UpdateData(); UpdateData();
PushToRenderers(); 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() void LateUpdate()
{ {
if (Time.time < _nextUpdate) return; if (Time.time < _nextUpdate) return;
@@ -201,7 +154,6 @@ public partial class LightUpdater : UdonSharpBehaviour
if (_directions[i] != TempDir) if (_directions[i] != TempDir)
{ {
_directions[i] = new Vector4(TempDir.x, TempDir.y, TempDir.z, 10f); _directions[i] = new Vector4(TempDir.x, TempDir.y, TempDir.z, 10f);
_directions[i] = TempDir;
_directions_isDirty = true; _directions_isDirty = true;
} }
@@ -249,13 +201,14 @@ public partial class LightUpdater : UdonSharpBehaviour
} }
// --- Scene light sources --- // --- Scene light sources ---
if (_sceneLights != null) if (otherLightSources != null)
{ {
for (int j = 0; j < _sceneLightCount && currentCount < maxLights; j++) for (int j = 0; j < otherLightSources.Length && currentCount < maxLights; j++)
{ {
LightdataStorage data = _sceneLights[j]; Transform t = otherLightSources[j];
if (data == null || !data.gameObject.activeInHierarchy) continue; if (t == null || !t.gameObject.activeInHierarchy) continue;
Transform t = data.transform;
LightdataStorage data = t.GetComponent<LightdataStorage>();
Vector3 pos = t.position; Vector3 pos = t.position;
float range = (data != null) ? data.range * t.localScale.x: t.localScale.x; float range = (data != null) ? data.range * t.localScale.x: t.localScale.x;

View File

@@ -1,4 +1,4 @@
using UdonSharp; using UdonSharp;
using UnityEngine; using UnityEngine;
using VRC.SDKBase; using VRC.SDKBase;
using VRC.Udon; using VRC.Udon;
@@ -10,10 +10,6 @@ public enum LightType { Sphere, Spot }
[UdonBehaviourSyncMode(BehaviourSyncMode.None)] [UdonBehaviourSyncMode(BehaviourSyncMode.None)]
public class LightdataStorage : UdonSharpBehaviour public class LightdataStorage : UdonSharpBehaviour
{ {
[Header("System")]
[Tooltip("The main LightUpdater in the scene. This is required for dynamic lights.")]
public LightUpdater lightUpdater;
[Header("Type")] [Header("Type")]
[Tooltip("Select the logical light type for this source.")] [Tooltip("Select the logical light type for this source.")]
@@ -40,22 +36,6 @@ public class LightdataStorage : UdonSharpBehaviour
[Tooltip("0 = no shadows, 1-4 = shadow map index")] [Tooltip("0 = no shadows, 1-4 = shadow map index")]
public float shadowMapIndex = 0f; // 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 // Convert to a Vector4 for your shader upload
public Vector4 GetFinalColor() public Vector4 GetFinalColor()
{ {

View File

@@ -1,4 +1,4 @@
 
using System.Security.Permissions; using System.Security.Permissions;
using UdonSharp; using UdonSharp;
using UnityEngine; using UnityEngine;
@@ -18,30 +18,10 @@ public class ShadowcasterUpdater : UdonSharpBehaviour
private MaterialPropertyBlock _mpb; 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() void Start()
{ {
_mpb = new MaterialPropertyBlock(); _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(); ApplyTextureData();
} }
@@ -51,47 +31,43 @@ public class ShadowcasterUpdater : UdonSharpBehaviour
{ {
if (mat == null) continue; if (mat == null) continue;
mat.GetPropertyBlock(_mpb); mat.GetPropertyBlock(_mpb);
if (ShadowcasterTexture != null) _mpb.SetTexture(_propShadowTex, ShadowcasterTexture); _mpb.SetTexture("_Udon_shadowCasterTex" + "_" + shadowcasterIndex.ToString(), ShadowcasterTexture);
_mpb.SetColor(_propShadowColor, TextureColor); _mpb.SetColor("_Udon_shadowCasterColor" + "_" + shadowcasterIndex.ToString(), TextureColor);
_mpb.SetColor(_propOutsideColor, OutsideColor); _mpb.SetColor("_Udon_OutSideColor" + "_" + shadowcasterIndex.ToString(), OutsideColor);
_mpb.SetFloat(_propMinBrightness, MinBrightness); _mpb.SetFloat("_Udon_MinBrightnessShadow" + "_" + shadowcasterIndex.ToString(), MinBrightness);
mat.SetPropertyBlock(_mpb); mat.SetPropertyBlock(_mpb);
} }
} }
void LateUpdate() 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) foreach (Renderer mat in rendererTargets)
{ {
if (mat == null) continue; if (mat == null) continue;
mat.GetPropertyBlock(_mpb); mat.GetPropertyBlock(_mpb);
_mpb.SetVector(_propPlaneOrigin, originVec); float quadHalfWidth = 0.5f;
_mpb.SetVector(_propPlaneUinv, uinvVec); float quadHalfHeight = 0.5f;
_mpb.SetVector(_propPlaneVinv, vinvVec);
_mpb.SetVector(_propPlaneNormal, nVec); // 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); mat.SetPropertyBlock(_mpb);
} }

View File

@@ -2,20 +2,16 @@
#define InLoopSetup(_Udon_LightPositions, LightCounter, count, i) \ #define InLoopSetup(_Udon_LightPositions, LightCounter, count, i) \
if (LightCounter >= count) break; \ if (LightCounter >= count) break; \
\ \
float3 lightVec = _Udon_LightPositions[LightCounter].xyz - i.worldPos; \ float distanceFromLight = length(i.worldPos - _Udon_LightPositions[LightCounter].xyz); \
float distanceFromLight = length(lightVec); \
if (distanceFromLight > _LightCutoffDistance) continue; \ if (distanceFromLight > _LightCutoffDistance) continue; \
\ \
float contrib = 0.0; \ float contrib = 0.0;
float3 L = lightVec / max(distanceFromLight, 1e-4);
#endif #endif
#ifndef OutLoopSetup #ifndef OutLoopSetup
#define OutLoopSetup(i, _Udon_PlayerCount) \ #define OutLoopSetup(i, _Udon_PlayerCount) \
int count = (int)_Udon_PlayerCount; \ int count = (int)_Udon_PlayerCount; \
float invSqMul = max(1e-4, _InverseSqareMultiplier); \
bool shadowCastingEnabled = _EnableShadowCasting > 0.5; \
\ \
float4 dmax = float4(0,0,0,1); \ float4 dmax = float4(0,0,0,1); \
float dIntensity = 0; float dIntensity = 0;

View File

@@ -1,7 +1,7 @@
#ifndef Lambert #ifndef Lambert
#define Lambert(q ,i, N) \ #define Lambert(q ,i, N) \
/* 'L' is inherited from InLoopSetup, avoiding an expensive normalize() */ \ float3 L = normalize(q - i.worldPos); /* q = light position */ \
half NdotL = saturate(dot(N, L) * 0.5 + 0.5); /* one-sided Lambert */ \ float NdotL = saturate(dot(N, L) * 0.5 + 0.5); /* one-sided Lambert */ \
if (NdotL <= 0) continue; \ if (NdotL <= 0) continue; \
#endif #endif

View File

@@ -1,26 +1,24 @@
#ifndef LightTypeCalculations #ifndef LightTypeCalculations
#define LightTypeCalculations(_Udon_LightColors ,LightCounter, i, NdotL, dIntensity, radius, Lightposition) \ #define LightTypeCalculations(_Udon_LightColors ,LightCounter, i, NdotL, dIntensity, radius, Lightposition) \
half typeId = _Udon_LightType[LightCounter]; \ float invSqMul = max(1e-4, _InverseSqareMultiplier); \
\ \
if(typeId == 0) \ if(_Udon_LightType[LightCounter] == 0) \
{ \ { \
float distAtten = max(1.0, distanceFromLight - radius) * invSqMul; \ contrib = _Udon_LightColors[LightCounter].a / max(1e-4, max(0, max(1, distanceFromLight - radius) * invSqMul) * max(0, max(1, distanceFromLight - radius) * invSqMul)); \
contrib = _Udon_LightColors[LightCounter].a / max(1e-4, distAtten * distAtten); \
\ \
dIntensity += contrib; \ dIntensity += contrib; \
} \ } \
else if (typeId == 1) \ else if (_Udon_LightType[LightCounter] == 1) \
{ \ { \
float distAtten = distanceFromLight * invSqMul; \ float invSq = _Udon_LightColors[LightCounter].a / max(1e-4, (distanceFromLight * invSqMul) * (distanceFromLight * invSqMul)); \
float invSq = _Udon_LightColors[LightCounter].a / max(1e-4, distAtten * distAtten); \
\ \
contrib = dot(-L, normalize(_Udon_LightDirections[LightCounter].xyz)); \ contrib = dot(normalize(i.worldPos - Lightposition), normalize(_Udon_LightDirections[LightCounter].xyz)); \
contrib = smoothstep(radius,_Udon_LightDirections[LightCounter].w, contrib); \ contrib = smoothstep(radius,_Udon_LightDirections[LightCounter].w, contrib); \
\ \
contrib = contrib * invSq; \ contrib = contrib * invSq; \
dIntensity += contrib; \ dIntensity += contrib; \
} \ } \
half3 LightColor = _Udon_LightColors[LightCounter].xyz; \ float3 LightColor = _Udon_LightColors[LightCounter].xyz; \
#endif #endif

View File

@@ -1,10 +0,0 @@
#ifndef MOONLIGHT_CORE_INCLUDED
#define MOONLIGHT_CORE_INCLUDED
#include "Variables.hlsl"
#include "DefaultSetup.hlsl"
#include "LightStrength.hlsl"
#include "Lambert.hlsl"
#include "Shadowcaster.cginc"
#endif

View File

@@ -1,40 +1,14 @@
#ifndef MOONLIGHT_GLOBAL_VARIABLES_INCLUDED #ifndef MoonlightGlobalVariables
#define MOONLIGHT_GLOBAL_VARIABLES_INCLUDED #define MoonlightGlobalVariables \
\
float _InverseSqareMultiplier; float _InverseSqareMultiplier; \
float _LightCutoffDistance; float _LightCutoffDistance; \
\
float4 _Udon_LightPositions[MAX_LIGHTS]; /* xyz = position */ float4 _Udon_LightPositions[MAX_LIGHTS]; /* xyz = position */ \
float4 _Udon_LightColors[MAX_LIGHTS]; /* xyz = position */ float4 _Udon_LightColors[MAX_LIGHTS]; /* xyz = position */ \
float4 _Udon_LightDirections[MAX_LIGHTS]; /* xyz = direction, w = cos(halfAngle) */ float4 _Udon_LightDirections[MAX_LIGHTS]; /* xyz = direction, w = cos(halfAngle) */ \
float _Udon_LightType[MAX_LIGHTS]; /* 0 = sphere, 1 = cone */ float _Udon_LightType[MAX_LIGHTS]; /* 0 = sphere, 1 = cone */ \
float _Udon_ShadowMapIndex[MAX_LIGHTS]; float _Udon_ShadowMapIndex[MAX_LIGHTS];\
float _Udon_PlayerCount; /* set via SetFloat */ float _Udon_PlayerCount; /* set via SetFloat */ \
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;
#endif #endif

View File

@@ -35,7 +35,11 @@ Shader "DeMuenu/World/Hoppou/Particles/LitParticles_2SP"
#define MAX_LIGHTS 80 // >= maxPlayers in script #define MAX_LIGHTS 80 // >= maxPlayers in script
#include "UnityCG.cginc" #include "UnityCG.cginc"
#include "Includes/Moonlight.hlsl" #include "Includes/LightStrength.hlsl"
#include "Includes/Lambert.hlsl"
#include "Includes/DefaultSetup.hlsl"
#include "Includes/Variables.hlsl"
#include "Includes/Shadowcaster.cginc"
@@ -75,6 +79,35 @@ Shader "DeMuenu/World/Hoppou/Particles/LitParticles_2SP"
float4 _EmmissiveColor; float4 _EmmissiveColor;
float _EmmissiveStrength; 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 vert (appdata v)
{ {
v2f o; v2f o;
@@ -116,25 +149,20 @@ Shader "DeMuenu/World/Hoppou/Particles/LitParticles_2SP"
float4 ShadowCasterMult_1 = 1; float4 ShadowCasterMult_1 = 1;
float4 ShadowCasterMult_2 = 1; float4 ShadowCasterMult_2 = 1;
if (shadowCastingEnabled) if ((((_Udon_ShadowMapIndex[LightCounter] > 0.5) && (_Udon_ShadowMapIndex[LightCounter] < 1.5) && (_EnableShadowCasting > 0.5)) || (_Udon_ShadowMapIndex[LightCounter] > 2.5)) && _EnableShadowCasting)
{ {
half smIndex = _Udon_ShadowMapIndex[LightCounter]; float4 sc1 = SampleShadowcasterPlaneWS_Basis(
if ((smIndex > 0.5 && smIndex < 1.5) || smIndex > 2.5) _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,
float4 sc1 = SampleShadowcasterPlaneWS_Basis( _Udon_shadowCasterTex_1, _Udon_OutSideColor_1, _Udon_shadowCasterColor_1, _BlurPixels, _Udon_shadowCasterTex_1_TexelSize.xy);
_Udon_LightPositions[LightCounter].xyz, i.worldPos, ShadowCasterMult_1 = max(sc1, _Udon_MinBrightnessShadow_1);
_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); if (_Udon_ShadowMapIndex[LightCounter] > 1.5 && (_EnableShadowCasting > 0.5)) {
ShadowCasterMult_1 = max(sc1, _Udon_MinBrightnessShadow_1); float4 sc2 = SampleShadowcasterPlaneWS_Basis(
} _Udon_LightPositions[LightCounter].xyz, i.worldPos,
if (smIndex > 1.5) _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);
float4 sc2 = SampleShadowcasterPlaneWS_Basis( ShadowCasterMult_2 = max(sc2, _Udon_MinBrightnessShadow_2);
_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) * ShadowCasterMult_1 * ShadowCasterMult_2; dmax = dmax + contrib * float4(LightColor, 1) * ShadowCasterMult_1 * ShadowCasterMult_2;

View File

@@ -37,13 +37,17 @@ Shader "DeMuenu/World/Hoppou/Standard_2SP"
#pragma vertex vert #pragma vertex vert
#pragma fragment frag #pragma fragment frag
#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 //Moonlight Defines
#define MAX_LIGHTS 80 // >= maxPlayers in script #define MAX_LIGHTS 80 // >= maxPlayers in script
//Moonlight Defines END //Moonlight Defines END
#include "UnityCG.cginc"
#include "Includes/Moonlight.hlsl"
struct appdata struct appdata
{ {
float4 vertex : POSITION; float4 vertex : POSITION;
@@ -85,6 +89,35 @@ Shader "DeMuenu/World/Hoppou/Standard_2SP"
float _EmmissiveStrength; 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 vert (appdata v)
{ {
v2f o; v2f o;
@@ -143,25 +176,20 @@ Shader "DeMuenu/World/Hoppou/Standard_2SP"
float4 ShadowCasterMult_1 = 1; float4 ShadowCasterMult_1 = 1;
float4 ShadowCasterMult_2 = 1; float4 ShadowCasterMult_2 = 1;
if (shadowCastingEnabled) 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))
{ {
half smIndex = _Udon_ShadowMapIndex[LightCounter]; float4 sc2 = SampleShadowcasterPlaneWS_Basis(
if ((smIndex > 0.5 && smIndex < 1.5) || smIndex > 2.5) _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,
float4 sc1 = SampleShadowcasterPlaneWS_Basis( _Udon_shadowCasterTex_2, _Udon_OutSideColor_2, _Udon_shadowCasterColor_2, _BlurPixels, _Udon_shadowCasterTex_2_TexelSize.xy);
_Udon_LightPositions[LightCounter].xyz, i.worldPos, ShadowCasterMult_2 = max(sc2, _Udon_MinBrightnessShadow_2);
_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 (smIndex > 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, _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 = dmax + contrib * float4(LightColor, 1) * NdotL * ShadowCasterMult_1 * ShadowCasterMult_2;

View File

@@ -39,13 +39,17 @@ Shader "DeMuenu/World/Hoppou/Standard_Lightmap_2SP"
#pragma multi_compile _ LIGHTMAP_ON #pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile _ DIRLIGHTMAP_COMBINED #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 //Moonlight Defines
#define MAX_LIGHTS 80 // >= maxPlayers in script #define MAX_LIGHTS 80 // >= maxPlayers in script
//Moonlight Defines END //Moonlight Defines END
#include "UnityCG.cginc"
#include "Includes/Moonlight.hlsl"
struct appdata struct appdata
{ {
float4 vertex : POSITION; float4 vertex : POSITION;
@@ -93,6 +97,37 @@ Shader "DeMuenu/World/Hoppou/Standard_Lightmap_2SP"
float _EmmissiveStrength; 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 vert (appdata v)
{ {
v2f o; v2f o;
@@ -155,25 +190,21 @@ Shader "DeMuenu/World/Hoppou/Standard_Lightmap_2SP"
float4 ShadowCasterMult_1 = 1; float4 ShadowCasterMult_1 = 1;
float4 ShadowCasterMult_2 = 1; float4 ShadowCasterMult_2 = 1;
if (shadowCastingEnabled) if ((((_Udon_ShadowMapIndex[LightCounter] > 0.5) && (_Udon_ShadowMapIndex[LightCounter] < 1.5) && (_EnableShadowCasting > 0.5)) || (_Udon_ShadowMapIndex[LightCounter] > 2.5)) && _EnableShadowCasting)
{ {
half smIndex = _Udon_ShadowMapIndex[LightCounter]; float4 sc1 = SampleShadowcasterPlaneWS_Basis(
if ((smIndex > 0.5 && smIndex < 1.5) || smIndex > 2.5) _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,
float4 sc1 = SampleShadowcasterPlaneWS_Basis( _Udon_shadowCasterTex_1, _Udon_OutSideColor_1, _Udon_shadowCasterColor_1, _BlurPixels, _Udon_shadowCasterTex_1_TexelSize.xy);
_Udon_LightPositions[LightCounter].xyz, i.worldPos, ShadowCasterMult_1 = max(sc1, _Udon_MinBrightnessShadow_1);
_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); if (_Udon_ShadowMapIndex[LightCounter] > 1.5 && (_EnableShadowCasting > 0.5))
ShadowCasterMult_1 = max(sc1, _Udon_MinBrightnessShadow_1); {
} float4 sc2 = SampleShadowcasterPlaneWS_Basis(
if (smIndex > 1.5) _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,
float4 sc2 = SampleShadowcasterPlaneWS_Basis( _Udon_shadowCasterTex_2, _Udon_OutSideColor_2, _Udon_shadowCasterColor_2, _BlurPixels, _Udon_shadowCasterTex_2_TexelSize.xy);
_Udon_LightPositions[LightCounter].xyz, i.worldPos, ShadowCasterMult_2 = max(sc2, _Udon_MinBrightnessShadow_2);
_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 = dmax + contrib * float4(LightColor, 1) * NdotL * ShadowCasterMult_1 * ShadowCasterMult_2;

View File

@@ -49,13 +49,17 @@ Shader "DeMuenu/World/Hoppou/WaterFlat_2SP"
#pragma vertex vert #pragma vertex vert
#pragma fragment frag #pragma fragment frag
#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 //Moonlight Defines
#define MAX_LIGHTS 80 // >= maxPlayers in script #define MAX_LIGHTS 80 // >= maxPlayers in script
//Moonlight Defines END //Moonlight Defines END
#include "UnityCG.cginc"
#include "Includes/Moonlight.hlsl"
struct appdata struct appdata
{ {
float4 vertex : POSITION; float4 vertex : POSITION;
@@ -92,6 +96,35 @@ Shader "DeMuenu/World/Hoppou/WaterFlat_2SP"
float _MinTransparency; float _MinTransparency;
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;
//Watershader specific //Watershader specific
float _SpecPower, _SpecIntensity; float _SpecPower, _SpecIntensity;
float3 _AmbientFloor; float3 _AmbientFloor;
@@ -186,25 +219,20 @@ Shader "DeMuenu/World/Hoppou/WaterFlat_2SP"
float4 ShadowCasterMult_1 = 1; float4 ShadowCasterMult_1 = 1;
float4 ShadowCasterMult_2 = 1; float4 ShadowCasterMult_2 = 1;
if (shadowCastingEnabled) if ((((_Udon_ShadowMapIndex[LightCounter] > 0.5) && (_Udon_ShadowMapIndex[LightCounter] < 1.5) && (_EnableShadowCasting > 0.5)) || (_Udon_ShadowMapIndex[LightCounter] > 2.5)) && _EnableShadowCasting)
{ {
half smIndex = _Udon_ShadowMapIndex[LightCounter]; float4 sc1 = SampleShadowcasterPlaneWS_Basis(
if ((smIndex > 0.5 && smIndex < 1.5) || smIndex > 2.5) _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,
float4 sc1 = SampleShadowcasterPlaneWS_Basis( _Udon_shadowCasterTex_1, _Udon_OutSideColor_1, _Udon_shadowCasterColor_1, _BlurPixels, _Udon_shadowCasterTex_1_TexelSize.xy);
_Udon_LightPositions[LightCounter].xyz, i.worldPos, ShadowCasterMult_1 = max(sc1, _Udon_MinBrightnessShadow_1);
_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); if (_Udon_ShadowMapIndex[LightCounter] > 1.5 && (_EnableShadowCasting > 0.5)) {
ShadowCasterMult_1 = max(sc1, _Udon_MinBrightnessShadow_1); float4 sc2 = SampleShadowcasterPlaneWS_Basis(
} _Udon_LightPositions[LightCounter].xyz, i.worldPos,
if (smIndex > 1.5) _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);
float4 sc2 = SampleShadowcasterPlaneWS_Basis( ShadowCasterMult_2 = max(sc2, _Udon_MinBrightnessShadow_2);
_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);
}
} }
//Watershader specific //Watershader specific
@@ -216,7 +244,6 @@ Shader "DeMuenu/World/Hoppou/WaterFlat_2SP"
//dmax = dmax + contrib * float4(LightColor, 1); // accumulate light contributions //dmax = dmax + contrib * float4(LightColor, 1); // accumulate light contributions
} }
//dmax.xyz = min(dmax * dIntensity, 1.0); //dmax.xyz = min(dmax * dIntensity, 1.0);