I've been tinkering with rendering billiard balls in XNA/D3D (DX11). I've written a Blinn-Phone shader that uses SamplerState in the HLSL to map my billiard textures to a sphere FBX that I generated in VisualStudio2012.
There are two problems I'm having, both most visible on the rightmost ball in the picture below.
1) You can see the texture reveals where the underlying polygons of the sphere are.
2) At the bottom edge of the third line where just a little white is visible below the stripe, it looks very aliased or jagged.
The texture application seems to be largely beyond my control, as the interpolation between the vertex normals is done within the pipeline, not by me.
So, how could I improve this? Generate a new sphere with more polygons?
I've done the following for the antialiasing, but frankly it seemed to do very little if anything:
graphics.PreferMultiSampling = true;
graphics.ApplyChanges();
GraphicsDevice.PresentationParameters.MultiSampleCount = 4;
Here's my texture map state, for what its worth. Any ideas would be greatly appreciated. If you need more info, let me know!
sampler2D ColorSampler = sampler_state {
Texture = <ColorTexture>;
FILTER = MIN_MAG_MIP_LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};
To complement Rahul's answer, there is a third, more involved option (although I would definitely opt for simply increasing the number of polygons) : you mentioned that you are using a shader - and I'll assume you're talking about a pixel shader. The issue arises because the texture coordinates are linearly interpolated inside the triangles in the pixel shader : but since you know that you are dealing with spheres, it becomes possible to manually compute the UV coordinates per pixel in the pixel shader (use the standard acos(z) and atan(y/x) formula with the (x,y,z) point being the current point rasterized in the object coordinate).
Using that, even if you use a very coarsely tesselated sphere, your should still be able to get relatively smooth textures.
EDIT: although I don't have a snippet at hand, here is a pseudo code:
Vertex shader:
- take the initial coordinates of the current vertex (without any matrix transform ; I'll assume that your sphere vertices are centered around the origin) and pass them directly to the pixel shader as a varying vec3 P
.
Pixel shader:
- 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
- use the (u,v) above to sample your texture in the tex2D()
You'll need to make sure that these uv coordinates indeed correspond to how your texture has been generated, but if so, you should get an almost distortion free mapping.