66 lines
2.7 KiB
HLSL
66 lines
2.7 KiB
HLSL
#ifndef CURVED_WORLD_INCLUDED
|
|
#define CURVED_WORLD_INCLUDED
|
|
|
|
// Bend frame: the camera view by default. PortalMeadow can pin it to a fixed world-space frame
|
|
// (e.g. a portal) so the bend stays still while the world is only seen through that portal.
|
|
float4x4 _CurvedWorldFrame, _CurvedWorldFrameInv;
|
|
float _CurvedWorldFrameFixed;
|
|
|
|
float3 CurvedWorldToFrame(float3 positionWS)
|
|
{
|
|
return _CurvedWorldFrameFixed > 0.5 ? mul(_CurvedWorldFrame, float4(positionWS, 1)).xyz : TransformWorldToView(positionWS);
|
|
}
|
|
float3 CurvedFrameToWorld(float3 positionFS)
|
|
{
|
|
return mul(_CurvedWorldFrameFixed > 0.5 ? _CurvedWorldFrameInv : UNITY_MATRIX_I_V, float4(positionFS, 1)).xyz;
|
|
}
|
|
float3 CurvedWorldDirToFrame(float3 directionWS)
|
|
{
|
|
return mul((float3x3)(_CurvedWorldFrameFixed > 0.5 ? _CurvedWorldFrame : UNITY_MATRIX_V), directionWS);
|
|
}
|
|
float3 CurvedFrameDirToWorld(float3 directionFS)
|
|
{
|
|
return mul((float3x3)(_CurvedWorldFrameFixed > 0.5 ? _CurvedWorldFrameInv : UNITY_MATRIX_I_V), directionFS);
|
|
}
|
|
|
|
// Shared by the ground and the grass; also usable as a Shader Graph custom function.
|
|
void CurvedWorld_float(float3 PositionOS, float Curvature, float StartDistance,
|
|
float HorizontalInfluence, float BendAngle, out float3 Out)
|
|
{
|
|
#ifdef SHADERGRAPH_PREVIEW
|
|
Out = PositionOS;
|
|
#else
|
|
float3 positionVS = CurvedWorldToFrame(TransformObjectToWorld(PositionOS));
|
|
// Rotate the bend frame around the camera's forward axis (degrees).
|
|
// 0 = down, 90 = right, 180 = up, 270 = left.
|
|
float s, c;
|
|
sincos(radians(BendAngle), s, c);
|
|
float lateral = dot(positionVS.xy, float2(c, s));
|
|
float distanceFromCamera = max(0.0, -positionVS.z - StartDistance);
|
|
float bend = (distanceFromCamera * distanceFromCamera
|
|
+ lateral * lateral * HorizontalInfluence) * Curvature;
|
|
positionVS.xy += float2(s, -c) * bend;
|
|
Out = TransformWorldToObject(CurvedFrameToWorld(positionVS));
|
|
#endif
|
|
}
|
|
|
|
// Preserve existing Shader Graph custom functions using the original signature.
|
|
void CurvedWorld_float(float3 PositionOS, float Curvature, float StartDistance,
|
|
float HorizontalInfluence, out float3 Out)
|
|
{
|
|
CurvedWorld_float(PositionOS, Curvature, StartDistance, HorizontalInfluence, 0, Out);
|
|
}
|
|
|
|
float3 CurvedWorldNormalVS(float3 positionVS, float3 normalVS, float Curvature,
|
|
float StartDistance, float HorizontalInfluence, float BendAngle)
|
|
{
|
|
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));
|
|
// Inverse transpose of the bend Jacobian; the gradient is perpendicular to its direction.
|
|
return normalVS - gradient * dot(float2(s, -c), normalVS.xy);
|
|
}
|
|
#endif
|