Việc tính toán bình thường từ các vị trí đỉnh khá đơn giản bằng cách sử dụng sản phẩm vectơ chéo.
Các sản phẩm chéo của hai vectơ và (lưu ý , hoặc đôi khi ) là một vuông góc với véc tơ để và , chiều dài , với góc giữa và . Hướng của vectơ sẽ phụ thuộc vào thứ tự của phép nhân: ngược với (hai hướng vuông góc với mặt phẳng).v u × v u ∧ v u v | | u × v | | = | | bạn | | ⋅bạnvu × vu∧vuv||u×v||=||u||⋅||v||sin(θ)θuvu×vv×u
Nếu bạn không quen thuộc với sản phẩm chéo, tôi mời bạn đọc về nó và cảm thấy thoải mái với nó. Định mức sau đó sẽ có vẻ đơn giản.
Tiêu chuẩn che bóng phẳng
Nếu bạn có tam giác , là một vectơ vuông góc với tam giác và có chiều dài tỷ lệ với diện tích của nó. Vì bình thường là vectơ đơn vị vuông góc với mặt phẳng của tam giác, nên bạn có thể nhận được bình thường với:ABCAB×AC
N=AB×AC||AB×AC||
Trong mã, điều này sẽ trông giống như n = normalize(cross(b-a, c-a))
ví dụ. Chỉ cần áp dụng điều này trên tất cả các khuôn mặt của bạn và bạn sẽ có quy tắc trên mỗi khuôn mặt.
For each triangle ABC
n := normalize(cross(B-A, C-A))
A.n := n
B.n := n
C.n := n
Lưu ý rằng điều này giả định các đỉnh không được chia sẻ giữa các hình tam giác. Tôi không quen thuộc với API Kinect; Rất có thể chúng được chia sẻ, trong trường hợp đó bạn sẽ phải sao chép chúng hoặc chuyển sang giải pháp tiếp theo:
Thông thường bóng mờ
Sau khi chiếu sáng với các thông số được tính toán như trên, bạn sẽ thấy rằng các cạnh tam giác là rõ ràng. Nếu điều này không được mong muốn, thay vào đó, bạn có thể tính toán các quy tắc trơn tru, bằng cách tính đến tất cả các khuôn mặt có chung một đỉnh.
Ý tưởng là nếu một đỉnh giống nhau được chia sẻ bởi ba tam giác , và chẳng hạn, bình thường sẽ là trung bình của , và . Hơn nữa, nếu là một tam giác lớn và là một hình nhỏ, bạn có thể muốn chịu ảnh hưởng của nhiều hơn .T 2 T 3 N N 1 N 2 N 3 T 1 T 2 N N 1 N 2T1T2T3NN1N2N3T1T2NN1N2
Hãy nhớ làm thế nào các sản phẩm chéo tỷ lệ với diện tích? Nếu bạn thêm các sản phẩm chéo sau đó bình thường hóa tổng, nó sẽ thực hiện chính xác tổng trọng số mà chúng tôi muốn. Vì vậy, thuật toán trở thành:
For each vertex
vertex.n := (0, 0, 0)
For each triangle ABC
// compute the cross product and add it to each vertex
p := cross(B-A, C-A)
A.n += p
B.n += p
C.n += p
For each vertex
vertex.n := normalize(vertex.n)
Kỹ thuật này được giải thích chi tiết hơn trong bài viết này của Iñigo Quilez: chuẩn hóa thông minh của lưới .
Để biết thêm về thông thường, xem thêm:
x
là sản phẩm chéo)