Criando uma malha curvada dentro da esfera com base nas coordenadas da imagem da textura

8

No Blender, criei uma esfera com uma textura panorâmica por dentro. Também criei manualmente uma malha plana (curvada para corresponder ao tamanho da esfera) que fica na parede interna, onde posso desenhar uma textura diferente.

Isso é ótimo, mas eu realmente quero reduzir o trabalho manual e fazer parte desse trabalho em um script - como ter uma variável para a imagem panorâmica e coordenadas da área na fotografia que quero substituir por uma nova malha.

A parte mais difícil de fazer isso será criar uma malha curvada no código que possa ficar na parede interna de uma esfera.

Alguém pode me apontar na direção certa?

user5025
fonte
Você pode elaborar o que gostaria que acontecesse com menos esforço? Explique seu método atual e seu resultado final com mais detalhes?
perfil completo de Seth Battin
Além disso, por que essas duas malhas precisam interagir? Você poderia simplesmente especificar o tamanho e as coordenadas da malha interna e desenhá-la onde quer que fosse? Por que ele precisa ser especificado em termos da esfera externa?
perfil completo de Seth Battin
Eu gostaria de poder mapear uma imagem equiretangular no interior de uma esfera e fazer com que os quadros de imagem retangulares (na imagem) contenham imagens dinâmicas. No entanto, não quero recriar tudo desde o início sempre que apresentar uma nova imagem equiretangular ... Para facilitar, gostaria de tirar a imagem achatada e usar algo como o photoshop para encontrar o coordenadas xy de um quadro de imagem e uma nova malha que se encolhe envolto na esfera que corresponde às coordenadas 2D.
user5025
Você está ciente de que o Unity suporta skyboxes? Parece que é isso que você está tentando alcançar.
MichaelHouse
Estou ciente das caixas de sky, mas infelizmente não resolve o meu problema. Preciso de uma maneira de criar uma malha curva (que ficará perfeitamente no interior de uma esfera), com base nas coordenadas de uma moldura em uma imagem retangular.
user5025

Respostas:

0

O que você está tentando alcançar parece muito relacionado a isso:

Análogo de coordenadas esféricas em dimensões n

no seu caso, em 2 dimensões, basta usar esta fórmula para mapear os vértices do retângulo que você possui (vamos torcer para que ele seja subdividido) em sua esfera (não se esqueça de multiplicar pelo halfDiameter em algum lugar. Somente matemáticos estão vivendo em uma esfera unitária todos os outros pessoas decentes estão usando diâmetros ...)

EDIT: Como tudo isso é um pouco vago, dou mais algumas idéias O que você precisa desta fórmula para ser usado:

x = r*sinθ*cosφ
y = r*sinθ*sinφ
z = r*cosθ

Sendo θ e φ as coordenadas esféricas que você está procurando (Latitude e Longitude) para obtê-lo, você pega as coordenadas x / y dos pontos na parte da imagem panorâmica como tal:

public Void getPointPosOnSphere(float Longitude,float Latitude,float r) {
    x = r*Mathf.sin(Longitude)*Mathf.cos(Latitude);
    y = r*Mathf.sin(Longitude)*Mathf.sin(Latitude);
    z = r*Mathf.cos(Longitude);
    return new Vector3(x,y,z);
}

//here you could have a for loop iterating through points of your rectangle for each
//point you'd have associated a map coordinate :
Vector3 pointSpacePos = getPointPosOnSphere(pointCoordY,pointCoordX,HalfDiamater);
//End of the for loop

você mapeará seu quad em uma esfera com base em sua posição xy em um sistema de coordenadas 2D convertido para a posição 3D no espaço de acordo com o mapeamento da esfera.

Edição: Acabei de ter uma idéia, para ir mais longe, você pode encapsular as coordenadas do plano na esfera usando valores UV, como tal:

for(int i = 0;i < vertices.Length; i++) {
    vertices[i] = getPointPosOnSphere(UV[i].y,UV[i].x,HalfDiamater);
}

Lá você pode gerenciar a posição quad no seu software 3D favorito (ou mesmo através do código através da unidade) apenas atribuindo valores UV (se de 0 a 1 em ambos os eixos, o quad será envolvido em toda a esfera)

AVISO: O uso de UV exigirá a conversão de Radianos em Graus. (como UV é de 0 a 1)

Géry Arduino
fonte
0

A resposta de Géry Arduino acima me indicou a direção certa, mas eu gostaria de acrescentar algumas coisas aqui.

1) O seguinte não funcionará em unidade devido às diferenças do sistema de coordenadas

    return new Vector3(x,y,z); 

mude isso para

    return new Vector3(x,z,y);

2) Não fiquei claro quanto ao intervalo de entrada de valores longos e latinos definidos na assinatura do método

     public Void getPointPosOnSphere(float Longitude,float Latitude,float r)

Os valores de Longitude e Latitude devem estar em radianos. Seu alcance é o seguinte

     Longitude: 0°-180° (0 - π)
     Latitude: 0°-360° (0 - 2π)
Snakebyte
fonte