Anyways I got the height map, normals, vertex shade, and tile number figured out, but I can't for the life of me get the specific tile to show up on my terrain. I read all kinds of great articles, but still don't quiet understand the pixel shaders. I am having trouble in the pixel shader which specifies the particular pixel and associating that with the coordinate of the specific tile texture I wish to lay down.
Can anyone help me out, or point me in the right direction for placing a specific texture/tile (stored in a larger texture) on my terrain mesh. Also, for the texture coordinates that get passed in to the pixel shader, I am presuming these are the coordinates in the texture that are associated with that particular pixel? If the tiles are specified at the vertex level, or associated with 4 vertices that will change in the up coming tile (and are shared among up to 8 other tiles), how do you assign the texture corrdinates? Also, how do you tell the pixel shader what tile to use? I am so confused on this subject, I hope I am asking the right question.
Below are the specifics on what I have so far. Sorry so long, but I wanted to include as much info as possible without including irrelevant items...
Here is a picture of what I have rendered so far. It is a generic texture for now. Height maps are done, along with normal lighting, and vertex shading. Off to the right side are the 2 textures that are going to be used for the tiles. There are 128 tiles total.
The ground mesh is 513 by 513 and right now all the verticies are shared. I have seen some people use separate verticies for each tile, but I do not want to increase the number of verticies unless I absolutely have to. Eventually I will split these into 33x33 pieces to do some quick culling.
Below is how the mesh is being created
// Build vertices. // We are working on X first as if they were rows, then Z would be the colums. // The reason behind this is because the map files are oriented this way. m_GroundVertices.resize(m_NumGroundVertices); int k = 0; for(int i = 0; i < m_SizeOfZ; ++i) { for(int j = 0; j < m_SizeOfX; ++j) { m_GroundVertices[k].x = j * m_SpaceBetweenXCells; m_GroundVertices[k].y = m_pMapFile->GetMapInfo()->pMapVertex[k].pos.y; m_GroundVertices[k].z = i * m_SpaceBetweenZCells; ++k; // Next vertex } } // Build indices. m_GroundIndices.resize(m_NumGroundTriangles * 3); // Generate indices for each quad. k = 0; for(int i = 0; i < numZCells; ++i) { for(int j = 0; j < numXCells; ++j) { // b ---- c // | /| // | / | // ^ | / | // | |/ | // z+ a ---- d // y is up // x+ -> DWORD a = (i * m_SizeOfX) + j; DWORD b = ((i + 1) * m_SizeOfX) + j; DWORD c = ((i + 1) * m_SizeOfX) + (j + 1); DWORD d = (i * m_SizeOfX) + (j + 1); m_GroundIndices[k] = a; m_GroundIndices[k + 1] = b; m_GroundIndices[k + 2] = c; m_GroundIndices[k + 3] = a; m_GroundIndices[k + 4] = c; m_GroundIndices[k + 5] = d; // next quad k += 6; } }
Below is the vertex buffer. Right now for the texture coordinates I am just wraping the tile over and over.
for(int i = 0; i < m_SizeOfX; ++i){ for(int j = 0; j < m_SizeOfZ; ++j) { DWORD index = i * m_SizeOfX + j; v[index].pos = m_GroundVertices[index]; v[index].normal = m_pMapFile->GetMapInfo()->pMapVertex[index].normal; v[index].tex0 = D3DXVECTOR2((float)i, (float)j) * texScale; v[index].col = m_pMapFile->GetMapInfo()->pMapVertex[index].col; }}// Also the index buffer for completnessfor(DWORD i = 0; i < m_NumGroundTriangles * 3; ++i){ k = (DWORD)m_GroundIndices;}
Below is the VS and PS
uniform extern float4x4 gWorld;uniform extern float4x4 gWorldInvTrans;uniform extern float4x4 gWVP;uniform extern float4 gAmbientMtrl;uniform extern float4 gAmbientLight;//uniform extern float4 gDiffuseMtrl;uniform extern float4 gDiffuseLight;uniform extern float4 gSpecularMtrl;uniform extern float4 gSpecularLight;uniform extern float gSpecularPower;uniform extern float3 gLightVecW;uniform extern float3 gEyePosW;uniform extern texture gTex;sampler TexS = sampler_state{ Texture = <gTex>; MinFilter = Anisotropic; MagFilter = LINEAR; MipFilter = LINEAR; MaxAnisotropy = 8; AddressU = WRAP; AddressV = WRAP;}; struct OutputVS{ float4 posH : POSITION0; float4 diffuse : COLOR0; float4 spec : COLOR1; float2 tex0 : TEXCOORD0;};OutputVS DirLightTexVS(float3 posL : POSITION0, float3 normalL : NORMAL0, float2 tex0: TEXCOORD0, float4 c : COLOR0){ // Zero out our output. OutputVS outVS = (OutputVS)0; // Transform normal to world space. float3 normalW = mul(float4(normalL, 0.0f), gWorldInvTrans).xyz; normalW = normalize(normalW); // Transform vertex position to world space. float3 posW = mul(float4(posL, 1.0f), gWorld).xyz; //======================================================= // Compute the color: Equation 10.3. // Compute the vector from the vertex to the eye position. float3 toEye = normalize(gEyePosW - posW); // Compute the reflection vector. float3 r = reflect(-gLightVecW, normalW); // Determine how much (if any) specular light makes it into the eye. float t = pow(max(dot(r, toEye), 0.0f), gSpecularPower); // Determine the diffuse light intensity that strikes the vertex. float s = max(dot(gLightVecW, normalW), 0.0f); // Compute the ambient, diffuse and specular terms separatly. float3 spec = t*(gSpecularMtrl*gSpecularLight).rgb;//float3 diffuse = s*(gDiffuseMtrl*gDiffuseLight).rgb; float3 diffuse = s*(c*gDiffuseLight).rgb; float3 ambient = gAmbientMtrl*gAmbientLight; // Sum all the terms together and copy over the diffuse alpha. outVS.diffuse.rgb = ambient + diffuse;//outVS.diffuse.a = gDiffuseMtrl.a; outVS.diffuse.a = c.a; outVS.spec = float4(spec, 0.0f); //======================================================= // Transform to homogeneous clip space. outVS.posH = mul(float4(posL, 1.0f), gWVP); // Pass on texture coordinates to be interpolated in rasterization. outVS.tex0 = tex0; // Done--return the output. return outVS;}float4 DirLightTexPS(float4 c : COLOR0, float4 spec : COLOR1, float2 tex0 : TEXCOORD0) : COLOR{ float3 texColor = tex2D(TexS, tex0).rgb; float3 diffuse = c.rgb * texColor; return float4(diffuse + spec.rgb, c.a); }technique DirLightTexTech{ pass P0 { // Specify the vertex and pixel shader associated with this pass. vertexShader = compile vs_2_0 DirLightTexVS(); pixelShader = compile ps_2_0 DirLightTexPS(); // Specify the render/device states associated with this pass. //FillMode = Wireframe; }}
Vertex format
//===============================================================struct VertexPNTC{ VertexPNTC() :pos(0.0f, 0.0f, 0.0f), normal(0.0f, 0.0f, 0.0f), tex0(0.0f, 0.0f), col(0x00000000){} VertexPNTC(float x, float y, float z, float nx, float ny, float nz, float u, float v, D3DCOLOR c):pos(x,y,z), normal(nx,ny,nz), tex0(u,v), col(c){} VertexPNTC(const D3DXVECTOR3& v, const D3DXVECTOR3& n, const D3DXVECTOR2& uv, D3DCOLOR c) :pos(v), normal(n), tex0(uv), col(c){} D3DXVECTOR3 pos; D3DXVECTOR3 normal; D3DXVECTOR2 tex0; D3DCOLOR col; static IDirect3DVertexDeclaration9* Decl;};
Thanks ahead to anyone who can direct me on what I need to do in the pixel shader to get the individual tiles down on the mesh. Also, I am going to guess that the way I need to specify the initial texture coordinates needs to change.
[Edited by - Zoa on June 27, 2010 12:46:14 AM]