Làm thế nào để người ta tránh được hiệu ứng cầu thang trên sàn gỗ trong chuyển động nghệ thuật pixel?


21

Tôi đang kết xuất các họa tiết ở tọa độ pixel chính xác để tránh hiệu ứng làm mờ do khử răng cưa (các họa tiết là pixel-art và sẽ trông rất tệ nếu được lọc). Tuy nhiên, do chuyển động của các vật thể liên quan đến vận tốc, trọng lực và tương tác vật lý thay đổi, quỹ đạo được tính toán với độ chính xác subpixel.

Ở tốc độ không gian màn hình đủ lớn (vt lớn hơn 2 hoặc 3 pixel), điều này hoạt động rất tốt. Tuy nhiên, khi vận tốc nhỏ, hiệu ứng cầu thang đáng chú ý có thể xuất hiện, đặc biệt là dọc theo các đường chéo. Đây không còn là vấn đề ở tốc độ không gian màn hình rất chậm (v << 1 pixel mỗi giây) vì vậy tôi chỉ tìm kiếm một giải pháp cho các giá trị vận tốc trung gian.

Bên trái là quỹ đạo được vẽ cho một vận tốc lớn, thu được bằng cách làm tròn đơn giản các tọa độ đối tượng. Ở giữa, bạn có thể thấy những gì xảy ra khi vận tốc trở nên nhỏ hơn và hiệu ứng cầu thang mà tôi đang nói đến. Ở bên phải, quỹ đạo của quỹ đạo tôi muốn lấy.

tọa độ pixel cho quỹ đạo đối tượng

Tôi quan tâm đến các ý tưởng thuật toán để lọc quỹ đạo để giảm thiểu răng cưa, trong khi vẫn giữ hành vi ban đầu ở vận tốc lớn và nhỏ. Tôi có quyền truy cập vào, t, vị trí và vận tốc tức thời, cũng như số lượng giá trị trước đó tùy ý, nhưng vì nó là mô phỏng thời gian thực, tôi không biết về các giá trị trong tương lai (mặc dù nếu cần, một ước tính có thể được ngoại suy theo các giả định nhất định) . Lưu ý rằng do mô phỏng vật lý, thay đổi hướng đột ngột cũng có thể xảy ra.

Câu trả lời:


18

Đây là một phác thảo nhanh, trên đỉnh đầu của tôi, về một thuật toán phải hoạt động tốt.

  1. Đầu tiên, tính toán hướng di chuyển của đối tượng và kiểm tra xem nó gần hơn theo chiều ngang hay dọc.
  2. Nếu hướng gần với chiều dọc (chiều ngang) hơn, hãy điều chỉnh vị trí của đối tượng dọc theo vectơ chỉ hướng đến tâm của hàng pixel (cột) gần nhất.
  3. Làm tròn vị trí đến tâm của pixel gần nhất.

Trong mã giả:

if ( abs(velocity.x) > abs(velocity.y) ) {
    x = round(position.x);
    y = round(position.y + (x - position.x) * velocity.y / velocity.x);
} else {
    y = round(position.y);
    x = round(position.x + (y - position.y) * velocity.x / velocity.y);
}

Chỉnh sửa: Yep, đã thử nghiệm, hoạt động khá độc đáo.


+1, điều này hoạt động tốt đáng ngạc nhiên! Tôi nhận thấy những cú nhảy ngược kỳ lạ với chuyển động tròn với vận tốc chậm, bởi vì việc điều chỉnh có thể được thực hiện theo hướng ngược lại với vectơ vận tốc (thường là OK, nhưng không phải với độ cong quỹ đạo nhỏ). Điều đó có thể được giải quyết bằng cách nhân velocity.y / velocity.xvới hệ số hiệu chỉnh tỷ lệ với vận tốc.
sam hocevar

