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

Posted

技术标签:

【中文标题】球体在使用纹理渲染时显示多边形【英文标题】:Sphere reveals polygons when rendered with a texture 【发布时间】:2013-03-19 00:56:45 【问题描述】:

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

【问题讨论】:

【参考方案1】:

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

使用它,即使您使用非常粗糙的镶嵌球体,您仍然应该能够获得相对平滑的纹理。

编辑:虽然我手头没有sn-p,但这里有一个伪代码:

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

【讨论】:

如果您碰巧有任何示例 sn-p 可以执行此手动互操作,那么在此线程中会很方便。 手头没有sn-p,但我用伪代码更新了答案。它还取决于您的纹理是如何生成的(uv 坐标应该匹配:如果您使用墨卡托投影来生成纹理,那么您应该使用墨卡托投影而不是我上面的公式!)。【参考方案2】:

你有几个选择:

    更精细地镶嵌。您看到的是通过分段平面几何近似球体的错误,一种使其不那么明显的方法是将其拆分为更小的部分。

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

【讨论】:

【参考方案3】:

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

最后,结果好多了:

【讨论】:

以上是关于球体在使用纹理渲染时显示多边形的主要内容,如果未能解决你的问题,请参考以下文章

多边形与 Openlayers 叠加时显示多个弹出窗口

使用 alpha 混合组件合成纹理

Opengl:地球纹理

FreeType - 纹理图集 - 为什么我的文字渲染为四边形?

如何在三个js中将多个纹理裁剪为多边形

使用 OpenGL C++ 渲染到纹理