Преобразование 2:1 эквидистантная панорама на Кубе карте

Я'м работает на простого зрителя 3D панорама на сайте. Для мобильного исполнения причин, почему я'м с помощью three.js` рендера с помощью CSS3. Для этого нужна карта куб, разделенный на 6 отдельных изображений.

Я'м запись изображения на iPhone с Google Android Скачать приложения, или подобные программы, которые создают 2:1 эквидистантные панорамы. Я потом изменить и преобразовать их в кубической карты с этого сайта: http://gonchar.me/panorama/ (вспышка)

Желательно, я'd, как, чтобы сделать преобразование себя, либо "на лету" в three.js, если это's возможные, или в фотошопе. Я нашел Андрея Hazelden'действия Photoshop, и они, кажется, довольно близко, но прямой конвертации доступен. Есть ли математический способ, чтобы преобразовать эти, или какой-то скрипт, который это делает? Я'd, как, чтобы избежать прохождения через 3D-приложения, такие как блендер, если это возможно.

Может быть, это длинный выстрел, но я думал, что я'д спросить. У меня есть хороший опыт с JavaScript, но я'м довольно новыми для three.js. Я'м также решаются полагаться на функциональность в WebGL, так как кажется, либо медленно или глючит на мобильных устройствах. Поддержка тоже еще не везде.

Комментарии к вопросу (2)
Решение

Если вы хотите сделать это на стороне сервера, есть много вариантов. http://www.imagemagick.org/ имеет кучу инструментов командной строки, которые можно нарезать изображение на куски. Можно поставить команду, чтобы сделать это в сценарий, и просто запустить, что каждый раз у вас новый имидж.

Трудно сказать совсем какой алгоритм используется в программе. Мы можем попытаться перепроектировать совсем то, что происходит при подаче квадратной сетке в программу. Я'вэ использовал сетка из Википедии

Что дает . это дает нам ключ к пониманию того, как построена коробка.

Визуализация сферы с линиями широты и долготы, один он, и куб вокруг него. Сейчас проект с точки в центре сферы производит искаженной сетки на куб.

Математически взять полярных координатах R, θ, ø, для сферы Р=1, 0 < θ < π, -π/4 < ø < 7π/4

  • х= р грех θ соѕ ø
  • г= р грех θ грех ø
  • З= Р COS и

в центре проекта на Кубе. Сначала мы разделим на четыре региона по широте -π/4 < ø < π/4, π/4 < ø < 3π/4, 3π/4 < ø < 5π/4, 5π/4 < ø < 7π/4. Это будет либо проект к одной из четырех сторон верхней или нижней части.

Предположим, что мы находимся в первой стороне -π/4 < ø < π/4. Центральная проекция (грех θ потому что ø, грех θ грех ø, COS и) будет (грех θ потому что ø, грех θ грех ø, значение cos θ), которая попадает в Х=1 самолет, когда

  • грех θ соѕ ø = 1

так

  • а = 1 / (грех θ соз ø)

и прогнозируемая точка

  • (1, Тан ø, кроватка θ / соѕ ø)

Если кроватка θ / соѕ ø | < 1 это будет на передней грани. В противном случае, она будет проецироваться на верхней или нижней, и вы будете нуждаться в другой проекции для этого. Лучшего теста для верхнего используется тот факт, что минимальное значение функции COS ø будет Косинус π/4 = 1/√2, поэтому проекции точки всегда на высоте если кроватка θ / (1/√2) > 1 или Tan θ < 1/√2. Это работает как θ < 35º или 0.615 радианах.

Положить это вместе в Python

import sys
from PIL import Image
from math import pi,sin,cos,tan

def cot(angle):
    return 1/tan(angle)

# Project polar coordinates onto a surrounding cube
# assume ranges theta is [0,pi] with 0 the north poll, pi south poll
# phi is in range [0,2pi] 
def projection(theta,phi): 
        if theta2.527:
            return projectBottom(theta,phi)
        elif phi  7*pi/4:
            return projectLeft(theta,phi)
        elif phi > pi/4 and phi  3*pi/4 and phi  5*pi/4 and phi  1:
            return projectTop(theta,phi)
        return ("Left",x,y,z)

def projectFront(theta,phi):
        x = tan(phi-pi/2)
        y = 1
        z = cot(theta) / cos(phi-pi/2)
        if z < -1:
            return projectBottom(theta,phi)
        if z > 1:
            return projectTop(theta,phi)
        return ("Front",x,y,z)

def projectRight(theta,phi):
        x = -1
        y = tan(phi)
        z = -cot(theta) / cos(phi)
        if z < -1:
            return projectBottom(theta,phi)
        if z > 1:
            return projectTop(theta,phi)
        return ("Right",x,-y,z)

def projectBack(theta,phi):
        x = tan(phi-3*pi/2)
        y = -1
        z = cot(theta) / cos(phi-3*pi/2)
        if z < -1:
            return projectBottom(theta,phi)
        if z > 1:
            return projectTop(theta,phi)
        return ("Back",-x,y,z)

def projectTop(theta,phi):
        # (a sin θ cos ø, a sin θ sin ø, a cos θ) = (x,y,1)
        a = 1 / cos(theta)
        x = tan(theta) * cos(phi)
        y = tan(theta) * sin(phi)
        z = 1
        return ("Top",x,y,z)

def projectBottom(theta,phi):
        # (a sin θ cos ø, a sin θ sin ø, a cos θ) = (x,y,-1)
        a = -1 / cos(theta)
        x = -tan(theta) * cos(phi)
        y = -tan(theta) * sin(phi)
        z = -1
        return ("Bottom",x,y,z)

# Convert coords in cube to image coords 
# coords is a tuple with the side and x,y,z coords
# edge is the length of an edge of the cube in pixels
def cubeToImg(coords,edge):
    if coords[0]=="Left":
        (x,y) = (int(edge*(coords[2]+1)/2), int(edge*(3-coords[3])/2) )
    elif coords[0]=="Front":
        (x,y) = (int(edge*(coords[1]+3)/2), int(edge*(3-coords[3])/2) )
    elif coords[0]=="Right":
        (x,y) = (int(edge*(5-coords[2])/2), int(edge*(3-coords[3])/2) )
    elif coords[0]=="Back":
        (x,y) = (int(edge*(7-coords[1])/2), int(edge*(3-coords[3])/2) )
    elif coords[0]=="Top":
        (x,y) = (int(edge*(3-coords[1])/2), int(edge*(1+coords[2])/2) )
    elif coords[0]=="Bottom":
        (x,y) = (int(edge*(3-coords[1])/2), int(edge*(5-coords[2])/2) )
    return (x,y)

# convert the in image to out image
def convert(imgIn,imgOut):
    inSize = imgIn.size
    outSize = imgOut.size
    inPix = imgIn.load()
    outPix = imgOut.load()
    edge = inSize[0]/4   # the length of each edge in pixels
    for i in xrange(inSize[0]):
        for j in xrange(inSize[1]):
            pixel = inPix[i,j]
            phi = i * 2 * pi / inSize[0]
            theta = j * pi / inSize[1]
            res = projection(theta,phi)
            (x,y) = cubeToImg(res,edge)
            #if i % 100 == 0 and j % 100 == 0:
            #   print i,j,phi,theta,res,x,y
            if x >= outSize[0]:
                #print "x out of range ",x,res
                x=outSize[0]-1
            if y >= outSize[1]:
                #print "y out of range ",y,res
                y=outSize[1]-1
            outPix[x,y] = pixel

imgIn = Image.open(sys.argv[1])
inSize = imgIn.size
imgOut = Image.new("RGB",(inSize[0],inSize[0]*3/4),"black")
convert(imgIn,imgOut)
imgOut.show()

В проекции функция принимает тэта и значений фи и возвращает координаты в Кубе от -1 до 1 в каждом направлении. В cubeToImg берет (х,у,Z) координат и преобразует их в выходной координаты изображения.

Этот алгоритм, кажется, сделать геометрию право использовать изображение Букингемского дворца, мы получаем Это, кажется, сделать большинство линий в правой мощения.

Мы получаем несколько артефактов изображения. Это из-за того, что 1 на 1 карту пикселей. Что нам нужно сделать, это использовать обратное преобразование. А чем цикл через каждый пиксель в исходном и найти соответствующий пиксель в цель, мы петле через целевые изображения и найти ближайший исходного пикселя.

import sys
from PIL import Image
from math import pi,sin,cos,tan,atan2,hypot,floor
from numpy import clip

# get x,y,z coords from out image pixels coords
# i,j are pixel coords
# face is face number
# edge is edge length
def outImgToXYZ(i,j,face,edge):
    a = 2.0*float(i)/edge
    b = 2.0*float(j)/edge
    if face==0: # back
        (x,y,z) = (-1.0, 1.0-a, 3.0 - b)
    elif face==1: # left
        (x,y,z) = (a-3.0, -1.0, 3.0 - b)
    elif face==2: # front
        (x,y,z) = (1.0, a - 5.0, 3.0 - b)
    elif face==3: # right
        (x,y,z) = (7.0-a, 1.0, 3.0 - b)
    elif face==4: # top
        (x,y,z) = (b-1.0, a -5.0, 1.0)
    elif face==5: # bottom
        (x,y,z) = (5.0-b, a-5.0, -1.0)
    return (x,y,z)

# convert using an inverse transformation
def convertBack(imgIn,imgOut):
    inSize = imgIn.size
    outSize = imgOut.size
    inPix = imgIn.load()
    outPix = imgOut.load()
    edge = inSize[0]/4   # the length of each edge in pixels
    for i in xrange(outSize[0]):
        face = int(i/edge) # 0 - back, 1 - left 2 - front, 3 - right
        if face==2:
            rng = xrange(0,edge*3)
        else:
            rng = xrange(edge,edge*2)

        for j in rng:
            if j=2*edge:
                face2 = 5 # bottom
            else:
                face2 = face

            (x,y,z) = outImgToXYZ(i,j,face2,edge)
            theta = atan2(y,x) # range -pi to pi
            r = hypot(x,y)
            phi = atan2(z,r) # range -pi/2 to pi/2
            # source img coords
            uf = ( 2.0*edge*(theta + pi)/pi )
            vf = ( 2.0*edge * (pi/2 - phi)/pi)
            # Use bilinear interpolation between the four surrounding pixels
            ui = floor(uf)  # coord of pixel to bottom left
            vi = floor(vf)
            u2 = ui+1       # coords of pixel to top right
            v2 = vi+1
            mu = uf-ui      # fraction of way across pixel
            nu = vf-vi
            # Pixel values of four corners
            A = inPix[ui % inSize[0],clip(vi,0,inSize[1]-1)]
            B = inPix[u2 % inSize[0],clip(vi,0,inSize[1]-1)]
            C = inPix[ui % inSize[0],clip(v2,0,inSize[1]-1)]
            D = inPix[u2 % inSize[0],clip(v2,0,inSize[1]-1)]
            # interpolate
            (r,g,b) = (
              A[0]*(1-mu)*(1-nu) + B[0]*(mu)*(1-nu) + C[0]*(1-mu)*nu+D[0]*mu*nu,
              A[1]*(1-mu)*(1-nu) + B[1]*(mu)*(1-nu) + C[1]*(1-mu)*nu+D[1]*mu*nu,
              A[2]*(1-mu)*(1-nu) + B[2]*(mu)*(1-nu) + C[2]*(1-mu)*nu+D[2]*mu*nu )

            outPix[i,j] = (int(round(r)),int(round(g)),int(round(b)))

imgIn = Image.open(sys.argv[1])
inSize = imgIn.size
imgOut = Image.new("RGB",(inSize[0],inSize[0]*3/4),"black")
convertBack(imgIn,imgOut)
imgOut.save(sys.argv[1].split('.')[0]+"Out2.png")
imgOut.show()

Результаты этого стоят

Комментарии (13)

Учитывая отличную принято отвечать, я хотел бы добавить мой соответствующий реализации C++, исходя из рад.

Для тех, кто не знаком с OpenCV, думать мать в качестве изображения. Мы сначала построим две карты, которые перераспределяют от изображения эквидистантная в соответствующих кубической карты лицо. Затем, мы делаем тяжелую работу (т. е. сопоставление с интерполяцией) с помощью OpenCV.

Код можно сделать более компактным, если читаемость не вызывает опасений.

// Define our six cube faces. 
// 0 - 3 are side faces, clockwise order
// 4 and 5 are top and bottom, respectively
float faceTransform[6][2] = 
{ 
    {0, 0},
    {M_PI / 2, 0},
    {M_PI, 0},
    {-M_PI / 2, 0},
    {0, -M_PI / 2},
    {0, M_PI / 2}
};

// Map a part of the equirectangular panorama (in) to a cube face
// (face). The ID of the face is given by faceId. The desired
// width and height are given by width and height. 
inline void createCubeMapFace(const Mat &in, Mat &face, 
        int faceId = 0, const int width = -1, 
        const int height = -1) {

    float inWidth = in.cols;
    float inHeight = in.rows;

    // Allocate map
    Mat mapx(height, width, CV_32F);
    Mat mapy(height, width, CV_32F);

    // Calculate adjacent (ak) and opposite (an) of the
    // triangle that is spanned from the sphere center 
    //to our cube face.
    const float an = sin(M_PI / 4);
    const float ak = cos(M_PI / 4);

    const float ftu = faceTransform[faceId][0];
    const float ftv = faceTransform[faceId][1];

    // For each point in the target image, 
    // calculate the corresponding source coordinates. 
    for(int y = 0; y < height; y++) {
        for(int x = 0; x < width; x++) {

            // Map face pixel coordinates to [-1, 1] on plane
            float nx = (float)y / (float)height - 0.5f;
            float ny = (float)x / (float)width - 0.5f;

            nx *= 2;
            ny *= 2;

            // Map [-1, 1] plane coords to [-an, an]
            // thats the coordinates in respect to a unit sphere 
            // that contains our box. 
            nx *= an; 
            ny *= an; 

            float u, v;

            // Project from plane to sphere surface.
            if(ftv == 0) {
                // Center faces
                u = atan2(nx, ak);
                v = atan2(ny * cos(u), ak);
                u += ftu; 
            } else if(ftv > 0) { 
                // Bottom face 
                float d = sqrt(nx * nx + ny * ny);
                v = M_PI / 2 - atan2(d, ak);
                u = atan2(ny, nx);
            } else {
                // Top face
                float d = sqrt(nx * nx + ny * ny);
                v = -M_PI / 2 + atan2(d, ak);
                u = atan2(-ny, nx);
            }

            // Map from angular coordinates to [-1, 1], respectively.
            u = u / (M_PI); 
            v = v / (M_PI / 2);

            // Warp around, if our coordinates are out of bounds. 
            while (v < -1) {
                v += 2;
                u += 1;
            } 
            while (v > 1) {
                v -= 2;
                u += 1;
            } 

            while(u < -1) {
                u += 2;
            }
            while(u > 1) {
                u -= 2;
            }

            // Map from [-1, 1] to in texture space
            u = u / 2.0f + 0.5f;
            v = v / 2.0f + 0.5f;

            u = u * (inWidth - 1);
            v = v * (inHeight - 1);

            // Save the result for this pixel in map
            mapx.at(x, y) = u;
            mapy.at(x, y) = v; 
        }
    }

    // Recreate output image if it has wrong size or type. 
    if(face.cols != width || face.rows != height || 
        face.type() != in.type()) {
        face = Mat(width, height, in.type());
    }

    // Do actual resampling using OpenCV's remap
    remap(in, face, mapx, mapy, 
         CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));
}

Учитывая следующие данные:

Следующие лица создаются:

Изображение предоставлено Optonaut.

Комментарии (2)

Я написал скрипт, чтобы отрезать автоматически кубической карты на отдельные файлы (параметра posx.ПНГ, negx.ПНГ букет.ПНГ, negy.ПНГ, posz.PNG и negz.ПНГ). Он также будет упакуйте 6 файлов в один .zip-файл.

Источник здесь: https://github.com/dankex/compv/blob/master/3d-graphics/skybox/cubemap-cut.py

Вы можете изменять массив в набор файлов изображения:

name_map = [ \
 ["", "", "posy", ""],
 ["negz", "negx", "posz", "posx"],
 ["", "", "negy", ""]]

Преобразованные файлы:

Комментарии (0)

Здесь'ы (наивно) модифицированная версия Ива Альба'ы совершенно фантастический ответ, который преобразует одно лицо за раз, выплевывает шесть различных изображений и сохраняет оригинальный образ'ы тип файла.

Кроме того, большинство случаев, вероятно, ожидать шесть отдельных изображений, главным преимуществом преобразования одно лицо за раз заключается в том, что она позволяет работать с огромными изображениями намного меньше памяти.

#!/usr/bin/env python
import sys
from PIL import Image
from math import pi, sin, cos, tan, atan2, hypot, floor
from numpy import clip

# get x,y,z coords from out image pixels coords
# i,j are pixel coords
# faceIdx is face number
# faceSize is edge length
def outImgToXYZ(i, j, faceIdx, faceSize):
    a = 2.0 * float(i) / faceSize
    b = 2.0 * float(j) / faceSize

    if faceIdx == 0: # back
        (x,y,z) = (-1.0, 1.0 - a, 1.0 - b)
    elif faceIdx == 1: # left
        (x,y,z) = (a - 1.0, -1.0, 1.0 - b)
    elif faceIdx == 2: # front
        (x,y,z) = (1.0, a - 1.0, 1.0 - b)
    elif faceIdx == 3: # right
        (x,y,z) = (1.0 - a, 1.0, 1.0 - b)
    elif faceIdx == 4: # top
        (x,y,z) = (b - 1.0, a - 1.0, 1.0)
    elif faceIdx == 5: # bottom
        (x,y,z) = (1.0 - b, a - 1.0, -1.0)

    return (x, y, z)

# convert using an inverse transformation
def convertFace(imgIn, imgOut, faceIdx):
    inSize = imgIn.size
    outSize = imgOut.size
    inPix = imgIn.load()
    outPix = imgOut.load()
    faceSize = outSize[0]

    for xOut in xrange(faceSize):
        for yOut in xrange(faceSize):
            (x,y,z) = outImgToXYZ(xOut, yOut, faceIdx, faceSize)
            theta = atan2(y,x) # range -pi to pi
            r = hypot(x,y)
            phi = atan2(z,r) # range -pi/2 to pi/2

            # source img coords
            uf = 0.5 * inSize[0] * (theta + pi) / pi
            vf = 0.5 * inSize[0] * (pi/2 - phi) / pi

            # Use bilinear interpolation between the four surrounding pixels
            ui = floor(uf)  # coord of pixel to bottom left
            vi = floor(vf)
            u2 = ui+1       # coords of pixel to top right
            v2 = vi+1
            mu = uf-ui      # fraction of way across pixel
            nu = vf-vi

            # Pixel values of four corners
            A = inPix[ui % inSize[0], clip(vi, 0, inSize[1]-1)]
            B = inPix[u2 % inSize[0], clip(vi, 0, inSize[1]-1)]
            C = inPix[ui % inSize[0], clip(v2, 0, inSize[1]-1)]
            D = inPix[u2 % inSize[0], clip(v2, 0, inSize[1]-1)]

            # interpolate
            (r,g,b) = (
              A[0]*(1-mu)*(1-nu) + B[0]*(mu)*(1-nu) + C[0]*(1-mu)*nu+D[0]*mu*nu,
              A[1]*(1-mu)*(1-nu) + B[1]*(mu)*(1-nu) + C[1]*(1-mu)*nu+D[1]*mu*nu,
              A[2]*(1-mu)*(1-nu) + B[2]*(mu)*(1-nu) + C[2]*(1-mu)*nu+D[2]*mu*nu )

            outPix[xOut, yOut] = (int(round(r)), int(round(g)), int(round(b)))

imgIn = Image.open(sys.argv[1])
inSize = imgIn.size
faceSize = inSize[0] / 4
components = sys.argv[1].rsplit('.', 2)

FACE_NAMES = {
  0: 'back',
  1: 'left',
  2: 'front',
  3: 'right',
  4: 'top',
  5: 'bottom'
}

for face in xrange(6):
  imgOut = Image.new("RGB", (faceSize, faceSize), "black")
  convertFace(imgIn, imgOut, face)
  imgOut.save(components[0] + "_" + FACE_NAMES[face] + "." + components[1])
Комментарии (0)

Нашел этот вопрос, и даже если ответы хорошие, я думаю, есть еще некоторые раскрыты, так что вот мои два цента.

Во-первых: если у вас действительно есть для преобразования изображений сами (т. е. из-за некоторых конкретных требований программного обеспечения), Дон'т.

Причина в том, что, хотя есть очень простое сопоставление между эквидистантная проекция и кубической проекции, отображение между областями не просто: когда вы установить соответствие между конкретной точкой вашего пункта назначения, изображения и точку в источнике с элементарный расчет, как только вы преобразовать обе точки в пикселях, округляя тебя очень исходные приближения это вовсе'т считаю размер пикселей, и качество изображения обязан быть низким.

Во-вторых: даже если вам нужно сделать преобразование во время выполнения, вы уверены, что вам нужно сделать преобразование на всех? Если есть некоторые очень жесткие проблемы с производительностью, если вам просто нужен скайбокс, создают очень большой сферы, сшить эквидистантной texure на него, и от вас идут. Три JS обеспечивает сфера уже, насколько я помню ;-)

В-третьих: НАСА предоставляет инструмент для преобразования между все мыслимые прогнозы (я только что узнал, испытал его, и работает как шарм). Вы можете найти его здесь:

Проектор Г. — Глобальный Проектор Карта

и я считаю разумным думать, что ребята знают, что они делают ;-)

Надеюсь, что это помогает

Обновление: получается, что "парней" И знаете, что они делают до какого-то момента: созданный кубической карты имеет отвратительную границу, которая делает преобразование не так просто...

Обновление 2: нашли окончательным инструментом для эквидистантной к кубической карты преобразования, и это's посетило erect2cubic.

Это'ы небольшая утилита, которая создает скрипт, который нужно скормить Хугин, таким образом:

$ erect2cubic --erect=input.png --ptofile=cube.pto
$ nona -o cube_prefix cube.pto 

(информация почерпнутая из Винай'ов хаки Страница)

и будет генерировать все 6 граней кубической карты. Я'м использовать его для моего проекта, и это работает!

Единственным недостатком этого подхода является то, что erect2cubit скрипт `она's не в стандартном дистрибутиве Ubuntu (что я'м через) и мне пришлось прибегнуть к инструкции в этой ссылке:

