3d 球体在使用纹理渲染时显示多边形

3d 球体在使用纹理渲染时显示多边形,3d,xna,direct3d,phong,3d,Xna,Direct3d,Phong,我一直在尝试在XNA/D3D(DX11)中渲染台球。我编写了一个Blinn Phone着色器,它使用HLSL中的SamplerState将我的台球纹理映射到我在VisualStudio2012中生成的球体FBX 我遇到了两个问题,在下图中最右边的球上可以看到这两个问题 1) 您可以看到纹理显示球体底层多边形的位置。 2) 在第三条线的底部边缘,条纹下方可见一点白色,看起来锯齿状或锯齿状 纹理应用程序似乎在很大程度上超出了我的控制范围,因为顶点法线之间的插值是在管道中完成的,而不是由我完成的 那么

我一直在尝试在XNA/D3D(DX11)中渲染台球。我编写了一个Blinn Phone着色器,它使用HLSL中的SamplerState将我的台球纹理映射到我在VisualStudio2012中生成的球体FBX

我遇到了两个问题,在下图中最右边的球上可以看到这两个问题

1) 您可以看到纹理显示球体底层多边形的位置。
2) 在第三条线的底部边缘,条纹下方可见一点白色,看起来锯齿状或锯齿状

纹理应用程序似乎在很大程度上超出了我的控制范围,因为顶点法线之间的插值是在管道中完成的,而不是由我完成的

那么,我该如何改进这一点呢?生成包含更多多边形的新球体

我为抗锯齿做了以下工作,但坦率地说,它似乎没有什么作用:

        graphics.PreferMultiSampling = true;
        graphics.ApplyChanges();
        GraphicsDevice.PresentationParameters.MultiSampleCount = 4;
这是我的纹理贴图状态,不管它值多少钱。任何想法都将不胜感激。如果你需要更多信息,请告诉我

sampler2D ColorSampler = sampler_state {
    Texture = <ColorTexture>;
    FILTER = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};
sampler2D ColorSampler=sampler\u状态{
纹理=;
过滤器=最小值最大值最小值线性;
地址u=包裹;
地址v=包裹;
};

您有两个选择:

  • 更精细地细分。你看到的是通过分段平面几何近似球体的错误,一种使球体不那么可见的方法是将其分割成更小的部分

  • 对纹理进行过滤,使其从蓝色->白色(应用高斯模糊,然后将模糊图像用作纹理)的过渡不太明显


  • 为了解决这个问题,我使用3DSMax代替VS2012的内置模型生成器。我将球体的比例设置为2”,并将分段数增加到64。导出到FBX时,我启用了“涡轮平滑”,而不知道它是什么

    最后,结果要好得多:


    为了补充Rahul的答案,还有第三个更复杂的选项(尽管我肯定会选择简单地增加多边形的数量): 你提到你正在使用一个着色器,我假设你正在谈论一个像素着色器。问题的出现是因为纹理坐标在像素着色器中的三角形内线性插值:但是因为你知道你在处理球体,所以可以在pixe中手动计算每个像素的UV坐标l着色器(使用标准acos(z)和atan(y/x)公式,其中(x,y,z)点是在对象坐标中光栅化的当前点)

    使用该方法,即使使用非常粗糙的镶嵌球体,也应该能够获得相对平滑的纹理

    编辑:虽然我手头没有代码片段,但这里有一个伪代码:

    顶点着色器:
    -获取当前顶点的初始坐标(无任何矩阵变换;我将假设球体顶点以原点为中心),并将它们作为
    变量vec3 P
    直接传递给像素着色器

    像素着色器:
    -
    r=sqrt(P.x*P.x+P.y*P.y+P.z*P.z)

    -
    theta=acos(P.z/r)

    -
    phi=atan2(P.y/r,P.x/r)

    -
    u=theta*2/pi;v=phi/(2*pi)+0.5

    -使用上面的(u,v)在tex2D()中对纹理进行采样


    您需要确保这些uv坐标确实与纹理的生成方式相对应,但如果是这样,您应该获得几乎无失真的贴图。

    如果您碰巧有任何执行此手动互操作的示例代码段,则在该线程中使用该代码段会很方便。手边没有代码段,但我用伪代码更新了答案代码。这还取决于纹理的生成方式(uv坐标应匹配:如果使用墨卡托投影生成纹理,则应使用墨卡托投影,而不是上面的公式!)。