Files
Ipseity-Demo/Assets/_Content/Shaders/Include/CurvedServerVertex.hlsl
T
2026-09-28 14:58:25 +02:00

54 lines
2.5 KiB
HLSL

#ifndef CURVED_SERVER_VERTEX_INCLUDED
#define CURVED_SERVER_VERTEX_INCLUDED
#include "CurvedWorld.hlsl"
#include "PortalMeadowRegion.hlsl"
#include "Assets/_Content/Shaders/EnkiBilal/Include/Mask.hlsl"
// Parameters are declared in CurvedServerLitInput.hlsl's UnityPerMaterial cbuffer.
// Portal masks are global matrices written by PortalManager.
float4x4 _Mask0, _Mask1, _Mask2;
void ClipServerRegion(float4 positionCS)
{
float depth = positionCS.z;
#if !UNITY_REVERSED_Z
depth = lerp(UNITY_NEAR_CLIP_VALUE, 1, depth);
#endif
float3 bentWS = ComputeWorldSpacePosition(GetNormalizedScreenSpaceUV(positionCS), depth, UNITY_MATRIX_I_VP);
// The mask is a camera projection, so it uses the displayed (bent) position.
float maskAlpha;
Mask_float(bentWS, _MaskID, _Mask0, _Mask1, _Mask2, maskAlpha);
clip(maskAlpha - 0.5);
if (_MeadowRegion.w <= 0) return;
float3 view = CurvedWorldToFrame(bentWS);
float s, c;
sincos(radians(_BendAngle), s, c);
// This bend is a shear: depth and the perpendicular lateral axis stay unchanged.
float lateral = dot(view.xy, float2(c, s));
float distance = max(0, -view.z - _StartDistance);
view.xy -= float2(s, -c) * (distance * distance + lateral * lateral * _HorizontalInfluence) * _Curvature;
float3 originalWS = CurvedFrameToWorld(view);
ClipMeadowRegion(originalWS, positionCS.xy);
}
void BendServerFrame(inout float3 positionOS, inout float3 normalOS, inout float4 tangentOS)
{
float3 positionVS = CurvedWorldToFrame(TransformObjectToWorld(positionOS));
float3 normalVS = CurvedWorldDirToFrame(TransformObjectToWorldNormal(normalOS));
normalVS = CurvedWorldNormalVS(positionVS, normalVS, _Curvature,
_StartDistance, _HorizontalInfluence, _BendAngle);
normalOS = TransformWorldToObjectNormal(CurvedFrameDirToWorld(normalVS));
// Deform the tangent with the Jacobian to preserve the server's normal map.
float s, c;
sincos(radians(_BendAngle), s, c);
float lateral = dot(positionVS.xy, float2(c, s));
float3 gradient = 2 * _Curvature * float3(_HorizontalInfluence * lateral * float2(c, s),
-max(0.0, -positionVS.z - _StartDistance));
float3 tangentVS = CurvedWorldDirToFrame(TransformObjectToWorldDir(tangentOS.xyz));
tangentVS += float3(s, -c, 0) * dot(gradient, tangentVS);
tangentOS.xyz = TransformWorldToObjectDir(CurvedFrameDirToWorld(tangentVS));
CurvedWorld_float(positionOS, _Curvature, _StartDistance, _HorizontalInfluence, _BendAngle, positionOS);
}
#endif