Câu đùa “Chỉ cái đến từ vùng Verlet của Pháp mới là Verlet, còn không thì chỉ là Euler sủi bọt” rất hay
Tôi tò mò làm sao để đi từ kiến thức về phát triển web, Gradle, Java sang giai đoạn tạo ra những thứ như thế này
Vì không học đại học ngành CS, đôi khi tôi cảm thấy dù học bao nhiêu ngôn ngữ lập trình cũng sẽ không bao giờ hiểu được những thứ này. Tôi có thử động vào OPENLY, LIBGDX, GODOT, Unity một chút, nhưng việc xây dựng mô phỏng vải từ đầu thật sự khiến tôi thấy mù mịt
Nó đơn giản hơn tưởng tượng rất nhiều. Tôi đã làm bản demo “vải bị xé” được liên kết ở đâu đó trong luồng này trước cả khi bắt đầu sự nghiệp kỹ sư phần mềm
Ở đây dùng tích phân Verlet cơ bản: cập nhật các vector 2D tạo thành lưới dựa trên vị trí hiện tại và vị trí trước đó, rồi ràng buộc để chúng giữ một khoảng cách nhất định với các điểm lân cận trực tiếp. Vẽ các đường giữa những điểm đó là thành vải. Tôi biết đến nó đầu tiên khi bị cuốn hút bởi mô phỏng vật lý và tìm hiểu, vì đây là một trong những thứ dễ triển khai nhất; công sức bỏ ra so với kết quả rất tốt. Tất nhiên, từ đó trở đi thì phức tạp hơn nhiều
Tôi cũng từng cảm thấy tương tự vì muốn học mô phỏng vật lý. Theo thời gian, tôi học được rằng cần tách miền kiến thức như vật lý khỏi các công cụ lập trình dùng để triển khai nó
Đặc biệt nếu bắt đầu từ phát triển game, ta dễ có cảm giác rằng mỗi loại mô phỏng chính như vật rắn, vải, lò xo, chất lưu đều sẽ có một cách lập trình tự nhiên và quen thuộc tương ứng. Ban đầu tôi từng nghĩ mô phỏng chất lưu cũng sẽ được biểu diễn tự nhiên trong ngôn ngữ bằng cách tạo lưới rồi chọn quy tắc cập nhật ở mỗi bước thời gian. Nhưng thực tế là phải mô hình hóa vấn đề bằng toán học và vật lý, rồi ánh xạ nó sang ngôn ngữ và công cụ; các công cụ đó không phải lúc nào cũng biểu đạt theo cách quen thuộc
Có những thuật toán dễ chuyển thành code, như mô phỏng vải dựa trên vị trí hạt và lò xo, nhưng khi muốn đi xa hơn, chính điều đó lại khiến tôi hiểu lầm. Cuối cùng tôi phải đào sâu hơn vào vật lý và phân tích số, rồi mới chuyển vấn đề sang code; code kết quả có thể thô và có nhiều con số ma thuật
Phát triển web không chỉ giới hạn trong Java và nhìn chung bị chi phối bởi bài toán tích hợp component. Có nhiều cấu trúc nhưng ít nội dung, tính toán được ủy thác cho thư viện; khi build thì vấn đề là độ phức tạp tích hợp, khi chạy thì là quy mô hệ thống phân tán
Ngược lại, viết mô phỏng có khối lượng tính toán lớn nên phần lớn code là nội dung thực sự. Nếu phát triển web là sự kết hợp của những thứ dị chất, thì mô phỏng đồng nhất hơn. Vấn đề là bị giới hạn bởi hiệu năng của một tiến trình đơn trong ngân sách thời gian do số khung hình mỗi giây quyết định
Vì vậy bạn có thể tập trung vào một môi trường thực thi duy nhất. Tôi khuyên dùng trình duyệt, vì nó giải quyết giúp vấn đề triển khai. Ganja[1] có lẽ là dự án mô phỏng tối thượng theo kiểu “nội dung chứ không phải cấu trúc”. Nó rất đặc biệt và khó hiểu nên việc bảo trì đã dừng lại, nhưng nó vẫn chạy. Ở phía có cấu trúc hơn một chút là D3, nơi các tác giả đã xây sẵn những thuật toán trực quan hóa/bố trí hiện đại như đồ thị lực[2]. Điểm khởi đầu thân thiện hơn có thể là họ Processing[3], bắt đầu từ Java rồi được port sang Python, JavaScript, v.v.
Tuy nhiên, một mô phỏng vải đơn lẻ chỉ ở mức như một tế bào của một con chuột nếu ví với game engine. Game engine rất lớn, và trong đó bạn cũng chủ yếu làm nhiều tích hợp nội bộ hơn là tự viết mô phỏng
1 - https://github.com/enkimute/ganja.js/blob/master/ganja.js
2 - https://github.com/d3/d3-force/tree/main/src
3 - https://processing.org/
Rốt cuộc tất cả đều là toán học và vật lý
Dù bạn không hỏi đích danh về phát triển game, các kiến thức như đồ họa, toán, chiếu sáng, vật lý nói chung hiện diện rất nhiều trong lĩnh vực đó. Nếu chỉ tìm riêng một chủ đề ngách như mô phỏng vải, có thể khó tìm được thông tin không gắn với tài liệu phát triển game
Hôm nay tôi đọc https://alextardif.com/LearningGraphics.html, nó có thể là kim chỉ nam theo nhiều hướng. https://learnopengl.com/ vẫn luôn được đánh giá tốt dù hiện nay đã có các API mới hơn như Vulkan, Metal, DX12. Tuy nhiên, có thể xem API chỉ chiếm khoảng 5% vấn đề cần giải quyết. Thành thật mà nói có khi còn ít hơn, nhưng Vulkan còn nặng nề hơn cả những gì tôi từng nghe
Nếu không muốn học C/C++, cộng đồng WebGL khá lớn, nên có thể bắt đầu từ các subreddit hoặc diễn đàn liên quan. Dù vậy, API và nền tảng gần như chỉ là lớp vỏ bao quanh phần ấn tượng và mới mẻ thực sự là mô phỏng vật lý
Nói thêm nguồn gốc: tôi là lập trình viên web/Gradle/Java, và sau một lần thử vài năm trước, giờ đang làm lại game engine trong thời gian rảnh
Nó không khó đến vậy. Trong JavaScript, hãy biểu diễn mỗi điểm bằng (x,y,z), gán khối lượng cho nó, rồi mỗi frame áp dụng trọng lực và thêm một chút nhiễu nếu cần
Mỗi khi một hạt muốn di chuyển, dùng lượng giác để truyền lực qua các cạnh sang những điểm khác, rồi thêm một chút suy giảm để tránh mất kiểm soát. Khối lượng sẽ quyết định về sau mỗi điểm bị lực tác động mạnh đến mức nào. Nếu 3D gây quá tải, hãy làm 2D trước
Gợi nhớ đến video của Polygon phân tích thiết kế vải đáng kinh ngạc trong Elden Ring: https://youtu.be/wSSqx-Dh6ko
Một điểm video chưa nhấn mạnh đủ là vải cũng có mục đích chức năng. Vải che khuất hình dạng kẻ địch, khiến khó phân biệt mô hình hơn
Trong một trò chơi lấy những pha cận chiến và hitbox chính xác—cũng có thể xem là khía cạnh sáng tạo nhất của các game FromSoft—làm cốt lõi, lớp vải bay tự do khiến người chơi khó phán đoán phải đặt nhân vật gần đến đâu để đánh trúng, hoặc phải giữ khoảng cách bao xa để không bị đánh trúng. Khi cộng thêm chuyển động và mẫu tấn công khó dự đoán, độ khó lại tăng lên và mỗi trận đấu trở nên độc nhất
Ngoài đời, vải cũng có tính chất tương tự. Một kẻ địch khoác áo choàng hay choàng áo choàng dài sẽ trông đáng sợ hơn nhiều và khó đối phó hơn
Cá nhân tôi không thích game FromSoft vì vòng lặp gameplay, nhưng về mặt thiết kế, tôi cho rằng chúng là một số video game được làm tốt nhất trong lịch sử
Tôi cũng có phiên bản của mình làm từ 14 năm trước: https://www.youtube.com/watch?v=G05M_Y6NQVM
Tôi đồng ý rằng cấu trúc cơ bản kiểu này rất đơn giản để triển khai, mà kết quả thì thật sự rất tuyệt
Cái đó là tôi làm. Phiên bản gốc tôi đăng lên CodePen là khoảng 13 năm trước
Bản thân tôi cũng không tin nổi, nhưng khi nhớ ra đó là trước cả khi tôi có công việc lập trình đầu tiên, thì đúng là cảm giác như đã rất lâu rồi
Video game Hitman năm 2000 cũng có vải, và Mirror's Edge năm 2008 có vải bị xé. Có lẽ cả hai đều không phải là đầu tiên
Những trình mô phỏng vải kiểu này luôn cho cảm giác hơi bất ổn ở mức nào đó. Khi tạo vải dạng lưới, nó bật nảy và bắt đầu chuyển động ngẫu nhiên
Tôi tự hỏi liệu có phải do sai số dấu phẩy động IEEE 754 tích lũy hay không
Nên tìm hiểu tích phân số trong bối cảnh mô phỏng vật lý hoặc game engine. Có thể bắt đầu từ https://en.wikipedia.org/wiki/Numerical_methods_for_ordinary...
Theo tôi hiểu, nguyên nhân không chỉ là sai số dấu phẩy động đơn thuần, mà còn đến từ bản chất của việc xấp xỉ một hàm liên tục bằng các bước rời rạc đơn giản. Bài Wikipedia được liên kết cũng có biểu đồ cho thấy với bước lớn, sai số đã tích lũy từ rất lâu trước khi độ chính xác dấu phẩy động trở thành vấn đề
Mỗi kỹ thuật tích phân số có những đánh đổi khác nhau. Có các phương pháp như Euler, Verlet, Runge-Kutta; một số cách có xu hướng làm tổng năng lượng tích lũy, còn cách khác lại có xu hướng làm mất năng lượng, và cả hai đều là hành vi sai. Các phương pháp phức tạp hơn thường hoạt động tốt hơn một chút, nhưng lại nảy sinh câu hỏi liệu lợi ích của việc mỗi bước phức tạp hơn có đáng hơn so với việc lặp nhiều lần một thuật toán đơn giản và nhanh hơn hay không
Trong mô phỏng vật lý, bảo toàn năng lượng không tự hoạt động theo mặc định nếu bạn không mã hóa nó một cách rõ ràng. Ví dụ, cần kiểu hiệu chỉnh trực tiếp định kỳ
Không chỉ do sai số làm tròn, mà còn do lượng tử hóa thời gian, cũng như những sai số nhỏ khác đến từ chính mô hình toán học
Nếu sai số theo hướng suy giảm, nó tạo hiệu ứng giống thực tế là năng lượng bị tiêu tán và chuyển động cuối cùng dừng lại; nếu theo hướng gia tốc, mô phỏng sẽ mất kiểm soát
Tôi muốn nói với tác giả trang này rằng họ đã làm rất tốt. Nó chạy nguyên bản không cần JavaScript bên ngoài, và hoạt động cả trên di động
Ngày nay khó mà nói được điều đó về hầu hết website dựa trên văn bản
Một tác phẩm thật sự ấn tượng. Đơn giản nhưng khiến người ta cứ muốn nhìn mãi, và cho thấy tích phân Verlet mạnh mẽ thế nào trong việc tạo ra mô phỏng vải tự nhiên và có vẻ hợp lý
Nếu quan tâm, tôi cũng khuyên đọc bài báo Jakobsen xuất phát từ game engine của Hitman. Đó là một tài liệu kinh điển
Thật hay khi thấy người ta thực sự đặt ra những câu hỏi khó về cách những thứ như thế này vận hành. Mỗi lần tôi lại có cảm giác rằng mọi thứ đều được tạo nên từ vô số bước nhỏ tích lũy qua nhiều năm
Tôi tự hỏi liệu người ta sẽ va vào điểm mà toán học giống như một bức tường, hay cứ tiếp tục gõ vào nó cho đến khi hiểu được
Điều thú vị nhất là chỉ cần thiết lập vài tham số và ràng buộc mà đã có thể tạo ra chuyển động chân thực như vậy
Tôi có cảm giác thế giới quanh ta có lẽ cũng chỉ là một tập hợp các mô hình và lực ẩn, và việc của chúng ta là khám phá rồi mô phỏng chúng. Một tác phẩm đẹp
1 bình luận
Các ý kiến trên Hacker News
Một ví dụ khác có thể xem trong trình duyệt: https://oimo.io/works/cloth/
Sau khi đọc bài của Marian Pekár, tôi đã hiểu tích phân Verlet và có thể tự làm mô phỏng vải: https://pikuma.com/blog/verlet-integration-2d-cloth-physics-...
Tôi tò mò làm sao để đi từ kiến thức về phát triển web, Gradle, Java sang giai đoạn tạo ra những thứ như thế này
Vì không học đại học ngành CS, đôi khi tôi cảm thấy dù học bao nhiêu ngôn ngữ lập trình cũng sẽ không bao giờ hiểu được những thứ này. Tôi có thử động vào OPENLY, LIBGDX, GODOT, Unity một chút, nhưng việc xây dựng mô phỏng vải từ đầu thật sự khiến tôi thấy mù mịt
Ở đây dùng tích phân Verlet cơ bản: cập nhật các vector 2D tạo thành lưới dựa trên vị trí hiện tại và vị trí trước đó, rồi ràng buộc để chúng giữ một khoảng cách nhất định với các điểm lân cận trực tiếp. Vẽ các đường giữa những điểm đó là thành vải. Tôi biết đến nó đầu tiên khi bị cuốn hút bởi mô phỏng vật lý và tìm hiểu, vì đây là một trong những thứ dễ triển khai nhất; công sức bỏ ra so với kết quả rất tốt. Tất nhiên, từ đó trở đi thì phức tạp hơn nhiều
Đặc biệt nếu bắt đầu từ phát triển game, ta dễ có cảm giác rằng mỗi loại mô phỏng chính như vật rắn, vải, lò xo, chất lưu đều sẽ có một cách lập trình tự nhiên và quen thuộc tương ứng. Ban đầu tôi từng nghĩ mô phỏng chất lưu cũng sẽ được biểu diễn tự nhiên trong ngôn ngữ bằng cách tạo lưới rồi chọn quy tắc cập nhật ở mỗi bước thời gian. Nhưng thực tế là phải mô hình hóa vấn đề bằng toán học và vật lý, rồi ánh xạ nó sang ngôn ngữ và công cụ; các công cụ đó không phải lúc nào cũng biểu đạt theo cách quen thuộc
Có những thuật toán dễ chuyển thành code, như mô phỏng vải dựa trên vị trí hạt và lò xo, nhưng khi muốn đi xa hơn, chính điều đó lại khiến tôi hiểu lầm. Cuối cùng tôi phải đào sâu hơn vào vật lý và phân tích số, rồi mới chuyển vấn đề sang code; code kết quả có thể thô và có nhiều con số ma thuật
Ngược lại, viết mô phỏng có khối lượng tính toán lớn nên phần lớn code là nội dung thực sự. Nếu phát triển web là sự kết hợp của những thứ dị chất, thì mô phỏng đồng nhất hơn. Vấn đề là bị giới hạn bởi hiệu năng của một tiến trình đơn trong ngân sách thời gian do số khung hình mỗi giây quyết định
Vì vậy bạn có thể tập trung vào một môi trường thực thi duy nhất. Tôi khuyên dùng trình duyệt, vì nó giải quyết giúp vấn đề triển khai. Ganja[1] có lẽ là dự án mô phỏng tối thượng theo kiểu “nội dung chứ không phải cấu trúc”. Nó rất đặc biệt và khó hiểu nên việc bảo trì đã dừng lại, nhưng nó vẫn chạy. Ở phía có cấu trúc hơn một chút là D3, nơi các tác giả đã xây sẵn những thuật toán trực quan hóa/bố trí hiện đại như đồ thị lực[2]. Điểm khởi đầu thân thiện hơn có thể là họ Processing[3], bắt đầu từ Java rồi được port sang Python, JavaScript, v.v.
Tuy nhiên, một mô phỏng vải đơn lẻ chỉ ở mức như một tế bào của một con chuột nếu ví với game engine. Game engine rất lớn, và trong đó bạn cũng chủ yếu làm nhiều tích hợp nội bộ hơn là tự viết mô phỏng
1 - https://github.com/enkimute/ganja.js/blob/master/ganja.js
2 - https://github.com/d3/d3-force/tree/main/src
3 - https://processing.org/
Dù bạn không hỏi đích danh về phát triển game, các kiến thức như đồ họa, toán, chiếu sáng, vật lý nói chung hiện diện rất nhiều trong lĩnh vực đó. Nếu chỉ tìm riêng một chủ đề ngách như mô phỏng vải, có thể khó tìm được thông tin không gắn với tài liệu phát triển game
Hôm nay tôi đọc https://alextardif.com/LearningGraphics.html, nó có thể là kim chỉ nam theo nhiều hướng. https://learnopengl.com/ vẫn luôn được đánh giá tốt dù hiện nay đã có các API mới hơn như Vulkan, Metal, DX12. Tuy nhiên, có thể xem API chỉ chiếm khoảng 5% vấn đề cần giải quyết. Thành thật mà nói có khi còn ít hơn, nhưng Vulkan còn nặng nề hơn cả những gì tôi từng nghe
Nếu không muốn học C/C++, cộng đồng WebGL khá lớn, nên có thể bắt đầu từ các subreddit hoặc diễn đàn liên quan. Dù vậy, API và nền tảng gần như chỉ là lớp vỏ bao quanh phần ấn tượng và mới mẻ thực sự là mô phỏng vật lý
Nói thêm nguồn gốc: tôi là lập trình viên web/Gradle/Java, và sau một lần thử vài năm trước, giờ đang làm lại game engine trong thời gian rảnh
Mỗi khi một hạt muốn di chuyển, dùng lượng giác để truyền lực qua các cạnh sang những điểm khác, rồi thêm một chút suy giảm để tránh mất kiểm soát. Khối lượng sẽ quyết định về sau mỗi điểm bị lực tác động mạnh đến mức nào. Nếu 3D gây quá tải, hãy làm 2D trước
Gợi nhớ đến video của Polygon phân tích thiết kế vải đáng kinh ngạc trong Elden Ring: https://youtu.be/wSSqx-Dh6ko
Trong một trò chơi lấy những pha cận chiến và hitbox chính xác—cũng có thể xem là khía cạnh sáng tạo nhất của các game FromSoft—làm cốt lõi, lớp vải bay tự do khiến người chơi khó phán đoán phải đặt nhân vật gần đến đâu để đánh trúng, hoặc phải giữ khoảng cách bao xa để không bị đánh trúng. Khi cộng thêm chuyển động và mẫu tấn công khó dự đoán, độ khó lại tăng lên và mỗi trận đấu trở nên độc nhất
Ngoài đời, vải cũng có tính chất tương tự. Một kẻ địch khoác áo choàng hay choàng áo choàng dài sẽ trông đáng sợ hơn nhiều và khó đối phó hơn
Cá nhân tôi không thích game FromSoft vì vòng lặp gameplay, nhưng về mặt thiết kế, tôi cho rằng chúng là một số video game được làm tốt nhất trong lịch sử
Tôi luôn thích kiểu hoạt ảnh vải này. Lần đầu tôi thấy có lẽ là demo vải bị xé trên CodePen của dissimulate, và thật khó tin là đoạn mã đó đã được viết từ 9 năm trước
[1] - https://codepen.io/dissimulate/pen/eZxEBO
[2] - https://github.com/Dissimulate/Tearable-Cloth
Tôi đồng ý rằng cấu trúc cơ bản kiểu này rất đơn giản để triển khai, mà kết quả thì thật sự rất tuyệt
Bản thân tôi cũng không tin nổi, nhưng khi nhớ ra đó là trước cả khi tôi có công việc lập trình đầu tiên, thì đúng là cảm giác như đã rất lâu rồi
Những trình mô phỏng vải kiểu này luôn cho cảm giác hơi bất ổn ở mức nào đó. Khi tạo vải dạng lưới, nó bật nảy và bắt đầu chuyển động ngẫu nhiên
Tôi tự hỏi liệu có phải do sai số dấu phẩy động IEEE 754 tích lũy hay không
Theo tôi hiểu, nguyên nhân không chỉ là sai số dấu phẩy động đơn thuần, mà còn đến từ bản chất của việc xấp xỉ một hàm liên tục bằng các bước rời rạc đơn giản. Bài Wikipedia được liên kết cũng có biểu đồ cho thấy với bước lớn, sai số đã tích lũy từ rất lâu trước khi độ chính xác dấu phẩy động trở thành vấn đề
Mỗi kỹ thuật tích phân số có những đánh đổi khác nhau. Có các phương pháp như Euler, Verlet, Runge-Kutta; một số cách có xu hướng làm tổng năng lượng tích lũy, còn cách khác lại có xu hướng làm mất năng lượng, và cả hai đều là hành vi sai. Các phương pháp phức tạp hơn thường hoạt động tốt hơn một chút, nhưng lại nảy sinh câu hỏi liệu lợi ích của việc mỗi bước phức tạp hơn có đáng hơn so với việc lặp nhiều lần một thuật toán đơn giản và nhanh hơn hay không
Không chỉ do sai số làm tròn, mà còn do lượng tử hóa thời gian, cũng như những sai số nhỏ khác đến từ chính mô hình toán học
Nếu sai số theo hướng suy giảm, nó tạo hiệu ứng giống thực tế là năng lượng bị tiêu tán và chuyển động cuối cùng dừng lại; nếu theo hướng gia tốc, mô phỏng sẽ mất kiểm soát
Tôi muốn nói với tác giả trang này rằng họ đã làm rất tốt. Nó chạy nguyên bản không cần JavaScript bên ngoài, và hoạt động cả trên di động
Ngày nay khó mà nói được điều đó về hầu hết website dựa trên văn bản
Một tác phẩm thật sự ấn tượng. Đơn giản nhưng khiến người ta cứ muốn nhìn mãi, và cho thấy tích phân Verlet mạnh mẽ thế nào trong việc tạo ra mô phỏng vải tự nhiên và có vẻ hợp lý
Nếu quan tâm, tôi cũng khuyên đọc bài báo Jakobsen xuất phát từ game engine của Hitman. Đó là một tài liệu kinh điển
Thật hay khi thấy người ta thực sự đặt ra những câu hỏi khó về cách những thứ như thế này vận hành. Mỗi lần tôi lại có cảm giác rằng mọi thứ đều được tạo nên từ vô số bước nhỏ tích lũy qua nhiều năm
Tôi tự hỏi liệu người ta sẽ va vào điểm mà toán học giống như một bức tường, hay cứ tiếp tục gõ vào nó cho đến khi hiểu được
Điều thú vị nhất là chỉ cần thiết lập vài tham số và ràng buộc mà đã có thể tạo ra chuyển động chân thực như vậy
Tôi có cảm giác thế giới quanh ta có lẽ cũng chỉ là một tập hợp các mô hình và lực ẩn, và việc của chúng ta là khám phá rồi mô phỏng chúng. Một tác phẩm đẹp