@Sam: Ý bạn là bán kính quay nhỏ (= độ cong cao), phải không? Điều đó thực sự có thể gây ra vấn đề với phép ngoại suy tuyến tính ở vận tốc thấp. (Về cơ bản, nó hoạt động miễn là bình phương vận tốc trên mỗi gia tốc lớn hơn 1 pixel.) Một giải pháp có thể (klugey) có thể là nhớ vị trí được làm tròn cuối cùng và sử dụng lại nếu nó ở gần vị trí thực hơn so với vị trí mới được tính toán. (Người ta cũng có thể thử ngoại suy bậc cao hơn, nhưng các công thức trở nên khá xấu xí.)
Ilmari Karonen

Thật vậy, tôi có nghĩa là bán kính nhỏ. Lỗi của tôi. Và cảm ơn cho các gợi ý bổ sung; hiệu suất không quan trọng ở đó, vì vậy tôi có thể đủ khả năng để cải thiện chất lượng.
sam hocevar

3

Không có nhiều thứ bạn thực sự có thể làm về điều đó cho một thế giới dựa trên vật lý nói chung. Nếu tất cả các đối tượng của bạn đang di chuyển dọc theo đường hoặc các vòng tròn cụ thể, bạn có thể làm gì đó. Nhưng bạn đang hoạt động theo vật lý thực tế. Đối tượng là nơi vật lý đặt nó; bạn chỉ đơn giản là vẽ một xấp xỉ dựa trên pixel của vị trí đó.

Nói chung, đó là điều bạn phải chấp nhận nếu bạn muốn gắn bó với tọa độ pixel. Không nên quá chú ý trừ khi bạn hiển thị ở độ phân giải cực kỳ nhỏ (dưới 640x480, mặc dù điều này phụ thuộc vào độ phân giải và kích thước gốc của màn hình).


Ngay cả ở độ phân giải cao, kết xuất được nâng cấp (hàng xóm gần nhất) để tăng cường diện mạo oldschool. Đây là một quyết định định hướng nghệ thuật.
sam hocevar

@SamHocevar: Nếu bạn muốn có "diện mạo trường học cũ", tại sao bạn không muốn có một "diện mạo trường học" đầy đủ ? Tại sao bước đi cầu thang, mà bất kỳ trò chơi "oldschool" nào sẽ có, không phải là một phần của hiệu ứng tổng thể mà bạn muốn đạt được?
Nicol Bolas

Tôi không nghĩ rằng bất kỳ trò chơi oldschool đàng hoàng nào cũng sẽ thực hiện một chuyển động chéo có hiệu ứng cầu thang đó, bởi vì nó sẽ trông giống như tào lao. Không giống như tào lao là một phần chính của hiệu ứng oldschool tôi muốn đạt được :-)
sam hocevar

@SamHocevar: Hầu hết các trò chơi ở trường học cũ là trò chơi hành động, và do đó, đừng di chuyển đủ chậm để chú ý. Họ cũng có xu hướng không di chuyển dọc theo các đường cong. Trò chơi đặc biệt mà tôi đã nghĩ đến là Solar Jetman, rất có hiệu ứng này khi di chuyển chậm. Cấp, máy ảnh luôn luôn tập trung vào bạn, vì vậy bạn nhận thấy nó trong phong trào thế giới, nhưng nó rất nhiều ở đó.
Nicol Bolas

3

Khi chuyển động chờ xử lý vuông góc với chuyển động cuối cùng (trong không gian màn hình), bỏ qua nó và sử dụng tọa độ màn hình cuối cùng. Nếu điều đó dẫn đến việc nói lắp không tốt như cầu thang, bạn có thể thử di chuyển tổng số chuyển động đang chờ xử lý và cuối cùng.

Tôi nghĩ vấn đề nằm ở v <sqrt (2). v> sqrt (2) phải luôn luôn di chuyển ít nhất một đường chéo đầy đủ, tránh hiệu ứng cầu thang. Có thể hữu ích cho việc cắt tỉa cần so sánh chuyển động trước.


+1 để chỉ ra giới hạn trên cho đề xuất của Ilmari chi tiết hơn nhưng bạn đang cung cấp thông tin hữu ích.
sam hocevar
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.