简体   繁体   English

在纹理球体上给定4个点,提取2d平面及其投影的纹理

[英]given 4 points on a textured sphere extract a 2d plane and it's projected texture

Setting the scene I'm working on a feature in scenekit where i have a camera at the center of a sphere. 设置场景我正在使用Scenekit中的某个功能,在该功能中,我在球体的中心有一个摄像头。 The sphere has a texture wrapped around it. 球体周围包裹着纹理。 Let's say it was a 360 degree image captured inside of a room. 假设这是在房间内部捕获的360度图像。

So far I have identified the positions on the sphere that correspond to the corners of the floor. 到目前为止,我已经确定了球面上与地板角对应的位置。 I can extract and create a new flat 2d plane that matches the dimensions of the floor from the camera's perspective. 我可以提取并创建一个新的平面2d平面,该平面与从相机的角度来看的地板尺寸相匹配。 Eg If the room had a long rectangular floor, I'd create a trapezoid shaped plane. 例如,如果房间的地板较长,我会创建一个梯形平面。

Problem But I would like for the new 2d plane to have the texture of the floor, not just the shape. 问题但是我希望新的2d平面具有地板的纹理,而不仅仅是形状。 How do I do this given that what I want to extract is not the original texture image, but the result of its projection onto the sphere? 考虑到我要提取的不是原始纹理图像,而是投影到球体上的结果,我该怎么做?

FYI I'm pretty new to scenekit and 3d graphics stuff and I'm even newer to opengl 仅供参考,我对Scenekit和3D图形工具还很陌生,而对opengl甚至还比较新

I assume that your image is structured in a way that lets you directly pick a pixel given an arbitrary direction. 我假设您的图像结构可以让您直接选择任意方向的像素。 Eg if the azimuth of the direction is mapped to the image's x-coordinate and the height of the direction to the image's y-coordinate, you would convert the direction to these parameters and pick the color at those coordinates. 例如,如果将方向的方位角映射到图像的x坐标,并将方向的高度映射到图像的y坐标,则可以将方向转换为这些参数,并在这些坐标处选择颜色。 If that is not the case, you have to find the intersection of the according ray (starting at the camera) with the sphere and find the texture coordinate at that intersection. 如果不是这种情况,则必须找到相应光线(从摄影机开始)与球体的交点,并找到该交点处的纹理坐标。 You can then pick the color using this texture coordinate. 然后,您可以使用此纹理坐标来选择颜色。

Now, you have basically two options. 现在,您基本上有两个选择。 The first option is generating a new texture for the plane. 第一种选择是为平面生成新的纹理。 The second option is sampling the spherical image from a shader. 第二个选项是从着色器采样球形图像。

Option 1 - Generate a new texture 选项1-生成新纹理

You know the extent of your plane, so you can generate a new texture whose dimensions are proportional to the plane's extents. 您知道平面的范围,因此可以生成新的纹理,其尺寸与平面的范围成比例。 You can use an arbitrary resolution. 您可以使用任意分辨率。 All you then need to do is fill the pixels of this texture. 然后,您需要做的就是填充此纹理的像素。 For this, you just generate the ray for a given pixel and find the according color in the spherical image like so: 为此,您只需生成给定像素的射线并在球面图像中找到相应的颜色,如下所示:

input: d1, d2, d3, d3 (the four direction vectors of the plane corners)
//  d3 +------+ d4
//  d1 +------+ d2
for x from 0 to texture width
    for y from 0 to texture height
        //Find the direction vector for this pixel through bilinear interpolation
        a = x / (width - 1) //horizontal interpolation parameter
        b = y / (height - 1) //vertical interpolation parameter
        d = (1 - a) * ((1 - b) * d1 + b * d3) + a * ((1 - b) * d2 + b * d4)
        normalize d
        //Sample the spherical image at d
        color = sample(d)
        //write the color to the new planar texture
        texture(x, y) = color
    next
next

Then, you have a new texture that you can apply to the plane. 然后,您可以将新纹理应用于平面。 Barycentric interpolation might be more appropriate if you express the plane as two triangles. 如果将平面表示为两个三角形,则重心插值可能更合适。 But as long as the plane is rectangular, the results will be the same. 但是,只要平面是矩形,结果将是相同的。

Note that the sample() method depends on your image structure and needs to be implemented appropriately. 请注意, sample()方法取决于您的图像结构,需要适当地实现。

Option 2 - Sample in a shader 选项2-在着色器中采样

In option 2, you do the same thing as in option 1. But you do it in a fragment shader. 在选项2中,您执行的操作与在选项1中相同。但是,您在片段着色器中进行了此操作。 You employ the vertices of the plane with their respective directions (this might be just the vertex position) and let the GPU interpolate them. 您使用平面的顶点及其各自的方向(这可能只是顶点位置),然后让GPU对其进行插值。 This gives you directly the direction d , which you can use. 这直接为您提供了方向d ,您可以使用它。 Here is some pseudo shader code: 这是一些伪着色器代码:

in vec3 direction;
out vec4 color;
void main()
{
    color = sample(normalize(direction));
}

If your image is a cube map, you can even let the GPU do the sampling. 如果您的图像是立方体贴图,您甚至可以让GPU进行采样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM