#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