Skip to main content
GameDev.net gamedev.net
🔒 Locked

Computing normals for terrain

Started by aker_jus May 3, 2003 at 7:47 AM 11 replies 650+ views
Original Post
aker_jus
aker_jus
How can I compute vertex normals for a terrain chunk? Suppose the chunk is 32x32, what should I do? So far, I am setting the ny to 1 and all other to 0. Any other ways? Thanks
GraphicsWare|RenderTechhttp://www.graphicsware.com3D Graphics & Solutions
Damage_Incorporated
Damage_Incorporated
my 3d math is beyond rusty but look up the cross product that should give you the info you need to calculate the normal for a surface/triangle, dot product can also come in handy when culling geometry. just look up any vector math tutorial and it will probably show you how to do this and a lot more...

- Damage Inc.
aker_jus
aker_jus
Can you point me at a tutorial? I almost now where I need to "move", along the lines of Cross vector and Dot product.
GraphicsWare|RenderTechhttp://www.graphicsware.com3D Graphics & Solutions
aker_jus
aker_jus
Thank you, I fixed them now. But I have a problem. I have a material for my terrain, with diffuse (1,1,1,1) and ambient (0,0,0).
For my light, I use directional, with direction = 0,-1,0 (downwards), ambient (1,1,1) and diffuse(1,1,1).

Now, something weird happens. If I disable lighting, the terrain is lit, where it should be black, right? When I enable lighting, the terrain''s color is dependant of the material, not the light. Also, the diffuse (material or light color) isnt changing anything, only the ambient is. For my scene ambient color, I use full white.

Any ideas? I believe that the diffuse light sets the color for a mesh after it is lit, not the ambient.
GraphicsWare|RenderTechhttp://www.graphicsware.com3D Graphics & Solutions
Sante05
Sante05
Try setting a lower ambient value
-----DevZing Blog (in Spanish)
aker_jus
aker_jus
I just did. Well, sorry to ask so many questions, but it was not directly my fault. I fixed it, but for the light, the Y is reversed! I was using 0,-1,0 as I told you for my directional light direction. I wasnt getting results whatsoever, and I wondered. So I switched to 0,1,0 and voila.. But why, its weird. Shouldnt it be the reverse way?

Anyway it works now, but if you could tell me why this happens, it would be excellent.
GraphicsWare|RenderTechhttp://www.graphicsware.com3D Graphics & Solutions
Zook
Zook
Could it be that your normals are pointing the wrong way? If you switch places of the two source vectors in the D3DXVec3Cross function the direction of the normal will be reversed.
aker_jus
aker_jus
Cool, do you think I have them reversed? I''ll try to see. Thank you very much!
GraphicsWare|RenderTechhttp://www.graphicsware.com3D Graphics & Solutions
JohnBolton
JohnBolton
You can compute cross products for each vertex, but if your terrain is a grid, this is a faster method (and gives you the same answer):


The 4 adjacent points in a uniform grid: A, B, C, D

B
|
C--0--A
|
D


The ratio of XY-scale to Z-scale: s = Sxy / Sz
The desired normal: N = cross(A,B) + cross(B,C) + cross(C,D) + cross(D,A), (then normalize)

A faster way to get the same answer:

Nx = 2 * s * (Cz - Az)
Ny = 2 * s * (Dz - Bz)
Nz = 4 * s^2
N = normalize( N )

And since N is normalized in the end, it can be divided by 2 * s:

Nx = Cz - Az
Ny = Dz - Bz
Nz = 2 * s
N = normalize( N )



[edited by - Jambolo on May 4, 2003 4:04:48 AM]
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
aker_jus
aker_jus
Cool I will do that.
GraphicsWare|RenderTechhttp://www.graphicsware.com3D Graphics & Solutions
DirectXXX
DirectXXX
this is quick and dirty ripped code from andy pikes tutorials


  
bool CAdvTerrain::CalcNormals()
{
DWORD numVertices;
DWORD numFaces;

// Get face and vertex count

numFaces = m_TerrainFaces;
numVertices = m_TerrainVerts;

WORD* pNumOfSharedPolygons = new WORD[numVertices]; //Array holds how many times this vertex is shared

D3DXVECTOR3* pSumVertexNormal = new D3DXVECTOR3[3 * numFaces]; //Array holds sum of all face normals for shared vertex


ADVT_CUSTOMVERTEX* pVertices;
short* pIndices;

D3DXVECTOR3 vNormal;

//Lock the vertex buffer

m_pTerrainVB->Lock(0, numVertices * sizeof(ADVT_CUSTOMVERTEX),(void **)&pVertices, 0);

m_pTerrainIB->Lock(0, 3 * numFaces * sizeof(short), (void **)&pIndices, 0);

int facenew = 0;
for (DWORD i=0; i < numFaces ; i++)
{
pNumOfSharedPolygons[pIndices[3*i+0]] = 0;

pSumVertexNormal[pIndices[3*i+0]] = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
pSumVertexNormal[pIndices[3*i+1]] = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
pSumVertexNormal[pIndices[3*i+2]] = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
}
for (DWORD i=0; i < numFaces ; i++)
{
D3DXVECTOR3 v0 = pVertices[pIndices[3*i+0]].p;
D3DXVECTOR3 v1 = pVertices[pIndices[3*i+1]].p;
D3DXVECTOR3 v2 = pVertices[pIndices[3*i+2]].p;

vNormal = GetTriangeNormal(&v0, &v1, &v2);



pNumOfSharedPolygons[pIndices[3*i+0]]++;
pNumOfSharedPolygons[pIndices[3*i+1]]++;
pNumOfSharedPolygons[pIndices[3*i+2]]++;

pSumVertexNormal[pIndices[3*i+0]] += vNormal;
pSumVertexNormal[pIndices[3*i+1]] += vNormal;
pSumVertexNormal[pIndices[3*i+2]] += vNormal;



}

// Direction vector OF DIRECTIONAL LIGHT TO TEST NORMALS dont need to enable d3d lighting

D3DXVECTOR3 lightpos = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
float factor = 0.0f;
//For each vertex, calculate the average normal

for(i = 0; i < numVertices; i++)
{
vNormal.x = pSumVertexNormal[i].x / pNumOfSharedPolygons[i];
vNormal.y = pSumVertexNormal[i].y / pNumOfSharedPolygons[i];
vNormal.z = pSumVertexNormal[i].z / pNumOfSharedPolygons[i];

D3DXVec3Normalize(&vNormal, &vNormal);
pVertices[i].n = vNormal;

D3DXVec3Normalize(&lightpos, &lightpos);
factor = D3DXVec3Dot(&vNormal, &lightpos);

if (factor < 0)
factor = 0;

float red = 25.0f * factor;
float gre = 185.0f * factor; // terrain green color

float blu = 55.0f * factor;

pVertices[i].d = D3DCOLOR_XRGB((int)red, (int)gre, (int)blu);
}

// Smooting stuff in rows and cols



float k = 0.0f;


m_pTerrainVB->Unlock();
m_pTerrainIB->Unlock();

return true;
}

aker_jus
aker_jus
I fixed it, it was mainly the Scene ambient color!! I had it white, thus overriding the light color. I will post some screenshots soon for you to see.
GraphicsWare|RenderTechhttp://www.graphicsware.com3D Graphics & Solutions

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.