Crear una malla curva en el interior de la esfera basada en coordenadas de imagen de textura

8

En Blender, he creado una esfera con una textura panorámica en el interior. También he creado manualmente una malla plana (curva para que coincida con el tamaño de la esfera) que se sienta en la pared interior donde puedo dibujar una textura diferente.

Esto es genial, pero realmente quiero reducir el trabajo manual y hacer parte de este trabajo en un guión, como tener una variable para la imagen panorámica y las coordenadas del área en la fotografía que quiero reemplazar con una nueva malla.

La parte más difícil de hacer esto será crear una malla curva en código que pueda ubicarse en la pared interior de una esfera.

¿Alguien puede señalarme en la dirección correcta?

usuario5025
fuente
¿Puedes dar más detalles sobre lo que te gustaría que suceda con menos esfuerzo? ¿Explica tu método actual y tu resultado final con más detalle?
Seth Battin
Además, ¿por qué estas dos mallas necesitan interactuar? ¿Podría simplemente especificar el tamaño y las coordenadas de la malla interna y dibujarla donde sea necesario? ¿Por qué necesita especificarse en términos de la esfera externa?
Seth Battin
Me gustaría poder mapear una imagen equirectangular en el interior de una esfera y hacer que los marcos rectangulares (en la imagen) contengan imágenes dinámicas. Sin embargo, no quiero recrear todo desde cero cada vez que quiero introducir una nueva imagen equirectangular ... Para que sea más fácil, me gustaría tomar la imagen aplanada y usar algo como Photoshop para encontrar el xy coordenadas de un marco de imagen, y tienen una nueva malla que se contrae envuelta a la esfera que corresponde a esas coordenadas 2d.
user5025
¿Eres consciente de que Unity admite skyboxes? Parece que eso es lo que estás tratando de lograr.
MichaelHouse
Soy consciente de los skyboxes, pero desafortunadamente no resuelve mi problema. Necesito una forma de crear una malla curva (que se asentará perfectamente en el interior de una esfera), basada en las coordenadas de un marco de imagen en una imagen equirectangular.
user5025

Respuestas:

0

Lo que intenta lograr parece estar muy relacionado con esto:

Análogo de coordenadas esféricas en n dimensiones

en su caso en 2 dimensiones, simplemente use esta fórmula para mapear los vértices del rectángulo que tiene (esperemos que esté subdividido) en su esfera (no olvide multiplicar por el medio diámetro en alguna parte. Solo los matemáticos viven en una esfera unitaria) las personas decentes usan diámetros ...)

EDITAR: Como todo esto es un poco vago, doy algunas ideas más Lo que necesita de esta fórmula para ser utilizado:

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

θ y φ son las coordenadas esféricas que está buscando (Latitud y Longitud) para obtenerlo, toma las coordenadas x / y de los puntos en una parte de la imagen 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

entonces obtendría su quad mapeado en una esfera basada en su posición xy en un sistema de coordenadas 2D traducido a la posición 3D en el espacio de acuerdo con el mapeo de la esfera.

EDITAR: Acabo de tener una idea, para ir más allá, podría encapsular las coordenadas del plano en la esfera utilizando valores UV como tales:

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

Allí podría administrar la posición cuádruple en su software 3D favorito (o incluso por código a través de la unidad) simplemente asignando valores UV (si de 0 a 1 en ambos ejes, entonces el quad se envolverá alrededor de la esfera)

ADVERTENCIA: El uso de UV requerirá que realice una conversión de radianes a grados. (como UV es de 0 a 1)

Géry Arduino
fuente
0

La respuesta de Géry Arduino anterior me señaló en la dirección correcta, pero me gustaría agregar un par de cosas aquí.

1) El seguimiento no funcionará en unidad debido a las diferencias del sistema de coordenadas

    return new Vector3(x,y,z); 

cambia esto a

    return new Vector3(x,z,y);

2) No estaba claro en el rango de entrada de valores largos y lat definidos en la firma del método

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

Los valores de longitud y latitud deben estar en radianes. Su rango es el siguiente

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