mirror of
https://github.com/DeMuenu/MoonlightVRC.git
synced 2025-12-13 19:33:56 +00:00
Initial commit
This commit is contained in:
90
Shader/MoonsLight.cingc
Normal file
90
Shader/MoonsLight.cingc
Normal file
@@ -0,0 +1,90 @@
|
||||
#ifndef MOONSLIGHT_INCLUDED
|
||||
#define MOONSLIGHT_INCLUDED
|
||||
|
||||
// You can override this before including if TEXCOORD2 is taken:
|
||||
// #define MOONSLIGHT_TEXCOORD TEXCOORD4
|
||||
#ifndef MOONSLIGHT_TEXCOORD
|
||||
#define MOONSLIGHT_TEXCOORD TEXCOORD2
|
||||
#endif
|
||||
|
||||
// Pick a safe max for your target hardware.
|
||||
#ifndef MAX_LIGHTS
|
||||
#define MAX_LIGHTS 80
|
||||
#endif
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
// ---------- Uniforms (set from script as Global/Material arrays) ----------
|
||||
uniform float4 _LightPositions[MAX_LIGHTS]; // xyz = pos, w = radius
|
||||
uniform float4 _LightColors[MAX_LIGHTS]; // xyz = rgb (not normalized), w = intensity scalar
|
||||
uniform float4 _LightDirections[MAX_LIGHTS]; // xyz = dir, w = half-angle in degrees (cone)
|
||||
uniform float _LightType[MAX_LIGHTS]; // 0 = sphere, 1 = cone
|
||||
uniform float _PlayerCount;
|
||||
|
||||
// ---------- Helpers you can inject into your v2f / vertex ----------
|
||||
#define MOONSLIGHT_V2F_MEMBERS float3 worldPos : MOONSLIGHT_TEXCOORD;
|
||||
|
||||
inline void MoonsLight_FillV2F(float4 vertexOS, out float3 worldPos)
|
||||
{
|
||||
worldPos = mul(unity_ObjectToWorld, vertexOS).xyz;
|
||||
}
|
||||
|
||||
// ---------- Core lighting (return value is 0..1 rgba contribution) ----------
|
||||
inline float4 MoonsLight_Accumulate(float3 worldPos, float3 worldNormal)
|
||||
{
|
||||
float3 N = normalize(worldNormal);
|
||||
float4 accum = float4(0,0,0,1);
|
||||
float dIntensity = 0.0;
|
||||
|
||||
int count = (int)_PlayerCount;
|
||||
|
||||
[loop]
|
||||
for (int idx = 0; idx < MAX_LIGHTS; idx++)
|
||||
{
|
||||
if (idx >= count) break;
|
||||
|
||||
float3 q = _LightPositions[idx].xyz;
|
||||
float radius = _LightPositions[idx].w;
|
||||
|
||||
float3 L = normalize(q - worldPos);
|
||||
float NdotL = saturate(dot(N, L) * 0.5 + 0.5); // one-sided Lambert
|
||||
float contrib = 0.0;
|
||||
|
||||
if (_LightType[idx] == 0.0)
|
||||
{
|
||||
// Sphere (SDF-ish falloff reused from your code)
|
||||
float sd = length(worldPos - q) - radius;
|
||||
sd = lerp(1.0, -sd, step(0.0, sd));
|
||||
contrib = min(1.0, max(max(sd, max(0.01, _LightColors[idx].a) / (sd * sd)), 0.01));
|
||||
dIntensity += contrib * NdotL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cone (directional spot)
|
||||
float threshold = (-1 + _LightDirections[idx].w / 180.0);
|
||||
contrib = min(dot(normalize(worldPos - q), -normalize(_LightDirections[idx].xyz)), 0.0);
|
||||
contrib = 1.0 - step(threshold, contrib);
|
||||
float distanceFromLight = length(worldPos - q);
|
||||
contrib = min(1.0, contrib * (max(0.01, _LightColors[idx].a) / (distanceFromLight * distanceFromLight)));
|
||||
dIntensity += contrib * NdotL;
|
||||
}
|
||||
|
||||
float3 lightRgb = normalize(_LightColors[idx].xyz);
|
||||
accum += contrib * float4(lightRgb, 1.0);
|
||||
}
|
||||
|
||||
accum.xyz = normalize(accum.xyz);
|
||||
accum.xyz = min(accum.xyz * dIntensity, 1.0);
|
||||
accum.w = 1.0;
|
||||
return min(accum, 1.0);
|
||||
}
|
||||
|
||||
// Optional: reuse your camera-distance fade
|
||||
inline float4 MoonsLight_ApplyDistanceFade(float4 color, float3 worldPos, float distanceFadeMultiplier, float distanceMin)
|
||||
{
|
||||
float dist = length(_WorldSpaceCameraPos.xyz - worldPos) / 100.0;
|
||||
color.xyz *= min(1.0, max(distanceMin, max(0.0, 1.0 - abs(dist) * distanceFadeMultiplier)));
|
||||
return color;
|
||||
}
|
||||
|
||||
#endif // MOONSLIGHT_INCLUDED
|
||||
Reference in New Issue
Block a user