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

问题描述 投票:1回答:3

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

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9UQWpRdi5wbmcifQ==” alt =“台球被渲染”>

3d xna direct3d phong
3个回答
1
投票

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

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

EDIT:尽管我手边没有代码段,但这是一个伪代码:

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

您有两个选择:

  1. 细细地细分。您所看到的是通过分段平面几何体近似球体的错误,一种使其不可见的方法是将其拆分为较小的块。

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

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

    最后,结果要好得多:

    “在此处输入图像描述”


    1
    投票

    您有两个选择:


    0
    投票

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

    © www.soinside.com 2019 - 2024. All rights reserved.