Planar mapping and normals

Started by
21 comments, last by jpventoso 15 years, 11 months ago
Hi everybody :) Excuse my English... I'm implementing LightMaps in my 3D engine using the planar mapping algorithm. I will explain it for whoever is interested. Steps (for each polygon): 1- Obtain the polygon normal and choose the greater element to generate the texture coordinates using the remaining elements: For a polygon (suppose a triangle) [A B C], I get the normal [N] and compare:

if (Abs(N.x) > Abs(N.y)) (Abs(N.x) > Abs(N.z)) then
   Make UV coordinates from the YZ elements of the polygon. 
   Set variable "Flag = 1"
if (Abs(N.y) > Abs(N.yx) (Abs(N.y) > Abs(N.z)) then
   Make UV coordinates from the XZ elements of the polygon. 
   Set variable "Flag = 2"
else
   Make UV coordinates from the XY elements of the polygon. 
   Set variable "Flag = 3"

2- The next step in the algorithm is to obtain the maximum and minimum of these coordinates, in order to clamp them to the range [0..1]: For each coordinate:

   Save the minimum U into U_Min
   Save the minimum V into V_Min
   PolygonVertex.U = (PolygonVertex.U - U_Min) / (U_Max - U_Min) 
   PolygonVertex.V = (PolygonVertex.V - V_Min) / (V_Max - V_Min) 

- Then, the lightmap position vectors are transformed into world space by using the equation of the plane to obtain the remaining unknown element:

if Flag = 1 then
   // Vertex 1
   V1.x = - (N.y * U_Min + N.z * V_Min & D) / N.x; // Plane equation
   V1.y = U_Min 
   V1.z = V_Min 
   // Vertex 2
   V2.x = - (N.y * U_Max + N.z * V_Min & D) / N.x; // Plane equation 
   V2.y = U_Max 
   V2.z = V_Min 
   // Vertex 3
   V3.x = - (N.y * U_Min + N.z * V_Max & D) / N.x; // Plane equation
   V3.y = U_Min 
   V3.z = V_Max 
if Flag = 2 then
   // Vertex 1
   V1.x = U_Min 
   V1.y = - (N.x * U_Min + N.z * V_Min & D) / N.y; 
   V1.z = V_Min 
   // Vertex 2
   V2.x = U_Max 
   V2.y = - (N.x * U_Max + N.z * V_Min & D) / N.y; 
   V2.z = V_Min 
   // Vertex 3
   ... 
if Flag = 3 then
   ... 

Now, to achieve the standard per pixel lighting, I need to do the product N.L for every pixel (or lumel, in this case). I can easily get the L factor from the previous algorithm, just interpolating between through the vertices:

Edge1 = V2 - V1 
Edge2 = V3 - V1 
for each pixel U 
   for each pixel V 
     Pixel = V1 + Edge1 * U + Edge2 * V 

Finally (!), here comes my problem: I don't know how to get the same interpolation factor for the N (normal) factor just like I did for the L factor. That's because I have only the normal of the plane, and what I need is the normal for each vertex V1, V2, and V3. The Planar Mapping algorithm projects the vectors into the UV plane and changes its orientation depending on the normal N, so I can't see how can I get my original normals. Is there another equation that allows me to get the original vectors from the equation of the plane, the normal of the plane and/or the transformed vectors (V1, V2, V3)? Better still, is there a matrix that represents the transformation done, so I can get the original vectors from the new ones (V1, V2 and V3)? I will appreciate any help :) Thanks guys!
Advertisement
Quote:
I don't know how to get the same interpolation factor for the N (normal) factor just like I did for the L factor. That's because I have only the normal of the plane, and what I need is the normal for each vertex V1, V2, and V3.


I don't quite understand what you're asking in this sentence. You want vertex normals?
Why can't you just sum up the plane normals around each vertex?
Oops, I know sometimes (almost anytime :) ) I'm not clear...
I will be more graphical now:

After getting the texture coordinates with planar mapping, I have only one normal for the entire triangle, the normal of the plane the polygon lies on. When I compute the N.L product my result is:



Instead, I need the normals of the original vertices of the triangle, in order to make an interpolation between them for Phong Shading:


(This last capture uses dynamic lighting instead of lightmaps).

But after the world space transform I don't know how to get them.
If I make the interpolation from the normal 1 to 3 (in the order of the vertex buffer) my results are wrong:



I hope you can help me... Thanks!
From what I remember:

For a triangle, the Phong (?) interpolated normal is:

N = N0*w0 + N1*w1 + N2*w2

where barycentric weights:
w0 = 1 - u - v
w1 = u
w2 = v

N0,N1,N2 are the vertex normals of your triangle.

[Edited by - JakeM on May 10, 2008 7:33:24 PM]
Thanks for your answer, but I already knew that formula :(. In fact, that's the one I'm applying in the third screenshot.

I will try to show my problem in another way.

By creating the lightmap for each triangle, I get the minimum and maximum U and V, and the vertices of the plane for the lightmap are created from these values, which generates a projection that may be, for example:

Case 1:



Case 2:



Where N1, N2 and N3 are the vertex normals, and Np is the plane normal.

This makes me unable to interpolate the vertex normals, as the projection on the plane for the lightmap may vary depending on the position values for each vertex.

On the other hand, I know that it is possible to apply Phong Shading on a lightmap.
Does anyone could do this?
Is it necessary to implement another different technique than Planar Mapping?
For a vertex normal, I average the normals of all the triangles that share the vertex. It comes out looking nice and smooth.
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
Well, I kinda do that now, by using the plane normal (screenshot 1)... But it doesn't come out looking nice and smooth in my case :(

How do you achieve that with just an average? I assume that you're talking about cubic meshes or spheres with a high poly count...?
Quote:Original post by jpventoso
Well, I kinda do that now, by using the plane normal (screenshot 1)... But it doesn't come out looking nice and smooth in my case :(

How do you achieve that with just an average? I assume that you're talking about cubic meshes or spheres with a high poly count...?


Well, on the first one it looks like the entire polygon is lighted evenly based on that polygon's normal.

What I was referring to was how to find the vertex normals, although you still have to interpolate between them. The entire process would work something like this:

//pseudocodefor every polygon p {  for every vertex i in polygon p {    for every polygon q which uses vertex i {      vertex_normal += polygon_normal[q] / number_of_polygons_that_use_vertex_i    }  }for every point x in polygon p {  for every vertex i in polygon p {    point_normal[x] += weight*vertex_normal  }}

Where weight is inverse proportional to the distance between point[x] and vertex, and the sum of all weight = 1.

We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
Wow, at a first glimpse I didn't understand a thing but that algorithm seems to be just the solution I'm looking for! :)

I'm going to print it and think about it carefully; Thanks for the help!

I'll post any news tomorrow. Thanks again!
Quote:
This makes me unable to interpolate the vertex normals, as the projection on the plane for the lightmap may vary depending on the position values for each vertex.


How do you plan to use this interpolated normal? Are you trying to project it to 2D? If so, why?

This topic is closed to new replies.

Advertisement