# OSM buildings windows orientation problem with true origin enabled

**URL:** <https://community.cesium.com/t/osm-buildings-windows-orientation-problem-with-true-origin-enabled/38877>\
**Category:** Cesium for Unreal\
**Created:** [February 24, 2025, 4:06pm UTC](https://community.cesium.com/t/osm-buildings-windows-orientation-problem-with-true-origin-enabled/38877 "2025-02-24T16:06:24Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![ureadulose](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/ureadulose/32/14000_2.png) [@ureadulose](https://community.cesium.com/u/ureadulose)\
**Post date:** [February 24, 2025, 4:06pm UTC](https://community.cesium.com/t/osm-buildings-windows-orientation-problem-with-true-origin-enabled/38877/1 "2025-02-24T16:06:24Z")

</div>

Hello.

I am getting to know with OSM buildings. I am trying out levels from here: [GitHub - CesiumGS/cesium-unreal-samples: Getting Started Sample Project for Cesium for Unreal](https://github.com/CesiumGS/cesium-unreal-samples).

When Georeference’s origin placement is set to ‘LongitudeLatitudeHeight’ the orientation of procedurally generated windows is ok

 ![OriginPlacement: LongitudeLatitudeHeight](https://global.discourse-cdn.com/cesium/original/3X/8/2/82ead33f9fb355e0de3b6a6e69d82bcebac05044.jpeg)

But when it is set to ‘TrueOrigin’ it gets messed up (see pic. 2)

 ![OriginPlacement: TrueOrigin](https://global.discourse-cdn.com/cesium/original/3X/d/b/db609114db77b15b197e825c4839a9e0f0e670cd.jpeg)

As far as I understood the problem is that in both ML\_ProceduralWindowsMetadata and ML\_ProceduralWindowsMetadata in this section:

 ![MF_TriplanarWindows](https://global.discourse-cdn.com/cesium/original/3X/c/a/cac3a8158ee399698ca2971cb144351daff7fda1.png)

we are calling MF\_TriplanarWindows which is used to generate window-grid.

But inside MF\_TriplanarWindows:

 ![Screenshot from 2025-02-24 18-24-48](https://global.discourse-cdn.com/cesium/original/3X/a/3/a378f63027ef53ba06d33a4523d5a2b546b2a600.png)  
we are retrieving current Absolute World Position in absolute UE coordinates, while we should (I guess) take current ENU (or ESU) position. I mean we should be geoawared to have a correct information about Z-axis.

I tried to somehow modify those Material Functions (MF\_TriplanarWindows and ML\_ProceduralWindowsMetadata), but I can’t think of way of getting current geographical-awared positions inside material function as we can’t get references to actors from MF.

How can I resolve this issue?  
Maybe there are some other ways for correct orientation of windows with ‘True origin’ enabled?

p.s. Unreal Engine 5.4.4, cesium 2.10

---

<div class="post-metadata">

**Author:** ![Kevin\_Ring](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/kevin_ring/32/2003_2.png) [@Kevin\_Ring](https://community.cesium.com/u/Kevin_Ring)\
**Post date:** [February 25, 2025, 5:52am UTC](https://community.cesium.com/t/osm-buildings-windows-orientation-problem-with-true-origin-enabled/38877/2 "2025-02-25T05:52:36Z")

</div>

Hi @ureadulose,

It’s a tough problem. Even if we had a material function to compute an ENU (or similar) coordinate system, we’d run into precision problems with it due to the limited floating-point precision available on GPUs (or at least in Unreal materials). But you might be able to get started by porting some GLSL from CesiumJS to HLSL and Unreal:

- [cesium/packages/engine/Source/Shaders/Builtin/Functions/eastNorthUpToEyeCoordinates.glsl at main · CesiumGS/cesium · GitHub](https://github.com/CesiumGS/cesium/blob/main/packages/engine/Source/Shaders/Builtin/Functions/eastNorthUpToEyeCoordinates.glsl)
- [cesium/packages/engine/Source/Shaders/Builtin/Functions/geodeticSurfaceNormal.glsl at main · CesiumGS/cesium · GitHub](https://github.com/CesiumGS/cesium/blob/main/packages/engine/Source/Shaders/Builtin/Functions/geodeticSurfaceNormal.glsl)

---

<div class="post-metadata">

**Author:** ![ureadulose](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/ureadulose/32/14000_2.png) [@ureadulose](https://community.cesium.com/u/ureadulose)\
**Post date:** [February 25, 2025, 7:47pm UTC](https://community.cesium.com/t/osm-buildings-windows-orientation-problem-with-true-origin-enabled/38877/3 "2025-02-25T19:47:31Z")

</div>

@Kevin_Ring thank you for the reply!

Here is what I came with now:  
In MF\_TriplanarWindows I inserted custom HLSL shader node:

 ![custom node inserted in the 'beginning' of MF_TriplanarWindows](https://global.discourse-cdn.com/cesium/original/3X/7/f/7f02227aadec7c18a2ba34d2b871979021425320.png)  
the idea was:

1. Define radii constants inside shader
2. Get pixel in UE world space (AbsoluteWorldPosition node)
3. Transform it’s coordinates from unreal space to ECEF
4. Find rotation matrix that would “snap” current pixel position to normal in ECEF
5. Apply transformation  
and after that send this back to the other nodes.

Here is HLSL code:

```auto
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)

 ![Uncorrected shader](https://global.discourse-cdn.com/cesium/original/3X/e/4/e4131b7654873288f6018d158874355506e5ab66.jpeg)  
 !["Corrected" shader](https://global.discourse-cdn.com/cesium/original/3X/2/e/2e3fa9aa77a6ee15794c8afabf515e3ea206cd64.jpeg)

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.

---

<div class="post-metadata">

**Author:** ![Kevin\_Ring](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/kevin_ring/32/2003_2.png) [@Kevin\_Ring](https://community.cesium.com/u/Kevin_Ring)\
**Post date:** [March 3, 2025, 11:12am UTC](https://community.cesium.com/t/osm-buildings-windows-orientation-problem-with-true-origin-enabled/38877/4 "2025-03-03T11:12:26Z")

</div>

I think you have the right idea, but the transform is not quite right. I would suggest taking a look at this function and porting it to HLSL:

> <https://github.com/CesiumGS/cesium-unreal/blob/v2.14.0/Source/CesiumRuntime/Private/GeoTransforms.cpp#L203>

The inverse of the matrix returned by that function will take a position from Unreal world coordinates to a system centered at the given position where X points East, Y points South, and Z points Up. You could potentially even compute that on the CPU based on the camera position, and then pass it to the material using a Material Parameter Collection.
