   Texture atlas to tile a terrain (HLSL)
  I combined Riemers multitexturing example with this idea . I removed the mipmapping part as in this example he uses methods that require shader model 3.0 and I am sticking to 2.0. This actually worked I thought. If I used 2 textures/tiles from the atlas it worked fine. If I used a third then the texture displayed all haywire and messed up. So in a 2x2 tile atlas if I used to the top-left and top-right tile that worked as long as all the vertices used these. I then switched one vertex to use the top-right and the bottom-left (or anything that was at all different from what the other vertices are using) and it would mess up.I am trying to use a texture atlas to do multitexting and tile a terrain. Each vertex has 2 tiles and 2 weights associated with it. I would like each vertex to support any tiles that are in the atlas but only 2 at a time. The idea is that I can multitexture my terrain and send all of the tiles my game will need over to the gpu and just pull from it what I need.float4x4 xView; float4x4 xProjection; float4x4 xWorld; float3 xLightDirection; float xAmbient; bool xEnableLighting; /// Atlas Dimentions: /// - (x) inverse of the number of horizontal tiles (ex.: 4 tiles -> 0.25) /// - (y) inverse of the number of vertical tiles (ex.: 2 tiles -> 0.5) /// - (z) size of the tile in pixels (ex.: 128) float3 xAtlasDim;  //------- Texture Samplers -------- Texture xTextureAtlas; sampler TextureAtlasSampler = sampler_state { texture = <xTextureAtlas> ; magfilter = Linear; minfilter = Linear; mipfilter = Linear; AddressU = Mirror; AddressV = Mirror;}; //sampler TextureAtlasSampler = sampler_state { texture = <xTextureAtlas> ; magfilter = None; minfilter = None; mipfilter = None; AddressU = Wrap; AddressV = Wrap;};  struct VertexShaderInput {float4 inPosition : POSITION0;float3 inNormal: NORMAL;float4 inTileCoords: TEXCOORD0;float2 inTexCoords: TEXCOORD1;float2 inTexWeights: TEXCOORD2;// TODO: add input channels such as texture// coordinates and vertex colors here. };  struct VertexShaderOutput {float4 Position    : POSITION;float4 Color  : COLOR0;float3 Normal  : TEXCOORD0;float4 TileCoords    : TEXCOORD1;float2 TexCoords    : TEXCOORD2;float4 LightDirection    : TEXCOORD3;float2 TextureWeights    : TEXCOORD4; };  struct PixelShaderOutput {float4 Color : COLOR0; };   /// This function samples a texture with tiling from within a texture pack of the given /// attributes /// - uv are the texture coordinates of the pixel *inside the tile* /// - tile are the coordinates of the tile within the pack (ex.: 2, 1) /// - packTexFactors are some constants to perform the mipmapping and tiling float4 SampleTexturePackWrapped(float2 uv, float2 tile) {/// get width/height of the whole pack texture for the current lod level    float sizex = xAtlasDim.z / xAtlasDim.x; // width in pixelsfloat sizey = xAtlasDim.z / xAtlasDim.y; // height in pixels /// perform tilinguv = frac(uv); /// tweak pixels for correct bilinear filtering, and add offset for the wanted tileuv.x = uv.x * ((sizex * xAtlasDim.x - 1.0) / sizex) + 0.5 / sizex + xAtlasDim.x * tile.x;uv.y = uv.y * ((sizey * xAtlasDim.y - 1.0) / sizey) + 0.5 / sizey + xAtlasDim.y * tile.y; return tex2D(TextureAtlasSampler, uv); }  VertexShaderOutput VertexShaderFunction(VertexShaderInput input) {//Add your vertex shader code here.VertexShaderOutput output = (VertexShaderOutput)0; float4x4 preViewProjection = mul(xView, xProjection);float4x4 preWorldViewProjection = mul(xWorld, preViewProjection); output.Position = mul(input.inPosition, preWorldViewProjection);output.Normal = mul(normalize(input.inNormal), xWorld);output.TileCoords = input.inTileCoords;output.TexCoords = input.inTexCoords;output.LightDirection.xyz = -xLightDirection;output.LightDirection.w = 1;    output.TextureWeights = input.inTexWeights; return output; }  PixelShaderOutput PixelShaderFunction(VertexShaderOutput input) : COLOR0 {//Add your pixel shader code here.PixelShaderOutput output = (PixelShaderOutput)0;   float lightingFactor = 1;if (xEnableLighting)    lightingFactor = saturate(saturate(dot(input.Normal, input.LightDirection)) + xAmbient);//TODO: Replace 2s with height width in tiles.float2 tile1Coords = float2(input.TileCoords.x, input.TileCoords.y);float2 tile2Coords = float2(input.TileCoords.z, input.TileCoords.w); //output.Color = tex2D(TextureSampler0, tile1TexCoords) * input.TextureWeights.x;output.Color = SampleTexturePackWrapped(input.TexCoords, tile1Coords) * input.TextureWeights.x;output.Color += SampleTexturePackWrapped(input.TexCoords, tile2Coords) * input.TextureWeights.y;//output.Color += tex2D(TextureSampler0, tile2TexCoords) * input.TextureWeights.y; output.Color *= lightingFactor; return output; }    technique MultiTextured {pass Pass0{    // TODO: set renderstates here.VertexShader = compile vs_2_0 VertexShaderFunction();    PixelShader = compile ps_2_0 PixelShaderFunction();} } 
  In principle this is a great idea, but if you're using dx9, you'll no doubt end up with texture bleeding in one form or another. I went with your approach for my first terrain attempt and after weeks of researching, tweaking and generally pulling my hair out, I couldn't get rid of them. I settled for a multiple pass technique in the end which works great for what I need.Incidentally, if you're using dx10 or higher, try texture arrays.Good luck!   ;  My requirements were that I need to support many textures with the ability to multi-texture up to 4 at any given vertex with any given textures to sample from. Using the approach of having many samples wont work because you are limited by texture units. I then decided to use an atlas because I don't need mipmapping anyhow with the design of my game. That was a painful experience and caused a lot of confusion and it never did work completely as seen above.In short... I have decided to use 3d textures and they work great! I honestly cant say how much overhead this is or what it does with performance but it solves all my issues. I know they don't do mipmapping as planned but again no need for mipmapping. They are also very easy to understand and code for. I think I will use them for my animations as well. I think they will work well for animation. Seems like with the interpolation between frames you can chuck some not key frames for things like explosions. I am kind of curious if the mipmapping issue will actually be good for that. Seems like if you get further away you can sacrifice more frames as well as texture size. Again no need for mipmapping so I may just mess with that later.   