Mẹ ơi, không cần ma trận cũng được
(enkimute.github.io)- Đây là một thử nghiệm áp dụng Euclidean PGA đến cùng trong một forward renderer tương thích glTF, thay cho ma trận 4x4 vốn được dùng gần như theo quán tính trong đồ họa 3D
- Phép quay và tịnh tiến được biểu diễn bằng PGA motor gồm 8 số float, và phép hợp thành motor tổng quát được xử lý với 48 phép nhân và 40 phép cộng, ít hơn phép nhân ma trận 4x4 với 64 phép nhân và 48 phép cộng
- Biến đổi điểm nếu khai triển đơn thuần thì đắt hơn ma trận, nhưng với sandwich product tận dụng điều kiện chuẩn hóa thì có thể giảm xuống còn 21 phép nhân và 18 phép cộng; biến đổi hướng và hướng cơ sở còn rẻ hơn nữa
- Trong tangent space normal mapping, normal và tangent được thay bằng tangentRotor, giúp giảm dữ liệu đỉnh từ 12 float xuống 9 float, đồng thời đưa chi phí biến đổi sang world-space về mức gần tương đương cách dùng ma trận với 47 phép nhân và 38 phép cộng
- Để khớp với nội dung glTF thực tế, cần chuyển ma trận sang motor khi tải và theo dõi uniform scale bằng một float riêng; còn non-uniform scale thì cần xử lý hạn chế hoặc một đường fallback dùng ma trận 4x4
Forward renderer không dùng ma trận được xây bằng PGA
- Dự án là Look, Ma, No Matrices, với mục tiêu triển khai một forward renderer không dùng ma trận
- Từ sau SIGGRAPH 2019, Geometric Algebra, đặc biệt là Euclidean PGA, đã thu hút sự quan tâm trong cộng đồng đồ họa và machine learning, nhưng trong đồ họa 3D truyền thống thì nhiều trường hợp chỉ dừng ở mức gọi dual quaternion bằng tên khác là PGA motor
- Bản triển khai này tích hợp PGA algebra vào một engine 3D tương thích glTF, không chỉ đổi tên đại số mà còn cấu trúc lại nhiều phần trong pipeline đồ họa theo cách của PGA
- Bản triển khai đối chiếu là Khronos glTF viewer, và đây gần với một thí nghiệm thay thế ma trận không thỏa hiệp hơn là một bản cài đặt tối ưu hiệu năng
- Cuối cùng, hybrid solution rất có thể sẽ là lựa chọn tốt hơn
Vì sao cần hoài nghi ma trận 4x4
- Ma trận 4x4 đã giữ vai trò trung tâm rất lâu trong graphics API và pipeline fixed-function của GPU, và đến nay vẫn là công cụ mặc định của forward rendering thông thường
- GPU hiện đại đã tiến gần hơn tới bộ xử lý vô hướng lập trình được thay vì pipeline fixed-function, nên biểu diễn lấy ma trận làm trung tâm không còn là điều bắt buộc
- Trong engine 3D thực tế, nhiều ma trận chỉ chứa phép quay và tịnh tiến, tức là các ma trận trực giao
- PGA motor manifold biểu diễn toàn bộ chuyển động Euclid với chi phí tính toán và bộ nhớ thấp hơn, đồng thời vẫn bao hàm quaternion và dual quaternion mà không cần chuyển đổi
Biểu diễn dữ liệu PGA và các phép toán cơ bản
- PGA algebra được sinh từ bốn vector cơ sở
e0~e3e1,e2,e3lần lượt tương ứng với các mặt phẳngx=0,y=0,z=0- vector suy biến đặc biệt
e0biểu diễn mặt phẳng ở vô cực
- Trong shader, việc triển khai dùng các kiểu dựng sẵn của GLSL để tận dụng cộng, trừ và nhân vô hướng mà không cần nạp chồng toán tử
motor mat2x4line mat2x3point vec3direction vec3
- Hợp thành PGA motor tổng quát được thực hiện bằng geometric product
- Nhân ma trận 4x4: 64 phép nhân, 48 phép cộng
- Hợp thành motor tổng quát
gp_mm: 48 phép nhân, 40 phép cộng
- Với các tổ hợp biến đổi đặc biệt, có thể dùng các phép toán rẻ hơn
gp_rr: 16 phép nhân, 12 phép cộnggp_tt: 0 phép nhân, 3 phép cộnggp_rt/gp_tr: 12 phép nhân, 8 phép cộnggp_rm/gp_mr: 32 phép nhân, 24 phép cộnggp_tm/gp_mt: 12 phép nhân, 12 phép cộng
Tối ưu biến đổi điểm và hướng
- Trong PGA, khi biến đổi điểm
pbằng motorMthì dùng sandwich productM p M̃ - Nếu khai triển thẳng thì cần 33 phép nhân và 29 phép cộng, lớn hơn phép nhân ma trận-vectơ với 16 phép nhân và 12 phép cộng
- Nếu biến đổi công thức dựa trên việc motor đã chuẩn hóa thỏa
M M̃ = 1thì có thể hạ biến đổi điểm xuống còn 21 phép nhân, 18 phép cộng - Hướng, tức điểm ở vô cực, còn rẻ hơn vì hệ số
e123ngầm hiểu bằng 0- Biến đổi hướng tổng quát: 18 phép nhân, 12 phép cộng
- Biến đổi hướng cơ sở, ví dụ trục x, có thể hạ xuống tới 6 phép nhân và 4 phép cộng
- Tối ưu hướng cơ sở này về sau trở thành cơ sở để lung lay quan niệm rằng ma trận luôn là cách nhanh nhất trong xử lý tangent frame
Chuẩn hóa, căn bậc hai, ánh xạ mũ và log
- Squared pseudonorm của PGA motor có dạng Study Number
M M̃ = a + b e0123 - Chuẩn hóa không phải chỉ là chuẩn hóa vectơ đơn giản, mà là một quy trình đảm bảo motor kết quả trở thành phép biến đổi orthonormal
- Chi phí triển khai chuẩn hóa motor tổng quát: 21 phép nhân, 5 phép cộng
- Với phép tịnh tiến thuần hoặc quay thuần, có thể dùng các phiên bản hiệu quả hơn
- Phép biến đổi rigid giữa hai điểm, hai đường thẳng hoặc hai mặt phẳng
a,bđược biểu diễn bằngM = sqrt(b / a)- Geometric product
bacủa hai phần tử cùng loại tạo ra một motor tương ứng với gấp đôi phép biến đổi đi từasangb - Có thể tính dưới dạng
sqrt M = normalize(1 + M)
- Geometric product
- Logarithm của PGA motor là một scaled line, và scaled line có thể tạo ra motor quay bằng exponentiation
- Exponential map của ma trận 4x4 tổng quát vốn tốn kém về mặt số học, nhưng trên PGA motor manifold thì có dạng đóng hiệu quả
Nghịch đảo và phân rã motor
- Geometric Algebra cho phép tính nghịch đảo của các đối tượng đã chuẩn hóa một cách hiệu quả
- nghịch đảo mặt phẳng: chính nó
- nghịch đảo đường thẳng: đảo dấu
- nghịch đảo điểm: đảo dấu
- nghịch đảo motor: reversion
- Khi một bivector tổng quát không thỏa điều kiện Plücker nên không biểu diễn một line đơn lẻ, có thể tính nghịch đảo bằng Study Number inverse
- Bản triển khai render dùng hai kiểu factorization
- Euclidean factorization: phân rã motor thành một phép quay quanh gốc rồi tới một phép tịnh tiến
- Invariant factorization: phân rã motor thành phép tịnh tiến và phép quay giao hoán với nhau; trong 3D đây là dạng được biết đến theo định lý Mozzi-Chasles
- Khi hợp thành tangent frame với object-to-world motor, Euclidean factorization hữu ích do tính chất frame là bất biến theo tịnh tiến
Xử lý ma trận glTF và scale
- Để tương tác với nội dung glTF hiện có, cần chuyển ma trận sang PGA motor ngay lúc tải
- Ma trận trực giao 4x4 được chuyển sang motor bằng cách tận dụng tính đẳng cấu với quaternion
- Tất cả matrix và transformation nhập vào đều được chuyển đổi ở thời điểm load
- PGA motor chỉ xử lý rigid body transformation nên không bao gồm scaling
- Uniform scaling là bất biến với quay và tịnh tiến nên được theo dõi bằng một float cho mỗi node
- Total scale của mỗi phần tử được tính bằng tích giữa scale của nó và scale của parent
- Total scale được áp vào vertex ở thời điểm load hoặc ở bước đầu của vertex shader
- Với translation, parent scale được áp dụng ở thời điểm load và khi cập nhật animation
- Trong khoảng 400 tệp glTF ngẫu nhiên, các trường hợp có scale animation chiếm dưới 0,5%, còn fixed uniform scale thì xuất hiện khá nhiều
- Non-uniform scaling không bất biến theo quay nên khó xử lý hơn
- Với non-uniform scale tổng quát, một đường fallback dùng ma trận 4x4 gần như là không thể tránh khỏi
- Trong mẫu glTF, các trường hợp non-uniform scale chỉ xuất hiện ở leaf node; khi đó có thể áp scale riêng trước các biến đổi còn lại mà không ảnh hưởng tới animation key
Thay thế Model-View-Projection
- Forward renderer biến đổi mesh geometry trong object space sang screen space và quyết định mỗi tam giác phủ những pixel nào
- Trong pipeline thông thường, model và view được thay bằng PGA motor trong khi projection matrix thì không
- vertex position dùng
sw_mp - hướng normal và tangent dùng
sw_md
- vertex position dùng
- Projection matrix thường chỉ có 5 phần tử khác 0, nên thay vì ép chuyển sang PGA, bản triển khai dùng trực tiếp biểu thức projection
- Ở phía CPU, cập nhật scene graph hierarchy dùng hợp thành motor thay cho hợp thành ma trận nên giảm lượng tính toán
- Ở phía GPU, nếu chỉ so riêng phép biến đổi vertex thì motor có vẻ bất lợi, nhưng kết quả thay đổi khi cách biểu diễn tangent frame được đổi
Tối ưu tangent space normal mapping
- Vertex shader của một mesh normal-mapped theo tangent space thông thường phải biến đổi position, normal và tangent
- Vì normal, tangent và bitangent tạo thành một frame trực chuẩn, trong PGA chúng có thể được biểu diễn bằng tangentRotor đi từ canonical basis frame tới tangent frame mong muốn
- Cách này giúp giảm vertex descriptor
- Cách cũ: position 3 + normal 3 + tangent 4 + uv 2 = 12 float
- Cách PGA: position 3 + tangentRotor 4 + uv 2 = 9 float
- Số float trên mỗi đỉnh giảm 25%
- tangentRotor có double cover, và dấu của hệ số vô hướng được ghép với cờ handedness cổ điển để phân biệt even/odd k-reflection
- Cách này dựa vào signed zero, và vertex shader trích handedness bằng
sign(1/tangentRotor.x)
- Cách này dựa vào signed zero, và vertex shader trích handedness bằng
- Nếu biến đổi position, normal và tangent bằng ma trận 4x4 thì tổng cộng cần 48 phép nhân và 36 phép cộng
- Với PGA, toàn bộ tangent frame được biến đổi một lần rồi mới trích normal và tangent
- Hợp thành tangent frame: 16 phép nhân, 12 phép cộng
- Trích normal/tangent: 9 phép nhân, 8 phép cộng
- Biến đổi position: 21 phép nhân, 18 phép cộng
- 1 phép nhân để trích handedness
- Tổng cộng 47 phép nhân, 38 phép cộng
- Chi phí biến đổi đỉnh gần như tương đương cách dùng ma trận, còn lưu trữ transform thì giảm từ 32 float xuống 8 float
Fragment shader và ràng buộc của baked texture
- Để nạp nội dung hiện có, ở giai đoạn fragment shader vẫn cần TBN matrix trở lại
- Công cụ baking nướng lưới độ chi tiết cao xuống lưới thấp bằng cách nội suy vertex normal và tangent trên mặt tam giác, rồi dựng TBN matrix trực giao ở mỗi fragment để tạo texture normal trong tangent space
- Nội suy các basis vector tạo ra sai số điển hình của cách làm dựa trên ma trận, và sai số đó đã được baked sẵn vào texture
- Vì vậy, bản triển khai này trích riêng normal và tangent vector từ tangentRotor
- Nếu có thể kiểm soát cả công cụ baking, có thể truyền nguyên tangentRotor sang fragment shader rồi chuẩn hóa và dùng để biến đổi sampled normal
- Không cần tạo TBN matrix
- Không cần trích normal/tangent trong vertex shader
- Có thể giảm một varying parameter
- Đồng thời loại bỏ bước orthogonalization tốn kém trong fragment shader
Motor skinning và trộn animation
- PGA motor đẳng cấu với dual quaternion nên áp dụng cho skinning rất tự nhiên
- Sau khi chuyển inverse bind matrix sang motor, có thể blend bone motor theo cùng mẫu với dual quaternion skinning
- Các transformation được blend sẽ được chỉnh dấu để đi theo shortest arc, rồi transformation kết quả được chuẩn hóa lại
- Animation blending cũng làm tương tự ở phía CPU: blend trực tiếp các PGA motor rồi chuẩn hóa
Kết quả của thử nghiệm thay thế ma trận
- Việc thay ma trận hoàn toàn bằng PGA trong một forward renderer tương thích glTF là khả thi
- Dự đoán rằng chi phí biến đổi sẽ cao hơn không còn đơn giản đúng nữa khi áp dụng biểu diễn tangent frame và tối ưu sandwich product
- Trong trường hợp phổ biến là tangent space normal mapping, cách dùng PGA motor giữ chi phí vertex shader gần như ngang với cách dùng ma trận, đồng thời giảm mạnh memory footprint của vertex
- Mức cải thiện bộ nhớ cho phép chứa khoảng nhiều hơn 33% số đỉnh trong cùng một dung lượng lưu trữ là điểm đặc biệt nổi bật
- Kỹ thuật này có thể được áp dụng như một drop-in replacement cho engine 3D hiện có mà gần như không làm tăng chi phí vertex shader và không cần sửa phần còn lại của pipeline
1 bình luận
Các ý kiến trên Hacker News
Một trong những YouTuber về toán/đồ họa mà tôi thích, Freya Holmér, cách đây không lâu đã làm một video nhập môn đại số hình học rất hay: https://www.youtube.com/watch?v=htYh-Tq7ZBI&ab_channel=Freya...
Nếu bạn quan tâm đến đồ họa 3D, đặc biệt là spline/đường cong Bézier, thì tất cả video của cô ấy đều đáng xem
Cá nhân tôi luôn thấy đại số tuyến tính khó, nhưng cách tiếp cận kiểu đại số Clifford này trực quan hơn nhiều
Thư viện này do enkimute, tác giả bài gốc, tạo ra; dù chỉ là một script một file, không cần build, nó vẫn là một thư viện khá đáng kinh ngạc, cung cấp cả đại số N chiều lẫn hỗ trợ dựng hình
Chẳng hạn có những giải thích khá ổn về các phần Freya lướt qua hơi nhanh hoặc bỏ qua, như tính không giao hoán của phép nhân
Đại số hình học từng là một bí ẩn hoàn toàn với tôi trong một thời gian, nhưng cuối cùng tôi hiểu ra theo cách này: nó chỉ là phép nhân đa thức, chỉ có điều có những đại lượng mà thứ tự nhân là quan trọng và bảng nhân thì kỳ lạ. Ví dụ
i*i = 1,i*j = -j*iHầu hết tài liệu nhập môn khiến tích hình học của hai vector
(x1*i + y1*j) * (x2*i + y2*j)trông sâu xa và huyền bí, nhưng thật ra nó giống hệt khai triển FOIL đã học trong đại số năm nhất:(x1*i + y1*i)(x2*i+y2*j) = x1*x2*i*i + x1*y2*i*j + y1*x2*j*i + y1*y2*j*j = (x1*x2 + y1*y2) + (x1*y2 - y2*x1)*i*jGiá trị trong ngoặc thứ nhất là tích vô hướng quen thuộc, còn giá trị trong ngoặc thứ hai tương ứng với tích có hướng quen thuộc, nhưng được biểu diễn bằng một cơ sở của chiều mới gọi là
i*j. Và khác với tích có hướng, nó tổng quát hóa được sang số chiều tùy ý; trong đại số hình học, nó được gọi là tích nêmKhi hiểu điều này, những thứ như suy ra công thức quay cũng trở nên dễ hơn. Vì các kỹ thuật đã học trong đại số có thể được áp dụng trực tiếp để giải các bài toán hình học
Nếu định nghĩa tích của một vector với chính nó là bình phương độ dài của vector đó, thì mọi thứ còn lại đều suy ra từ phép nhân đa thức đơn giản. Khá đẹp
“Nó hoạt động như thế nào?” và “Tại sao nó hoạt động?” là hai câu hỏi mà giáo viên toán phải cân bằng, và trong một khóa học không phải lúc nào cũng dễ trả lời tốt cả hai
Tích có hướng của hai vector 3 chiều là một vector khác vuông góc với mặt phẳng do hai vector đó tạo ra. Trong khi đó, tích đại số ngoài là một 2-vector, tức bivector, quét qua hình bình hành giữa hai vector và nằm trên mặt phẳng chứa hai vector đó. Trong 3 chiều, vector tích có hướng vuông góc với mặt phẳng bivector này
Đặc biệt, để định nghĩa một tích song tuyến tính
m:V x V -> Vtrên không gian vectorV, điều đó chính xác tương đương với việc chỉ cần định nghĩamcho các cặp vector cơ sở. Nếu gọi đây là “tính chất phổ quát của tích tensor”, có lẽ người ta sẽ chỉ nói “à, ra vậy”Với nội suy phép quay, có nhiều cách tiếp cận như đại số hình học, quaternion, thậm chí nội suy toàn bộ ma trận, nên khá thú vị: https://www.gamedev.net/tutorials/programming/math-and-physi...
Nhưng sau khi tối ưu code bằng tay, code cuối cùng trong hầu hết các cách tiếp cận gần như giống nhau. Khác biệt nằm ở cách ta hiểu các quy tắc và khả năng
Trong phạm vi hiểu biết hạn chế của tôi, đại số hình học có vẻ là cách tiếp cận nhất quán và mạnh mẽ nhất. Nó lạ lẫm, và ban đầu khá khó tiếp nhận, nhưng những người vượt qua được rào cản đó thì đều thích
Ngược lại, ai cũng dùng quaternion nhưng lại phàn nàn rằng không hiểu chúng, và nói rằng muốn trực quan hóa thì cần cả một cuốn sách. Kiểu như cuốn 『Visualizing Quaternions』 của Andrew J. Hanson và Steve Cunningham
Đại số hình học thì thú vị, còn quaternion thì không. Với đại số hình học tôi có cảm giác mình hiểu được, còn với quaternion, dù theo các bài giảng và bài tập, điều duy nhất tôi chắc chắn là mình không hiểu. Giờ khi đã biết một chút đại số hình học, cuối cùng tôi cũng có cảm giác phần nào hiểu quaternion
https://www.goodreads.com/en/book/show/4419538
Nếu bạn quan tâm đến chủ đề này, có một bộ slide hay lướt qua các khái niệm Grassman/Clifford/đại số hình học: http://www.terathon.com/gdc12_lengyel.pdf
Cũng có một trang hay khác: https://mattferraro.dev/posts/geometric-algebra
Cũng không thể bỏ qua bài “A swift introduction to projective geometric algebra” xuất sắc của Sudgy: https://www.youtube.com/watch?v=0i3ocLhbxJ4
Và trang tham khảo tiêu biểu là https://bivector.net
Bạn cũng có thể tham gia Discord bivector với hơn 1.000 giáo sư, nhà nghiên cứu và người đam mê: https://discord.gg/vGY6pPk
Thành thật mà nói, tôi không thích cách đại số hình học tạo ra đủ loại phần tử hỗn hợp nếu không cẩn thận xem đang nhân cái gì với cái gì
Việc với một không gian n chiều mà có thể cần tới
2^nhạng tử cũng khiến nó có vẻ khó xử lýNó lẽ ra phải giúp xử lý hình học, tức tích vô hướng, tốt hơn, nhưng tôi chưa thấy lời giải thích thuyết phục nào về lý do không thể chỉ dùng tích nêm và toán tử sao Hodge hoặc musical isomorphism
Thứ “ma thuật” biến bivector
u^vthành phép quay trong mặt phẳng đóe^(u^v)tvề bản chất cũng là dùng musical isomorphism để biến 2-formu^vthành một tự đẳng cấu tuyến tính, rồi hiểue^(u^v)tnhư lũy thừa ma trậnMột ví dụ khác thường được nhắc tới là có thể gộp các phương trình Maxwell thành một phương trình, nhưng với dạng vi phân thì vốn đã có thể tóm tắt thành hai phương trình đúng vì những lý do khác nhau, nên tôi không hiểu lợi ích của việc gộp chúng thành một
2^nhạng tử” đôi khi là một ảo giác về tiết kiệmVí dụ vector pháp tuyến biến đổi khác với vector vị trí. Bạn có thể biểu diễn cả hai bằng cùng một cấu trúc dữ liệu, nhưng phải theo dõi bên trong đó là loại vector nào và phải thêm các trường hợp đặc biệt xử lý khác nhau ở khắp nơi trong code
Đại số hình học đối diện trực tiếp với chuyện này: dùng cơ sở
(i,j,k)cho vector, và dùng cơ sở riêng(j*k, k*i, i*j)cho loại khácTheo nghĩa một phương trình tốt hơn hai hay bốn phương trình, đây là một ví dụ hay cho thấy không gian chiều cao hơn đôi khi lại kinh tế hơn về mặt lưu trữ so với chiều thấp hơn
Điện trường khác từ trường theo cách khá giống với việc vector khác bivector. Bạn có thể xử lý đặc biệt điện trường và từ trường bằng các phương trình riêng, hoặc có thể xử lý chúng một cách đồng nhất theo một cách
Quaternion có
w=1, x,y,z=0là đồng nhất, còn quaternion nhưw=0, x=1hoặcw=0, x=y=0.7chỉ tương ứng với phép quay 180 độNếu muốn phép quay tùy ý, bạn cần tổ hợp của cả hai. Tức là trộn “một chút phép quay 180 độ quanh đường thẳng này, và một chút phép quay 0 độ/đồng nhất”. Việc có cả scalar lẫn bivector chính là ý này
Nếu bạn đang cố “cẩn thận” tránh sự pha trộn bằng tích nêm và tích vô hướng thì bạn đang dùng sai. Tích hình học mới là nhân vật chính, và nó tạo ra những sự pha trộn rất tuyệt
Ví dụ nếu xử lý pháp tuyến, bạn phải theo dõi ít nhất hai không gian n chiều biến đổi khá khác nhau
Việc biểu diễn điểm, mặt phẳng, đường thẳng, pháp tuyến, phép tịnh tiến và phép quay bằng một kiểu multivector duy nhất cùng các quy tắc nhất quán, một khi hiểu ra, đem lại cảm giác khá giải phóng. Dù bản thân tôi vẫn đang học
Phần nội suy hoạt ảnh ở phía dưới thật sự rất ngầu, nhưng tôi ước các mô hình ở phần còn lại của trang bớt năng động một chút
Toán học đã đủ khó ngay cả khi không có chú voi con cổ vũ
Nếu tác giả đang xem, tôi mong khi dùng lần đầu viết tắt PGA thì hãy định nghĩa nó
Nó thêm một vector cơ sở null vào các vector cơ sở của không gian đang làm việc. Nhờ vậy, các đối tượng hình học không đi qua gốc tọa độ cũng có thể được biểu diễn bằng đại số
Những thuật toán như thế này có hiệu quả ngay cả khi xét tới GPU không?
Tôi có ấn tượng mơ hồ rằng GPU được tối ưu cho các phép toán ma trận, nên tò mò liệu dùng công thức hóa bằng đại số hình học có làm mất lợi thế đó và thực tế không vượt lên được không
Đây chỉ là phỏng đoán của người không rành, nên nếu sai thì mong được sửa
Thực tế là toàn bộ shader core vốn đã là SIMD, nên không nhất thiết có thể làm như vậy. Có GPU làm, có GPU không
PGA có chi phí hiểu không nhỏ, nhưng là một cách rất tốt để xử lý điều thứ nhất. Dù sao thì thường cũng nên thử cách đơn giản nhất và dễ triển khai nhất trước
Phần triển khai có được sau khi dùng PGA để giải quyết điều thứ nhất là đủ để dựng prototype phần còn lại của chương trình, benchmark và tìm nút thắt cổ chai thật sự. May mắn là trong đa số trường hợp, đó hoặc là cách tính nhanh nhất, hoặc đủ nhanh để không trở thành nút thắt
Ngay cả khi nó trở thành nút thắt, nó vẫn giúp bạn hiểu sâu vấn đề đang giải. Tôi nghĩ nên có sự hiểu đó trước khi bắt đầu bào từng chu kỳ với hy vọng làm cho nó đủ nhanh
Việc này trông như một cuộc tranh hơn thua rất nhỏ ở rìa cuối của tiến bộ
Chuyện hoạt ảnh skeletal 3D vẫn dùng ma trận 4x4 trên GPU nghĩa là thứ toán được phát triển cho mục đích này trên CPU thời khoảng Half-Life 1 vẫn còn ở tuyến đầu. Từ 1998 đến 2024 là 26 năm
1.000 năm nữa hoạt ảnh 3D có lẽ vẫn sẽ như vậy
Bài này vượt quá phạm vi hiểu của tôi, nhưng tiêu đề làm tôi nhớ tới một thử nghiệm khi làm trình kết xuất 3D đơn giản
Sau nhiều lần thất bại khi cố học đại số tuyến tính, trong lúc tắm tôi chợt nghĩ rằng quay 3D chẳng qua là ba phép quay 2D, mà cái đó thì mình đã biết. Khoảng một giờ sau, tôi đã có một trình kết xuất wireframe 3D có cả phối cảnh
Khuyên mọi người nên thử một lần