3d 球体在使用纹理渲染时显示多边形
我一直在尝试在XNA/D3D(DX11)中渲染台球。我编写了一个Blinn Phone着色器,它使用HLSL中的SamplerState将我的台球纹理映射到我在VisualStudio2012中生成的球体FBX 我遇到了两个问题,在下图中最右边的球上可以看到这两个问题 1) 您可以看到纹理显示球体底层多边形的位置。3d 球体在使用纹理渲染时显示多边形,3d,xna,direct3d,phong,3d,Xna,Direct3d,Phong,我一直在尝试在XNA/D3D(DX11)中渲染台球。我编写了一个Blinn Phone着色器,它使用HLSL中的SamplerState将我的台球纹理映射到我在VisualStudio2012中生成的球体FBX 我遇到了两个问题,在下图中最右边的球上可以看到这两个问题 1) 您可以看到纹理显示球体底层多边形的位置。 2) 在第三条线的底部边缘,条纹下方可见一点白色,看起来锯齿状或锯齿状 纹理应用程序似乎在很大程度上超出了我的控制范围,因为顶点法线之间的插值是在管道中完成的,而不是由我完成的 那么
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;
};
sampler2D ColorSampler=sampler\u状态{
纹理=;
过滤器=最小值最大值最小值线性;
地址u=包裹;
地址v=包裹;
};
您有两个选择:
为了解决这个问题,我使用3DSMax代替VS2012的内置模型生成器。我将球体的比例设置为2”,并将分段数增加到64。导出到FBX时,我启用了“涡轮平滑”,而不知道它是什么 最后,结果要好得多:
为了补充Rahul的答案,还有第三个更复杂的选项(尽管我肯定会选择简单地增加多边形的数量): 你提到你正在使用一个着色器,我假设你正在谈论一个像素着色器。问题的出现是因为纹理坐标在像素着色器中的三角形内线性插值:但是因为你知道你在处理球体,所以可以在pixe中手动计算每个像素的UV坐标l着色器(使用标准acos(z)和atan(y/x)公式,其中(x,y,z)点是在对象坐标中光栅化的当前点) 使用该方法,即使使用非常粗糙的镶嵌球体,也应该能够获得相对平滑的纹理 编辑:虽然我手头没有代码片段,但这里有一个伪代码: 顶点着色器:
-获取当前顶点的初始坐标(无任何矩阵变换;我将假设球体顶点以原点为中心),并将它们作为
变量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坐标确实与纹理的生成方式相对应,但如果是这样,您应该获得几乎无失真的贴图。如果您碰巧有任何执行此手动互操作的示例代码段,则在该线程中使用该代码段会很方便。手边没有代码段,但我用伪代码更新了答案代码。这还取决于纹理的生成方式(uv坐标应匹配:如果使用墨卡托投影生成纹理,则应使用墨卡托投影,而不是上面的公式!)。