当使用纹理渲染时,球体会显示多边形

时间:2013-03-19 00:56:46

标签: 3d xna direct3d phong

我一直在修补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;
};

Billiard Balls Rendered

3 个答案:

答案 0 :(得分:1)

您有几个选择:

  1. Tesellate更精细。您所看到的是通过分段平面几何体近似球体的误差,并且使其不太可见的一种方法是将其分成更小的部分。

  2. 过滤纹理,使其从蓝色过渡到不太明显 - &gt;白色(应用高斯模糊,然后使用模糊图像作为纹理)。

答案 1 :(得分:1)

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

使用它,即使你使用非常粗糙的球体,你仍然可以获得相对平滑的纹理。

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

顶点着色器:
- 获取当前顶点的初始坐标(没有任何矩阵变换;我假设您的球体顶点以原点为中心)并将它们作为varying 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坐标确实对应于纹理的生成方式,但如果是这样,你应该得到几乎无失真的映射。

答案 2 :(得分:0)

如果它有助于其他人:为了解决这个问题,我使用了3DSMax而不是VS2012的内置模型构建器。我将球体的比例设置为2“,并将线段数增加到64.当导出到FBX时,我启用了”Turbo Smooth“而不知道它是什么。

最后,情况好多了:

enter image description here