1

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

台球渲染

4

3 回答 3

1

你有几个选择:

  1. 镶嵌得更细。您所看到的是通过分段平面几何近似球体的错误,一种使其不那么明显的方法是将其分割成更小的部分。

  2. 过滤您的纹理,使其从蓝色 -> 白色过渡不那么锐利(应用高斯模糊,然后使用模糊图像作为纹理)。

于 2013-03-19T03:29:20.937 回答
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 坐标确实与您的纹理生成方式相对应,但如果是这样,您应该获得几乎无失真的映射。

于 2013-03-20T21:20:24.593 回答
0

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

最后,结果要好得多:

在此处输入图像描述

于 2013-03-19T22:30:17.700 回答