mirror of
https://github.com/DeMuenu/MoonlightVRC.git
synced 2025-12-12 19:13:56 +00:00
Introduces shadowcaster support by adding shadow map index fields to light data, updating PlayerPositionsToShader and LightdataStorage to handle shadow map indices, and extending the shader and its includes to sample shadowcaster planes. Adds ShadowcasterUpdater script and editor preview for updating world-to-local matrices, and updates relevant arrays and property handling throughout the codebase. Also adds a sample plane mesh for shadowcasting.
57 lines
1.7 KiB
HLSL
57 lines
1.7 KiB
HLSL
#ifndef SHADOWCASTER_PLANE
|
|
#define SHADOWCASTER_PLANE
|
|
|
|
#include "UnityCG.cginc" // for tex2Dlod, etc.
|
|
|
|
static const float EPS = 1e-5;
|
|
|
|
// Returns whether segment hits the unit plane quad in plane-local z=0.
|
|
// Outputs uv in [0,1] and t in [0,1] along A->B.
|
|
inline bool RaySegmentHitsPlaneQuad(float4x4 worldToLocal, float3 rayOrigin, float3 rayEnd, out float2 uv, out float t)
|
|
{
|
|
float3 aP = mul(worldToLocal, float4(rayOrigin, 1)).xyz;
|
|
float3 bP = mul(worldToLocal, float4(rayEnd, 1)).xyz;
|
|
|
|
float3 d = bP - aP;
|
|
float dz = d.z;
|
|
|
|
// Parallel-ish to plane?
|
|
if (abs(dz) < EPS) return false;
|
|
|
|
// Intersect z=0
|
|
t = -aP.z / dz;
|
|
|
|
// Segment only
|
|
if (t < 0.0 || t > 1.0) return false;
|
|
|
|
float3 hit = aP + d * t;
|
|
|
|
// Inside 1x1 centered quad?
|
|
if (abs(hit.x) > 0.5 || abs(hit.y) > 0.5) return false;
|
|
|
|
uv = hit.xy + 0.5; // [-0.5,0.5] -> [0,1]
|
|
return true;
|
|
}
|
|
|
|
// Fragment-shader version: uses proper filtering/mips via tex2D
|
|
inline float4 SampleShadowcasterPlane(float4x4 worldToLocal, sampler2D tex, float3 rayOrigin, float3 rayEnd, float4 OutsideColor)
|
|
{
|
|
float2 uv; float t;
|
|
if (RaySegmentHitsPlaneQuad(worldToLocal, rayOrigin, rayEnd, uv, t))
|
|
return tex2D(tex, uv); // full color
|
|
|
|
return OutsideColor;
|
|
}
|
|
|
|
// Anywhere (vertex/geom/compute/custom code) version: forces LOD 0
|
|
inline float4 SampleShadowcasterPlaneLOD0(float4x4 worldToLocal, sampler2D tex, float3 rayOrigin, float3 rayEnd, float4 OutsideColor)
|
|
{
|
|
float2 uv; float t;
|
|
if (RaySegmentHitsPlaneQuad(worldToLocal, rayOrigin, rayEnd, uv, t))
|
|
return tex2Dlod(tex, float4(uv, 0, 0)); // full color at mip 0
|
|
|
|
return OutsideColor;
|
|
}
|
|
|
|
#endif
|