Calculate the normal value based on the model vertex coordinates.

Source: Internet
Author: User

Although the 3ds file is read, The 3ds file does not contain the vertex normal. To calculate the illumination, We need to manually calculate the normal. The process is as follows:

Three non-common points form a triangle:

Calculation method: the cross multiplication between the vector AB and the vector ac generates a straight line perpendicular to the plane where the Triangle abc is located. The vertical line is the normal line of vertex.

The following is the code: [corrected the normal calculation bug, 2012.04.04]

 1 void CModel3ds::CalcNormals()
2 {
3 for(int i = 0; i<m_PolygonNum; ++i)
4 {
5 Vector3 v1 = Vector3_Sub(Vector3(m_pVBbuff[m_pIBbuff[i].p1].X, m_pVBbuff[m_pIBbuff[i].p1].Y, m_pVBbuff[m_pIBbuff[i].p1].Z),
6 Vector3(m_pVBbuff[m_pIBbuff[i].p2].X, m_pVBbuff[m_pIBbuff[i].p2].Y, m_pVBbuff[m_pIBbuff[i].p2].Z));
7 Vector3 v2 = Vector3_Sub(Vector3(m_pVBbuff[m_pIBbuff[i].p1].X, m_pVBbuff[m_pIBbuff[i].p1].Y, m_pVBbuff[m_pIBbuff[i].p1].Z),
8 Vector3(m_pVBbuff[m_pIBbuff[i].p3].X, m_pVBbuff[m_pIBbuff[i].p3].Y, m_pVBbuff[m_pIBbuff[i].p3].Z));
9 Vector3 tmp1 = Vector3_cross(v1,v2);
10 m_pVBbuff[m_pIBbuff[i].p1].nx += tmp1.x;
11 m_pVBbuff[m_pIBbuff[i].p1].ny += tmp1.y;
12 m_pVBbuff[m_pIBbuff[i].p1].nz += tmp1.z;
19 m_pVBbuff[m_pIBbuff[i].p2].nx += tmp1.x;
20 m_pVBbuff[m_pIBbuff[i].p2].ny += tmp1.y;
21 m_pVBbuff[m_pIBbuff[i].p2].nz += tmp1.z;
28 m_pVBbuff[m_pIBbuff[i].p3].nx += tmp1.x;
29 m_pVBbuff[m_pIBbuff[i].p3].ny += tmp1.y;
30 m_pVBbuff[m_pIBbuff[i].p3].nz += tmp1.z;
31 }
32
33 for(int i = 0; i < m_VertexNum; ++i)
34 {
35 Vector3_norm(m_pVBbuff[i].nx,m_pVBbuff[i].ny,m_pVBbuff[i].nz);
36 }
37 }

The above code is simply to calculate the average value of the triangle with common vertices in its common vertices. His results are of course not accurate, but most of the time they work normally :)

The vector operation defined in the Code uses a function in a mathematical library I wrote. This mathematical library is not for efficiency, but for decoupling the above Code from dx, avoid code sending and contain a pile of header files. Otherwise, copying this code will be very likely to cause compilation failure due to header file problems, which will lead to a lot of troubles. Therefore, the following library code is just to ensure normal operation (or there may be bugs, but I will try to fix and avoid this situation ):

View Code

 1 #ifndef myVector_h__
2 #define myVector_h__
3
4 namespace MY_MATH
5 {
6 class Vector3
7 {
8 public:
9 Vector3():x(0),y(0),z(0){}
10 Vector3(float _x, float _y, float _z):x(_x),y(_y),z(_z){}
11 float x;
12 float y;
13 float z;
14 };
15
16 Vector3 Vector3_Sub(Vector3 src,Vector3 dest)
17 {
18 return Vector3(src.x - dest.x,src.y - dest.y,src.z - dest.z);
19 }
20
21 void Vector3_norm(float& x, float& y, float& z)
22 {
23 float tmp = sqrtf(x*x+y*y+z*z);
24 x = x/tmp;y = y/tmp; z=z/tmp;
25 }
26
27 void Vector3_norm(Vector3& vec)
28 {
29 float tmp = sqrtf(vec.x*vec.x + vec.y*vec.y + vec.z*vec.z);
30 vec.x = vec.x/tmp;
31 vec.y = vec.y/tmp;
32 vec.z = vec.z/tmp;
33 }
34
35 Vector3 Vector3_cross(Vector3& v1, Vector3& v2)
36 {
37 return Vector3(v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x);
38 }
39 }
40
41
42
43 #endif // myVector_h__

This is the basic illumination rendering based on the calculated normal. The HLSL version shader is as follows:

cbuffer mybuff
{
uniform row_major float4x4 world_matrix;
uniform row_major float4x4 view_matrix;
uniform row_major float4x4 proj_matrix;
uniform float4 light_pos;
};

struct VS_INPUT
{
float4 Position : POSITION;
float3 Norm : NORMAL0;
float2 Tex : TEXCOORD0;
};

struct VS_OUTPUT
{
float4 Position : SV_POSITION;
float3 lt : TEXCOORD0;
float3 norm : TEXCOORD1;
};

VS_OUTPUT VS_MAIN(VS_INPUT In)
{
VS_OUTPUT Output;
float4x4 tmp = mul(world_matrix,view_matrix);
tmp = mul(tmp,proj_matrix);
Output.Position = mul(In.Position, tmp);

Output.lt = normalize(light_pos - In.Position);
Output.norm = normalize(mul(In.Norm, world_matrix));

return Output;
}

float4 PS_MAIN(VS_OUTPUT In) : SV_Target
{
float4 diff = {1.0,1.0,1.0,1.0};
float4 ambient = {0.1,0.1,0.1,1.0};
return ambient + diff*saturate(dot(In.lt,In.norm));
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.