'wireframe' showing up somehow on terrain
hi
I did not know what to call this thread, but here is an image that shows the issue
As you can see there is lines showing up on the terrain and I don't know if they are supposed to or not. The terrain is only lighted, not textured. The lines seem to correspond to the triangle edges`.
Anybody got a clue why this is happening?
This is an artifact of per-vertex lighting, and there just isn't much you can do about it. I has to do with the way the color is interpolated across a triangle by the hardware. Using per-pixel lighting would probably make it far less obvious, but probably won't fix it completely either.
The good news is that when texturing is enabled, the artifact can barely be seen (depending on the texture, of course).
If you keep your triangle count high enough to avoid cases where a single triangle gets to big, it shouldn't prove to be a problem.
Hope this helps.
The good news is that when texturing is enabled, the artifact can barely be seen (depending on the texture, of course).
If you keep your triangle count high enough to avoid cases where a single triangle gets to big, it shouldn't prove to be a problem.
Hope this helps.
Okay that is good to hear[smile] and I am in fact using per-pixel lighting.
But on with the texturing then.
Thank you.
But on with the texturing then.
Thank you.
If you're using per-pixel lighting and getting these artifacts, you may indeed have an error in your shader. I'd recommend you have another look at it, and at per-pixel lighting articles to make sure it it correct.
If you'd like, you could post some code here, and get some comments on it's validity.
If you'd like, you could post some code here, and get some comments on it's validity.
It may also be your input data, if no vertices are shared, and the normals all point in the same direction as the triangle, then you get nothing out of per pixel lighting. Smoothing out the normals by averaging all vertices that are connected can help improve the quality of per pixel lighting.
Hi
Here is my shader code:
After having looked at it more closely it certainly looks like the normals are somehow screwed.
Here is how I create my mesh and compute the normals, maybe there is an error:
Tell me if there are any more you need [wink]
Here is my shader code:
// FX parameter. Accessible from C++ fileuniform extern float4x4 WorldViewProjMatrix;// vectors describing view positionuniform extern float3 viewPos;// degree of shinynessuniform float specularPower = 50.0f;// position and color, describing the incoming lightuniform float3 lightDiffusePos = float3(0.0f,-1.0f,0.0f); // color vectors describing the different materialsuniform float4 diffuseMaterial = {0.9f, 0.9f,0.92f,1.0f};uniform float4 ambientMaterial = {1.0f, 1.0f,1.0f,1.0f};uniform float4 specularMaterial = {0.8f, 0.8f, 0.86f,1.0f};// color vectors describing the different light colorsuniform float4 lightDiffuseCol = float4(0.85, 0.85, 0.85, 1.0f);uniform float4 lightAmbientCol = float4(0.2f, 0.22f, 0.22f, 1.0f);uniform float4 lightSpecCol = float4(0.7f,0.7f,0.7f, 1.0f); // the output vertex structurestruct OutputVS{ // POSITION0 tells that this member corresponds to the // data member in the custom vertex structure with usage // D3DDECLUSAGE_POSITION and index 0 float4 posH : POSITION0; float3 normal : TEXCOORD0; float3 posW : TEXCOORD1; }; // VERTEX SHADER// input: the current position of vertex and the specified color// output: the transformed vertex OutputVS VS(float3 posL : POSITION0, float3 _normal : NORMAL0){ // initialize the output structure by zeroing it out OutputVS outVS = (OutputVS)0; // pass the normal outVS.normal = _normal; // pass the vertex position, already in world space outVS.posW = posL; // transform the vertex to homonegenous clip space outVS.posH = mul( float4( posL, 1.0f ), WorldViewProjMatrix ); // return the vertex return outVS;}// PIXEL SHADER// input: a normal and position// output: color of the current pixel by per-pixel-lightingfloat4 PS(float3 normal : TEXCOORD0, float3 posW : TEXCOORD1) : COLOR{ // be sure the normal is unit length normal = normalize( normal ); // normalize the light positions lightDiffusePos = normalize( -lightDiffusePos ); /***** Diffuse Component *****/ float lambDiff = max( dot( lightDiffusePos, normal), 0.0f ); float diff = lambDiff * ( diffuseMaterial * lightDiffuseCol ).rgb; /***** Specular Component *****/ // find the view vector float3 viewVector = normalize( viewPos - posW ); // calculate the amount of specular light using the half-way vector float lambSpecHalfWay = pow( max( dot( normal, normalize( lightDiffusePos + viewVector ) ), 0.0f ), 4 * specularPower ); float3 spec = lambSpecHalfWay * ( specularMaterial * lightSpecCol ).rgb; /***** Ambient Component *****/ float3 amb = ( ambientMaterial * lightAmbientCol ).rgb; if(diff <= 0.0f) spec = 0.0f; return float4( amb + diff + spec, diffuseMaterial.a ); } // TECHNIQUE, (ie. the composition of shadering)technique Terrain{ pass P0 { // set rendering states FillMode = Solid; // which vertex and pixel shader is associated with the pass vertexShader = compile vs_2_0 VS(); pixelShader = compile ps_2_0 PS(); }}
After having looked at it more closely it certainly looks like the normals are somehow screwed.
Here is how I create my mesh and compute the normals, maybe there is an error:
/************************************************************************/ /* Run through all the vertices and calculate the position. */ /* Push the vectors onto the mesh vertex buffer */ /************************************************************************/ int vertNum = 0; VertexPosNormal* v = 0; DXRESULT( m_pTerrainMesh->LockVertexBuffer( 0, (void**)&v ) ); for (int i = 0; i < vertexRows; i++) { for (int j = 0; j < vertexCols; j++) { // calculate the vertex position float vertPosZ = m_position.z + (float)( m_sizeOfQuads * i ); float vertPosX = m_position.x + (float)( m_sizeOfQuads * j ); float vertPosY = 0.0f; // translate vertex positions so that the middle vertex end // up at the position specified at construction vertPosX = vertPosX -( float)( numCols * m_sizeOfQuads ) / 2; vertPosZ = vertPosZ - (float)( numRows * m_sizeOfQuads ) / 2; // test for filtering of heights and specify the height if ( filter ) vertPosY = m_position.y + tempHeights[vertNum] - 200; else vertPosY = m_position.y + in[vertNum] - 10; // push the vertices, assign temp normal v[vertNum].mPos = Vector3( vertPosX, vertPosY, vertPosZ ); v[vertNum].mNormal = Vector3( 0.0f, 1.0f, 0.0f ); vertNum++; } } DXRESULT( m_pTerrainMesh->UnlockVertexBuffer() ); /************************************************************************/ /* Specify the indices for the mesh */ /************************************************************************/ int quad = 0; std::vector<DWORD> indices; indices.resize(numIndices); for (int i = 0; i < numRows; i++) { for ( int j = 0; j < numCols; j++ ) { // filling up indices indices[quad] = (DWORD)( j + i * vertexCols); indices[quad + 1] = (DWORD)( j + (i+1) * vertexCols); indices[quad + 2] = (DWORD)( j + i * vertexCols + 1); indices[quad + 3] = (DWORD)( j + i * vertexCols + 1 ); indices[quad + 4] = (DWORD)( j + (i+1) * vertexCols ); indices[quad + 5] = (DWORD)( j + 1 + (i+1) * vertexCols ); quad += 6; } } WORD* indexBuffer = 0; DWORD* attBuffer = 0; DXRESULT( m_pTerrainMesh->LockIndexBuffer( 0, (void**)&indexBuffer) ); DXRESULT( m_pTerrainMesh->LockAttributeBuffer( 0, &attBuffer) ); for (unsigned int i = 0; i < numTris; i++) { indexBuffer[i*3+0] = (WORD)indices[i*3+0]; indexBuffer[i*3+1] = (WORD)indices[i*3+1]; indexBuffer[i*3+2] = (WORD)indices[i*3+2]; attBuffer = 0; // subset 0 } DXRESULT( m_pTerrainMesh->UnlockIndexBuffer() ); DXRESULT( m_pTerrainMesh->UnlockAttributeBuffer() ); // compute normals DXRESULT( D3DXComputeNormals( m_pTerrainMesh, 0 ) ); DWORD* adj = new DWORD[ m_pTerrainMesh->GetNumFaces() * 3 ]; DXRESULT( m_pTerrainMesh->GenerateAdjacency( 0.001f, adj ) ); DXRESULT( m_pTerrainMesh->OptimizeInplace( D3DXMESHOPT_VERTEXCACHE | D3DXMESHOPT_ATTRSORT, adj, 0, 0, 0 ) ); delete[] adj;
Tell me if there are any more you need [wink]
Out of curiosity, does sending in the adjacency to the normal generation function affect anything?
I think this is called "mach banding", see 16.2.3 Polygon Mesh Shading in
http://www.futuretech.blinkenlights.nl/gouraud.html
I think only with normal mapping it will go away. Because with phong with normals are still interpolated. But normal mapping a terrain might not be practical because of the size of the normal map needed. But as others have said, once a texture is on it it cannot be seen.
http://www.futuretech.blinkenlights.nl/gouraud.html
I think only with normal mapping it will go away. Because with phong with normals are still interpolated. But normal mapping a terrain might not be practical because of the size of the normal map needed. But as others have said, once a texture is on it it cannot be seen.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement