54 lines
2.5 KiB
HLSL
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
|