I am creating a 3D spherical curved display (only a part of a sphere). The camera usually is inside of this sphere. This display has texture coordinates. The image below shows the display with its texture coordinates.

enter image description here

The method to generate the geometry (mesh) receives 4 parameters. These parameters are direction vectors which are pointing at the corners of the display. topLeftCorner, bottomLeftCorner, topRightCorner and bottomRightCorner.

I calculated the position / normal / texture coordinates in the following way:

Eigen::Quaternionf topLeft(0,topLeftCorner.x(), topLeftCorner.y(), topLeftCorner.z());
Eigen::Quaternionf topRight(0,topRightCorner.x(), topRightCorner.y(), topRightCorner.z());
Eigen::Quaternionf bottomLeft(0,bottomLeftCorner.x(), bottomLeftCorner.y(), bottomLeftCorner.z());
Eigen::Quaternionf bottomRight(0,bottomRightCorner.x(), bottomRightCorner.y(), bottomRightCorner.z());

//calculate vertexData
unsigned long long counter = 0;
for (int y = 0; y <= countSegmentsVertical; ++y)
    Eigen::Quaternionf slerpedQuaternionHorizontalLeft = bottomLeft.slerp(static_cast<float>(y) / static_cast<float>(countSegmentsVertical), topLeft);
    Eigen::Quaternionf slerpedQuaternionHorizontalRight = bottomRight.slerp(static_cast<float>(y) / static_cast<float>(countSegmentsVertical), topRight);

    for (int x = 0; x <= countSegmentsHorizontal; ++x)
        Eigen::Quaternionf slerpedQuaternionVertical = slerpedQuaternionHorizontalRight.slerp(static_cast<float>(x) / static_cast<float>(countSegmentsHorizontal),slerpedQuaternionHorizontalLeft);
        Eigen::Vector3f position = slerpedQuaternionVertical * Eigen::Vector3f(0,0,-1);
        position *= radius;

        data[counter].positionX = position.x();
        data[counter].positionY = position.y();
        data[counter].positionZ = position.z();
        data[counter].normalX = -position.x()/m_radius;
        data[counter].normalY = -position.y()/m_radius;
        data[counter].normalZ = -position.z()/m_radius;
        data[counter].textureCoordinateU = 1 - static_cast<float>(x) / static_cast<float>(countSegmentsHorizontal);
        data[counter].textureCoordinateV = static_cast<float>(y) / static_cast<float>(countSegmentsVertical);

short description: by slerping between topLeft and bottomLeft, I receive the left position (P0). by slerping between topRight and bottomRight, I receive the right position (P1). by slerping between left and right position, I receive the final position (P2). The next image illustrates this enter image description here

so far, everything is working fine. Lets go to the problem: Now I need to invert the problematic: having the four corners and a 3D point on the sphere (P2 in world coordinates). Lets call this point P'. The result should be the P2 texture coordinates.

My idea is to invert both vertical slerps with an quaternion (P') which is not lying exactly between the corners. If this is possible (I don't know), the next step would be to invert the horizontal slerp. the result should be the texture coordinate P2.

I am not sure if this is possible in this way, so maybe there is an other maybe easier way to calculate the point P' in texture coordinates.

BTW: The four corner vectors which form the geometry can be totally different than this image shows. So there is no way to say "Okay, in world coordinates you first can look at the Y coordinate and somehow match the value to the corners", because this display can be rotated around each axis, scale in horizontal and vertical angle or even don't be "rectangular" at all.

  • $\begingroup$ If the four corners can really be arbitrary (non rectangular) then I think you'll have to derive something akin to inverse bilinear interpolation, but using slerps instead of lerps. $\endgroup$ Sep 2, 2020 at 23:58


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.