Блог с описанием как установить и использовать erect2cubic

чтобы узнать, как установить его.

Полностью стоит!

Комментарии (0)

сайт cmft студия преобразование поддерживает фильтрации различных прогнозы РВБ/ЛДР до cubemaps.

https://github.com/dariomanesku/cmftStudio

Комментарии (0)

Здесь'с JavaScript-версию Benjamn Добелл's код. В convertFace необходимо пройти два `ìобъекты mageData и лицо удостоверение (0-6).

Предоставленный код можно смело использовать в веб-работник, поскольку она не имеет зависимостей.


        // convert using an inverse transformation
        function convertFace(imgIn, imgOut, faceIdx) {
            var inPix = shimImgData(imgIn),
                        outPix = shimImgData(imgOut),
                        faceSize = imgOut.width,
                        pi = Math.PI,
                        pi_2 = pi/2;

            for(var xOut=0;xOut
Комментарии (0)

Https://github.com/denivip/panorama очень простое приложение c++, которая преобразует эквидистантная панорама куб карты на основе ответа на Ива Альба =>

Комментарии (2)

Возможно, я что-то пропустил. Но кажется, что большинство, если не все представлены код трансформации может быть несколько некорректно. Они принимают сферическую панораму (эквидистантная --- 360 градусов по горизонтали и 180 градусов по вертикали) и, кажется, преобразуются в грани куба, используя декартово <-> цилиндрические трансформации. Они не должны использовать декартово <-> сферические трансформации. См http://mathworld.wolfram.com/SphericalCoordinates.html

Я полагаю, что пока они обратного расчета от кубик в панораму, то она должна отработать. Но изображения лиц куб может незначительно отличаться при использовании сферического преобразования.

Если я начну с этого эквидистантная (сферическая панорама):

Тогда, если я использую цилиндрические преобразования (что я не 100% уверен, что это правильно в этот раз), я получаю такой результат:

Но если я использую сферической трансформации, я получаю такой результат:

Они не то же самое. Но мой сферический результате преобразования, кажется, совпадает с результатом Данке се, но его ссылка не показать таким преобразованиям, которые он использует, насколько я могу прочитать его.

Так что я недоразумение кода используется многие из участников этой темы?

Комментарии (0)

Я создал решение для этой проблемы с использованием OpenGL и сделали инструмент командной строки вокруг него. Он работает как с изображениями и видео, и это самый быстрый инструмент, который я нашел там.

Convert360 - проект на GitHub.

В OpenGL шейдеров - фрагмент шейдер, используемый для перепроецирования.

Использование такое же простое, как:

$ pip install convert360
$ convert360 -i ~/Pictures/Barcelona/sagrada-familia.jpg -o example.png -s 300 300

Чтобы получить что-то вроде этого:

Комментарии (0)

Существуют различные представления карты окружающей среды. Здесь хороший обзор.

Обзор - Панорамные Изображения

Если вы используете фотосферы (или любое приложение панорамы на то пошло), вы, вероятно, уже имеют горизонтальный широта / долгота представление. Затем вы можете просто нарисовать текстурированный three.js SphereGeometry. Вот учебник о том, как визуализировать землю.

Туториал - как сделать Землю в WebGL?

Удачи :).

Комментарии (0)