使用OpenGL在2D梯形中进行纹理的投影插值

fixmycode

我必须用投影机从计算机上显示的图像映射一个物理立方体。我立即意识到使用3D多维数据集和相机投影来尝试将虚拟图像拟合到真实对象上的问题,因此我决定简化该问题并使用多维数据集的2D表示并在2D空间中移动每个顶点直到它适合物体为止。该软件现已完成,除了一些细节:纹理。

我使用的是LWJGL,我的数据结构基于其文档中的一些示例。

我使用了7个顶点来表示2D空间中真实立方体的3个可见面,这将创建3个梯形(或不规则四边形)覆盖每个面,我将它们映射为您在此图像中看到的ST(或UV)坐标,请记住这一切都是二维的:

显示贴图坐标的测试纹理

这是一个代码块,我在其中将顶点数据加载到缓冲区中,并将它们全部以XYZWRGBASTPQ的顺序保存到VBO中(请注意,Z始终为0,默认情况下PQ为0,1):

vertices = new VertexData[7];
vertices[0] = new VertexData().setXY(0, 0).setST(0.5f, 0.5f);
vertices[1] = new VertexData().setXY(0.5f, 1f/3).setST(0.5f, 0);
vertices[2] = new VertexData().setXY(0, 2f/3).setST(0, 0);
vertices[3] = new VertexData().setXY(-0.5f, 1f/3).setST(0, 0.5f);
vertices[4] = new VertexData().setXY(-0.5f, -1f/3).setST(0, 1);
vertices[5] = new VertexData().setXY(0, -2f/3).setST(0.5f, 1);
vertices[6] = new VertexData().setXY(0.5f, -1f/3).setST(1, 1);

0是六边形的中心,从右上角开始逆时针从1-6开始,绘制为三角形扇形。

当梯形仍为平行四边形时,一切都很好,这是另一个纹理测试:

另一个纹理测试

但是问题是,当边不相等时,纹理投影在三角形上,因此当尝试投影纹理时,它看起来不像预期的那样:

可怕的纹理投影

我读了很多关于这个主题的文章,其中一些是:

了解Q纹理坐标...

在OpenGL ES 2.0中透视梯形的正确纹理

四边形插值,第1部分

到目前为止,没有什么让我接近解决问题的,我所知道的是与纹理的Q坐标有关。

我的顶点着色器是最低要求:

#version 150 core

in vec4 in_color;
in vec4 in_position;
in vec4 in_texture;

out vec4 pass_color;
out vec4 pass_texture;

void main(void) {
    pass_color = in_color;
    pass_texture = in_texture;
    gl_Position = in_position;
}

而且我的片段着色器真的很简单,现在我正在使用textureProj,因为我试图摆弄Q坐标。

#version 330 core

in vec4 pass_color;
in vec4 pass_texture;
out vec4 color;

uniform sampler2D texture_diffuse;

void main(void) {
    color = pass_color;
    color = textureProj(texture_diffuse, pass_texture);
}

我愿意发布每段代码,以备您需要。我只需要向正确的方向推进即可。

fixmycode

因此,在潜入互联网后,我偶然发现了一个解决方案,不幸的是,我对三角形风扇进行UV绘制的方式与该风扇不兼容,因此我不得不将我的三角形风扇转换成由三个三角形组成的一组,每个三角形由两个三角形组成,我通过在面之间复制共享顶点来做到这一点:

VertexData[] vertices = new VertexData[12];
int i = 0;
for(VertexData vert : oldVertices){
    vertices[i++] = new VertexData(vert);
}
vertices[7] = new VertexData(vertices[1]);
vertices[7].setST(1, 0.5f);

vertices[8] = new VertexData(vertices[0]);
vertices[9] = new VertexData(vertices[3]);
vertices[10] = new VertexData(vertices[0]);
vertices[11] = new VertexData(vertices[5]);

int[][] faces = {
    {0, 1, 2, 3},
    {4, 11, 10, 9},
    {6, 7, 8, 5}
};

if(qMapping) TextureUtils.qMapFaces(vertices, faces);

