球体在使用纹理渲染时显示多边形
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”而不知道它是什么。
最后,结果好多了:
【讨论】:
以上是关于球体在使用纹理渲染时显示多边形的主要内容,如果未能解决你的问题,请参考以下文章