@Kevin_Ring thank you for the reply!
Here is what I came with now:
In MF_TriplanarWindows I inserted custom HLSL shader node:
the idea was:
- Define radii constants inside shader
- Get pixel in UE world space (AbsoluteWorldPosition node)
- Transform it’s coordinates from unreal space to ECEF
- Find rotation matrix that would “snap” current pixel position to normal in ECEF
- Apply transformation
and after that send this back to the other nodes.
Here is HLSL code:
struct MyFunctions {
// Unreal to ECEF
float3 UnrealPositionToEcef(float3 unrealPos) {
return float3(unrealPos.y, unrealPos.x, unrealPos.z) * 0.01; // Convert cm to meters
}
// WGS84
float3 OneOverEllipsoidRadiiSquared() {
return float3(
1.0 / (6378137.0 * 6378137.0),
1.0 / (6378137.0 * 6378137.0),
1.0 / (6356752.314245 * 6356752.314245)
);
}
// Computes the geodetic normal for an ECEF position
// (based on https://github.com/CesiumGS/cesium/blob/main/packages/engine/Source/Shaders/Builtin/Functions/geodeticSurfaceNormal.glsl)
float3 CalculateEllipsoidNormal(float3 ecefPos, float3 oneOverEllipsoidRadiiSquared) {
return normalize(ecefPos * oneOverEllipsoidRadiiSquared);
}
// Helper function to create a rotation matrix from an axis and angle
float3x3 RotationMatrixFromAxisAngle(float3 axis, float angle) {
float c = cos(angle);
float s = sin(angle);
float t = 1.0 - c;
float x = axis.x;
float y = axis.y;
float z = axis.z;
return float3x3(
t * x * x + c, t * x * y - s * z, t * x * z + s * y,
t * x * y + s * z, t * y * y + c, t * y * z - s * x,
t * x * z - s * y, t * y * z + s * x, t * z * z + c
);
}
// Aligns Unreal world position with the ellipsoid normal
float3 AlignWorldPositionToEllipsoid(float3 worldPos, float3 ecefNormal) {
// Define the "up" vector (Z-axis in Unreal)
float3 up = float3(0, 0, 1);
// Compute the rotation axis (cross product of up and ellipsoid normal)
float3 axis = cross(up, ecefNormal);
// Compute the rotation angle (dot product of up and ellipsoid normal)
float angle = acos(dot(up, ecefNormal));
// Construct a rotation matrix from the axis and angle
float3x3 rotationMatrix = RotationMatrixFromAxisAngle(axis, angle);
// Transform the world position using the rotation matrix
return mul(rotationMatrix, worldPos);
}
};
MyFunctions f;
float3 ecefPos = f.UnrealPositionToEcef(unrealPos);
float3 oneOverRadiiSquared = f.OneOverEllipsoidRadiiSquared();
float3 ecefNormal = f.CalculateEllipsoidNormal(ecefPos, oneOverRadiiSquared);
return f.AlignWorldPositionToEllipsoid(unrealPos, ecefNormal);
So far by messing with different transformations I got this result (i will provide screenshot with unchanged-shader version of MF_TriplanarWindows too)
I guess that on the ‘left’ sides there are straight lines corresponding to the ‘new horizon’ line, but on the ‘right’ sides there are still problems.
Am I on the right way and what problems does the HLSL code have? Are my key points correct and there is some error in implementation of my steps, or did I misunderstood some key ideas?
I understood that there are some issues with precision and I guess that is why it looks so glitchy, but the outlines are visible and from the distance it’s kinda ok.