有了这些信息,我现在可以使用BitLush的算法,该算法基本上根据每个面的对角线的差来计算Q坐标插值:

public static void qMapFaces(VertexData[] vertices, int[][] faces){
    for(int[] face : faces){
        VertexData[] verts = new VertexData[4];
        int j = 0;
        for(int i : face){
            verts[j++] = vertices[i];
        }

        float ax = verts[2].getXYZ()[0] - verts[0].getXYZ()[0];
        float ay = verts[2].getXYZ()[1] - verts[0].getXYZ()[1];
        float bx = verts[3].getXYZ()[0] - verts[1].getXYZ()[0];
        float by = verts[3].getXYZ()[1] - verts[1].getXYZ()[1];

        float cross = ax * by - ay * bx;

        if(cross != 0) {
            float cx = verts[0].getXYZ()[0] - verts[1].getXYZ()[0];
            float cy = verts[0].getXYZ()[1] - verts[1].getXYZ()[1];

            float s = (ax * cy - ay * cx) / cross;

            if(s > 0 && s < 1){
                float t = (bx * cy - by * cx) / cross;

                if(t > 0 && t < 1){
                    float[] qi = new float[4];
                    qi[0] = 1 / (1 - t);
                    qi[1] = 1 / (1 - s);
                    qi[2] = 1 / t;
                    qi[3] = 1 / s;

                    int q = 0;
                    for(VertexData vertex : verts){
                        float[] stpq = vertex.getSTPQ();
                        vertex.setSTPQ(stpq[0] * qi[q], stpq[1] * qi[q], 0, qi[q]);
                        q++;
                    }
                }
            }
        }
    }
}

在对Q坐标进行插值后,投影效果得到了很大改善,但是由于无法同时控制两个面的插值,因此纹理在边缘的对齐方式不太好。这对我的项目来说不是问题,但是如果有人找到解决方案,请与我联系!

Q映射之前和之后

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用OpenGL在2D梯形中进行纹理的投影插值

来自分类Dev

使用现代OpenGL进行2D渲染的正交投影

来自分类Dev

使用c / awk / shell对2d数据进行双线性插值

来自分类Dev

在OpenGL中绘制2D纹理

来自分类Dev

从数据到OpenGL 2D纹理

来自分类Dev

使用PyOpenCL在OpenCL中进行快速2d直方图

来自分类Dev

为什么在用sampler2D将其渲染到曲面后对我的纹理进行插值

来自分类Dev

在OpenGL的正投影中使用纹理

来自分类Dev

使用OpenGL矩阵转换将纹理从“ 1D”映射到“ 2D”

来自分类Dev

如何在2D opengl中进行拾取?

来自分类Dev

如何在 OpenGL 中进行 2D 缩放(GLFW,很高兴)?

来自分类Dev

如何对多个高速多边形碰撞(2D)进行插值?

来自分类Dev

创建OpenGL 2D视图相机,但使用模型视图投影相机

来自分类Dev

C#Xna像2D图像一样对2D图像的边缘进行插值

来自分类Dev

C#Xna像2D图像一样对2D图像的边缘进行插值

来自分类Dev

按纵横比拉伸的 OpenGL 2D 投影

来自分类Dev

在OpenGL中绘制多个2D纹理

来自分类Dev

Qt / OpenGL尝试显示2D纹理

来自分类Dev

OpenGL 2D纹理无法正确显示C ++

来自分类Dev

openGL 2D 视差滚动纹理撕裂/接缝

来自分类Dev

如何在MySQL中进行插值

来自分类Dev

在Dymola / Modelica中进行插值?

来自分类Dev

在Dymola / Modelica中进行插值?

来自分类Dev

通过着色器进行OpenGL投影纹理映射

来自分类Dev

通过着色器进行OpenGL投影纹理映射

来自分类Dev

opengl:glGetTexImage用于2d纹理和1d纹理数组混淆

来自分类Dev

插值缺失值2d python

来自分类Dev

Opengl Shader:在两个纹理之间插值

来自分类Dev

用相同的1d数组对2d数组的每一行进行插值

Related 相关文章

热门标签

归档