毛皮纹理在兔子身上显得粗糙

Posted

技术标签:

【中文标题】毛皮纹理在兔子身上显得粗糙【英文标题】:Fur texture appears coarsely on Bunny 【发布时间】:2014-03-18 07:38:02 【问题描述】:

我编写此代码以将纹理应用于以层格式提供的兔子模型。兔子是使用纹理绘制的,但纹理看起来不像毛皮,而是看起来像粗糙的点。

void GLRenderer::paintGL()

    // Set light
    GLfloat light_position[] =  lightPositionX, lightPositionY, lightPositionZ, 0.0 ;
    glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Enabling texture
    glEnable(GL_TEXTURE_2D);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

    bindTexture(QImage("fur4.bmp"));

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    glEnable(GL_NORMALIZE);
    glLoadIdentity();

    glBegin(GL_TRIANGLES);

        for( int i = 0 ; i < objPLYParser.g_vpX.size() ; i+=3 )
        
                float vector1[3], vector2[3], vCross[3], normalizationValue;
                vector1[0] = objPLYParser.g_vpX[i] - objPLYParser.g_vpX[i+1];
                vector1[1] = objPLYParser.g_vpY[i] - objPLYParser.g_vpY[i+1];
                vector1[2] = objPLYParser.g_vpZ[i] - objPLYParser.g_vpZ[i+1];

                vector2[0] = objPLYParser.g_vpX[i] - objPLYParser.g_vpX[i+2];
                vector2[1] = objPLYParser.g_vpY[i] - objPLYParser.g_vpY[i+2];
                vector2[2] = objPLYParser.g_vpZ[i] - objPLYParser.g_vpZ[i+2];

                // Cross product
                vCross[0] = vector1[1] * vector2[2] - vector2[1] * vector1[2];
                vCross[1] = vector2[0] * vector1[2] - vector1[0] * vector2[2];
                vCross[2] = vector1[0] * vector2[1] - vector2[0] * vector1[1];

                // Value to do normalization with
                normalizationValue = sqrt( vCross[0]*vCross[0] + vCross[1]*vCross[1] + vCross[2]*vCross[2] );

                 float normal[3];
                 normal[0] = vCross[0]/normalizationValue;
                 normal[1] = vCross[1]/normalizationValue;
                 normal[2] = vCross[2]/normalizationValue;

                 glNormal3f(normal[0],normal[1],normal[2]);

            glTexCoord2f(0.0, 0.0);
            glVertex3f(objPLYParser.g_vpX[i],objPLYParser.g_vpY[i],objPLYParser.g_vpZ[i]);

            glTexCoord2f( 1.0,0.0);
            glVertex3f(objPLYParser.g_vpX[i+1],objPLYParser.g_vpY[i+1],objPLYParser.g_vpZ[i+1]);

            glTexCoord2f(1.0, 1.0);
            glVertex3f(objPLYParser.g_vpX[i+2],objPLYParser.g_vpY[i+2],objPLYParser.g_vpZ[i+2]);
        


    glEnd();
    glDisable(GL_TEXTURE_2D);

我尝试过的纹理文件:

我得到的输出:

有什么建议我可能在这里做错了吗?

【问题讨论】:

你确定兔子有纹理坐标吗? @concept3d 对不起,我没听懂你的问题? 我问的问题在答案中得到了更好的解释,你需要对你的兔子进行 UV 映射,换句话说,使用一些 3D 程序给它纹理坐标(或生成它们)。 @concept3d 我可以参考任何资源来生成它们吗?我能找到的只是如何将纹理映射到哑立方体上。 【参考方案1】:

在这些行中:

glTexCoord2f(0.0, 0.0);
...

glTexCoord2f( 1.0,0.0);
...

glTexCoord2f(1.0, 1.0);
...

您提供的纹理坐标将整个纹理的一半映射到每个单独的三角形。您所看到的是整个毛皮纹理密集地平铺在网格上。

您需要提供更好的纹理坐标。

【讨论】:

我可以参考任何资源吗?我能找到的只是如何将纹理映射到哑立方体上。 :( 获取/创建/生成纹理坐标的方法有很多。在您的情况下,我建议您需要获取一些已经拥有它们的数据 - 我确信这对于像斯坦福兔子这样的模型必须存在(原始数据是没有的 3D 扫描,但它肯定已经被参数化了) .否则,要么获取可用于创建它们的建模工具,要么开始研究网格参数化。【参考方案2】:

首先,您可以使用简单的对象空间映射,例如对于 (x, y, z) 顶点,您可以使用 (x*scale, (y+z)*scale) 纹理坐标。然后您可以调整规模

【讨论】:

以上是关于毛皮纹理在兔子身上显得粗糙的主要内容,如果未能解决你的问题,请参考以下文章

Javascript/PixiJS 不加载纹理

2020年,家里兔子下了崽

兔子生兔子问题

生兔子的经典编程算法

兔子繁衍问题

兔子问题